Перейти к содержанию

Отредактировать библиотеку под замену шунта для ina219


Рекомендуемые сообщения

Подскажите как правильно расширить диапазон по току и напряжению в модуле ina219 ? Шунт заменил на такой:

 

Opera Снимок_2022-07-09_145903_prom.ua.png

Opera Снимок_2022-07-09_145922_prom.ua.png

шунт на 3750мкОм

библиотеку взял INA219_WE-master

менять в скетче данные не получается, значит нужно лезть в библиотеку. Насколько я понял мне нужно свои данные вставить сюда:

Screenshot_7.png

Но есть у меня сомнения, может еще где-то надо подправить ? И еще, если с током понятно, что решается заменой шунта, а вот с напряжением не очень. У меня 36 вольт, а там расчитано на 26 вольт, вот не могу сообразить , если делитель напряжения делать, то как его подключать к модулю, чтоб не повлияло на показания?

Вот файл конфигурации:

This is a library for the INA219 Current Sensor Module
*
* You'll find an example which should enable you to use the library. 
*
* You are free to use it, change it or build on it. In case you like 
* it, it would be cool if you give it a star.
* 
* If you find bugs, please inform me!
* 
* Written by Wolfgang (Wolle) Ewald
* https://wolles-elektronikkiste.de/en/ina219-current-and-power-sensor (English)
* https://wolles-elektronikkiste.de/ina219 (German)
*
*******************************************/

#include "INA219_WE.h"

INA219_WE::INA219_WE(int addr){
#ifndef USE_TINY_WIRE_M_
    _wire = &Wire;
#endif
    i2cAddress = addr;   
}

INA219_WE::INA219_WE(){
#ifndef USE_TINY_WIRE_M_
    _wire = &Wire;
#endif
    i2cAddress = 0x40;   
}

#ifndef USE_TINY_WIRE_M_
INA219_WE::INA219_WE(TwoWire *w, int addr){
    _wire = w;
    i2cAddress = addr; 
}

INA219_WE::INA219_WE(TwoWire *w){
    _wire = w;
    i2cAddress = 0x40;
}
#endif
    
bool INA219_WE::init(){ 
    if( !reset_INA219() )
    {
        return false;
    }
    setADCMode(BIT_MODE_12);
    setMeasureMode(CONTINUOUS);
    setPGain(PG_320);
    setBusRange(BRNG_32);
    shuntFactor = 1.0;
    overflow = false;
    shuntVoltageOffset = 0.0;
    offsetIsSet = false;
    
    return true;
}

bool INA219_WE::reset_INA219(){
    byte ack = writeRegister(INA219_CONF_REG, INA219_RST); 
    return ack == 0;
}

void INA219_WE::setCorrectionFactor(float corr){
    calValCorrected = calVal * corr;
    writeRegister(INA219_CAL_REG, calValCorrected);
}

void INA219_WE::setShuntVoltOffset_mV(float offs){
    shuntVoltageOffset = offs;
    offsetIsSet = true; 
}

void INA219_WE::setADCMode(INA219_ADC_MODE mode){
    deviceADCMode = mode;
    uint16_t currentConfReg = readRegister(INA219_CONF_REG);
    currentConfReg &= ~(0x0780);  
    currentConfReg &= ~(0x0078);
    uint16_t adcMask = mode<<3;
    currentConfReg |= adcMask;
    adcMask = mode<<7;
    currentConfReg |= adcMask;
    writeRegister(INA219_CONF_REG, currentConfReg);
}

void INA219_WE::setMeasureMode(INA219_MEASURE_MODE mode){
    deviceMeasureMode = mode;
    uint16_t currentConfReg = readRegister(INA219_CONF_REG);
    currentConfReg &= ~(0x0007);
    currentConfReg |= deviceMeasureMode;
    writeRegister(INA219_CONF_REG, currentConfReg);
}

