// © 2024 Алексей Надёжин, batterytest.ru. Модификация и использование фрагментов этого кода допускается только с разрешения автора. // Телеграм @ammo1, ammo1@mail.ru #define vers "v 1.0. 10.4.2024" // версия #define serialmills 5000; //Периодичность вывода в com-порт, мс #include #include #include //убрать, если используется плата без Wi-Fi INA226 ina; // Запуск INA GyverOLED oled; unsigned long startMillis; //Время в момент начала измерения unsigned long MillisTake; //Время следующего измерения unsigned long MillisCom; //Время следующего вывода в COM-порт unsigned long seconds; unsigned long minutes; unsigned long hours; float U; //напряжение в вольтах float I; //ток в миллиамперах float mwh = 0; //милливатт-часы float mah = 0; //миллиампер-часы float Ustop = 0.9; //Напряжение остановки измерения в вольтах. int animacount = 20; //количество миганий дохлой батарейкой до снижения яркости float calibrU = 1; //множитель коррекции напряжения при калибровке int calibrI = 0; //калибровочное значение тока (отрицательное или положительное) const uint8_t dead_128x64[] PROGMEM = { //Картинка с дохлой батарейкой 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b11000000, 0b11000000, 0b11000000, 0b11000000, 0b11000000, 0b01100000, 0b01100000, 0b01100000, 0b01100000, 0b01100000, 0b00110000, 0b00110000, 0b00110000, 0b00110000, 0b00110000, 0b00111000, 0b00011000, 0b00011000, 0b00011000, 0b00011000, 0b00011000, 0b00011100, 0b00001100, 0b00001100, 0b00001100, 0b00001100, 0b00001100, 0b00001110, 0b00001110, 0b00000110, 0b00000110, 0b00000110, 0b00000110, 0b00000111, 0b00000011, 0b00000011, 0b00000011, 0b00000011, 0b00000011, 0b00000011, 0b00000011, 0b00000011, 0b00000110, 0b00000110, 0b00011110, 0b00011100, 0b00111100, 0b01111100, 0b01111000, 0b11111000, 0b11110000, 0b11110000, 0b11100000, 0b11000000, 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b11000000, 0b11000000, 0b11000000, 0b11000000, 0b11000000, 0b01100000, 0b01100000, 0b01100000, 0b01100000, 0b00110000, 0b00110000, 0b00110000, 0b00110000, 0b00110000, 0b00011000, 0b00011000, 0b00011000, 0b00011000, 0b00011000, 0b00011100, 0b00001100, 0b00001100, 0b00001100, 0b00001100, 0b00001110, 0b00000110, 0b00000110, 0b00000110, 0b00000110, 0b00000110, 0b00000011, 0b00000011, 0b00000011, 0b00000011, 0b00000011, 0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001, 0b00000011, 0b00000111, 0b01111111, 0b11111111, 0b11111111, 0b11111110, 0b11111100, 0b11110000, 0b11000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b10000000, 0b11100000, 0b01110000, 0b00110000, 0b00011000, 0b00011000, 0b00011100, 0b00011100, 0b00011110, 0b00011110, 0b00001111, 0b00011111, 0b00011011, 0b00011011, 0b00110011, 0b00110001, 0b01100001, 0b01100001, 0b11000001, 0b11000000, 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b10000000, 0b11111000, 0b11111100, 0b11111110, 0b11111110, 0b00111110, 0b00011110, 0b00001110, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001, 0b00000011, 0b00001111, 0b11111111, 0b11111111, 0b11111111, 0b11111100, 0b11111000, 0b11000000, 0b00000000, 0b00000000, 0b10000000, 0b11111000, 0b11111111, 0b11100111, 0b11100000, 0b11100000, 0b01110000, 0b01110000, 0b11110000, 0b11000000, 0b11000000, 0b10000000, 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001, 0b00000001, 0b00000011, 0b00000110, 0b00001110, 0b00011100, 0b01110000, 0b11100000, 0b11000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00001100, 0b00011100, 0b00011000, 0b00011000, 0b00110000, 0b10110000, 0b11111000, 0b11111110, 0b01101111, 0b01100011, 0b01100000, 0b11100000, 0b11000000, 0b11000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001, 0b00001111, 0b00111111, 0b11111111, 0b11111111, 0b11110000, 0b11000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b11000000, 0b11110011, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b11111100, 0b01111110, 0b11111111, 0b11111111, 0b10000001, 0b00000001, 0b00000001, 0b00000011, 0b00000011, 0b00000111, 0b00011110, 0b00111100, 0b11110001, 0b11000001, 0b00000011, 0b00000111, 0b00001110, 0b00111100, 0b11111000, 0b11110000, 0b11000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000011, 0b00001111, 0b01111110, 0b11111000, 0b11000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000011, 0b00000011, 0b00000001, 0b00000000, 0b10000000, 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b10000000, 0b11000000, 0b11000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b11111110, 0b11111111, 0b11111111, 0b11111111, 0b00110011, 0b00110011, 0b00110011, 0b00110011, 0b01110011, 0b01110011, 0b01100011, 0b01100011, 0b01100011, 0b01100011, 0b01100111, 0b00000111, 0b00000111, 0b00000111, 0b00000110, 0b00001110, 0b00001110, 0b00011100, 0b00011100, 0b01111000, 0b11110000, 0b11100000, 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b10000000, 0b11000000, 0b11100000, 0b11110000, 0b11111100, 0b11111111, 0b11111111, 0b11111111, 0b11111111, 0b01111111, 0b00011111, 0b00000001, 0b00000000, 0b00000011, 0b00000111, 0b00001111, 0b00111100, 0b11111000, 0b11100000, 0b11000000, 0b10000000, 0b10000000, 0b10000000, 0b10000001, 0b11111111, 0b11111111, 0b11011100, 0b11000000, 0b11000000, 0b11000001, 0b11111111, 0b11111111, 0b11111110, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b10000000, 0b11111111, 0b11111111, 0b01111110, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001, 0b00000011, 0b00000011, 0b01100011, 0b01111110, 0b00111110, 0b00001110, 0b00001111, 0b00001101, 0b00011100, 0b00011000, 0b00011000, 0b00111000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001, 0b00000011, 0b00000111, 0b00000111, 0b00000111, 0b00000111, 0b00001110, 0b00001110, 0b00001100, 0b00011100, 0b00011100, 0b10011000, 0b10011000, 0b10111000, 0b10111000, 0b10111000, 0b10111000, 0b10111000, 0b11111000, 0b11011000, 0b11011100, 0b11011100, 0b11111110, 0b11101111, 0b11101111, 0b11110111, 0b11110001, 0b11110000, 0b11111000, 0b01111000, 0b01111100, 0b01111110, 0b01111110, 0b01111111, 0b00111111, 0b00111111, 0b00111111, 0b00111111, 0b00011111, 0b00011111, 0b00001111, 0b00000011, 0b00000001, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001, 0b00000111, 0b00011111, 0b00111111, 0b01111111, 0b11111001, 0b11110001, 0b11100001, 0b11000001, 0b10000001, 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b10000000, 0b11000000, 0b11110000, 0b11111100, 0b01111111, 0b00011111, 0b00000111, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b11000000, 0b11000000, 0b11000000, 0b11000000, 0b11000000, 0b11100000, 0b11100000, 0b11100000, 0b11100000, 0b11100000, 0b11100000, 0b11100000, 0b01100000, 0b01100000, 0b01100000, 0b01110000, 0b01110000, 0b01110000, 0b00111000, 0b00111000, 0b00111100, 0b00111100, 0b00111100, 0b00111100, 0b00011110, 0b00011110, 0b00011110, 0b00011110, 0b00011110, 0b00001111, 0b00001111, 0b00001111, 0b00001111, 0b00001111, 0b00000111, 0b00000111, 0b00000111, 0b00000111, 0b00000011, 0b00000011, 0b00000011, 0b00000011, 0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001, 0b00000011, 0b00000111, 0b00001111, 0b00001111, 0b00011111, 0b01111111, 0b01111110, 0b01111100, 0b11111100, 0b11111000, 0b11111000, 0b11111100, 0b11111100, 0b11111110, 0b01111110, 0b01110111, 0b01110111, 0b01110011, 0b01110001, 0b01111000, 0b01111000, 0b00111000, 0b00111000, 0b00111000, 0b00111000, 0b00111100, 0b00111100, 0b00011100, 0b00011100, 0b00011100, 0b00011100, 0b00011100, 0b00001110, 0b00001110, 0b00001110, 0b00001110, 0b00001110, 0b00000111, 0b00000111, 0b00000111, 0b00000111, 0b00000111, 0b00000111, 0b00000011, 0b00000011, 0b00000011, 0b00000011, 0b00000011, 0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, }; void setup() { WiFi.mode(WIFI_OFF); //Отключение WiFi. убрать, если используется плата без Wi-Fi WiFi.forceSleepBegin(); //Отключение модуля WiFi. убрать, если используется плата без Wi-Fi Serial.begin(74880); //скорость 74880 нужна, чтобы неотключаемая отладочная информация ESP8266 выводилась не кракозябрами Serial.println(); //Перевод строки после вывода служебной информации ESP8266 Serial.print("BatteryTest "); Serial.print(vers); Serial.println(" (c) A. Nadezhin, batterytest.ru"); oled.init(); // инициализация экрана // Если экран расположен не вверх ногами, закомментируйте две следующие строки oled.flipH(true); // true/false - отзеркалить по горизонтали oled.flipV(true); // true/false - отзеркалить по вертикали oled.clear(); // очистка oled.home(); // курсор в 0,0 oled.setScale(2); // масштаб текста (1..4) oled.print("BatteryTest"); Serial.print(F("INA226...")); // Проверяем наличие и инициализируем INA226 if (ina.begin()) { // ina.begin(4, 5) // Для ESP32/ESP8266 можно указать пины I2C Serial.println(F("connected!")); } else { Serial.println(F("not found!")); oled.setCursor(0, 5); oled.print("Нет INA226"); while (1); } // INA226 имеет возможность встроенной калибровки измерения тока, при помощи специального калибровочного значения // После запуска библиотека автоматически рассчитает и запишет калибровочное значение на основе введенных данных // Полученное значение можно прочитать, используя метод .getCalibration(); для изменения и/или сохранения в EEPROM Serial.print(F("Calibration value: ")); Serial.println(ina.getCalibration()); // Далее полученное значение можно изменять для подстройки под реальное сопротивление шунта и сохранять в EEPROM // Чтобы записать калибровочное значение в INA226 существует метод .setCalibration(value); // ina.setCalibration(ina.getCalibration() + 10); // Прочитать-модифицировать-записать калибровочное значение // Так же, можно использовать метод .adjCalibration(offset); для подстройки калибровки без непосредственного чтения // ina.adjCalibration(10); // Увеличить калибровочное значение на 10 // ina.adjCalibration(-110); // Уменьшить калибровочное значение на 110 // Можно хранить в EEPROM и загружать в INA226 именно смещение калибровки вместо непосредственного значения ina.adjCalibration(calibrI); //Калибровочное значение тока // Для повышения помехозащищенности INA226 имеет возможность настроить время выборки напряжения и тока // INA226 будет захватывать "кусок" сигнала выбранной продолжительности, что повысит точность на шумном сигнале // По умолчанию выборка занимает 1100 мкс, но может быть изменена методом .setSampleTime(канал, время); // Варианты времени выборки см. в таблице (файл INA226.h) ina.setSampleTime(INA226_VBUS, INA226_CONV_8244US); // Повысим время выборки напряжения в 8 раз ina.setSampleTime(INA226_VSHUNT, INA226_CONV_8244US); // Повысим время выборки тока в 8 раз // Так же имеется возможность использовать встроенное усреднение выборок // Усреднение применяется и для напряжения и для тока и пропорционально увеличивает время оцифровки // Рекомендуется на шумной нагрузке, устанавливается методом .setAveraging(кол-во усреднений) (см. таблицу в INA226.h) ina.setAveraging(INA226_AVG_X4); // Включим встроенное 4х кратное усреднение, по умолчанию усреднения нет oled.setScale(1); title: startMillis = millis(); //Время начала отсчёта смены заставки oled.setCursor(0, 3); oled.print(" "); oled.print(vers); //вывод версии oled.setCursor(0, 4); oled.print(" "); oled.setCursor(0, 5); oled.print(" (с) Алексей Надёжин"); oled.setCursor(0, 6); oled.print(" "); oled.setCursor(0, 7); oled.print(" batterytest.ru"); waitbattery: //Ждём подключения батарейки if (millis() > (startMillis + 10000)) goto title; //заново выводим первую заставку через 10 секунд if (millis() > (startMillis + 5000)) if (millis() < (startMillis + 35300)) //через 5 секунд меняем заставку на подсказку { oled.setCursor(0, 3); oled.print("Подключите "); //Пробелы в конце затирают то, чтоб было до этого на экране oled.setCursor(0, 4); oled.print("нагрузочный резистор"); oled.setCursor(0, 5); oled.print(" "); oled.setCursor(0, 6); oled.print("Установите батарейку"); oled.setCursor(0, 7); oled.print("или аккумулятор "); } if (millis() > 3600000) //Требование перезапуска, если прошёл час после включения. Нужно для того, чтобы не переполнился счётчик времени. { oled.clear(); oled.setScale(2); oled.setCursor(0, 1); oled.print("Долгий"); oled.setCursor(0, 3); oled.print("простой."); oled.setCursor(0, 5); oled.print("Перезапуск"); halt: goto halt; } delay(500); //Задержка между измерениями (нужна в том числе для того, чтобы не падал ESP8266) read_ina(); //Чтение данных из INA if (U < 0.5) goto waitbattery; //ждём, пока появится напряжение больше 0.5 В if (I < 0.5) //проверка, есть ли потребление больше 0.5 мА { oled.clear(); oled.setScale(2); oled.setCursor(0, 1); oled.print("Подключите"); oled.setCursor(0, 3); oled.print("нагрузочный"); oled.setCursor(0, 5); oled.print("резистор"); goto waitbattery; } startMillis = millis(); //Сброс времени начала отсчёта metering(); //Первое измерение if (U > 15) { oled.clear(); oled.setScale(2); oled.setCursor(0, 1); oled.print("Напряжение"); oled.setCursor(0, 3); oled.print("выше"); oled.setCursor(0, 5); oled.print("15 вольт"); halt3: goto halt3; } //Определение типа батарейки для установки напряжения окончания теста. По умолчанию 0.9V (батарейки 1.5V, аккумуляторы 1.2V) if (U > 2) Ustop = 2; //Батарейки 3V (CR 2032, CR123A и пр.) if (U > 3.5) Ustop = 2.5; //Литиевые аккумуляторы 3.7V if (U > 5.4) Ustop = 5.4; //"Крона" 9V if (U > 10.5) Ustop = 10.5; //Свинцовые батареи 12V oled.clear(); oled.setScale(1); oled.setCursor(0, 2); oled.print("Тест до "); oled.setCursor(50, 1); oled.setScale(2); oled.print(Ustop, 1); oled.print(" v"); oled.setScale(1); oled.setCursor(0, 7); oled.print("Калиб. U "); oled.print(calibrU); oled.print(" I "); oled.print(calibrI); Serial.print("Test end voltage: "); Serial.print(Ustop, 1); Serial.print(" V"); Serial.print(" Calibration U: "); Serial.print(calibrU); Serial.print(" Calibration I: "); Serial.println(calibrI); Serial.println(" h:m:s V mA mWh mAh"); datacom(); //Вывод первого значения в COM-порт premeter: delay(500); // Пауза между измерениями metering(); if (millis() < (startMillis + 2600)) goto premeter; //3 секунды запускаем измерение каждые 0.5 сек, чтобы на экране оставалось напряжение окончания delay(500); //Задержка перед первым измерением в цикле // Подготовка экрана, вывод обозначений параметров мелким шрифтом oled.clear(); oled.setScale(1); oled.setCursorXY(50, 31); oled.print("V"); oled.setCursorXY(40, 55); oled.print("mA"); oled.setCursorXY(111, 31); oled.print("mWh"); oled.setCursorXY(111, 55); oled.print("mAh"); oled.setScale(2); // масштаб текста (1..4) } //конец setup //////////////////////////////////////////////////////////////////////////////////////////////////////////////// void loop(void) { if (millis() >= (startMillis + MillisTake)) //Пора ли делать измерение? { MillisTake = (millis() - startMillis + 500); //Устанавливаем время следующего измерения metering(); //Измерение //рассчитываем и выводим время seconds = (millis() - startMillis) / 1000; minutes = seconds / 60; hours = minutes / 60; seconds %= 60; minutes %= 60; timeprint (); //вывод времени на экран // Вывод значений на экран oled.setCursor(0, 3); if (U >= 10) oled.print(U,1); // Если напряжение больше 10 В оставляем только 1 знак после запятой else oled.print(U,2); oled.setCursor(0, 6); autonum (I, 0, 48, 3); autonum (mwh, 60, 24, 4); autonum (mah, 60, 48, 4); if (millis() >= (startMillis + MillisCom)) datacom(); // Вывод в COM-порт если настало время if (millis() > (startMillis + 5000)) //Если прошло болеее 5 секунд с начала, проверяем не закончился ли тест if (Ustop > U) // Проверка, не пора ли заканчивать тест { /////////////////////////////////////////// Финальный экран datacom(); // Вывод в COM-порт последнего значения Serial.println("END"); animat: // Вывод картинки с дохлой батарейкой oled.drawBitmap(0, 0, dead_128x64, 128, 64, BITMAP_NORMAL, BUF_ADD); delay(2000); oled.clear(); oled.setScale(2); timeprint (); //вывод времени oled.setScale(3); autonum (mwh, 0, 17, 5); autonum (mah, 0, 40, 5); oled.setScale(2); oled.setCursorXY(92, 24); oled.print("mWh"); oled.setCursorXY(92, 47); oled.print("mAh"); delay(3000); if (animacount == 0) goto animat; //Если яркость уже снижена ничего делать не надо animacount --; if (animacount == 0) oled.setContrast(1); //уменьшаем яркость, чтобы меньше выгорал экран goto animat; } }//финал цикла измерения }//финал основного цикла ////////////////////////////////////////////////////////////////////// ///////////////////// функции /////////////////////////////////////// void metering() //измерение { read_ina(); //Чтение данных из INA mah += (I/7200); //7200 измерений в час mwh += (I/7200 * U); //Serial.print (U, 9); //Для отладки - вывод значений измерений и подсчтов в COM-порт с 9 знаками после запятой //Serial.print (" V "); //Serial.print (I, 9); //Serial.print (" mA "); //Serial.print (mah, 9); //Serial.print (" mAh "); //Serial.print (mwh, 9); //Serial.println(" mwh"); } void read_ina() //Чтение данных из INA { U = ina.getVoltage(); U *= calibrU; I = ina.getCurrent(); I *= 1000; } void timeprint() //Вывод времени { oled.setCursor(0, 0); if (millis() < (startMillis + 36000000000)) //Проверка, не превышен ли лимит 1000 часов { oled.print(hours); oled.print(":"); if (minutes < 10) oled.print("0"); oled.print(minutes); oled.print(":"); if (seconds < 10) oled.print("0"); oled.print(seconds); } else oled.print(">1000 часов"); } void autonum(float param, int x, int y, int numdigit) //Вывод на экран целого числа с автовставкой пробелов для выравнивания по правому краю //x, y - координаты курсора, numdigit - количесто цифр 3, 4 или 5 //дробное значение автоматически округляется { oled.setCursorXY(x, y); if (numdigit == 5) if (param < 9999.5) oled.print(" "); if (numdigit >= 4) if (param < 999.5) oled.print(" "); if (param < 99.5) oled.print(" "); if (param < 9.5) oled.print(" "); if (param < 99999.5) oled.print(param, 0); else oled.print(">100K"); if (numdigit == 4) if (param >= 9999.5) oled.print(" "); //затираем mAh/mWh в режиме измерения если значение больше 9999 } void datacom() //вывод строки данных в COM-порт { MillisCom = millis() - startMillis + serialmills; //Устанавливаем время следующего вывода в порт Serial.print(hours); Serial.print(":"); if (minutes < 10) Serial.print("0"); Serial.print(minutes); Serial.print(":"); if (seconds < 10) Serial.print("0"); Serial.print(seconds); Serial.print(" "); Serial.print(U, 4); //напряжение, 4 знака после запятой Serial.print(" "); Serial.print(I, 2); //ток, 2 знака после запятой Serial.print(" "); Serial.print(mwh, 1); //энергия, 1 знак после запятой Serial.print(" "); Serial.println(mah, 1); //ёмкость, 1 знак после запятой } //The End :)