Car Speedometer on 7 segements?

radiogareth

Senior Member
Here's an interesting project....
After seeing the MPH (dual 7 segment) display in my Mazda RX8 dashboard my son (who is building a Haynes Roadster, a 'Caterham 7' style car) has decided he would like the same sort of thing in his so is planning a digital dashboard. So my initial thoughts are use a M2 part to measure the pulses provided by the gearbox output shaft (2 per revolution, already a nice 5 volt square wave).

The Mazda display seems to update at around the 0.5 to 0.7 seconds rate - faster and the digits all turns into a blur and slower is, well, slower......

I've spreadsheeted all the figures allowing for gear ratios, diff ratio and tyre size and I get the following 'pulses pre second' figures as minimum (6 Hz at 700 rpm in first gear) and maximum (244 Hz at 6,000 in overdrive).

I'm planning on using the count command (possibly at elevated clock speed to get a decent count at slow speeds) and then the 'Case' command to output a suitable 2*4 bit code to a pair of 4511 BCD-7 Segment driver chips.

Might there be a better way of doing this? A theoretical string of 0 to 130 MPH 'select Var' and then 'case Var to Var' might take a while, even at SetFreq M32.

Thoughts welcome........
 

RexLan

Senior Member
I built the digital dash with RPM and all the engine pressures & temperatures. Worked well but you have to individually calibrate your sensors if you want them accurate.

I think you will get a much better result with a MAX 7219 to drive the display.

I also know you will want to do a rolling average on the count which once it is loaded it will give a new value with every new sample and it will be very accurate. I would have a minimum of 5 samples and preferably 8 before letting it go. If you try to get a value based on one count it will likely be all over the place.

You may also find that a simply coil circuit with a 4013 flip flop using PULSIN will give you much more accuracy and also eliminate the gear stuff.

I also think you will need at least an 18x chip and you may very will run out of time if you try for 500 ms updates ... 1 sec updates are much more than the driver can ever process anyway so not need.

I had an overlay made
 

Attachments

radiogareth

Senior Member
Thanks RexLan. Food for thought. I'd forgotten the pulsin command which will work nicely with the faily slow pulses from the gearbox output - this is for the MPH, not RPM - that is another project in hand :) Nice dash btw, my son Josh has already designed the housing and front panel, a combination of 3-D printed back with compartments and a laser cut/etched reverse overlay.
As far as I know the 18M2 is the successor to the 18X and offers improved everything. With only a pair of serial commands to send which the MAX 7219 reads it should be plenty fast enough. I'll have a crack at the maths and see what the numbers look like. There is going to be an issue with the display voltage though as its 3 leds per segment so Vf is over 6 volts......the MAX 7219 is 5.5 max.....
 

westaust55

Moderator
So my initial thoughts are use a M2 part to measure the pulses provided by the gearbox output shaft ......
:
:
I'm planning on using the count command (possibly at elevated clock speed to get a decent count at slow speeds) and then the 'Case' command to output a suitable 2*4 bit code to a pair of 4511 BCD-7 Segment driver chips.

Might there be a better way of doing this? A theoretical string of 0 to 130 MPH 'select Var' and then 'case Var to Var' might take a while, even at SetFreq M32.

Thoughts welcome........
If you use an X2 PICAXE part (20X2 ?) then you have available the BINtoBCD code that will convert a value 00 to 99 into the required BCD value.
Then driving the two 4511 chips via a single PICAXE port would provide a quick way to control a 2-digit display without the need for SELECT . . . (plus many) CASE statements or numerous IF . . . THEN statements
 

oracacle

Senior Member
If the pick up if ok the output from the great box you only need the diff ratio and wheel size. If this actually the case you should be able to pre calculate the distance for each pulse for the maths.

As for the display, if you are issuing a dedicated picaxe then you could multiplex the displays abs use look up to find the pub baked to generate the correct outputs for each number. It would require added least 10 output pins. I built a clock using this idea and out seemed to work fine for that.
 

radiogareth

Senior Member
Unfortunately no OBD2, its running a Megasquirt ECU (MS1, Ver 3.0) which is only concerned with the engine. The gearbox is hybrid in as much as it has a cable speedo output and an electronic sensor, 2 pulses per rev. Its that which I'm basing my maths on. Bin to BCD will be handy, no reason I can't use a 20X2 so I'll have a read on that.
Thanks all.....
 

radiogareth

Senior Member
Took some finding bintoBCD....tried this on the sim, but the count goes wrong after 9??
dirsb=%11111111
main:
For b1=0 to 99
b1 =bintobcd b1
pinsb=b1
pause 100
next b1
goto main