void INA219_WE::setPGain(INA219_PGAIN gain){
    devicePGain = gain;
    uint16_t currentConfReg = readRegister(INA219_CONF_REG);
    currentConfReg &= ~(0x1800);
    currentConfReg |= devicePGain;
    writeRegister(INA219_CONF_REG, currentConfReg);
    
    switch(devicePGain){
        case PG_40:
            calVal = 20480;
            currentDivider_mA = 50.0;
            pwrMultiplier_mW = 0.4;
            shuntOverflowLimit = 4000;
            break;
        case PG_80:
            calVal = 10240;
            currentDivider_mA = 25.0;
            pwrMultiplier_mW = 0.8;
            shuntOverflowLimit = 8000;
            break;
        case PG_160:
            calVal = 8192;
            currentDivider_mA = 20.0;
            pwrMultiplier_mW = 1.0;
            shuntOverflowLimit = 16000;
            break;
        case PG_320:
            calVal = 4096;
            currentDivider_mA = 10.0;
            pwrMultiplier_mW = 2.0;
            shuntOverflowLimit = 32000;
            break;
    }
    
    writeRegister(INA219_CAL_REG, calVal);
            
}

void INA219_WE::setBusRange(INA219_BUS_RANGE range){
    deviceBusRange = range;
    uint16_t currentConfReg = readRegister(INA219_CONF_REG);
    currentConfReg &= ~(0x2000);
    currentConfReg |= deviceBusRange;
    writeRegister(INA219_CONF_REG, currentConfReg);
}

void INA219_WE::setShuntSizeInOhms(float shuntSize){
    shuntFactor = shuntSize / 0.1;
}

float INA219_WE::getShuntVoltage_mV(){
    int16_t val;
    val = (int16_t) readRegister(INA219_SHUNT_REG);
    if((abs(val))== shuntOverflowLimit){
        overflow = true;
    }
    else{
        overflow = false;
    }
    return (val * 0.01);
}


float INA219_WE::getBusVoltage_V(){
    uint16_t val;
    val = readRegister(INA219_BUS_REG);
    val = ((val>>3) * 4);
    return (val * 0.001);
}


float INA219_WE::getCurrent_mA(){
    int16_t val;
    int16_t offsetCurrent = 0;
    val = (int16_t)readRegister(INA219_CURRENT_REG);
    if(offsetIsSet){
        offsetCurrent = (int16_t)(shuntVoltageOffset * 100.0 * calVal / 4096.0);
    }
    return ((val - offsetCurrent) / (currentDivider_mA * shuntFactor));
}

float INA219_WE::getBusPower(){
    uint16_t val;
    float busPwr = 0.0;
    if(offsetIsSet){
        float current = getCurrent_mA();
        float busVolt = getBusVoltage_V();
        busPwr = current * busVolt;   
    }
    else{
        val = readRegister(INA219_PWR_REG);
        busPwr = val * pwrMultiplier_mW / shuntFactor;
    }
    return busPwr;
}

bool INA219_WE::getOverflow(){
    uint16_t val;
    val = readRegister(INA219_BUS_REG);
    if(val & 1){ 
        overflow = true;
    }
    return overflow;
}

void INA219_WE::startSingleMeasurement(){
    uint16_t val = readRegister(INA219_BUS_REG); // clears CNVR (Conversion Ready) Flag
    val = readRegister(INA219_CONF_REG);
    writeRegister(INA219_CONF_REG, val);
    uint16_t convReady = 0x0000;
    while(!convReady){
        convReady = ((readRegister(INA219_BUS_REG)) & 0x0002); // checks if sampling is completed
    }
}


bool INA219_WE::startSingleMeasurement(unsigned long timeout_us){
    uint16_t val = readRegister(INA219_BUS_REG); // clears CNVR (Conversion Ready) Flag
    val = readRegister(INA219_CONF_REG);
    writeRegister(INA219_CONF_REG, val);
    uint16_t convReady = 0x0000;
    unsigned long convStart = micros();
    while(!convReady && (micros() - convStart < timeout_us)){
        convReady = ((readRegister(INA219_BUS_REG)) & 0x0002); // checks if sampling is completed
    }
    if(convReady) {
        return true;
    } else {
        return false;
    }
}

