Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with computeVolt and compiler optimisation #93

Open
anvgfr opened this issue Aug 25, 2024 · 1 comment
Open

Problem with computeVolt and compiler optimisation #93

anvgfr opened this issue Aug 25, 2024 · 1 comment

Comments

@anvgfr
Copy link

anvgfr commented Aug 25, 2024

Hello,

using your library to make data acquisition i noticed that sometimes computeVolt return a bad result, due to some compiler optimisation, like in this output :

Channel 1 and 2 are wrong : rms is rounded as int before calling computeVolt to get Vapp, it should be 0V !

# Channel 0 : rms=0.8519 / min=0 / max=2 /  Vapp = 97897.4375V / min=0.0000V / max=0.0040V /  I=5933178.0000A
# Channel 1 : rms=0.9333 / min=-1 / max=3 /  Vapp = 0.0000V / min=-0.0020V / max=0.0060V /  I=0.0000A
# Channel 2 : rms=0.9070 / min=0 / max=2 /  Vapp = 68943856272903503872.0000V / min=0.0000V / max=0.0040V /  I=4178415527426349072384.0000A
# Channel 3 : rms=0.7184 / min=-1 / max=1 /  Vapp = -0.0000V / min=-0.0020V / max=0.0020V /  I=-0.0000A
# Channel 4 : rms=0.9837 / min=-1 / max=3 /  Vapp = -0.0000V / min=-0.0020V / max=0.0060V /  I=-0.0020A

I am running on ESP32 with Arduino_ESP32 library (Arduino IDE version 2.3.2), AdaFruit latest release (2.5.0).
Chips is an ADS1015 (from techniot bought on Amazon)

Original parts of the code producing random wrong value some times:

> > MainPowerChannel.RMSValue = MainPowerChannel.RMSValue / MainSampleRead;
> > MainPowerChannel.RMSValue = sqrt(MainPowerChannel.RMSValue);
> > // Convert to Volt using ADC resolution
> > MainPowerChannel.Vapp = adcComputeVolts(iMainVoltageADC, MainPowerChannel.RMSValue);
> 

(source is used to get the right ADC object to used on a list of 2...)

float adcComputeVolts(int _source, int16_t value) {
  if (_source >= NB_MAX_ADC_CHANNEL) return -1;
  int adsid = _source / NB_CHANNEL_BY_ADC;
  int adspin = _source % NB_CHANNEL_BY_ADC;
  //Serial.printf("ACV? %d=(%d,%d) %d\r\n",_source,adsid,adspin,value);
  //int16_t retvalue=value*1;
  return ads[adsid].computeVolts(value);
}

to solve temporarly this problem i had to use the source value before calling computeVolt in my own code (using a printf or another operation. (removing one or the other comment)

reading the current library code, i found that the current operation give priority on the division of the full range value (float) by the resolution BEFORE applying current source value.

float Adafruit_ADS1015::computeVolts(int16_t counts) 
{
  // see data sheet Table 3
  float fsRange;
  switch (m_gain) {
  case GAIN_TWOTHIRDS:
    fsRange = 6.144f;
    break;
  case GAIN_ONE:
    fsRange = 4.096f;
    break;
  case GAIN_TWO:
    fsRange = 2.048f;
    break;
  case GAIN_FOUR:
    fsRange = 1.024f;
    break;
  case GAIN_EIGHT:
    fsRange = 0.512f;
    break;
  case GAIN_SIXTEEN:
    fsRange = 0.256f;
    break;
  default:
    fsRange = 0.0f;
 }
 return counts * (fsRange / (32768 >> m_bitShift));
}

So i changed the order of the code to do the multiplication first then the division (better for accurancy)

  // Change order of operation to do upscaling before downscaling;
  return (fsRange*counts) / (32768 >> m_bitShift);

And now i did'nt get any problem with the calculation.

@anvgfr
Copy link
Author

anvgfr commented Aug 28, 2024

For other users that will come on this problem :

Searching more for this problem since it still occurs, i fall on a weird bug in espressif SDK with floating point calculation errors due to context switching.
It seems to have been corrected in 5.1.0 version and for the ESP32-S3, but since it is not my target, i suspect that the problem is wider and not corrected on the 4.4 branch too.

#espressif/esp-idf#11690

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant