sandeepmistry / node-chip-io

Johnny-Five IO Plugin for the Next Thing Co. C.H.I.P.
MIT License
96 stars 28 forks source link

Fix precision on Voltage sensor #44

Closed norgeous closed 7 years ago

norgeous commented 7 years ago

Observation

When running the command:

node examples/battery-voltage.js

I get an output like:

1487607821720 Device(s) C.H.I.P.
1487607821772 Connected C.H.I.P.
1487607821853 Repl Initialized
>> Battery voltage is 0.00V
Battery voltage is 4.11V
Battery voltage is 4.11V
Battery voltage is 4.11V
Battery voltage is 4.11V
Battery voltage is 4.11V
Battery voltage is 4.11V
Battery voltage is 4.11V

There should not be multiple console.log of the same message.

Remove the fixed precision in the examples/battery-voltage.js to see what is happening, change:

console.log('Battery voltage is ' + voltage.toFixed(2) + 'V');

to:

console.log('Battery voltage is ' + voltage + 'V');

Then I get an out like:

1487608400879 Device(s) C.H.I.P.
1487608400916 Connected C.H.I.P.
1487608400994 Repl Initialized
>> Battery voltage is 0V
Battery voltage is 4.1107000000000005V
Battery voltage is 4.111800000000001V
Battery voltage is 4.1107000000000005V
Battery voltage is 4.111800000000001V
Battery voltage is 4.1107000000000005V
Battery voltage is 4.111800000000001V
Battery voltage is 4.1107000000000005V
Battery voltage is 4.111800000000001V

Conclusion

This PR changes the precision to 4 decimal places, and applies it (earlier) before the change event is emitted, resulting in an output like:

1487608700666 Device(s) C.H.I.P.
1487608700703 Connected C.H.I.P.
1487608700781 Repl Initialized
>> Battery voltage is 0.0000V
Battery voltage is 4.1107V
Battery voltage is 4.1096V
Battery voltage is 4.1107V
Battery voltage is 4.1096V
Battery voltage is 4.1107V
Battery voltage is 4.1096V
Battery voltage is 4.1107V
Battery voltage is 4.1118V
Battery voltage is 4.1107V
Battery voltage is 4.1118V
Battery voltage is 4.1107V
Battery voltage is 4.1118V
Battery voltage is 4.1107V

There are sequential duplicates and we now have 4dp precision.

sandeepmistry commented 7 years ago

Hey @norgeous,

Thanks for submitting, is there any particular reason "4dp precision." was selected?

norgeous commented 7 years ago

Everything after the 4th digit is garbage. It is an effect of the way its calculated. There is no actual information after the 4th dp. I suspect that 4dp is the max resolution of the sensor. 4dp = mV resolution.

Battery voltage is 4.1107000000000005V
Battery voltage is 4.111800000000001V

As you can see from this sample, 4.1107000000000005 has no info other than 4.1107, the 000000000005 part is meaningless.

sandeepmistry commented 7 years ago

@norgeous it would be nice to mathematically determine the precision using some info from the data sheet.

norgeous commented 7 years ago

@sandeepmistry Looking at the data sheet, we can see:

Channel Registers 000h Step FFFh
Battery Voltage 78h, 79h 0 mV 1.1 mV 4.5045 V

The precision is 4dp, with a 0.0011 V step. There are 4095 possible values.

sandeepmistry commented 7 years ago

@norgeous nice! Thanks for the info from the data sheet!

norgeous commented 7 years ago

Thanks @sandeepmistry, I agree with your comment. So after much research and testing, I think the best solution actually is:

var voltage = (value * 11) / 10000;

Simple right? I guess it's not a good idea to multiply by floating numbers in js. I'll change the PR to this way now...

Test case:

(3817 * 1.1) / 1000 = 4.1987000000000005
(3817 * 11) / 10000 = 4.1987
sandeepmistry commented 7 years ago

@norgeous thanks!

Simple right? I guess it's not a good idea to multiply by floating numbers in js. I'll change the PR to this way now...

I would say JS per say, it applies to floating point in all languages.