SignalK / SensESP

Universal Signal K sensor framework for the ESP32 platform
https://signalk.org/SensESP/
Apache License 2.0
146 stars 80 forks source link

temperature_sender.cpp in the examples calculates incorrectly #638

Closed Techstyleuk closed 1 year ago

Techstyleuk commented 1 year ago

I was looking more at your Temp sender code and couldn't work it out, but I think I found an error, that you may have corrected with the R1 value: Code: const float Vin = 3.3; const float R1 = 51.0; auto* analog_input = new AnalogInput(36); analog_input->connect_to(new AnalogVoltage()) ->connect_to(new VoltageDividerR2(R1, Vin, "/12V_alternator/temp/sender")) ->connect_to(new TemperatureInterpreter("/12V_alternator/temp/curve")) ->connect_to(new Linear(1.0, 0.0, "/12V_alternator/temp/calibrate")) ->connect_to( new SKOutputFloat(sk_path, "/12V_alternator/temp/sk", metadata));

the "analog input" is measured in Bits from 0-1023, this is then translated to Voltage by the "AnalogVoltage" transform, but this calculation gets you the percentage of the max voltage, not the actual voltage, therefore the rest of the calcs don't work out correctly - this had me stumped for a bit but if you change that line to: Code: analog_input->connect_to(new AnalogVoltage(Vin,Vin)) then it worked out, the first "Vin" sets the max voltage to the input voltage you have stated above and then the second "Vin" is the multiplier to get it back to voltage from percentage.

In discussions on the slack channel it was pointed out by @ba58smith that it should read:

Code: const float Vin = 3.3; const float R1 = 51.0; auto* analog_input = new AnalogInput(36, 1000, "/temp_analog_in/", Vin); ->connect_to(new VoltageDividerR2(R1, Vin, "/12V_alternator/temp/sender")) ->connect_to(new TemperatureInterpreter("/12V_alternator/temp/curve")) ->connect_to(new Linear(1.0, 0.0, "/12V_alternator/temp/calibrate")) ->connect_to( new SKOutputFloat(sk_path, "/12V_alternator/temp/sk", metadata));

I will try to make the change

ba58smith commented 1 year ago

@Techstyleuk, I just made up that config path in my answer on Slack: "/temp_analog_in/",. To match with this example, it should probably be "/12V_alternator/temp/analog_in/".

Also, in my Slack answer, I did not use Vin as the last parameter to AnalogInput - I specifically used 3.3, and I did that on purpose. While it's likely that the max allowable voltage into pin 36 is the same as the voltage used as the input to the VoltageDivider, that might not always be the case. You might use the 5.0V source on the ESP32 for your voltage divider circuit, for some reason. And for a very few ESP boards, the analog in pins do NOT scale up to 3.3, they scale only to 1.0, so for those boards, that last parameter should be 1.0.

What IS always the case is that, if you want AnalogInput to scale its output to something between 0.0 and 3.3, you should use 3.3 as that last parameter. And you should use the actual voltage input into your voltage divider circuit in the parameter to VoltageDividerR2().

So if you want to have a variable with a name that is informational, you could add: const float max_analog_in_voltage = 3.3;, then use that as the last parameter to AnalogInput().

You could do something similar for the voltage into the voltage divider circuit: const float volt_div_v_in = 3.3;.

Of course, it will work no matter how you get 3.3 into both of those slots, but for these reasons, I wouldn't assume they're always the same.

ba58smith commented 1 year ago

Closed with PR #639