Strange, unless I need to chop up the byte into two nibbles of 4 each with some masking....
 

westaust55

Moderator
Took some finding bintoBCD....tried this on the sim, but the count goes wrong after 9??
:
:
:
Strange, unless I need to chop up the byte into two nibbles of 4 each with some masking....
Try this:
Code:
dirsb=%11111111
main:
For b1=0 to 99
b[B][COLOR="#FF0000"]2[/COLOR][/B] =bintobcd b1
pinsb=b[B][COLOR="#FF0000"]2[/COLOR][/B]
pause 100
next b1
goto main
using b1 = bintobcd b1 is in effect "trashing"/corrupting the FOR...NEXT counter (byte variable b1)
 

radiogareth

Senior Member
Well, this simulates fine.... Although Pulsin seems preferable its the inverse of what I wanted so I tried looking at count again, this is a lot simpler to fix for my maths skills(?).
I suspect that the latch enable/disable won't be needed as the PICAXE will be doing just that with its Port B. If that is the case its only using 40 Bytes out of 4096!! Shame a baby picaxe doesn't support the BINtoBCD command. The refresh rate should be just above 0.5 seconds, easy to change if its a bit twitchy.
Code:
'Ford MT75 Gearbox output device - Hall Effect 2 pulses per RPM
'Sensor wiring:Black (Or black with blue trace) = 12v Ign fed live.
'Yellow (Or yellow with brown trace) = Output to speedo.
'Brown = earth as per Fords standard.Thanks to WestAus for advice :-)
#Picaxe20x2			'Define Processor	
#no_data			'Saves download time
dirsb=%11111111		'sets Port B to all outputs
dirsc=%00000010		'Sets Port C to all inputs except C.1
Speedo:			'Procedure name
	count C.0,500, b0 ; count pulses in 0.5secs (at 4MHz) (Max signal 250 Hz)
	let b1=b0*20/18	'180 Hz=100MPH Scaling factor gives ANS=99
	Low c.1		'Latch disable - may not be needed
	if b1>=180 then let b1=b1-180:endif 'Fiddle to allow counters to show over 99!
	b2 =bintobcd b1	'Do BIN to BCD conversion	
	pinsb=b2		'Place result on Port B for 4511x2
	High c.1		'Latch enable on 4511 - may not be needed
	goto Speedo		'Go around and do it again
Thanks for the suggestions, any comments welcome still, next step hardware.......
 

hippy

Ex-Staff (retired)
Or even ...

bcd = bin / 10 * 6 + bin

Using PE6 That can all be wrapped in a Macro ...

#Macro BinToBcd(bvar)
bvar = bvar / 10 * 6 + bvar
#EndMacro

b0 = 12
BinToBcd(b0)
SerTxd( #b0 )

That will print 18 (decimal) which is $12 (hex/bcd).
 

hippy

Ex-Staff (retired)
Question : With a two digit display, what happens when speed goes above 99 mph / kph ?
 

radiogareth

Senior Member
Ok, Back on this having spent some time working on the engine management (Megasquirt Extra) such that the engine now runs :)

I've built some hardware and as I have a good stock of 20M2's have used the modified code snippet. But the count seems to miss out 9 and produces understandably strange count progressions once decoded by a pair of 4511's.
I did download PE6, but on loading my existing code it spat out the #picaxe20M2 command. Surely its backwards compatible???

Comments welcome. In this listing I've added a loop to count up and try and see if I'd made a hardware error or not.
Code:
#Picaxe20M2			'Define Processor	
#no_data			'Saves download time
dirsb=%11111111		'sets Port B to all outputs
dirsc=%00000010		'Sets Port C to all inputs except C.1
Speedo:			'Procedure name
	for b0=0 to 255
	'count C.0,500, b0 ; count pulses in 0.5secs (at 4MHz) (Max signal 250 Hz)
	let b1=b0*20/18	'180 Hz=100MPH Scaling factor gives ANS=99
	'Low c.1		'Latch disable - may not be needed
	if b1>=180 then let b1=b1-180:endif 'Fiddle to allow counters to show over 99!
	'b2 =bintobcd b1	'Do BIN to BCD conversion
	b2 = b1 / 10 * 16
	b2 = b1 // 10 + b2 
	'b2 = bin / 10 * 6 + bin	
	pinsb=b2		'Place result on Port B for 4511x2
	'High c.1		'Latch enable on 4511 - may not be needed
	pause 1000
	next b0
	goto Speedo		'Go around and do it again
 

hippy

Ex-Staff (retired)
It is probably worth adding a DEBUG or SERTXD so you can check the values in b0, b1 and b2 are as you would expect them to be. You can also simulate the code to see and check what is happening.

