[Ovmsdev] 3 bytes to char
Nikolay Shishkov
nshishkov at yahoo.com
Thu Jun 25 07:35:05 HKT 2015
Thanks again...I seem to not been able to grasp the idea and would appreciate a code example.For example byte1=0x07, byte2=0xDC, byte3=0xC0If I put these in excel and calculate 7*256*256 + 220*256 + 192 I get 520264.Then when I divide this by 10000, I get 52.0264. And this matches the 52% shown by the car.
Currently my code for this conversion is: sv1 = (unsigned long)can_databuffer[4]; sv1 = sv1*65536UL;
sv2 = (unsigned long)can_databuffer[5]; sv2 = sv2*256UL;
sv3 = (unsigned long)can_databuffer[6]; sv3 = sv3;
car_SOC = (char)((unsigned long)(sv1 + sv2 + sv3 + 5000UL)/10000UL);
And the result for car_SOC is 49. How is this possible?And what would be the correct way to put these 3 bytes together and divide them by 10000 to get to the final value in char?
Thanks in advance,Nikolay
On Monday, June 22, 2015 3:58 PM, Mark Webb-Johnson <mark at webb-johnson.net> wrote:
Division is kind of nasty in 8bit. Actually very nasty. Unless you are dividing by 2, 4, 8, 16, etc. Divide by 2^N is the same as >>N, and that is the shortcut you want to do if at all possible.
That said, your solution seems ok, except the value[2] should be <<8, and you probably want to add 5000 just before divide by 10000, to round correctly.
If you don’t need too much precision, you might find an inaccurate kludge may be good enough.
For example:
205/2048 = 0.1000976562
and that is pretty close to 0.1. So multiply by 205, then shirt right 11 spaces is pretty close to divide by 10. Multiplication is much less expensive than division.
If you look at MiFromKm and KmFromMi in utils.c, you can see similar sorts of approximations to avoid big divisions.
Regards, Mark.
On 22 Jun, 2015, at 4:30 pm, Nikolay Shishkov <nshishkov at yahoo.com> wrote:
I have a situation where I need to convert a value that is stored as 3 bytes to a char.The can be for example 7ED95, which is reported in 3 consequtive bytes 07, ED, 95.This value in decimal is 519573, which corresponds to a 51.9% SOC. Is the proper way to do this conversion (from the 3 bytes to the value of 51) like this:
char soc = (char)(((unsigned long)value[1]<<16 + (unsigned long)value[2]<<16 + (unsigned long)value[3])/10000);
I have been doing stuff like that before with unions, but can't remember how either.
Thanks,
Nikolay _______________________________________________
OvmsDev mailing list
OvmsDev at lists.teslaclub.hk
http://lists.teslaclub.hk/mailman/listinfo/ovmsdev
_______________________________________________
OvmsDev mailing list
OvmsDev at lists.teslaclub.hk
http://lists.teslaclub.hk/mailman/listinfo/ovmsdev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openvehicles.com/pipermail/ovmsdev/attachments/20150624/84e8df6f/attachment.htm>
More information about the OvmsDev
mailing list