Speedo converter basics

Changster

New Member
Hi all,
i'm a noob at the programming stuff. I used to be a TV engineer but the programming side is a challenge for me so i'm getting stuck in with this 'simple' project.
I've just accuired a small scooter with a digital speedo but its in kilometers so ive done some testing and the speed input at aprox 70mph is about 2khz from a gearbox VR sensor. I've conditioned the signal into a nice 0-5V pulse which will vary from 0Hz to 2KHz and i would like to put a PICAXE between the sensor and the existing speedo so the kms will read as mph, so i just need to reduce the pulses by 1.61 to 1.
I've looked at the the programming side and i think i need to use counter to collect the pulses and read them into a memory location and then read them out at a slower rate... does this sound feasible? or would an interupt style program be better?
ive got the axe091 breadboard kit using a 18m2 but im guessing a 08m2 will fit the bill too.
your thoughts would much appreciated.
 

hippy

Ex-Staff (retired)
Welcome to the PICAXE forum.

I think the greatest difficulty will be that you are attempting to do two things in parallel - determining the input frequency / pulse width and generating the output frequency / pulse width - the conversion between the two is possibly the easier part.

The internal timers can be configured in "compare" mode ( by poking SFR's ), and can toggle an output to give a background free-running output and can also reset the timebase clock for that but I don't think they can do both together without intervention by the program. At 2kHz that's a period of 500us which is quite short and I'm not sure how well that could be handled in a PICAXE which is also measuring the input frequency / pulse width. Perhaps two timers can be used together; one toggling the output, the other resetting the timebase clock ?

Another option may be using two PICAXE which allows the output generator more time to do what it needs to do.

I think it's going to be more complicated than imagined and probably not something anyone without experience is going to find at all easy. With the forthcoming PICmicro addition of NCO hardware things might get easier but that's not an ability current PICAXE have.

There's perhaps also the possibility of a more hardware only solution; PLL or similar, using some frequency to voltage and voltage to frequency combo.
 

hippy

Ex-Staff (retired)
Another option may be an I2C or SPI controlled oscillator which will allow the PICAXE to determine the output frequency and leave it to it, and that could of course be built using discrete logic.
 

vttom

Senior Member
My first thought was that he could use count on the input side and pwmout or hpwm on the output side. Can you not use count and pwm commands at the same time? Do they use the same timers?

How about pulsin and pwm?
 

MartinM57

Moderator
Measure the input frequency in the foreground and produce the output for the existing speedo via:
- toggling the output via a timer interrupt for low frequencies
- PWM for higher frequencies?

Probably moves the project away from "simple", as expressed in post#1 but I can't see why it's not feasible.
 

hippy

Ex-Staff (retired)
My first thought was that he could use count on the input side and pwmout or hpwm on the output side.
My thought there is that PWMOUT only provides certain frequency values though it may well have enough range. It's really an NCO with 8-bit timebase control plus divide by 1, 4, 16 and 64 options.

As ever there's more than one way to skin a cat, and from the 'idiot idea department' it occurred to me that the baud rate generator is a 16-bit NCO and the EUSART can generate a clock when used in synchronous mode, and that seems to work on the 18M2.

Use HSERSETUP as a shortcut to configure the basics, then tweak to make it synchronous, and just keep throwing bytes at the transmit register. Voila! Out of leg 11 on an 18M2 comes a pulse stream reflecting the baud rate ...

Code:
#Picaxe 18M2

Symbol RCREG            = $79   ' $199
Symbol TXREG            = $7A   ' $19A
Symbol SPBRGL           = $7B   ' $19B
Symbol SPBRGH           = $7C   ' $19C
Symbol RCSTA            = $7D   ' $19D
Symbol TXSTA            = $7E   ' $19E
Symbol BAUDCON          = $7F   ' $19F

' RCSTA

Symbol RX9D_BIT                 = bit0
Symbol OERR_BIT                 = bit1
Symbol FERR_BIT                 = bit2
Symbol ADDEN_BIT                = bit3
Symbol CREN_BIT                 = bit4
Symbol SREN_BIT                 = bit5
Symbol RX9_BIT                  = bit6
Symbol SPEN_BIT                 = bit7

' TXSTA

Symbol TX9D_BIT                 = bit0
Symbol TRMT_BIT                 = bit1
Symbol BRGH_BIT                 = bit2
Symbol SENDB_BIT                = bit3
Symbol SYNC_BIT                 = bit4
Symbol TXEN_BIT                 = bit5
Symbol TX9_BIT                  = bit6
Symbol CSRC_BIT                 = bit7

HSerSetup B4800_4, %000

PeekSfr TXSTA,b0
SYNC_BIT = 1
CSRC_BIT = 1
PokeSfr TXSTA, b0

PeekSfr RCSTA, b0
SREN_BIT = 0
CREN_BIT = 0
SPEN_BIT = 1
PokeSfr RCSTA, b0

Do
  PokeSfr TXREG, %01010011
Loop
Not sure how useful that is as the TXREG has to be updated regularly and one would still have to get data in to it to change the frequency, but maybe someone will find it useful. Adding -

ReadAdc C.0, b0
PokeSfr SPBRGL, b0

Allowed a pot to change the frequency but poking SPBRGH didn't seem to work. It's probably poking too quickly and continually resetting the BRG timer.
 

mrburnette

Senior Member
<...>
I've just accuired a small scooter with a digital speedo but its in kilometers so ive done some testing and the speed input at aprox 70mph is about 2khz from a gearbox VR sensor. I've conditioned the signal into a nice 0-5V pulse which will vary from 0Hz to 2KHz and i would like to put a PICAXE between the sensor and the existing speedo so the kms will read as mph, so i just need to reduce the pulses by 1.61 to 1.
To simplify, you need a digital prescaler in software that will provide 100 pulses out for every 161 pulses in... simple statement.
So there is a digital speedo that takes pulses and provides readings... but these pulses must be time-bases in some manner since speed is a time based measurement. Inside the digital counter must be something that resets the speed display when no pulses are being fed to the system; it must also diminish the digital value displayed as the pulse train is retarded. We have to make some assumptions and some testing will have to confirm the assumptions.

Assumption: A simple RC integrator takes the pulses (of fixed width) and produces a voltage proportional the the pulse train count-over-time... the simplest display would then be a voltmeter calibrated in speed units.

So, what we need is to create a pulse of the same width but of reduced frequency... as you indicated, "reduce the pulses by 1.61 :: 1.

How would we do this if we were to count? We know that in the end, we need 100 pulses out for 161 in, but since we cannot use decimals, we need to consider an alternate solution... if we were just buffering the pulses, it would be 1 out for 1 in. So, how about simplifying to 10 out for 16 in? This produces only a small error and may be acceptable.

To count in code to 10 for 16 iterations, we could use something brute force like this:
symbol counter = b0
symbol variable = b1

do
counter = 0
for variable = 1 to 16
select case variable
case 1
inc counter
case 2
'inc counter
case 3
inc counter
case 4
'inc counter
case 5
inc counter
case 6
inc counter
case 7
'inc counter
case 8
inc counter
case 9
inc counter
case 10
'inc counter
case 11
inc counter
case 12
'inc counter
case 13
inc counter
case 14
'inc counter
case 15
inc counter
case 16
inc counter
end select
next

loop
If we run the code in the simulator, we can see that 16 loops leaves the counter with a value of 10... which is to say that I REM'ed out 6 of the increment statements. Taking this to the next level, we just need to modify the For/Next to be a COUNT instruction and the INC to be a PULSOUT instruction. Use the "time" parameter of PULSOUT to set the pulse-width to something close to what the original pulses are... and test.

There may be serious issues at lower bike speeds if the hypothetical RC pulse-to-voltage integrator is "upset" about the missing pulses... but you will not know unless you test.

- Ray
 

vttom

Senior Member
How would we do this if we were to count? We know that in the end, we need 100 pulses out for 161 in, but since we cannot use decimals, we need to consider an alternate solution... if we were just buffering the pulses, it would be 1 out for 1 in. So, how about simplifying to 10 out for 16 in? This produces only a small error and may be acceptable.
Cool. I like this idea. To take it 1 step further, a 16:10 reduction is the same as 8:5. I think the code to subtract 3 pulses from every 8 could be as easy as:

Code:
' By way of example, pin1 is the input pin, pin 2 is the output pin
low 2
do

  ' Echo first pulse to output
  do : loop until pin1 = 1
  high 2
  do : loop until pin1 = 0
  low 2

  ' Echo second pulse to output
  do : loop until pin1 = 1
  high 2
  do : loop until pin1 = 0
  low 2

  ' Remove third pulse
  do : loop until pin1 = 1
  do : loop until pin1 = 0

  ' Echo forth pulse to output
  do : loop until pin1 = 1
  high 2
  do : loop until pin1 = 0
  low 2

  ' Echo fifth pulse to output
  do : loop until pin1 = 1
  high 2
  do : loop until pin1 = 0
  low 2

  ' Remove sixth pulse
  do : loop until pin1 = 1
  do : loop until pin1 = 0

  ' Echo seventh pulse to output
  do : loop until pin1 = 1
  high 2
  do : loop until pin1 = 0
  low 2

  ' Remove eigth pulse
  do : loop until pin1 = 1
  do : loop until pin1 = 0

loop ' Repeat forever
 

g6ejd

Senior Member
Now that I've read the question properly I'll answer it a little more coherently than my last now deleted answer :rolleyes:

What I think you should do is to implement a digital phase-locked loop. So when the input pulse goes high you set your output pulse (pin) high too. Then you start to measure the input pulse duration, having got that time count, reduce it by 0.805 (1.61/2 for half a cycle pulse duration) then set you output pin low, then wait for the next leading edge, and repeat the process, that's it.
 

vttom

Senior Member
Actually, I got to thinking about this some more and came up with the following:

Code:
' By way of example, pin1 is the input pin, pin 2 is the output pin
low 2
do

  do : loop until pin1 = 1 : high 2
  do : loop until pin1 = 0 : low 2
  do : loop until pin1 = 1
  do : loop until pin1 = 0 : high 2
  do : loop until pin1 = 1 : low 2
  do : loop until pin1 = 0
  do : loop until pin1 = 1 : high 2
  do : loop until pin1 = 0 : low 2
  do : loop until pin1 = 1
  do : loop until pin1 = 0 : high 2
  do : loop until pin1 = 1 : low 2
  do : loop until pin1 = 0
  do : loop until pin1 = 1 : high 2
  do : loop until pin1 = 0 : low 2
  do : loop until pin1 = 1
  do : loop until pin1 = 0

loop ' Repeat forever
 

Changster

New Member
Guys! huge thx for your replies!

to answer one of the questions: the odometer does increment with kms so after the comversion it will then increment in miles but thats not a problem..

i will get programming and testing and see what the outcome is..

Thanks again for all your wise words!
 

Goeytex

Senior Member
Unlike a Hall sensor, a VR sensor has a minimum speed that it needs to generate a usable signal .

Question: What is the minimum speed in KPH that your display reads while the scooter is moving?
Question: What is the maximum speed of the Scooter ?
Question: Is your conditioned signal a 50 percent duty cycle?
Question: Do you have an oscilloscope?
 

hippy

Ex-Staff (retired)
The first thing to test is what the speedo itself actually uses to determine the speed; frequency ( pulse counting ) or pulse width measuring. That will determine what the conversion PICAXE has to produce; non-50% duty signals should work if it is counting pulses but that may not if measuring pulse width.

That should also show any affects using a PICAXE signal rather than original source signal. For example, if the original source signal is a sine wave then it could be using the pulse width of the signal squared-up at its 75% point; such a pulse width would be narrower than a square wave signal at the same frequency.

Basically, find if it's frequency you have to scale up or pulse width.
 

Changster

New Member
Hi Guys,

the minimum speed it will read when i push it along is 3-5kph and ive seen the pulses on the scope and they are low amplitude and get larger as speed increases.. This is what the original speedo works from.

Ive put this VR sensor thru a zero crossing detector and the waveform is 50/50 (0-5V) and the frequency increases with speed.

Max speed of the scooter is aprox 70mph (110kph) and the frequency is at this speed is aprox 2KHz +/- 250Hz and this was measured on my handheld Fluke scope.

Did a test and even with my zero crossing detector in place it still reads the pulses ok and reads the correct speed.
 

gengis

New Member
I think you are making life more difficult than it needs be.

I just repaired my '91 vintage truck speedo, and in the process learned how they did it. The general idea is to take the trigger (in my case a magnetic reed switch that grounds a floating input, based on drive shaft revolutions - I think it is ~8 pulses per 360 degrees - no idea how that relates to road speed) That signal is sent to a IC that produces a ~20 ms pulse. That pulse is current limited via a 38 ohm resistor and charges a smoothing capacitor across the meter movement (the movement itself has an 88 ohm internal resistance, and takes about 3.7 volts for full scale deflection - 100 MPH in this case) The pulses are voltage regulated and fixed at ~20 milliseconds width and the frequency just follows the input signal. The cap across the meter, originally 220 microfarads, smooths out the meter so the needle isn't trying to follow the pulses - so it isn't "pulse width modulated" but just simply follows the input pulse with a fixed width and amplitude output pulse. My cap was flaky and causing the meter to peg, have palsy and occasionally work OK. It was a 220 uf 16 volt cap and I replaced it with a 1,000 uf 25 volt cap - the meter is rock steady now. The circuit I have on my Dodge truck is almost identical to what Volvo and Porsche used and was made by VDO. I had a chance to work on a Ford Speedo and they use a three terminal stepper motor for all the gauges - one circuit board and 7 cheap little plastic housed steppers moving all the needles.
 

mrburnette

Senior Member
<...>
Ive put this VR sensor thru a zero crossing detector and the waveform is 50/50 (0-5V) and the frequency increases with speed.

Max speed of the scooter is aprox 70mph (110kph) and the frequency is at this speed is aprox 2KHz +/- 250Hz and this was measured on my handheld Fluke scope.
What I proposed and what vttom prototyped is the generation of scaling by selective subtraction and vttom's HI/LOW code should respect the approximate 50% duty cycle. Unknown is how (IF) the digital speedo will integrate the signal or will simply count the pulses over against a timebase.

While playing, you may also take some license with when the missing pulses actually occur in the span of 16 input pulses... for example, does spreading the missing pulses out across the period of 16 input pulses work better than eliminating all the pulses at the beginning/end? Or, maybe eliminate the pulses in pairs... for pulse counting, one would "assume" that it really will not matter, but if there is some strange magic going on in the speedo, well, testing should give you the answer.

To bad you don't have a variable frequency 5V square wave generator.

- Ray
 

mrburnette

Senior Member
If you have a PICAXE then you have one !
Oh, my... you software guys! Sometimes, it is just easier to pull down the old test equipment and connect... there is something magical about flipping a few switches and having something done without having to write dedicated code...

TOUCHE:D
 

vttom

Senior Member
What I proposed and what vttom prototyped is the generation of scaling by selective subtraction and vttom's HI/LOW code should respect the approximate 50% duty cycle.
Actually, my 2nd example above produces 4 pulses with a 1:2 (high:low) duty cycle, and a fifth pulse with a 1:3 duty cycle.

Here's another thought... Use 2 PICAXEs. The first PICAXE uses count to measure the incoming frequency and do the KPH-to-MPH maths. The second PICAXE produces a continuous output at the desired frequency and duty-cycle. They would need to be fairly high pin-count devices so you can asynchronously transfer the frequency information from one to the other in a broadside (rather than serial) manner so that the receiving PICAXE can quickly sample new data without glitching the output signal.
 

mrburnette

Senior Member
Actually, my 2nd example above produces 4 pulses with a 1:2 (high:low) duty cycle, and a fifth pulse with a 1:3 duty cycle.
I stand corrected... One (me) should really read the code rather than just glance at it... my bad :(

Personally, I just don't think such a simple concept should be engineered into a multi-PICAXE scenario... $eem$ $o Wa$teful.

Maybe utilize an "M" series and work through the quasi-multitasking. In the 8::5 (16::10) ratio frequency reduction proposal, we only need to fire output pulses when the counter is:
= 1, fire
= 3, fire
= 4, fire
= 6, fire
= 8, fire
Clear counter, Loop forever

I do not know if PULSOUT is a 'blocking instruction' and the online reference is no help: http://www.picaxe.com/BASIC-Commands/Digital-InputOutput/pulsout/
Some commands clearly indicate they block:
http://www.picaxe.com/BASIC-Commands/Digital-InputOutput/rfin/
Are users to assume that all blocking commands are so noted? Personally, I like my documentation to include a positive statement/icon/graph to indicate behavior that differ across product models.
(Yes, I'm sure if I search the forum... my bad... strike 2.)

If the pulses must be a uniform 50% duty cycle and the frequency must be smooth (not choppy), a simple VCO with a diode clipper could be used to generate uniform pulses from PWM output from the PICAXE that is integrated in an external RC network... the resulting voltage uniformly changing the frequency of the VCO... linearity can be handled by creating a lookup table in EEPROM. With 555's being dirt cheap, this would likely be less expensive and more flexible than a 2-PICAXE implementation... but that is my educated guess.


Changster said,
Ive put this VR sensor thru a zero crossing detector and the waveform is 50/50 (0-5V) and the frequency increases with speed.
So, until we get the results of how the speedo reacts to non-square wave pulses, I don't know if I'm barking up an empty tree or not.


- Ray
 
Last edited:

mrburnette

Senior Member
But you don't! The PWM wizard will do it for you!
<...>
Wizards, Warlocks, Witches... I'm over Halloween and my trusty ol' function generator and Tek dual-trace scope honestly need to be powered-cycled from time to time: the capacitors in the power supplies appreciate it so much.
 

Changster

New Member
Guys, many thanks for your input, ive got it working of sorts and have changed vttom code so the 08M2 runs at 8MHz. it works really well up to about 500-600Hz and then the speedo reads erratically. If i switch from kph to mph it works accurately too! Any ideas to speed up its sampling/processing?
 

eclectic

Moderator
Guys, many thanks for your input, ive got it working of sorts and have changed vttom code so the 08M2 runs at 8MHz. it works really well up to about 500-600Hz and then the speedo reads erratically. If i switch from kph to mph it works accurately too! Any ideas to speed up its sampling/processing?

working of sorts?

Can you post your current code and circuit?

e
 

booski

Senior Member
I don't know if anyone has mentioned this, but there is a chip, lm2971 i think (id have to check) that is a frequency to voltage converter. then use the output voltage on adc or something. my 2cents
 

jojojo

Senior Member
Hello,you said I've conditioned the signal into a nice 0-5V pulse which will vary from 0Hz to 2KHz

Are you sure?

If your motor is running at 12000 turns/minut (very high ...), the max frequency will be 200Hz. Not 2 Khz.

You can verify that, mesuring the output signal from reluctor sensor.

Regards.

Ho !

Sorry, you want to mesure the scoot speed, not motor speed. i am a bit silly, sometimes ...
 
Last edited:
Top