Calculate Average data
Nauketec
Posts: 51
Trying to average 4 sonar ping into a single value within a loop condition.
The first ping output is I2cData, how do I get an average count within 4 loops
· ' SRF10 Ranger
· I2cAddr = $e0
· I2cReg = 0
· I2cData = 80····· ' Ranging command - 80 for inches, 81 for cm, 82 for uS
· GOSUB· I2cByteWrite
· PAUSE· 70····· ' wait for ranging to complete
· I2cReg = 1······· ' address of light sensor register
· GOSUB· I2cByteRead
· I2cReg = 2········· ' address of first ranging result
· GOSUB· I2cWordRead
· DEBUG· 2,0,1, "Range ", DEC4 I2cData," Inches "
thanks a lot
Daniel
·
The first ping output is I2cData, how do I get an average count within 4 loops
· ' SRF10 Ranger
· I2cAddr = $e0
· I2cReg = 0
· I2cData = 80····· ' Ranging command - 80 for inches, 81 for cm, 82 for uS
· GOSUB· I2cByteWrite
· PAUSE· 70····· ' wait for ranging to complete
· I2cReg = 1······· ' address of light sensor register
· GOSUB· I2cByteRead
· I2cReg = 2········· ' address of first ranging result
· GOSUB· I2cWordRead
· DEBUG· 2,0,1, "Range ", DEC4 I2cData," Inches "
thanks a lot
Daniel
·
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- Stephen
In any case, in your PM you also showed a snippet of a simple state machine... you may find that averaging out your reading is not relevant depending on your state machine. If your sonar shows <= 2 meters 10x in a row, and that kicks you to the "interact" state, it may not matter what the average is, because your state machine will wait for things to be steady.
E.g.
The attached has some different sampling routines and comments about range times, if you want to average your readings.
(Aside -- something I've tested by tokenizing to the nth byte more than once -- if you are using BS2p40s as you mentioned here: http://forums.parallax.com/showthread.php?p=744688 than I2CIN and I2COUT are the *only* high level communication commands where I say *don't* wrap them in a subroutine. For reasons I can bore you with, I2CIN and I2COUT appear to be so cosmically compact in the interpreter that as long as you make your device, register and command values constants, you don't need subs. Others may say it's "dirty", but one of the advantages of an interpreted language is taking advantage of really sweet tokens. So I'm doing that in the attached example.)
DO
Post your material!
LOOP
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
In any case here's some comments and a revision of the "slave" program (this looks like a cool project btw).
On the LED slave program I DEFINED YOUR PINS and redid the part at the beginning (for clarity). Presuming the light show modes work. I can't encourage you enough to define your pins and use constants -- it makes a program much easier to read.
On the "main" program, you have it defined as bs2p but it looked like you used the "bit-banged" I2C routines available for the BS2 which does NOT have I2C built in? If there is not a really good reason, use I2CIN and I2COUT. See the stamp manual. Very very powerful and you can format incoming data on the fly, etc. See my example above.
I leave it to you to fold in the I2C and SRF10 reading snippet I attached above into your main program and test your sensors.
Then, please go through your main program and assign PIN names using the PIN definition. For example, at the beginning you have HIGH 6. If this read HIGH led, or HIGH chipSelect or whatever, it makes it easier for others who are looking at it, plus if you move pins around (for any reason, like say, a malfunction on opening night), you just have to change the ONE reference to the pin and know that the rest of your code should work as it always has.
Then come back with the next working (or semi-working ) version of the program and we'll take the next steps.
Remember I only edited the slave program, not the master program. I only attach it here so everything is one thread.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
By the way,·I am working from a circuit board that was already printed. So I cant just re-wire a pin.· I designed it a few months ago before I learned all these little tips on programming that should have been incorporated into the board design.· I learned a lot and will know better next time.· But this board is 10" by 11" to facilitate the 220 leds on it so I can't just make another and another and ....· but I have made some changes to it.· I did allow for some extra holes just for the unexpected changes.
thanks Daniel
Ahhh... you can always solder a jumper (wire) from point to point if desperation strikes
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
If you still want to use the bit-banged routine, the concept is the same, add each read to a variable then divide by the number of readings.
I do think that the state machine may serve you better as it will filter out noise (2 bad readings on an average could pull it down, even though it's false).
Also, I'll go check out the SRF10 documentation. Something doesn't seem quite right.
Last but not least, what kind of max range are you looking for? Regardless of stated distance capability, my experience with 40khz sonar units has been that you can get decent readings to say 2 or 3 meters then you may not be able to depend on them so well and they become much more subject to interference as the sound wave attenuates.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
One thing, I *do* think you should not use such a straight parsing of the ranges, e.g.
You need hysteresis here -- dampening -- the state machine example I posted would serve better -- then I do think you could bail on averaging samples.
Now, you've got SDA and SCL on 4 and 5 with all your bit banged routines. Can you, and do you want to, move SDA and SCL from 4 and 5 to 8/9 or 0/1 on either bank? It looks like not all of auxio is used?
'X8 NOT USED ' make this SDA
'X9 NOT USED ' make this SCL
I can't encourage you enough to do this and use the builtin i2c commands -- it will cut huge amounts of code and var space out of your program and eliminate *possible* sources of errors and problems. So if you have a ranging problem, you'll know it's the ranging, or how you are handling the ranging, but not i2c communication itself.
OK, onward -- you have a lot of cases in the program like this:
I thought that your master out was a subset of pins 0-3? OUTA is 0-3, OUTB is 4-7, etc. But you said this portion is working currently? -- wait -- I see, those are in/out with sound effects... regardless, if you are trying to put data 6, 7, 8 above that will not work.
The shift and such method will not work if you are wired like above because everything is grouped by "fours" -- pins 0-3, 4-7, 8-11, 12-15, etc. Pins 6 and 7 are the two highest bits of OUTB and pin8 is the lowest bit of bit OUTC.
If this is how it's wired than you would need to mask then add your mode to OUTS which is a word representing all 16 bits of the current i/o bank.
Presuming defs at bottom are current. See a few comments. Name definitions would really help. I see now why you are going through some of the acrobatics on reading/writing i/o -- the groups aren't necessarily aligned in chunks of 4 (which helps if you want to use OUTA/INA/DIRA and such). So since you prob. don't want to rewire anything if not necessary , I would shift to working on the entire words for OUTS/INS/DIRS because you can set whatever pins you want... but in a subroutine, e.g.
But this comes back to using ALIASES/VARIABLES and SUBROUTINES, like the send_mode example. That way you are cutting a possible source of error to *one* place, you can change how you handle it if you need to.
Here's a possible sub...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
Post Edited (Zoot) : 8/24/2008 4:22:37 AM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
I am a bit overwhelmed with all of it - it may take a moment for it to sink in.
I may need you to help me cut and paste some of it.· as far as the changing of the sonar pins should we do that first or try some of the other code first and do it later.· It is only 2 pins and I left spare holes on all the unused pins ·to make easy changes or add pull up or pull down resistors.· so let me know.
- get your sonar unit working properly, via i2c, without reading non-existent light sensor, and setting up range and analogue gain so you get the best results. Personally, I would write a small program that does JUST that without any extras. I also *would* move your I2C bus to aux 8/9. It's not much to wire and only two resistors. This will eliminate a slew of code, possible problems, and free up lots of variable space because you know that the problem will not be your·bit-banged ·i2c code. For a test program you'd really only need one variable --·a place to the hold range...e.g.
I2COUT, $E0, 0, [noparse][[/noparse] 80 ]
I2CIN, $E0, 2, [noparse][[/noparse] range.HIGHBYTE, range.LOWBYTE ]
DEBUG DEC5 range
If you have a breadboard, I would pop the BS2p40 from it's socket on your custom board, and just try it out on your bench -- the ranger, the stamp, and two pullups for SDA and SCL is all you need. [noparse][[/noparse]b]Read the documentation on the ranger[noparse][[/noparse]/b] regarding setting range and gain. Only you can experiment here to see what gives you the best sonar readings.
- go through your program and assign names to pins, etc. and use them. This is pretty much a tedious find/replace task, but it will make the code much easier to read (for you and others). Even if it doesn't work the way want, it'll be a good framework to start from. At that point I'm also more than happy to adjust code from my end.
- then we can start putting the pieces into back into place.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
For example, make sure that a sub like "writeMode" indeed puts the numbers you want on pins1-3 -- in it's own program -- then you know if you use that sub in your main progam you can use it like a "black box" and your primary chore in the main program will just be putting the pieces together and testing the logic and flow of the decision-making, rather than worrying if your logic is good AND if you're writing the right number to the pins AND if your ranging is working, etc.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
I am here and ready to knock this stuff out.· it is working but if you think it would make this project a lot easier to shift some pins I am ready to cut and move.· Moving the sonar to AUX pins is no problem.· While I am in there I could also change the P1 -P3 over to P0 - P2 like the other board and that would cut out some code to make it cleaner.· What do you think?
1. I'm a big fan of things that work. "It" is the sonar? The entire project? If it works, then why redo anything Confused.
2. Regardless, since you have a board I wouldn't move or cut anything unless absolutely necessary. There's no reason not to use the few lines of code for "translating" your slave/master 3 bit number from whatever the pin setups are. The only place where I had a real question was using all the bitbanged code for I2C when those functions are built-in to the BS2p40 -- and the only thing *preventing* you from using those is that the I2C bus must be on p0/p1 or p8/p9. And I still wouldn't cut or solder till you try out the ranger with the built in I2C and the Stamp without all the other stuff. And again, if it works....
3. If you did need to wire in a fresh SDA/SCL, I'm not sure you need to cut traces -- if you have access to the pins, then you can make a little "dongle" with +5v, gnd, SDA/SCL wires going to wherever they need to go on one side, and a plug/connector/header whatever on the other for the sonar -- maybe not as neat as using a header on the board, but then you don't have to modify anything with a knife. But see point #2.
4. it still sounds like the biggest challenge is getting not necessarily clean, but *useful* info from the ranger and using in the main part of your program. My reading of the documentation is that the default settings on the SRF10 are quite high -- setting down the range a bit and adjusting the gain for optimal performance will prob. be well worth the time playing with it on the bench. 11 meters seems awfully long for a 40khz sonar. I would try cutting it back to 3 meters or so, then notch it *up* a meter at a time and see where reliability starts to fall off.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
I made the layout with plenty of spare holes for last minute fixes, so not to worry. I have already moved the 3 bits to line up on P0 - P0
P1 - P1 and P2 - P2.
I thought you said I could AUXIO pins for sonar if so I can easily move them two please let me know.
Now that the MAINIO pins line up any idea for cleaner OUTA = 0 to OUTA = 7 code? or is that it?
Daniel
I saw in your 7 cases thread you moved your pins. Did you do that on the slave side also? In other words, post your current program with the current pin definitions
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
I just finished moving the main micro pins to line up pin for pin with the led micro so now I need to send the 7 cases out P0, P1, P2 to be recieved by the led micro P0, P1, P2 So now I am hope this put this "bit" to rest and I can just use OUTA and INA. On the main micro P3 is tied high through a 4.7k resistor. On the LED micro I am using P3 for my led matrix and it needs to stay an output.
daniel
I have the board working to a degree - - -
It is performing what it should do but . . .
The sonar could still use a simple averaging of the ping data.
The name of the ping data is i2cdata
What I am looking for is something that would read 5 (or whatever) pings store them so that
the 5 pings could be divided by 5 and that number lets call it AvgData·
Daniel
·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
Here is the current working main micro program.· Most of the OUTA comands are working but some are curiously going to mode7 ? ( the ones that are comented out)
What is working is:
What can be refined is:
Let me know what you think or just paste it in where you think it needs tweeking· I am understanding much more each time I have something to look at and compare to the manual.
Daniel
Post Edited (Nauketec) : 8/25/2008 5:25:18 AM GMT
You have not wrapped your mode function to a subroutine (e.g. writeMode) so it's really hard to tell where your error is coming from; will look at it again tonight.
I also used conditional definitions to turn off your debug statements (read the manual); your debug statements *will* take a lot of time in your main loop and should all be turned off when you are not using them.
See my comments within the code.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
The OUTA is a mystery!· All OUTA numbers are working except for OUTA = 1· this returns 1111
When I try OUTA = %0001 I also get 1111 (Remember that I have pull ups on P0 P1 P2 P3)
I am still working on that one but for now my next task is to take off the bench to hang it up in a larger room and test the sonar distances
Daniel
OUTA = %1111
will put HIGHs on pins 0-3 BUT ONLY IF THOSE PINS ARE OUTPUTS. Nowhere in your program do I see where you've defined your pins nor where you have set these pins to be outputs.
you can do either of the following (make sure this appears below a bank statement MAINIO/AUXIO so that you are affecting the correct i/o side of the bs2p40:
Or if you have named pins
Then when you change the value of OUTA whatever value you see there is what you'll get on the pins themselves to the outside world.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
Yeah I had a DIRS comand all the way in the head of the program but it must of got comented out and I fogot to bring it back
I have it on the wall now and got it to work up to 4 feet for it is now hitting walls and ceilings but it does work. The averaging would help. I will now try OUTA = 1 and see if that works
Daniel
I am reading all your notes and I think the sonar is the next big task when that is done the worst is over.· Let me know your thoughts
OK, I'm checking out your code and will post some snippets for you in a bit (need to check out SRF10).
One thing, I *do* think you should not use such a straight parsing of the ranges, e.g.
··· IF· i2cdata > Max_range THEN
····· GOTO mode1 'Breathing
··· ELSEIF ((i2cdata =< Max_range) AND( i2cdata >= Opt_Range)) THEN
····· GOTO mode2· 'wake up
·· ELSEIF ((i2cdata < Opt_Range) AND ( i2cdata >=Min_Range))THEN
····· GOTO mode3 'opt range
··· ELSEIF i2cdata < Min_Range THEN
···· GOTO mode6·· 'too close
··· ELSE
····· GOTO mode0
··· ENDIF
You need hysteresis here -- dampening -- the state machine example I posted would serve better -- then I do think you could bail on averaging samples.
Now, you've got SDA and SCL on 4 and 5 with all your bit banged routines. Can you, and do you want to, move SDA and SCL from 4 and 5 to 8/9 or 0/1 on either bank? It looks like not all of auxio is used?
'X8 NOT USED ' make this SDA
'X9 NOT USED ' make this SCL
I can't encourage you enough to do this and use the builtin i2c commands -- it will cut huge amounts of code and var space out of your program and eliminate *possible* sources of errors and problems. So if you have a ranging problem, you'll know it's the ranging, or how you are handling the ranging, but not i2c communication itself.
Post Edited (Nauketec) : 8/27/2008 3:57:26 AM GMT
The sonar seems to OK. Could you let me know how great the savings are to shift it to AUX pins 8,9?
I think if I could just build in a 3-4 inch "deadband" in each of the ((i2cdata =< Max_range) AND( i2cdata >= Opt_Range)) THEN statements it whould stop any bounce in the data. I will work on other areas and wait to hear your thoughts.
Daniel
For "dampening" you could do a simple check to see if the range is +/- a given amount, or do a counter like I suggested.
The state machine is a like a big "if/then" that keeps repeating and only goes to the next "then" if a certain count has been reached -- like the range has to be below the threshold 4x in a row or 8x in a row (or whatever gives you good results).
But I'm curious -- your most recent posted version doesn't have the bad INA statement removed (like in my edit) or the averaging code. It also doesn't have the conditional defs for removing all the debugs (this is slowing your sample time wayyyyyyyyyyy down). ?? The v.7 I posted was your exact version from earlier today with small edits (for sonar averaging) and I tokenized it in the Stamp IDE to make sure it was clean.
In any case, I dropped the following snipped into your most recent project and tokenized it.
e.g.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
Then check out the sonar averaging code I posted and either use it or adapt it -- it's not complicated -- a for/next loop goes through your maxrange portion of code and runs it 4 times -- each times it adds the result of the ranging (i2cdata) to another Word variable (sonarrange). After it's done that 4 times, it divides the final total (sonarrange) by 4. See FOR/NEXT in the Pbasic manual.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php