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

Question about ADC reading and code structure. #10

Open
AndyEveritt opened this issue Feb 10, 2022 · 3 comments
Open

Question about ADC reading and code structure. #10

AndyEveritt opened this issue Feb 10, 2022 · 3 comments

Comments

@AndyEveritt
Copy link

I can not currently source the ACS70331EOLCTR-2P5B3 current sensors so I have been looking for alternatives.

I found this sensor from TI https://www.ti.com/lit/ds/symlink/tmcs1101-q1.pdf?HQS=dis-dk-null-mousermode-dsf-pf-null-wwe&ts=1641839042153 which seems to be approximately the same, but the sensitivity for the 3.3V version only goes up to 200mV/A (instead of 400mV/A).

To make sure that I could change the source code to accept this sensor I looked for where the sensitivity and and current range is set. Potentially I am misunderstanding but the datasheet for the current sensor says its +/-2.5A with 400mV/A and 1.5V at 0A.
image

In the code src/misc/hardware_config.h, the sensor struct appears to be defined

struct SensorSpec {
  const char* name;
  const uint16_t range_milliamps;
  const float volts_per_amp;
  // These computed values are cached to speed up unit conversions.
  const float counts_per_amp;
  const float amps_per_count;
  const float milliamps_per_count;

  SensorSpec(const char* name_, uint16_t range_milliamps_, float volts_per_amp_)
      : name(name_),
        range_milliamps(range_milliamps_),
        volts_per_amp(volts_per_amp_),
        counts_per_amp(volts_per_amp * 4096 / 3.3),
        amps_per_count(1 / counts_per_amp),
        milliamps_per_count(1000 / counts_per_amp) {}

  // Convert adc value to milliamps.
  int adc_value_to_milliamps(int adc_value) const {
    return (int)(adc_value * milliamps_per_count);
  }

  // Convert adc value to amps.
  float adc_value_to_amps(int adc_value) const {
    return ((float)adc_value) * amps_per_count;
  }
};

As far as I can tell the conversion of adc value to (milli)amps does not take into account the 1.5V @ 0A offset that the sensor has?

For example, you create an instance of this struct using static const SensorSpec GMR_2P5_SENSOR("G2P5A", 2500, 0.4);. If the sensor was measuring 0A, it would output 1.5V, I believe this would read 2048 on the ADC (if you are using the an external 3.0V shunt reference for the ADC_VREF pin to improve ADC performance, which I can't see in the schematic either so might be a nice addition? Otherwise it will read ~1862).

Having just gone even deeper into trying to understand the code, I have now found that there is an offset for each of the ADC's in src/aquisition/analyzer.h which is applied to the value before it is converted to (milli)amps, which answers my question about if the sensor offset was being accounted for.

My new question (based on trying to get more familiar with embedded programming by learning from others) is why have you split the offset and other current sensor specific variables across 2 structs? I assume it is because the offset varies sensor to sensor so you need to calibrate it dynamically which would mean you couldn't use const for the sensor definition, which I assume is for some minor speed gain?

I appoligse for the long and convoluted question. I started typing as I was discovering to keep track of my train of thought. In essence, I would just like to understand why you have structured the code the way you have so I can learn and either apply or avoid it in my own coding.

Also it may be interesting to apply the recommended change to the circuit to improve the ADC performance
image

@globalcitizen
Copy link

globalcitizen commented Apr 23, 2022

The TI part is hall effect based. The originally specified part was GMR. There are also TMR parts. This paper and this site explain the differences. Based on that, maybe it would be best to look for TMR parts and these guys seem promising.

@zapta
Copy link
Owner

zapta commented Apr 23, 2022 via email

@globalcitizen
Copy link

Yep. MCA1101-5-3 is AMR based, according to the datasheet. This 2015 review (part one, part two compares AMR to the other approaches in more quantum physical detail than my mathematical literacy will stand for. But the result seems to be: if it's not TMR, it's functionally prior-generation and therefore potentially not the best thing to design for in terms of design longevity.

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

3 participants