Вольтамперметр для источника питания на INA226

Микросхема INA226 (модуль) предназначена для высокоточного измерения напряжения, тока и потребляемой мощности. В модуле установлен шунт на 0,1 Ом, при этом модуль может измерять ток до 800 мА, но если заменить шунт например на 0,01 Ом, то диапазон измерения тока может быть расширен до 8 А.

Основные характеристики модуля на INA226:

  • Диапазон измеряемого напряжения 0–36 вольт
  • Максимальный ток 800 миллиампер (2 шага усиления, на 400 и 800 мА)
  • Напряжение питания 3 – 5,5 вольт
  • Потребляемая мощность (определяется самостоятельно):
    • Непрерывный режим: 0,35 мА
    • Режим пониженного энергопотребления: 2,3 мкА
  • Режимы измерения: непрерывный или по требованию
  • Количество выборок, которое собирается и усредняется 1, 4, 64, 128, 256, 512 или 1024
  • Время преобразования для измерения напряжения на восьми уровнях: от 0,14 до 8,2 мс
  • Связь через I2C, 4 настраиваемых адреса (модуль):
    • 0x40: A0, A1 не замкнут с VCC
    • 0x41: A0 = VCC, A1 не замкнут с VCC
    • 0x44: A0 не замкнут с VCC, A1 = VCC
    • 0x45: A0, A1 = VCC

На платформе Arduino (плата LGT8F328P-LQFP32 MiniEVB) используя модуль INA226 можно сделать простой, но высокоточный вольтамперметр для регулируемого источника питания, вся информация будет выводится на дисплей LCD1602 c модулем I2C. Дополнительно модуль производит измерение мощности, а измеряя потребляемый ток и время на дисплей можно выводить ампер-часы, что удобно при зарядке аккумуляторов. Так как будет измеряться ампер-часы, то будет добавлена кнопка для обнуления результата измерения.

Как использовать плату в Arduino IDE написано в статье — http://rcl-radio.ru/?p=129966

Настройки платы LGT8F328P-LQFP32 MiniEVB в Arduino IDE

Помимо платы LGT8F328P-LQFP32 MiniEVB можно использовать плату Arduino Nano изменив значение регистра OCR1A на 15624.

#include <Wire.h>
#include <INA226_WE.h>  // http://rcl-radio.ru/wp-content/uploads/2023/03/INA226_WE-master.zip
#include <LiquidCrystal_I2C.h> // // http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1 
LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей
INA226_WE ina226 = INA226_WE(0x40);
 
  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; 
  float ah;
  unsigned long times;
  unsigned long z;
 
void setup() {
  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A = 31249;
  TCCR1B |= (1 << WGM12);
// Prescaler 1024
  TCCR1B |= (1 << CS12) | (1 << CS10);
  TIMSK1 |= (1 << OCIE1A);
  sei();
  Serial.begin(9600);
  Wire.begin();
  ina226.init();
  pinMode(A0,INPUT_PULLUP); 
  ina226.setAverage(AVERAGE_1024);
  // AVERAGE_1_4_16_64_128_256_512_1024 > Количество выборок
  ina226.setConversionTime(CONV_TIME_1100);
  // CONV_TIME_140_204_332_588_1100_2116_4156_8244 - время измерения в мkс
  ina226.setCurrentRange(MA_800);
  // MA_800_400 - предел измерения тока
  // ina226.setCorrectionFactor(0.95); // калибровочный коэффициент измерения тока
  ina226.waitUntilConversionCompleted();
  lcd.init();lcd.backlight();
  lcd.print("   Power unit ");
  lcd.setCursor(0, 1);
  lcd.print(" 0-36V  0-800mA");
  delay(1000);
  lcd.clear();
}
 