void INA219_WE::powerDown(){
    confRegCopy = readRegister(INA219_CONF_REG);
    setMeasureMode(POWER_DOWN);
}

void INA219_WE::powerUp(){
    writeRegister(INA219_CONF_REG, confRegCopy);
    delayMicroseconds(40);  
}   

#ifndef USE_TINY_WIRE_M_
uint8_t INA219_WE::writeRegister(uint8_t reg, uint16_t val){
  _wire->beginTransmission(i2cAddress);
  uint8_t lVal = val & 255;
  uint8_t hVal = val >> 8;
  _wire->write(reg);
  _wire->write(hVal);
  _wire->write(lVal);
  return _wire->endTransmission();
}
  
uint16_t INA219_WE::readRegister(uint8_t reg){
  uint8_t MSByte = 0, LSByte = 0;
  uint16_t regValue = 0;
  _wire->beginTransmission(i2cAddress);
  _wire->write(reg);
  _wire->endTransmission(false);
  _wire->requestFrom(i2cAddress,2);
  if(_wire->available()){
    MSByte = _wire->read();
    LSByte = _wire->read();
  }
  regValue = (MSByte<<8) + LSByte;
  return regValue;
}
#else
uint8_t INA219_WE::writeRegister(uint8_t reg, uint16_t val){
  TinyWireM.beginTransmission(i2cAddress);
  uint8_t lVal = val & 255;
  uint8_t hVal = val >> 8;
  TinyWireM.send(reg);
  TinyWireM.send(hVal);
  TinyWireM.send(lVal);
  return TinyWireM.endTransmission();
}
  
uint16_t INA219_WE::readRegister(uint8_t reg){
  uint8_t MSByte = 0, LSByte = 0;
  uint16_t regValue = 0;
  TinyWireM.beginTransmission(i2cAddress);
  TinyWireM.send(reg);
  TinyWireM.endTransmission();
  TinyWireM.requestFrom(i2cAddress,2);
  MSByte = TinyWireM.receive();
  LSByte = TinyWireM.receive();
  regValue = (MSByte<<8) + LSByte;
  return regValue;
}
#endif

 

а вот сам скетч с заменой шунта:

/***************************************************************************
* Example sketch for the INA219_WE library
*
* This sketch shows how to use the INA219 module with a shunt different than 
* 0.1 ohms (R100) in continuous mode. 
* 
#* Further information can be found on:
* https://wolles-elektronikkiste.de/ina219 (German)
* https://wolles-elektronikkiste.de/en/ina219-current-and-power-sensor (English)
* 
***************************************************************************/
#include <Wire.h>
#include <INA219_WE.h>
#define I2C_ADDRESS 0x40

/* There are several ways to create your INA219 object:
 * INA219_WE ina219 = INA219_WE()              -> uses Wire / I2C Address = 0x40
 * INA219_WE ina219 = INA219_WE(ICM20948_ADDR) -> uses Wire / I2C_ADDRESS
 * INA219_WE ina219 = INA219_WE(&wire2)        -> uses the TwoWire object wire2 / I2C_ADDRESS
 * INA219_WE ina219 = INA219_WE(&wire2, I2C_ADDRESS) -> all together
 * Successfully tested with two I2C busses on an ESP32
 */
INA219_WE ina219 = INA219_WE(I2C_ADDRESS);