Your "if b1>=180" test won't actually fix things when the count gets over 99, only when it gets over 180, so perhaps that is the problem.
 

radiogareth

Senior Member
OK, now I'm confused....
This only counts to 8, before carrying '1' to the next digit. I.e. the conversion is faulty???
Code:
#Picaxe 20m2		'Define Processor	
#no_data			'Saves download time
dirsb=%11111111		'sets Port B to all outputs
dirsc=%00000010		'Sets Port C to all inputs except C.1
Speedo:			'Procedure name
	b0=b0+1		'test number generator
	if b0>=180 then let b0=b0-180:endif 'Fiddle to allow counters to show over 99!
	let b1=b0*20/18	'180 Hz=100MPH Scaling factor gives ANS=99
	b2 = b1 / 10 * 16	'Bin to BCD
	b2 = b1 // 10 + b2'Bin to BCD
	pinsb=b2		'Place result on Port B for 4511x2
	goto Speedo		'Go around and do it again
But this works as expected....
Code:
#picaxe 20x2
dirsb=%11111111
Speedo:			'Procedure name
	b0=b0+1
	if b0>=180 then let b0=b0-180: endif
	b2 =bintobcd b0	'Do BIN to BCD conversion	
	pinsb=b2		'Place result on Port B for 4511x2
	goto Speedo
Greater minds than mine needed here. This is on the simulator. I tried using Word variables in case my conversion sum was rolling over the byte variable and treading on something. I still get the same effect?

I've also spotted the wrong placement of zero adjust so theoretically when you reach 100 MPH it shows 00, then starts counting up again. The driver should be able to tell the difference between 101 and 1 MPH.....

The problem with PE6 was operator error, clash of processors. I have to say, compared to PE5, it seems harder to find info about stuff. Like Macro, for instance. Where's the 'help' facility??
 
Last edited:

radiogareth

Senior Member
That seems to be the problem Hippy. Remove the scaling sum/B1 step and it seems to be fine again, however, reinstating the sum to scale B0 (*20/18) (ie change itself rather than a new variable) upsets the apple cart again???
Work in progress.....
 

radiogareth

Senior Member
True indeed Westaus55, but I'm only counting for 0.5 of a second so I get a decent refresh rate. Hence the maths... I am still puzzled why the Bin to BCD goes wrong though???
 

radiogareth

Senior Member
I have stripped it right down to see what is going on and watched it simulate as the variable counts up.
Its my conversion sum that's causing the problem "b0*20/18" does what I want to the numbers but the maths in PICAXE seem to be giving me the problem. So when the count is 9, 9*20=180/18=10 which is exactly what happening.
This fails, skipping 9 each time.
Code:
#Picaxe 20m2		'Define Processor	
#no_data			'Saves download time
dirsb=%11111111		'sets Port B to all outputs
dirsc=%00000010		'Sets Port C to all inputs except C.1
Speedo:			'Procedure name
	b0=b0+1		'Test count only actual will be 0-245 max.
	let b1=b0*20/18	'Scaling sum to adjust
	
	b2 = b1 / 10 * 16	'Bin to BCD
	b2 = b1 // 10 + b2'Bin to BCD
	

	pinsb=b2		'Place result on Port B for 4511x2
	goto Speedo
But this works as required....
Code:
#Picaxe 20m2		'Define Processor	
#no_data			'Saves download time
dirsb=%11111111		'sets Port B to all outputs
dirsc=%00000010		'Sets Port C to all inputs except C.1
Speedo:			'Procedure name
	b0=b0+1		'Test count only actual will be 0-245 max.
	let b1=b0*10/18	'Scaling sum to adjust
	
	b2 = b1 / 10 * 16	'Bin to BCD
	b2 = b1 // 10 + b2'Bin to BCD
	

	pinsb=b2		'Place result on Port B for 4511x2
	goto Speedo
Looks like I'm stuck with a once per second refresh rate unless I can find a good fix for the maths involved. Basically I have 180 pulses that represent 100 mph. For 'simplicity' scaling to 100 and then using BINtoBCD looks like quick and simple. I'll try it with the 1 second refresh rate and see what the 'user feel' is like.
 

hippy

Ex-Staff (retired)
This fails, skipping 9 each time.
Okay; I can see what is happening ...

