Случилось у меня, наверное то, что иногда случается и у всех — неожиданно перестала закрываться крышка телефона 🙁 Оказалось, что сильно «распух» аккумулятор. Пришлось заменить.
«Бочкообразный прямоугольник» раздувшегося аккумулятора забросил в стол и вспомнил о нем лишь через год…Встала задачка запитать Arduino Pro mini с датчиком давления и передатчиком. Замерил напряжение — нормальные 3,6В! Видимо АКБ осталась вполне рабочей.
Захотелось узнать — потянет ли такой аккумулятор питание устройства в течение хотя бы часа?
Для ответа на вопрос смастерил стенд:
Задача скетча — имитировать работу устройства и фиксировать напряжение батареи в течение требуемого периода времени.
#define led 13 //светодиод тут #include <EEPROM.h> #define tPress 1000 //период включения ПРД #define nPer 20 //число пер.вкл.ПРД между замерами #define maxAddr 1024 //объем EEPROM byte aLow; byte aHigh; unsigned int valAlt; long int valPress; int addr; int Nbuf; long readVcc() { // Read 1.1V reference against AVcc // set the reference to Vcc and the measurement to the internal 1.1V reference #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) ADMUX = _BV(MUX5) | _BV(MUX0); #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) ADMUX = _BV(MUX3) | _BV(MUX2); #else ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); #endif delay(2); // Wait for Vref to settle ADCSRA |= _BV(ADSC); // Start conversion while (bit_is_set(ADCSRA,ADSC)); // measuring uint8_t low = ADCL; // must read ADCL first - it then locks ADCH uint8_t high = ADCH; // unlocks both long result = (high<<8) | low; result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000 return result; // Vcc in millivolts } void MasToEE(unsigned int tAlt) { //запись в EEPROM замера EEPROM.write(addr, lowByte(tAlt)); EEPROM.write(addr+1, highByte(tAlt)); } void setup() { // initialize the digital pin as an output. pinMode(led, OUTPUT); //--------- начало блока считывания данных из EEPROM ------------- Serial.begin(19200); Serial.println("Read EEPROM from MC. Ver LiPo_test_3"); for (addr=0; addr<maxAddr; addr = addr +4) { aLow = EEPROM.read(addr); aHigh = EEPROM.read(addr+1); Serial.print(addr); Serial.print("; "); Serial.print(aLow+aHigh*256); //напряж.без ПРД Serial.print("; "); aLow = EEPROM.read(addr+2); aHigh = EEPROM.read(addr+3); Serial.print(aLow+aHigh*256); //напряж при вкл ПРД Serial.print("; "); Serial.println(); } Serial.println("The End Read EEPROM"); //------- окончание блока считывания ------------------ addr = 0; Nbuf = 0; //индикатор начала фиксации напряжения for (int i=0; i < 10; i++) { digitalWrite(led, HIGH); //включим delay(200); digitalWrite(led, LOW); //погасим delay(200); } } void loop() { long int tTek = millis(); Nbuf++; if (Nbuf >= nPer) { //каждые nPer отсчетов делаем замер Nbuf = 0; valAlt = readVcc(); //это напр при выкл ПРД MasToEE(valAlt); //запись в EEPROM digitalWrite(led,HIGH); //вкл.модуляция перед. delay(200); //пусть поработает addr = addr + 2; valAlt = readVcc(); //это напр при вкл ПРД MasToEE(valAlt); //запись в EEPROM digitalWrite(led,LOW); //выкл.модуляция перед. addr = addr + 2; } // каждый раз даем 300 мс меандр 1000Гц for (int i=0; i<300; i++) { digitalWrite(led,HIGH); //вкл.модуляция перед. delayMicroseconds(500); digitalWrite(led,LOW); //выкл.модуляция перед. delayMicroseconds(500); } ; if (addr >= maxAddr) { //останов while (1) { //непрерывно передаем "точки" digitalWrite(led,HIGH); //вкл.модуляция перед. delay(200); digitalWrite(led,LOW); //выкл.модуляция перед. delay(300); } ; } while ((tTek + tPress) > millis()) {} }
Программа работает следующим образом.
Сначала по последовательному каналу выводится содержимое EEPROM микроконтроллера (потом в мониторе копируем текст в буфер и сохраняем его в текстовый файл с расширением .csv).
Затем, собственно, запускается цикл имитации работы устройства (периодически включается передатчик — именно он, вместе со светодиодами, дает основную нагрузку по питанию). Делается замер напряжения при выключенном передатчике, затем при включенном. Периодичность регистрации замеров определяется константами tPress * nPer и, в приведенном скетче равно 20 сек.
Напряжение питания определяется в процедуре readVcc(), которая была ранее подробно описана. Результат измерения в мВ записывается в две байтовые ячейки EEPROM микроконтроллера. Емкости ATmega328 хватает больше чем на полтора часа.
По заполнении EEPROM программа «останавливается» в непрерывном цикле.
Пример файла .csv
Read EEPROM from MC. Ver LiPo_test_3
0; 3606; 3583;
4; 3606; 3583;
8; 3606; 3583;
12; 3606; 3583;
График, выполненный средствами MS Excel выглядит так:
здесь напряжение питания в миливольтах (синим — при выключенном передатчике, сиреневым — при включенном).
ИТОГ: аккумулятор вполне подойдет для разовой часовой задачи (высотомер для модели ракеты).
Решил сделать эту запись, т.к. тут можно убедиться, что пятивольтовый Pro mini нормально работает при трехвольтовом питании; интересным может оказаться пример использования EEPROM в качестве накопителя регистратора.