Не могу правильно считать напряжение батарейки из RTC
- Войдите на сайт для отправки комментариев
Чт, 22/10/2015 - 23:17
Arduino pro mini.
Хочется сделать контроль напряжения аккумулятора в часах реального времени RTC.
Взял таблетку lir2032, измерил напряжение 3,9В.
Подключил минус таблетки к GND, плюс через резистор 2,2Мом к A7.
Резистор нужен, чтобы при отключении питания arduino не разрядить таблетку, т.к. в отключке таблетка начинает со скоростью миллиамперов разряжаться через arduino.
Запускаю такой скетч
void loop() { int lu=readvcc(); Serial.print("Vcc "); Serial.println(lu); delay(100); adcnr(_60,t20);//режим adcnoisereduction 60ms int la7=analogRead(A7); Serial.print("A7 "); Serial.print(la7); Serial.print(" Vbat "); Serial.println((long)la7*lu/1023); delay(1000); }
Вывод в serial
Vcc 5068 A7 655 Vbat 3244 Vcc 5068 A7 643 Vbat 3185 Vcc 5068 A7 653 Vbat 3234 Vcc 5068 A7 671 Vbat 3324 Vcc 5068 A7 674 Vbat 3339 Vcc 5068 A7 660 Vbat 3269 Vcc 5068 A7 644 Vbat 3190 Vcc 5068 A7 661 Vbat 3274 Vcc 5068 A7 672 Vbat 3329 Vcc 5068 A7 666 Vbat 3299
Главный вопрос: почему так скачет напряжение?
Ведь опорное правильно считывается и оно стабильно.
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(75); // 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 }
Благодарю.
Присоединяюсь к вопросу. При измерении напряжения в наручных часах сильно пригает напряжение. Использую встроенный ИОН на 1,1 вольт. Измеряю напряжение на батарйке CR3230 через делитель 330кОм и 1МОм. Показания пляшут от 2.32 до 2.58 вольт.
Здесь вопрос как подключаете. Даже если в специальном держателе , то будет плавать. А если на макетке или в руках, то еще сильнее. Вообще разброс слишком сильный получился, обычно не более +/- 5 если даже соединение не очень, а если хорошее, то обычно получается +/- 2.
Если конденсатор в параллель + и - таблетки поставить, чтобы сглаживал колебания?
Только как рассчитать номинал конденсатора, чтобы саморазряд через него был небольшой?
Может есть спец микросхемы для определения напряжения на vbat (ну и параллельно с драйвером для зарядки Li ion)?
Пока решил программно, понаблюдав за скачками и сделав выводы:
1) отбрасываем первые два значения,
2) на нескольких последовательных измерениях находим мин и макс,
3) усредняем.
void loop() {
int lu=readvcc();
Serial.print("Vcc ");
Serial.println(lu);
delay(100);
byte ln=6;
int la=analogRead(A7);
la=analogRead(A7);
uint lmax=analogRead(A7);
uint lmin=lmax;
do{
int la=analogRead(A7);
//Serial.println(la);
if (la>lmax) {lmax=la;}
else if (la<lmin) {lmin=la;}
} while (--ln>0);
Serial.print("min ");
Serial.print(lmin);
Serial.print(" max ");
Serial.print(lmax);
Serial.print(" mid ");
uint lmid=(lmax+lmin)>>1;
Serial.print(lmid);
Serial.print(" Vbat ");
Serial.println((long)lmid*lu/1023);
dms(1000);
}
Результат
osetroff, проверь для начала аппаратную часть - подключи батарею без мегаомных резисторов.
Подключил
Да, теперь еще и опорное пляшет :(
Понаблюдаю еще.
Зато показания пина стали стабильными. Отсюда вывод - сопротивление было выбрано слишком большое и внешние наводки давали соответствующий результат.
Да, теперь еще и опорное пляшет :(
напряжение питания у тебя скачет
nevkon, благодарю!
Взял mosfet bss138:
pin10-1k-gate,+ на drain,source - на аналоговый вход.
Между gate и GND 10k для стекания заряда на землю при отключении arduino.
Теперь и во включенном и в отключенном состоянии arduino таблетка не расходуется.
А для измерения подаю HIGH на pin10.
Теперь с делителем повожусь и отчитаюсь.
Вопрос: а внутреннее опорное 1,1В тоже пляшет в зависимости от внешнего VCC?
Вообще не должно плясать, я так понимаю там встроенный стабилизатор его получает. Знающие подправят если не так.
Всё верно. Внутренний источник опорного напряжения не зависит от питания контроллера и генерирует от 1,2 до 1 вольта. Это напряжение индивидуально для каждой микросхемы и должно определяться опытным путем.
Пока у меня на 5V pro mini работает так:
1) усредняем опорное напряжение при каждом его считывании;
2) пропускаем два первых считывания;
3) считываем n раз, определяя минимальное напряжение;
4) рассчитываем Vbat от усредненного опорного + константа-корректор и минимального считанного напряжения.
Вывод
Позже попробую с делителем.
Интересно, наводки на резисторы делителя еще ухудшат точность, чем в моем случае, когда сигнал с + таблетки подается через mosfet на аналоговый вход?
4) рассчитываем Vbat от усредненного опорного + константа-корректор и минимального считанного напряжения.
почему бы просто не печатать "4.99"?
Все получилось.
После mosfet поставил делитель r1=2,2Mom (2190000 Om, измерял тестером), r2=680K (656000 Om).
Код:
Вывод
Нужно только правильный mosfet, чтобы через 1k с пина открывался полностью (для 5В bss138 работает,для 3.3В - нет). И с gate на землю не нужен 10k, т.к. через пин замечательно все стекает. Даже пробовал установить пин в 1 а потом убрать питание arduino.