Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

KMH to MPH conversion

Status
Not open for further replies.

ChriX

Member
I'm doing a project with a 16F628 and a GPS receiver. The only problem is that I need to get a reading in MPH rather than KMH as given by the receiver so I need to do a conversion on the PIC. It's relatively simple to do (when not dealing with asm that is!) as it's only a multiplication by 0.621.

I have a number that can be from 000.0 to 999.9 stored in BCD, using 4 registers with one digit in each, so I guess ill need to convert that to a 16 bit binary number and then multiply it before changing it back to BCD, but i'm really unsure about dealing with numbers less than 1 in binary and the multiplication.

Any help appreciated! I'm sure someone must have come across this before so I thought there would be code snippets around to help, but i've not managed to find any.
 
Since you are working with 4 digits accuracy, you need a more precise constant of conversion (i.e. 0.6214).

Multiply each BCD digit by 62.14, 6.214, 0.6214 and 0.06214 respectively then add the results up.

Also,

62.14 = 15907/256
6.214 = 25451/4096
0.6214 = 40722/65536
0.06214 = 65155/1048576
 
First convert to 16 bit as you suggest. However, forget the decimal point – treat the last digit at the units – IE multiply your value by 10. Better still if your input value will NEVER exceed 655 then multiply by 100.

So, 123.4 KM/H becomes 1234 in binary = 0x4D2 (or *10 = 12340 = 0x3034)

Then, the equation you need is

y=x-(x*256+x*8192+x*16384-x-x*16)/65536

While this may seem complicated, it's fairly easy in assembler.

To multiply by 256 you shift it left 8 bits = shift left one byte.
To multiply by 8192 you shift left 13 bits = shift left 2 bytes and right 3 bits.
To multiply by 16384 you shift the last number (*8192) left once.
To multiply by 16 you shift left 4 bits.

You then add and subtract the various bits and shift the whole thing right 2 byte (divide by 65536).

Add this to your original value and convert back to BCD. (Nigel has a very good binary to BCD conversion routine in his tutorial).

Now shift the digits right once or twice (divide by 10 or 100) and you have MPH.


When you put 0x3034 into the above algorithm you get 0x1DF4 = 7668 out.

So, 123.4 km/H = 76.68 MPH. – Should be 76.677205122087 using 1.609344 km = 1 Mile

Mike.
 
You could of course ignore the above and simply do

Y=X-(X*24814)/65536

Using a 16*16 bit multiply.:D

Using the above values,

12340 = 0x3034
0x3034*24814 = 0x12405058
0x12405058/65536 = 0x1240
0x3034-0x1240 = 0x1DF4

0x1DF4 converted to BCD = 7668

Therefore,
123.4 km/H = 76.68MPH

Mike.
 
Last edited:
even more simple

You could of course ignore the above and simply do

Y=X*40722/65536

Using ONLY ONE 16*16 bit multiply and forget the last word.
 
mcs51mc said:
You could of course ignore the above and simply do

Y=X*40722/65536

Using ONLY ONE 16*16 bit multiply and forget the last word.

Spoilsport, that was going to be my next answer.:p

Mike.
 
Wow, thanks guys, I actually get what is going on which is pretty rare - you explain it well!

The value in KMH will never be above 655, if I do find myself going 406 MPH on land I probably wont be looking at my little GPS! So I have multiplied by 100 and converted to 16 bit binary. Now trying to work out the multiply/divide.

Could you point out where the 16 bit binary to BCD routine is on Nigel's site? I can't see it.
 
Have a look at and scroll down to a routine called convert. This takes a 16 bit value and returns 5 digits which are BCD. It is very clever in the way it works.

Mike.
 
Pommie said:
Have a look at and scroll down to a routine called convert. This takes a 16 bit value and returns 5 digits which are BCD. It is very clever in the way it works.

Sorry, but I can't take the credit for the routine being 'clever' (which I agree it is), I got it from the PICList. As I recall there was a bit of a private competition on the PICList, with far cleverer people than me trying to create the best BIN/BCD routine - this was one I really liked, and I always use it.
 
Wow I just signed up today and already you gave me an idea!

a friend of mine has just bought a import and its in kph and he wants mph, his conversion was simple, its a new sticker for the speedo!

Problem is this leaves him with mph and the odometer/trip in kph.

I thought about using an old pic to take the signal from the gearbox and convert it, count pulses in, after X pulses send out Y pulses.