void setup() {
  Serial.begin(9600);
  Wire.begin();
  if(!ina219.init()){
    Serial.println("INA219 not connected!");
  }

  /* Set ADC Mode for Bus and ShuntVoltage
  *   * Mode *          * Res / Samples *     * Conversion Time *
    BIT_MODE_9        9 Bit Resolution             84 µs
    BIT_MODE_10       10 Bit Resolution            148 µs  
    BIT_MODE_11       11 Bit Resolution            276 µs
    BIT_MODE_12       12 Bit Resolution            532 µs  (DEFAULT)
    SAMPLE_MODE_2     Mean Value 2 samples         1.06 ms
    SAMPLE_MODE_4     Mean Value 4 samples         2.13 ms
    SAMPLE_MODE_8     Mean Value 8 samples         4.26 ms
    SAMPLE_MODE_16    Mean Value 16 samples        8.51 ms     
    SAMPLE_MODE_32    Mean Value 32 samples        17.02 ms
    SAMPLE_MODE_64    Mean Value 64 samples        34.05 ms
    SAMPLE_MODE_128   Mean Value 128 samples       68.10 ms
  */
  //ina219.setADCMode(SAMPLE_MODE_128); // choose mode and uncomment for change of default
  
  /* Set measure mode
    POWER_DOWN  - INA219 switched off
    TRIGGERED   - measurement on demand
    ADC_OFF     - Analog/Digital Converter switched off
    CONTINUOUS  - Continuous measurements (DEFAULT)
  */
  // ina219.setMeasureMode(CONTINUOUS); // choose mode and uncomment for change of default
  
 /* Set PGain
  * Gain *  * Shunt Voltage Range *         * Max Current *
    PG_40          40 mV               0.4 A * 0.1 / shuntSizeInOhms 
    PG_80          80 mV               0.8 A * 0.1 / shuntSizeInOhms 
    PG_160        160 mV               1.6 A * 0.1 / shuntSizeInOhms 
    PG_320        320 mV               3.2 A * 0.1 / shuntSizeInOhms (DEFAULT)
  */
 //ina219.setPGain(PG_320); // choose gain and uncomment for change of default
  
  /* Set Bus Voltage Range
    BRNG_16   -> 16 V
    BRNG_32   -> 32 V (DEFAULT)
  */
  // ina219.setBusRange(BRNG_32); // choose range and uncomment for change of default

  /* If the current values delivered by the INA219 differ by a constant factor
     from values obtained with calibrated equipment you can define a correction factor.
     Correction factor = current delivered from calibrated equipment / current delivered by INA219
  */
  // ina219.setCorrectionFactor(0.98); // insert your correction factor if necessary

  /* If you experience a shunt voltage offset, that means you detect a shunt voltage which is not 
     zero, although the current should be zero, you can apply a correction. For this, uncomment the 
     following function and apply the offset you have detected.   
  */
  // ina219.setShuntVoltOffset_mV(0.5); // insert the shunt voltage (millivolts) you detect at zero current

  /* Set shunt size
     If you don't use a module with a shunt of 0.1 ohms (R100) you can change set the shunt size 
     here. 
  */
  ina219.setShuntSizeInOhms(0.0333); // Insert your shunt size in ohms
  
  Serial.println("INA219 Set Shunt Size"); 
}

void loop() {
  float shuntVoltage_mV = 0.0;
  float loadVoltage_V = 0.0;
  float busVoltage_V = 0.0;
  float current_mA = 0.0;
  float power_mW = 0.0; 
  bool ina219_overflow = false;
  
  shuntVoltage_mV = ina219.getShuntVoltage_mV();
  busVoltage_V = ina219.getBusVoltage_V();
  current_mA = ina219.getCurrent_mA();
  power_mW = ina219.getBusPower();
  loadVoltage_V  = busVoltage_V + (shuntVoltage_mV/1000);
  ina219_overflow = ina219.getOverflow();
  
  Serial.print("Shunt Voltage [mV]: "); Serial.println(shuntVoltage_mV);
  Serial.print("Bus Voltage [V]: "); Serial.println(busVoltage_V);
  Serial.print("Load Voltage [V]: "); Serial.println(loadVoltage_V);
  Serial.print("Current[mA]: "); Serial.println(current_mA);
  Serial.print("Bus Power [mW]: "); Serial.println(power_mW);
  if(!ina219_overflow){
    Serial.println("Values OK - no overflow");
  }
  else{
    Serial.println("Overflow! Choose higher PGAIN");
  }
  Serial.println();
  
  delay(3000);
}

 

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
  • Сообщения

×
×
  • Создать...