Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By dynek
#75316
btidey wrote:I add a calibration factor into my ADC routines (adjustable remotely) and when this is used then the ADC is quite usable for things like battery monitoring.

Would you mind sharing the routine?
As well as explain how you define how it should be calibrated if you are far from the device and can't apply a definite voltage to check the value returned?
User avatar
By danbicks
#75323
dynek wrote:
btidey wrote:I add a calibration factor into my ADC routines (adjustable remotely) and when this is used then the ADC is quite usable for things like battery monitoring.

Would you mind sharing the routine?
As well as explain how you define how it should be calibrated if you are far from the device and can't apply a definite voltage to check the value returned?


Dynek

Here is a routine that I use, the calibration value is the potential divider ratio.

Code example to obtain actual battery voltage:
Code: Select allraw = analogRead(A0); // get raw a>d value
          Serial.print("Raw: "); Serial.println(raw);
          volt=raw/1023.0; // note volt is declared as a float and raw as an int
          volt=volt * 4.41; // this is the calibration value that you need to change to obtain precision, potential
          Divider ratio.
          Serial.print("Battery: "); Serial.println(volt); // print actual battery voltage
          Payload = volt; // prepare payload for MQTT publish
          RFIDBATT.publish(Payload.c_str());


Hope this helps, it is pretty straight forward.
Dans
User avatar
By btidey
#75333 When I said remotely calibrate I didn't mean automatically calibrate without any external measurement.

Rather I meant that I use a variable for the calibration factor that is stored locally but I can control remotely. I found that more convenient than fixing it in the firmware particularly if I have several devices using the same code.

A simple example would be
Code: Select allvoid checkBattery() {
   int adc;
   adc = analogRead(A0);
   battery_volts = (battery_volts * 15 + battery_mult * adc_cal * adc) / 16;
   }
}


where the function is called periodically in the loop to update the measured battery voltage (float battery_volts;).

battery_mult is a fixed factor reflecting the potential divider scaling the battery volts down.
e.g. float battery_mult = 57.0/10.0/1024; //47K 10K divider
adc_cal is the calibration factor.

I normally store this in a SPIFFS file along with any other config data. It is read during setup but can be updated by a server call. So I measure the battery voltage with a voltmeter then compare that against the battery_volts value to calculate the appropriate adc_cal value.

The function above contains a simple running average to reduce residual noise from the ADC
User avatar
By danbicks
#75337 I think this now clears the confusion for dynek. If you do not have a lot of config data this could be stored in eeprom as an alternative to spiffs.

I would opt for higher values of resistance in my potential divider as the values of 47k and 10k will give a constant current draw of 87.74uA based on an input voltage of 5 volts, this could be reduced further as the key with any battery operated device is to draw minimum quiescent current.

Great work though.

Dans