please help with Speed Detector
djh82uk
Posts: 193
Hiya Guys
Sometime last year I wrote some code for a picaxe chip to detect model train speed and output it to an LCD Screen
I want to improve it to use the TV Out, and run 4 detectors at the same time.
I want to use photodiodes, 1 to xmit and 1 to receive (x2). What sort of interfacing circuit will I need?
I am still struggling with the transistion to spin (wish there was a basic compiler [noparse]:([/noparse] ), I am trying to figure out how to do certain maths, but I think that just needs another good read of the manual.
If it's ok with you guys, I would like to try and start the code in steps, post it up and see where you think it is falling over, that way I can learn it a bit better I think.
But some info on the photodiodes would be good
Heres my maths so far, this is based on the distance between the sensors being 10cm, and the model scale is 1.76
Distance travelled in miles = 0.1/1609
(1 mile = 1609m)
Time to travel this distance in hours = P / (60 * 60 * 1000) where P is the time
So speed in mph = Dist / Time = (0.1 * 60 * 60 * 1000) / (1609 * P)
Therefore Speed = 223/P
Therefor Scale Speed = 223 * 76 = 17004 / P
so say it took 2.5 seconds to cross that 10cm it should show a speed of 68 MPH? Sorry my maths is not very good...
Thanks
DJH
Sometime last year I wrote some code for a picaxe chip to detect model train speed and output it to an LCD Screen
I want to improve it to use the TV Out, and run 4 detectors at the same time.
I want to use photodiodes, 1 to xmit and 1 to receive (x2). What sort of interfacing circuit will I need?
I am still struggling with the transistion to spin (wish there was a basic compiler [noparse]:([/noparse] ), I am trying to figure out how to do certain maths, but I think that just needs another good read of the manual.
If it's ok with you guys, I would like to try and start the code in steps, post it up and see where you think it is falling over, that way I can learn it a bit better I think.
But some info on the photodiodes would be good
Heres my maths so far, this is based on the distance between the sensors being 10cm, and the model scale is 1.76
Distance travelled in miles = 0.1/1609
(1 mile = 1609m)
Time to travel this distance in hours = P / (60 * 60 * 1000) where P is the time
So speed in mph = Dist / Time = (0.1 * 60 * 60 * 1000) / (1609 * P)
Therefore Speed = 223/P
Therefor Scale Speed = 223 * 76 = 17004 / P
so say it took 2.5 seconds to cross that 10cm it should show a speed of 68 MPH? Sorry my maths is not very good...
Thanks
DJH
Comments
distvar = 17004
speedvar = (result of count between both sensors being triggered)
FS.finalspeed(F.FDIV (distvar, speedvar))
or would it be better to do:
finalspeed = (distvar / speedvar)
Im gussing the floating point way is overkill?
my next step (if the above is ok?) is to figure out how to sense for the any of the sensors to be triggered then start some sort of counter until the 2nd sensor is triggered, then convert that to (I think) milliseconds, that would then be passed to the variable speedvar. I want it to be bi-directional, so I guess something along the lines of:
Wait until pin 1 or pin 2 = high
start counting
If pin1 was high then startpin=1 and endpin=2
Else
startpin=2 and endpin=1
wait until endpin = high
stop counting
convert count result to MS
then do maths
then display on TV
im still reading the manual, but if anyone has any help please post
Thanks
DJH
It's prob a real bad way of doing it, but I would like your thoughs
The INA will not let me display the pin number in square brackets, just so you don't think I missed them out.
pin 1 = one sensor
pin 2 = other sensor
Post Edited (djh82uk) : 6/19/2007 1:15:17 AM GMT
In the PICAXE application you designed and wrote, what circuit did you use to detect train speed? Did you use photo diodes or something else? The same circuit should work, but it will need to be adjusted slightly for the 3.3 volt device. Can you post the circuit for us to see? I believe a Google search or various beginner electronic books have similar circuits for triggering a crossing gate.
The Propeller can easily handle what you want to do. If you wanted, you could have a whole layout of detectors and report the data on the TV. Hang in there and keep asking questions. Don't be afraid to try things out, it is great that you want to learn Spin and the Propeller.
I think the floating point may be overkill, but I have not done anything like your application before to speak from experience. For now, focus on the basic algorithm and then upgrade it if you need to. Your math makes sense to me. I wrote it out in a form I better understand and I agree with what you are doing.
Though they seem complicated, I would recommend you go through the tutorial and application notes about the counters. I believe this may be a good option for you to consider in your algorithm. Another command to research is the waitpeq or waitpne. These will be the commands to use in the "wait until" in your pseudo code in the previous post.
I hope this gets you started in the right direction.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter
tdswieter.com
One little spark is all it takes for an idea to explode
Thanks for the input, with regards the picaxe, I was using reed switches but was very difficult to get them to always trigger, hence this new and improved version with better sensors (hopefully), TV output of speed etc. I figured I would try and convert some of my older projects before moving onto new ones, that way I hope to learn some of the differences. for instance the pic axe version would also write the max speed via i2c to be read later on, I know it can be done with prop, it's just figuring out how, but on step at a time I guess..
If someone could look at the below code, it does not support bi-directional travel yet, nor does it show the speed in decimal places (maybe use MSb and LSb???)
it's not giving any erros in the IDE now, but would like ppl's thoughts, I cannot test it as I do not have the sensors here, or the resisitors for tv output (on order)
DJH
The code you posted above is good in that there are no syntax errors, which are what the IDE tells you. Maybe you know this but you need to setup the direction of the IO pins (are they inputs or outputs?). Also, the way the code reads right now it will check sensor1 once and then move on. There needs to be some repeats or waitpeq in there to keep checking sensor1 until it achieves the desired state. Otherwise your code will just fall through and the cog will execute all of your code and then shut down only checking the pin once. Perhaps you know all of this and I am jumping the gun. Let me know if I need to explain it further.
How are you prototyping with the Propeller? Are you using the PropStick or a homemade board? If you want to test your code without the actual sensors, you could write a simple object to run in another cog. This new object would simulate the triggers and would have two output pins. You can attach those two output pins to the two input pins listed in your code above. The new object would be configurable so you can test different lengths of time (different speeds) from which one input turns on and then the other. Maybe later tonight I can code a simple object up and post it to help you out. I have a couple other things I need to finish first. Being able to test like this without drastic changes to the core code is one great feature of the Propeller.
Another thought, the code and the sensor setup will have to account for blinking or false reading that may be produced by your various rail cars going by. A debounce of the inputs may be needed. Maybe not depending on the physical setup of the sensor.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter
tdswieter.com
One little spark is all it takes for an idea to explode
I was intending on using a transmitter and receiver (at each sensor point), they would stick through a hole below the track, and would have heatshrink over them leaving just a hole at the top, if that makes sense, this is how other model railway items I have seen do it.
All I have here is a prop plug and protoboard (parallax one)
Both the pins would be inputs (I thought they were by default?) Something I will read up on.
I thought that would be the case with my code, I will try and read up on waitpeq and repeat, im just still struggling to see how to implement it.
Thanks for all your help timothym i'll get there in the end. [noparse]:)[/noparse]
Can you post the code you used in the PICAXE? If you can, then we can work through it block by block to see if we can port it over to Spin.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter
tdswieter.com
One little spark is all it takes for an idea to explode
As you can see, I am used to much simpler programming (tho able to do a lot less as a result)
Thank you for posting your PICAXE code.· I see how you are trying to convert it to Spin.· Here is some psuedo code that may help you, it is close to what you want to do.· This is just off the top of my head for one receiver, there may be ways it needs to be modified to run four.
As you get into Spin you should hopefully find·it as·easy·to use·as BASIC.· Spin can be powerful, but it also easy to use as a beginner.· Keep working at it.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter
tdswieter.com
One little spark is all it takes for an idea to explode
thanks for taking the time to make that object, once I get the resistors and rca jacks I can start playing with it.
I can see how your pseudo code works (which is a good start for me)
once I get chance I will try to convert mine to have the elements you put in the psuedo code [noparse]:)[/noparse]
Thanks Again
DJH
I have tried it with a delay instead of the waiting for input part, then also ran the results on some online speed calculator. And the speeds match up.
I know I have not used the waitpeq, I wanted to try to get it working, then make it better later.
I have a few questions tho, how can I make a piece of text red in colour?? Also how can I get the speed in decimal places?
Heres the code so far. (far from perfect)
Post Edited (djh82uk) : 6/22/2007 12:14:36 AM GMT
Would the pincheckend section work? As in would it loop back to the counter?
DJH
Post Edited (djh82uk) : 6/22/2007 12:16:18 AM GMT
it seems to think that the pins are always high (not connected to anything on protoboard). If I say "if low" then it stops and waits, but if I ground the pin nothing happens, i tried the belwo test code, do the pins need to be pulled high or pulled low? if so what value resistor? If check the voltage between any pin and VSS (Gnd) then I get a voltage between 0.2 and 0.3, isn't that enough to trigger a logical 1?
Im confused, if I pull the pins high then it will have no effect as it will take the path of least resistance??. If i pull it low it will have no effect because, even if I fully ground the pin then it still does not seem to register a logical low????
Post Edited (djh82uk) : 6/22/2007 12:57:10 AM GMT
Also in timothy's waitpeq example, how do I convert cnt into seconds?
I presume it has soemthing to do with clkfreq?
DJH
waitcnt(clkfreq + cnt)
for a 1-second delay, not counting the setup time the interpreter takes to "execute" the instruction.
Likewise
waitcnt(clkfreq / 100 + cnt)
yields a 0.01 second delay, plus the setup.
(Someone else could calculate the setup for you, but it is quite a small number so for what i've used it for, i just don't care).
So, in pseudocode:
(newcnt - oldcnt) / clockfrequency
should give you number of seconds, but if you want to use integer division you should think about scaling first. Another·pseudocode example:
(newcnt - oldcnt) * 100 / clockfrequency
should give you a number to approx 0.01 sec.
Hope this helps
·
Post Edited (codemonkey) : 6/22/2007 6:42:21 PM GMT
I have it outputting 3 seconds in the form of 3000ms for the best accuracy.
Now my next problem is decimal places for the final mph, with picaxe basic I simply used the MSB and LSB, how can I do it here?
I am going to try this
speed100 = speed * 100
Whole = Speed100 / 100
Remainder = Speed100 // 100
Where // means Mod, ie the remainder.
Thanks for the help
DJH
Next is tidying up code and try to get 4 speedcheck to run at the same time on different cogs
DJH
I see the problem in your code. First I assume that when you pasted the code, the tab format was lost - correct? Tab indenting is crucial in Spin, so anything under a repeat statement that you want repeated needs to be indented. The problem that I see is that "If pincheckstart := low" should be "IF pincheckstart == low". The "==" is used to return a true or false result. This should help to get your code working.
The waitpeq code though should be better because it puts the cog into a lower power down mode while it waits, though this may not be the best solution to get four running. If you want four, you could write a cogs to do one and then use four cogs, but them seems like a waste of processing power.
Glad to see your project coming along.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter
tdswieter.com
One little spark is all it takes for an idea to explode
Thanks for your help, I see what you mean about the pincheck statements, it's working very nice with waitpeq, but I cannot figure out the best way to do 4 seperate sensors, I was thinking I could use the same pub, pri sections and just pass it different variables for the pins?
Perhaps if the pins were not defined in con and just defined when each cog starts up?
I agree about the waste of processing power, but this board wont really be doing anything else, the only other feature I want to add after that is a max speed store in the eeprom.
Alternately you could try and get fancy having waitpeq watch all four pins (or eight if you still wanted it to be bidirectional) When a pin changed, record the start cnt and what direction. Then go back and waitpeq. When another pin changes record the start cnt and what direction. If there was a mating pair, calculate the speed, then go back and waitpeq again.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter
tdswieter.com
One little spark is all it takes for an idea to explode
I developed a product commercially like what you are describing using a PIC. It uses isolated sections·of track that get shorted by the locomotive's steel wheels to act as the sensors. It can be programmed for miles/hr or Kph in HO or N scale..... about 8 pages of assembler with the math, progammability,·and all.
Next production run will be an SX28.
It's called a Speed Tach 100, and you can see it (and buy it) at http://members.shaw.ca/dispatcher/misc.html
Cheers,
Peter (pjv)
..WatchPinsState := InA & WatchPinsMask 'see what it looks like right now.
..Repeat
....waitpne(WatchPinsState, WatchPinsMask, 0) 'Wait any pin change
....NewWatchPinsState := InA & WatchPinsMask 'see what it looks like right NOW
....<check which pin (could be multiple) changed and process it>
....WatchPinsState := NewWatchPinsState 're-load for another round
i used leading ... for alignment, forgot leading spaces get eaten. Someday i'll figure out how to avoid that.
Neither have I figured out how to check which pin was triggered...
DJH
WatchPinsState := InA & WatchPinsMask
then vamp with something like:
waitpne(WatchPinsState, WatchPinsMask, 0)
it will procede when InA is not equal to WatchPinsState (of course looking only at the pins specified by WatchPinsMask). In other words, as soon as anything changes, even a single pin, it will execute the next line of code. This is effectively the OR condition. I am currently using it to process 4 pushbuttons with debouncing on a single cog. I'm sure it would handle more, but i have no need for that (yet).
Post Edited (codemonkey) : 6/24/2007 4:15:06 PM GMT
The problem I see with that however, is would the 2nd waitpne consider the 1st sensor switching off (as train passes) as a change to the pins? If so it could mess things up depending on the length of the train.
if a short length train (shunter) goes over sensor 1, it is likley to untrigger sensor 1 before it triggers sensor 2.
Im gussing the 2nd INA would be a way of combating this? or if thr 2nd ina noticed the 2nd trigger has be set off, surely the 2nd waitpne will pick up on it and use it to trigger the calculation?
Also the reason I wanted to use seperate cogs, is if one sensor has just been triggered, and is in the middle of doing it's calculations when another trigger somewhere else gets triggered, then waitpne will not be looking for it and will ignore it?
Thanks
DJH
I presume I set the pinmask like this? %0011 for pins 1 & 2?
Im not sure how to check if it is the same pin doing the triggering.
Also how can I determine what pin was triggered? reading watchpin state? but how can I interface to it's individual bits?
DJH
Will have a play with it.
One other question, is there anyway to see which cog set a variable, basically to do the 4 speedtraps I was hoping to have each cog use the same pub method, however it uses variable to do the timing calcualtions, i was hoping I could do something like..
finaltime(cogid) := enditme(cogid) - starttime(cogid)
obviosuly does not work, ive looked on the forums, but most posts are way over my head
I then thought about having a seperate ,ethod for each cog, but thought it messy plus it will not update the tv display properly as they just overwrite each other. Unless I have a cog just to update the tv display every few seconds based on variables.
DJH