Запись EEPROM
- Войдите на сайт для отправки комментариев
Пт, 19/05/2017 - 12:26
Здравствуйте!
Собрал схему вольтметр/амперметр/измеритель ёмкости для LiPo 4S аккумулятора. Столкнулся впервые с EEPROM, и никак не могу понять как дописать код.
Мне нужно, что бы каждые 2 минуты значение ёмкости записывалось в память, а при напряжении в 16,78-16,80 Вольт (100% заряженая) значение обнулялось. При включении питания значение естественно должно считываться.
Скетч того, что я сделал ниже, как я понимаю в моём случае значение ёмкости записывается каждую секунду, а это плохо.
За любую помощь заранее огромное спасибо!
#include <LCD_1602_RUS.h> #include <MsTimer2.h> #include <EEPROM.h> LCD_1602_RUS lcd(0x3F, 16, 2); //инициализация дисплея по адресу 0х27 (для 2004) и 0x3F (для 1602) #define R1 560 //резистор делителя на + #define R2 36 //резистор делителя на - #define MEASURE_PERIOD 500 // время периода измерения int timeCount; // счетчик времени long sumVOLTAGE, sumCURRENT ; // переменные для суммирования кодов АЦП long averageVOLTAGE, averageCURRENT; // сумма кодов АЦП (среднее значение * 500) boolean flagReady; // признак готовности данных измерения float voltage = 0; float current = 0; float capacity = 0; int addr = 0; void setup() { lcd.init(); //включаем дисплей lcd.backlight(); //включаем подсветку MsTimer2::set(1, timerInterupt); // прерывания по таймеру, период 1 мс MsTimer2::start(); // разрешение прерывания EEPROM.get(addr, capacity); } void timerInterupt() { timeCount++; // +1 счетчик выборок усреднения sumVOLTAGE+= analogRead(A1); // суммирование кодов АЦП для напряжения sumCURRENT+= analogRead(A3); // суммирование кодов АЦП для тока // проверка числа выборок усреднения if ( timeCount >= MEASURE_PERIOD ) { timeCount= 0; averageVOLTAGE = sumVOLTAGE; // перегрузка среднего значения для напряжения averageCURRENT = sumCURRENT; // перегрузка среднего значения для тока sumVOLTAGE= 0; sumCURRENT= 0; flagReady= true; // признак результат измерений готов } } void loop () { voltage = averageVOLTAGE / 500. * 5.113 / 1024. / R2 * (R1 + R2); //расчёт напряжения current = (.0264 * ((averageCURRENT / 500.) - 505)); if (current<0.28) { current=0.0;// обнуляем нежелательное значение } capacity = capacity+current / 3600; EEPROM.put(addr, capacity); if (voltage>16.78){ capacity = 0.0; } lcd.setCursor (0, 0); lcd.print(L"Бат:"); lcd.print(voltage, 2); lcd.print(L"V "); lcd.setCursor (11, 0); lcd.print(current, 2); lcd.print(L"A "); lcd.setCursor (2, 1); lcd.print((float)((averageVOLTAGE / 500. * 5.113 / 1024. / R2 * (R1 + R2) - 13.2) / 3.6) * 100, 0); //расчёт процентов lcd.print(L"% "); lcd.setCursor (8, 1); lcd.print(capacity, 3); lcd.print(L"mAh "); delay(1000); }
ага - каждые 2 минуты - и жить этому процессору осталось 40 дней
Ну хорошо, но даже если не думать о двух минутах, то как реализовать запись по времени?
if ((millis() - previousMillis) >= T1) {}
1- ЕЕPROM при заливке скетча перешивается. Так что надо выделить ячейку для определения первый ли это проход после заливки или нет.
2 "каждые 2 минуты значение ёмкости" Это как. У вас что за две минуты аккум заряжается и разряжается . И по этому вы определяете есмкость?
3- косяки в ТЗ(техническом задании) => косяки в ПО(программном обеспечении)
2 "каждые 2 минуты значение ёмкости" Это как. У вас что за две минуты аккум заряжается и разряжается . И по этому вы определяете есмкость?
Запись нужна только для того, что бы знать сколько мА/ч было потрачено за всё время использования на одной зарядке. Т.е попользовался я аккумулятором полчаса, выключил, потом через какое то время опять включаю и счёт мА/ч продолжается. Поэтому я хотел, что бы значение мА/ч записывалось каждые пару минут, в случае, если я отключаю ардуину. А обнулять значение не кнопками, а по принципу - если напряжение составляет 100% от заряда, значит обнулить значение. Расчёт мА/ч мне не нужен супер точный, а лишь приблизительный.
У вас Ардуина стоит на устройстве зарядке или же как на смартфоне индикатор заряда батареи.
ЕЕPROM при заливке скетча по кнопке из arduino ide НЕ перезаписывается.
ЕЕPROM при заливке скетча по кнопке из arduino ide НЕ перезаписывается.
У вас Ардуина стоит на устройстве зарядке или же как на смартфоне индикатор заряда батареи.
Только как индикатор заряда и растраченой ёмкости
Понятно. Тогда когда у вам напряжение максимум. Точнее напряжение выше порога , то растрачено 0. А если ниже напряжение то в ЕЕPROM писать расход. Каковы единицы расхода byte,int,float,long ? Если ток обратный (зарядка) ничего не писать. Достиг максимума (выше порога) обнулился расход.
Курите это http://radioprog.ru/post/117 , особенно это EEPROM.update(address, value)ВместоEEPROM.write(address, value)
Понятно. Тогда когда у вам напряжение максимум. Точнее напряжение выше порога , то растрачено 0. А если ниже напряжение то в ЕЕPROM писать расход. Каковы единицы расхода byte,int,float,long ? Если ток обратный (зарядка) ничего не писать. Достиг максимума (выше порога) обнулился расход.
Напряжение максимум - любое предыдущее значение должно обнулиться.
Расход - записывать, скажем каждые 2 минуты.
Расход считается как float, поэтому я применил EEPROM.get и EEPROM.put.
Зарядки через ардуину не будет, т.к аккумулятор литиевый с балансирным входом. Поэтому счёт в этом случае вообще не требуется.
EEPROM.update...опять таки перезаписывается изменившееся значение, а т.к изменение ежесекундное, то и запись будет ежесекундная.
if ((millis() - previousMillis) >= T1) {}
Нужно только понять как использовать и как это работает)
Нужно только понять как использовать и как это работает)
http://arduino.ru/tutorials/BlinkWithoutDelay
http://robocraft.ru/blog/arduino/385.html
ЕЕPROM при заливке скетча по кнопке из arduino ide НЕ перезаписывается.
чуть не так - перезаписывать ЕЕPROM или нет, за это отвечает фьюз контроллера EESAVE
Всё, задача решена) Большое спасибо!
if ((millis() - previousMillis) >= T1) {} - реально рабочая штука)
Каждый жеж отрезок времени проверяем, а если нужны точные отрезки времени, то:
Каждый жеж отрезок времени проверяем, а если нужны точные отрезки времени, то:
Спасибо большущее, исправил)