GithubHelp home page GithubHelp logo

Comments (7)

hogthrob avatar hogthrob commented on June 18, 2024 1

Hi,
I see similar issues with this fine library:

Every read of a register adds 1 ms delay which is only in very rare cases helpful.

I can only assume this is to have a converted value ready (as conversion time is by default 532uS). But this really makes no sense in most cases. In continuous mode it will just add 1ms of wait, but as conversion start is not synchronized with register read, it does not add any value. We would get an equally up to date value without wait.
In averaging modes, waiting 1ms is completely pointless as well.
The only use case where it makes sense, is to wait for the first conversion to complete just after setting a mode which completes conversion in less then 1 ms.

Writing the register addr every time not always required

If the last read from the INA219 was from the same register and there was no reset in between, there is no need to write the register address again to the INA219.

I would be willing to provide a PR which implements:

  • start() -> trigger new conversion by "rewriting" the current mode, this is faster than using getPower_raw()
  • available() -> returns true if completed conversion is available by by reading the CNVR register
  • conditionally disabling 1ms wait in readRegister by calling a different constructor, in order to be fully backward compatible in terms of timing (some existing applications may rely on the 1ms delay.
  • cache last set register addr so that we save time if when reading the same register over and over, this would be only active if the 1ms delay is deactivated.

It will need 3 more bytes of data (for remembering the conversion mode and the last register) and a few bytes of code. Time-wise the impact in the backward compatible mode should be only very, very few cycles ( if(doWait) { ... } ).

@ladyada: My question before doing all of this (which would include migrating my application to use the Adafruit INA219 library from working INA219 code) is: Is there a good chance that this PR (assuming it meets the quality / code style requirements ) gets integrated quickly, i.e. my effort is not wasted with a sufficiently high probability?

from adafruit_ina219.

ladyada avatar ladyada commented on June 18, 2024

hmm can you try getPower_mW()?

from adafruit_ina219.

Ve2mrx avatar Ve2mrx commented on June 18, 2024

@ladyada :
I manually copied the latest library since the property update has not been picked up by the IDE yet. I updated my Sketches accordingly to use the getPower_mW function.

My remaining issue is that every value read is uncorrelated to its siblings in time. When I read voltage and current, they are read at different times.

Is the INA219 capable of taking one measurement then let you read the voltage and current registers without causing another measurement? I could not find in the Datasheet how to trigger a measurement, I'm guessing reading triggers a new set of measurements? If that is so, then then I think it's impossible to do.

The following code makes me think that reading a register triggers (or would trigger) a measurement for every register read. You have to start a read by writing the register pointer:

void Adafruit_INA219::wireReadRegister(uint8_t reg, uint16_t *value)
{

  _i2c->beginTransmission(ina219_i2caddr);
  #if ARDUINO >= 100
    _i2c->write(reg);                       // Register
  #else
    _i2c->send(reg);                        // Register
  #endif
  _i2c->endTransmission();
  
  delay(1); // Max 12-bit conversion time is 586us per sample

  _i2c->requestFrom(ina219_i2caddr, (uint8_t)2);  
  #if ARDUINO >= 100
    // Shift values to create properly formed integer
    *value = ((_i2c->read() << 8) | _i2c->read());
  #else
    // Shift values to create properly formed integer
    *value = ((_i2c->receive() << 8) | _i2c->receive());
  #endif
}

It would still be useful to have a triggered mode for power savings and synchronization to external events.

Thanks!
Martin

from adafruit_ina219.

Ve2mrx avatar Ve2mrx commented on June 18, 2024

I just found a nugget of valuable information in the INA219 datasheet (SBOS448G –AUGUST 2008–REVISED DECEMBER 2015), page 9, heading 8.3.1, at the very bottom:

The Mode control in the Configuration register also permits selecting modes to convert only voltage or current, either continuously or in response to an event (triggered). (p9, 8.3.1, paragraph 2)

Writing any of the triggered convert modes into the Configuration register (even if the desired mode is already programmed into the register) triggers a single-shot conversion. (p9, 8.3.1, paragraph 5)

I guess the INA219 CAN be triggered and ALL measurements be read before triggering another one! Correlated data is possible!

Martin

from adafruit_ina219.

Ve2mrx avatar Ve2mrx commented on June 18, 2024

Hi @hogthrob,
What I would have done would be to trigger a conversion, and read all values in holding variables. Then, either wait for another conversion request or start one automatically depending on a flag.

When needed, the program would trigger, wait, copy the array of correlated values, or simply trigger after reading if freshness is not an issue.

If correlation is not important, the auto-trigger flag would be set to auto and the values read as needed from the array, like it is now.

Of course, it might be a new function in the library, as Adafruit has mentioned that backwards compatibility is critical. I'm only a beginner, but I believe a Pro could implement it with backward compatibility.

Even if it lives only as a pull-request and never gets pulled in, it will be useful to others. Many great features live only in pull requests. My guess is that they want to keep code size and memory requirements to a minimum for small micro-controllers.

I might be able to dig back in this next week if you need me,

Martin

from adafruit_ina219.

ladyada avatar ladyada commented on June 18, 2024

we'd take a clean PR that requests both at once and places the values into pointers, ideally it would take two Adafruit_Sensor objects and set one to VOLTAGE and one to CURRENT type, then they could be timestamped as well. see

https://github.com/adafruit/Adafruit_LSM6DSOX/blob/master/Adafruit_LSM6DSOX.cpp#L190
it must pass CI and not break any existing code

from adafruit_ina219.

themindfactory avatar themindfactory commented on June 18, 2024

I have seen this also and I think paragraph 8.3.1.1 of the datasheets states why, at least when it does power measurement itself... I think the same holds true when you are doing it also.

from adafruit_ina219.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.