Микросхема 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;}
Вывод монитора порта:
…Помимо платы LGT8F328P-LQFP32 MiniEVB можно использовать плату Arduino Nano изменив значение регистра OCR1A на 15624….
Как это сделать? Как я понял, сдесь — OCR1A = 31249; меняем на 15624
void setup() {
cli();
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 31249;
«Как это сделать? Как я понял, сдесь — OCR1A = 31249; меняем на 15624»
да
Где точность лучше на ADS1110 или на INA226. Нужен точный V-A метр и Ом метр, что посоветуете?
1.Прав я или нет? Для коррекции показаний тока нужно раскомментировать строку 38 в скетче,а именно // ina226.setCorrectionFactor(0.95) и изменить коэффициент на свой? 2. Как откорректировать показания напряжения если они отличаются от реальных.
busVoltage_V = ina226.getBusVoltage_V();
>>>
busVoltage_V = ina226.getBusVoltage_V()*0.95;
0.95 КОЭФФИЦИЕНТ
А с током все верно?
Что нужно изменить в скетче для использования шунта 0,005 Ом?
ina226.setCorrectionFactor(0.95); // калибровочный коэффициент измерения тока
подберите коэффициент
Спасибо!
Собрал данный вольтамперметр. С калибровкой тока проблем нет, а вот с напряжением засада! Если устанавливаю коэффициент меньше 1,0 — то на дисплее 0,00. Тоже самое если на входе UBS стоит делитель, т.е. до 3.0 адекватно изменяется показания. С 3.0 до 3.99 показания изменяются с интервалом 0.01В. При коэффициенте 4.0 показания резко прыгают почти на 5в. В проекте использовал Pro mini 168 5v. Могут быть проблемы из-за этого?
Нет, не могут. Подробнее, что за коэффициент? Где Вы его ставите?
#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;} ЭТО ТОТ СКЕТЧ, КОТОРЫЙ ЗАЛИВАЮ
busVoltage_V = ina226.getBusVoltage_V()*3,99
3.99
Запятую в числах ставить нельзя
«`cpp
busVoltage_V = ina226.getBusVoltage_V()*3,99; // калибровочный коэффициент измерения напряжения
«`
Огромное спасибо автору за отличный прибор! Работает великолепно! Вот так откалибровал ток и напряжение —
«`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 Ом.
Здравствуйте. Не могу понять как изменить предел измерения тока. Можете тыкнуть носом где это в коде и как? Шунт 0.01.
current_mA = ina226.getCurrent_mA();
>>
current_mA = ina226.getCurrent_mA()*10.00;
Примерно так
Спасибо, помогло.