Christopher,
Second question first:
No, there are many different Pulse Per Mile ratio's. They can range anywhere from 1,000 to 30,000 PPM. Even within a specific manufacturer they can vary a lot.
So let's look a your case.
If a train is traveling East at 50... Woops, wrong problem. 
Ok, you have 4,000 pulses per mile, and you want miles per hour.
And, with a 500ms sample time, there are 7200 sample periods in 1 hour.<pre>(sec*minutes) 60*60 3600<br> ----------- = ----- = ----- = 7200<br> 0.500 0.500 0.500</pre>Or to do it with integers ...<pre>SampPerHour = 3600000 / MS per Sample<br> = 3600000 / 500<br> = 7200</pre>So to get Miles per hour you multiply the samplecount * 7200 and divide by the original PPM (4000)<pre> X * 7200<br>MPH = --------<br> 4000<br></pre>And to work it the other way, you can find out how many pulses you should capture for a given speed. Let's say 60MPH<pre> 60mph * PPM 60 * 4000<br>Pulses = ----------- * Samp.Period = ----------- * 0.500 = 33.33333<br> SampPerHour 7200</pre>And at this point you can see a potential problem with the integer math.
When counting pulses, there aren't any decimals. You either count 33, or 34. You can't count the .3333 in a single sample.
So let's say you've received 33 pulses. With the above formula ...<pre> 33 * 7200 237,600<br>MPH = --------- = ------- = 59.4<br> 4000 4000</pre>But then on the next Sample you get 34 pulses ....<pre> 34 * 7200 244,800<br>MPH = --------- = ------- = 61.2<br> 4000 4000</pre>Therefore, at 60mph it will be constantly jumping back and forth between 59 and 61 MPH.
You can average the samples to come up with a decimal. But, the more you average, the slower the response time of the reading.
In which case, if you can deal with a slower response time, it's better to use that time to grab a larger sample size.
For instance, if you had a 2 second sample instead of 500 ms, then the Samples per hour changes to 1800 instead of 7200, and at 60mph the number of pulses counted goes up to 133.333<pre> 133 * 1800 239,400<br>MPH = ---------- = ------- = 59.85<br> 4000 4000</pre>--- and ---<pre> 134 * 1800 241,200<br>MPH = ---------- = ------- = 60.30<br> 4000 4000</pre>Now, with some simple integer rounding (adding .5) you'll get 60mph on both. Of course, it will still wobble +/-1mph depending on the speed.
All this really depends on the PPM of the sensor. The higher the PPM, the smaller the sample size you can get away with, or the better the accuracy.
Also, since the numbers involved are larger than WORD's. It takes some DIV32 to handle it. So here's something that should get you closer... (no averaging, no rounding)
Code:
<font color="#000000"><b>RPMpin </b><font color="#008000"><b>VAR </b></font><b>PORTB</b>.<b>0 </b><font color="#0000FF"><b><i>' Input Pin
; -- These 2 are adjustable to achieve the desired results -------------------
</i></b></font><b>PPM </b><font color="#008000"><b>CON </b></font><b>4000 </b><font color="#0000FF"><b><i>' Pulses per mile
</i></b></font><b>MSperSample </b><font color="#008000"><b>CON </b></font><b>500 </b><font color="#0000FF"><b><i>' Sample time in milliseconds
; ----------------------------------------------------------------------------
</i></b></font><font color="#000080">@SampPerHour = 3600000 / _MSperSample
</font><b>SampPerHour </b><font color="#008000"><b>CON </b></font><b>EXT </b><font color="#0000FF"><b><i>' Samples per Hour
</i></b></font><b>MPH </b><font color="#008000"><b>VAR WORD
</b></font><b>GetMPH</b>:
<font color="#008000"><b>COUNT </b></font><b>RPMpin</b>, <b>MSperSample</b>, <b>MPH </b><font color="#0000FF"><b><i>' Get a sample
</i></b></font><b>MPH </b>= <b>MPH </b>* <b>SampPerHour </b><font color="#0000FF"><b><i>' Sample * Samples per hour
</i></b></font><b>MPH </b>= <font color="#008000"><b>DIV32 </b></font><b>PPM </b><font color="#0000FF"><b><i>' / Pulses per mile
</i></b></font><font color="#008000"><b>RETURN
</b></font>
This gives MPH since you specified the Pulses Per Mile. But maybe you want the result in Kilometer per hour. Piece of cake, just divide the PPM by 1.6093 (4000/1.6093=2486). Use that number for the PPM constant and it will read in KPH instead.
But frankly, I would use interrupts to count the pulses, and a timer to measure the sample time. But that's just me.
<br>
HTH,
Bookmarks