Code:
#Picaxe 20M2
SerTxd( "b0", 9, "b1", 9, "b2", 9, "b34", CR, LF )
For b0 = 16 To 19
  b1 = b0 *  20 / 18
  b2 = b1 /  10 * 16
  b2 = b1 // 10 + b2
  ; Report results ...
  b3 = b2 /  $10
  b4 = b2 // $10
  SerTxd( #b0, 9, #b1, 9, #b2, 9, "$", #b3,#b4, CR, LF )
Next
This gives the result ...
Code:
b0    b1    b2    b34
16    17    23    $17
17    18    24    $18
18    20    32    $20
19    21    33    $21
That is correct ...

17 * 20 / 18 = 18
18 * 20 / 18 = 20

That is basically integer rounding error. There can be no one-to-one consecutive integer mapping for *20/18.

You can look at it the opposite way round; what input (b0) value would there need to be to display 19 (b1) ?

b1 = b0 * 20 / 18

so, the reverse is

b0 = b1 * 18 / 20

for b1 to be 19, b0 would have to be -

b0 = 19 * 18 / 20 = 17.1

And there's no way to get a 17.1 integer count, it's either going to be 17 or 18.
 

hippy

Ex-Staff (retired)
Looking at actual speed for your count might help clarify things -

Code:
0   0.0
1   1.11111111111
2   2.22222222222
3   3.33333333333
4   4.44444444444
5   5.55555555556
6   6.66666666667
7   7.77777777778
8   8.88888888889
9  10.0
10 11.1111111111
11 12.2222222222
12 13.3333333333
13 14.4444444444
14 15.5555555556
15 16.6666666667
16 17.7777777778
17 18.8888888889
18 20.0
19 21.1111111111
Or another way of looking at the problem is; you have 9 input counts (0 to 8) and you want to map those to 10 output displays (0 to 9).

That can't be done with integers.
 
Last edited:

radiogareth

Senior Member
OK, reverting to the old sum *10/18 works as expected, once I swapped out a faulty 20M2. But a 1 second refresh rate is just a bit slow, so I tried *15/18 and counted for 0.75. That works nicely on all counts (sorry!!). The rev counter is also functional as if the fuel gauge. It all looks like this....2016-04-08 18.13.48.jpg
Once I PCB the 4511's and get the rest sorted I'll update the code snippets.
 

hippy

Ex-Staff (retired)
OK, reverting to the old sum *10/18 works as expected, once I swapped out a faulty 20M2. But a 1 second refresh rate is just a bit slow, so I tried *15/18 and counted for 0.75. That works nicely on all counts (sorry!!).
That would be expected because it's only when the multiplier is greater than the divisor that you end up with fewer numbers than you want to show; so 20/18 doesn't work but 10/18 and 15/18 will.

Of course, you could just change the period you are counting over to 0.6s (600ms) and then your conversion would be -

mph = count * 18 / 18

Or, more simply put, what you are counting would be the speed, no conversion needed.
 

radiogareth

Senior Member
Or if I count for 556 I get 100.08 :)

That should work :)
A mere 32 bytes, but SO MUCH functionality!!
Code:
'Ford MT75 Gearbox output device - Hall Effect 2 pulses per RPM
'Sensor wiring:Black (Or black with blue trace) = 12v Ign fed live.
'Yellow (Or yellow with brown trace) = Output to speedo.
'Brown = earth as per Fords standard.Thanks to WestAus for advice :-)
#Picaxe 20x2			'Define Processor	
#no_data			'Saves download time
dirsb=%11111111		'sets Port B to all outputs
dirsc=%00000010		'Sets Port C to all inputs except C.1
Speedo:			'Procedure name
	count C.0,556, b0 ; count pulses in 0.5secs (at 4MHz) (Max signal 250 Hz)
	if b0>=100 then let b0=b0-100:endif 'Fiddle to allow counters to show over 99!
	b1 =bintobcd b0	'Do BIN to BCD conversion	
	pinsb=b1		'Place result on Port B for 4511x2
	goto Speedo		'Go around and do it again
 

hippy

Ex-Staff (retired)
Even more compact, good for 0 mph to 255 mph ...

Code:
#Picaxe 20x2
#no_data
dirsb=%11111111
dirsc=%00000010
do
  count C.0, 556, b0
  pinsB = b0 / 10 * 6 + b0 // $A0
loop
 

radiogareth

Senior Member
Erco, Neat solution:) My son had already chosen the display size. Hippy does that mean it correctly 'carrier the first and second '100', still displaying 00-99? Is 'do-loop' now the preferred way? I first used 'goto' in about 1978!!
 

hippy

Ex-Staff (retired)
Yes, the code does appear to work displaying 0-99 for 0-99 and 100-199. I tested it by simulating in a FOR-NEXT and it looked okay.

I prefer DO-LOOP but a label and a GOTO are just the same.
 
Top