I have seen circuits like this on sale but usually cost much more than what they are worth etc, I may get round to building one one day.

Little harder than number crunching as the output needs to be their all the time, IE I cant wait for a 1000 pulses then output 621 etc, I guess I need to measure the number of pulses in say 0.5 seconds and then work out a frequency to output, but then I'm doing 2 things at once, I think I just found why these gadgets are expensive....
 
But, may I ask do you want with MPH since I had asssumed since the UK was in the EEC and was a party to metirification(sloppy) I would have assumed most of the speed signs were now in K/H. Are just pandering to a ludite?
 
Paul Obrien said:
But, may I ask do you want with MPH since I had asssumed since the UK was in the EEC and was a party to metirification(sloppy) I would have assumed most of the speed signs were now in K/H. Are just pandering to a ludite?

All road signs in the UK (and car speedometers) are in miles, and are required to be so by law!.

We also still drive on the correct side of the road :D
 
Still holding out against tide, I had no idea were that bad, how far have you since new pence?
 
Paul Obrien said:
Still holding out against tide, I had no idea were that bad, how far have you since new pence?

We still have pounds and new pence, although most of Europe has changed to the Euro.

Although all weights in shops have to be in kg, even after all these years most shops still price goods in both kg and lb's. I always ask for a 1/4lb of ham or whatever, NEVER in kg :D

Mind you, I was brought up on pounds, shillings and pence!.
 
lez said:
Little harder than number crunching as the output needs to be their all the time, IE I cant wait for a 1000 pulses then output 621 etc, I guess I need to measure the number of pulses in say 0.5 seconds and then work out a frequency to output, but then I'm doing 2 things at once, I think I just found why these gadgets are expensive....

Not hard at all. A PIC18 is 10 million instructions/sec.
You'd set up an interrupt when the tach signal transitions. You can either count the number of pulses for each 250mS block and then the display routine looks at how many pulses have happened over the last 2 sec or so. The downside here is that you need a lot of pulses to get good resolution (particularly for low rpm), and that mean a slower response.

Or you can use a CCP module and its interrupt to check how many clock cycles happen between tach pulses. It's potentially more susceptible to noise (averaging helps) and there are also some resolution issues.
 
lez said:
Little harder than number crunching as the output needs to be their all the time, IE I cant wait for a 1000 pulses then output 621 etc, I guess I need to measure the number of pulses in say 0.5 seconds and then work out a frequency to output, but then I'm doing 2 things at once, I think I just found why these gadgets are expensive....

You don't have to wait for 1000 pulses to output 621 pulses. You can perform a part of the conversion on every pulse. The equation for conversion from Kilometer to Mile is:

KM = 0.6214 x Mile
KM pulse count = 0.6214 x Mile pulse count.
Earlier, 0.6214 = 40722/65536

First, you assign a 16-bit register as an accumulator. For every Mile pulse detected, you add 40722 to that register. Everytime the register overflows (i.e., generates a carry), you generate a KM pulse.

The name of this algorithm escapes me right now but it is a form of electronic gearing.

You don't even need interrupts to detect Mile pulses. You can use timer0 to count incoming pulses. You scan it periodically for any change in value and any change in value from the previous scan is the pulse count.
 
motion said:
KM pulse count = 0.6214 x Mile pulse count.

This cannot be correct.

When a car is travelling at constant speed, KM pulses will appear more frequent than mile pulses because one KM is shorter than one mile.

However, if you are referring to the pulse period and not the counts, then it is correct.

For every Mile pulse detected, you add 40722 to that register. Everytime the register overflows (i.e., generates a carry), you generate a KM pulse.

The register takes 65536 to give a carry. This would resulted in KM pulses being less than the mile pulses, which is the opposite one wanted.
 
Last edited:
eblc1388 said:
This cannot be correct.

When a car is travelling at constant speed, KM pulses will appear more frequent than mile pulses because one KM is shorter than one mile.

The pulses are coming from a rotational counter such as a magnet on a wheel. If the wheel travels one mile it will give out more pulses than if it travels one km. Therefore mile pulses arrive faster than km pulses and Motions calculations are correct.

Mike.
 
motion said:
The name of this algorithm escapes me right now but it is a form of electronic gearing.

I don't know the name of it but I first came across it to draw diagonal line on a bitmapped display.

Mike.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top