[Ovmsdev] 3 bytes to char

Mark Webb-Johnson mark at webb-johnson.net
Thu Jun 25 14:33:44 HKT 2015


Nikolay,

Please take care with RAM usage. It is very very tight on these little microcontrollers.

I think the simplest way for yours is something like this:

(((unsigned long)(can_databuffer[4)<<16) +
((unsigned long)(can_databuffer[5)<<8) +
((unsigned long)(can_databuffer[6)) +
5000UL) / 10000UL

Not sure why you are getting a rounding error. Are you sure that the SOC hasn’t dropped between logging the data and plugging in OVMS?

Here is what I get:

$ echo 'ibase=16; scale=2; 07DCC0/02710' | bc
51.52

Regards, Mark.

> On 25 Jun, 2015, at 7:35 am, Nikolay Shishkov <nshishkov at yahoo.com> wrote:
> 
> 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=0xC0
> If 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 <mailto: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 <mailto:OvmsDev at lists.teslaclub.hk>
>> http://lists.teslaclub.hk/mailman/listinfo/ovmsdev
> 
> 
> _______________________________________________
> OvmsDev mailing list
> OvmsDev at lists.teslaclub.hk <mailto:OvmsDev at lists.teslaclub.hk>
> http://lists.teslaclub.hk/mailman/listinfo/ovmsdev <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/20150625/1efa4567/attachment.htm>


More information about the OvmsDev mailing list