void loop() {
  if(digitalRead(A0)==LOW){ah=0;delay(200);}
  ina226.readAndClearFlags();
  shuntVoltage_mV = ina226.getShuntVoltage_mV();
  busVoltage_V = ina226.getBusVoltage_V();
  current_mA = ina226.getCurrent_mA();
  power_mW = ina226.getBusPower();
  loadVoltage_V  = busVoltage_V + (shuntVoltage_mV/1000);
  Serial.print("Ushunt [mV]: "); Serial.println(shuntVoltage_mV); // напряжение шунта
  Serial.print("U [V]: "); Serial.println(busVoltage_V); // напряжение шины
  Serial.print("Un [V]: "); Serial.println(loadVoltage_V); // напряжение нагрузки
  Serial.print("I [mA]: "); Serial.println(current_mA);
  Serial.print("Power [mW]: "); Serial.println(power_mW);
  if(!ina226.overflow){Serial.println("OK");}else{Serial.println("ERROR");}
  Serial.println();
  lcd.setCursor(0, 0);
  lcd.print(loadVoltage_V,2);lcd.print(" ");lcd.setCursor(6, 0);lcd.print("V");
  lcd.setCursor(9, 0);
  if(power_mW/1000<10){lcd.print(power_mW/1000,3);}
  if(power_mW/1000>=10 && power_mW/1000<100){lcd.print(power_mW/1000,2);}
  if(power_mW/1000>=100){lcd.print(power_mW/1000,1);}
  lcd.print(" ");lcd.setCursor(14, 0);lcd.print("W");
  lcd.setCursor(0, 1);
  lcd.print(abs(current_mA/1000),3);lcd.print(" ");lcd.setCursor(6, 1);lcd.print("A");
  lcd.setCursor(9, 1);
  if(ah<10){lcd.print(ah,3);}
  if(ah>=10&&ah<100){lcd.print(ah,2);}
  if(ah>=100&&ah<1000){lcd.print(ah,1);}
  lcd.print(" ");lcd.setCursor(14, 1);
  lcd.print("Ah");
  delay(200); 
  Serial.println(ah,6);
  Serial.print("Time: ");Serial.print(z);Serial.println(" sec");
  Serial.println(ah/z*3600);
}
 
ISR(TIMER1_COMPA_vect){z++;ah = ah + current_mA/1000/3600;}

Вывод монитора порта:

Аккумуляторы для поломоечных машин

Comments

  1. …Помимо платы LGT8F328P-LQFP32 MiniEVB можно использовать плату Arduino Nano изменив значение регистра OCR1A на 15624….

    Как это сделать? Как я понял, сдесь — OCR1A = 31249; меняем на 15624
    void setup() {
    cli();
    TCCR1A = 0;
    TCCR1B = 0;
    TCNT1 = 0;

    OCR1A = 31249;

  2. 1.Прав я или нет? Для коррекции показаний тока нужно раскомментировать строку 38 в скетче,а именно // ina226.setCorrectionFactor(0.95) и изменить коэффициент на свой? 2. Как откорректировать показания напряжения если они отличаются от реальных.

  3. Собрал данный вольтамперметр. С калибровкой тока проблем нет, а вот с напряжением засада! Если устанавливаю коэффициент меньше 1,0 — то на дисплее 0,00. Тоже самое если на входе UBS стоит делитель, т.е. до 3.0 адекватно изменяется показания. С 3.0 до 3.99 показания изменяются с интервалом 0.01В. При коэффициенте 4.0 показания резко прыгают почти на 5в. В проекте использовал Pro mini 168 5v. Могут быть проблемы из-за этого?

  4. #include
    #include // http://rcl-radio.ru/wp-content/uploads/2023/03/INA226_WE-master.zip
    #include // // http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1
    LiquidCrystal_I2C lcd(0x27,16,2); // Устанавливаем дисплей
    INA226_WE ina226 = INA226_WE(0x40);

    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;
    float ah;
    unsigned long times;
    unsigned long z;

    void setup() {
    cli();
    TCCR1A = 0;
    TCCR1B = 0;
    TCNT1 = 0;
    OCR1A = 15624;
    TCCR1B |= (1 << WGM12);
    // Prescaler 1024
    TCCR1B |= (1 << CS12) | (1 << CS10);
    TIMSK1 |= (1 < Количество выборок
    ina226.setConversionTime(CONV_TIME_1100);
    // CONV_TIME_140_204_332_588_1100_2116_4156_8244 — время измерения в мkс
    ina226.setCurrentRange(MA_800);
    // MA_800_400 — предел измерения тока
    ina226.setCorrectionFactor(0.77); // калибровочный коэффициент измерения тока
    ina226.waitUntilConversionCompleted();
    lcd.init();lcd.backlight();
    lcd.print(» Power unit «);
    lcd.setCursor(0, 1);
    lcd.print(» 0-100V 0-16A»);
    delay(2000);
    lcd.clear();
    }

    void loop() {
    if(digitalRead(A0)==LOW){ah=0;delay(200);}
    ina226.readAndClearFlags();
    shuntVoltage_mV = ina226.getShuntVoltage_mV();
    busVoltage_V = ina226.getBusVoltage_V()*3,99; // калибровочный коэффициент измерения напряжения
    current_mA = ina226.getCurrent_mA();
    power_mW = ina226.getBusPower();
    loadVoltage_V = busVoltage_V + (shuntVoltage_mV/1000);
    Serial.print(«Ushunt [mV]: «); Serial.println(shuntVoltage_mV); // напряжение шунта
    Serial.print(«U [V]: «); Serial.println(busVoltage_V); // напряжение шины
    Serial.print(«Un [V]: «); Serial.println(loadVoltage_V); // напряжение нагрузки
    Serial.print(«I [mA]: «); Serial.println(current_mA);
    Serial.print(«Power [mW]: «); Serial.println(power_mW);
    if(!ina226.overflow){Serial.println(«OK»);}else{Serial.println(«ERROR»);}
    Serial.println();
    lcd.setCursor(0, 0);
    lcd.print(loadVoltage_V,2);lcd.print(» «);lcd.setCursor(6, 0);lcd.print(«V»);
    lcd.setCursor(9, 0);
    if(power_mW/1000=10 && power_mW/1000=100){lcd.print(power_mW/1000,1);}
    lcd.print(» «);lcd.setCursor(14, 0);lcd.print(«W»);
    lcd.setCursor(0, 1);
    lcd.print(abs(current_mA/1000),3);lcd.print(» «);lcd.setCursor(6, 1);lcd.print(«A»);
    lcd.setCursor(9, 1);
    if(ah=10&&ah=100&&ah<1000){lcd.print(ah,1);}
    lcd.print(" ");lcd.setCursor(14, 1);
    lcd.print("Ah");
    delay(200);
    Serial.println(ah,6);
    Serial.print("Time: ");Serial.print(z);Serial.println(" sec");
    Serial.println(ah/z*3600);
    }

    ISR(TIMER1_COMPA_vect){z++;ah = ah + current_mA/1000/3600;} ЭТО ТОТ СКЕТЧ, КОТОРЫЙ ЗАЛИВАЮ

  5. Огромное спасибо автору за отличный прибор! Работает великолепно! Вот так откалибровал ток и напряжение —
    «`cpp
    void loop() {
    if(digitalRead(A0)==LOW){ah=0;delay(200);}
    ina226.readAndClearFlags();
    shuntVoltage_mV = ina226.getShuntVoltage_mV();
    busVoltage_V = ina226.getBusVoltage_V()*3.07; // калибровочный коэффициент измерения напряжения
    current_mA = ina226.getCurrent_mA()*25.26;
    power_mW = ina226.getBusPower();
    «`
    Делитель стоит 33К/15К, шунт 0.005 Ом.

Добавить комментарий

Войти с помощью: