Очередное определение уровня заряда аккумулятора

Lictor
Offline
Зарегистрирован: 01.10.2015


int zarya[2]; //переменная для хранения 3 последний значений напряжения
unsigned long ms;  //счетчик секунд
unsigned long ms2;
int Bat;  //заряд батареи в Вольтах
byte q;    // счетчик
void setup() {
  Serial.begin(9600);
  pinMode(2, OUTPUT);
  pinMode(A1, INPUT);
}
void loop() {
  ms = millis();
  if (ms - ms2 > 1000) {
    ms2 = ms;
    q++;
    digitalWrite(2, HIGH);   //активируем делитель
    delay(50);   //ждем пока напряжение выравняется
    zarya[q] = analogRead(A1);  //считываем напряжение
    digitalWrite(2, LOW);   //отключаем делитель
    if (q == 3) {
      q = 0;
      Bat = ((zarya[0] + zarya[1] + zarya[2]) / 3 * 5 /*опорное напр*/ / 1024 ) * 2 /*напряжение на аккумуляторе*/ ; //усредняем и пересчитываем
    }
    Serial.print(Bat);  //выводим результат 1 раз в секунду, хотя оно меняется лишь 1 раз в 3 сек.
  }
}
Lictor
Offline
Зарегистрирован: 01.10.2015

И так, доброго всем времени суток. Поскольку при создании первого поста я куда-то не туда нажал, суть проблемы пишу ниже. Необходимо определять сколько осталось до разряда аккумулятора. Для этого было решено контролировать его напряжение. Был собран резисторный делитель, НО! для того что бы схема постоянно не потребляла ток было принято решение включать делитель лишь раз в секунду, как именно думаю понятно из схемы и кода. 

Прошу указать замечания по схеме, есть ли какие-то критичесикие несоответствия законам физики, успеет ли выровняться напряжение на аналогвоом входе, а так же помочь упростить код. Заранее благодарен.

 

PS поправочный коэффициент связанный с опорным напряжением внесу позже, так же пересчет в проценты сделаю тоже опосля, после прочтения даташита на аккум, до какого состояния его можно разряжать и заряжать.

 

 

int zarya[2]; //переменная для хранения 3 последний значений напряжения
unsigned long ms;  //счетчик секунд
unsigned long ms2;
int Bat;  //заряд батареи в Вольтах
byte q;    // счетчик
void setup() {
  Serial.begin(9600);
  pinMode(2, OUTPUT);
  pinMode(A1, INPUT);
}
void loop() {
  ms = millis();
  if (ms - ms2 > 1000) {    kol();  }
  
}

void kol() {
  ms2 = ms;
    q++;
    digitalWrite(2, HIGH);   //активируем делитель
    delay(50);   //ждем пока напряжение выравняется
    zarya[q] = analogRead(A1);  //считываем напряжение
    digitalWrite(2, LOW);   //отключаем делитель
    if (q == 3) {
      q = 0;
      Bat = ((zarya[0] + zarya[1] + zarya[2]) / 3 * 5 /*опорное напр*/ / 1024 ) * 2 /*напряжение на аккумуляторе*/ ; //усредняем и пересчитываем
    }
    Serial.print(Bat);  //выводим результат 1 раз в секунду, хотя оно меняется лишь 1 раз в 3 сек.
  }

 

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Надо полагать -10В это в простонародии GND. Схема не рабочая. Транзистор никогда открываться не будет. На входе А2 будешь всегда получать примерно 2.1В, т.е. по сути (напряжение на выходе Digital 2 минус падение напряжения на БЭ переходе транзистора)/2

Lictor
Offline
Зарегистрирован: 01.10.2015

Andy пишет:

Надо полагать -10В это в простонародии GND. Схема не рабочая. Транзистор никогда открываться не будет. На входе А2 будешь всегда получать примерно 2.1В, т.е. по сути (напряжение на выходе Digital 2 минус падение напряжения на БЭ переходе транзистора)/2

Про -10В Вы правы, это просто земля. Но почему транзистор открываться не будет? Земля ардуино и аккумулятора общая. 

Ну фиг с ним с транзитором, если его заменить на реле?

Datak
Offline
Зарегистрирован: 09.10.2014

Lictor, транзистор нужно переставить вниз, под нижний резистор.

В цепь базы обязательно включить токоограничивающий резистор.
А вообще, я бы туда поставил MOSFET (полевой транзистор). Так, навскидку, не скажу, но по-моему у них характеристики для данных целей намного лучше. Кстати, токоограничивающий резистор в этом случае можно не ставить.

Lictor
Offline
Зарегистрирован: 01.10.2015

Datak пишет:

Lictor, транзистор нужно переставить вниз, под нижний резистор.

В цепь базы обязательно включить токоограничивающий резистор.
А вообще, я бы туда поставил MOSFET (полевой транзистор). Так, навскидку, не скажу, но по-моему у них характеристики для данных целей намного лучше. Кстати, токоограничивающий резистор в этом случае можно не ставить.

 

Благодарю за ответ, но скетч будет работать коректно? Насколько быстро выравнивается напряжение после открытия транзистора на аналоговом входе?

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Datak пишет:
транзистор нужно переставить вниз, под нижний резистор.
Тогда транзистор не нужен вообще. При закрытом транзисторе ток будет протекать через верхний резистор и защитный диод входа А2.

Datak
Offline
Зарегистрирован: 09.10.2014

Цитата:
Благодарю за ответ, но скетч будет работать коректно? Насколько быстро выравнивается напряжение после открытия транзистора на аналоговом входе?

По поводу кода -

int zarya[2]; //переменная для хранения 3 последний значений напряжения

- это переменная для хранения двух последних значений, не трёх.

В остальном, вроде, пойдёт для начала.

Насчёт "успеет ли установиться" значение на аналоговом входе - так не скажу, придётся экспериментировать. Теоретически, время будет сильно зависеть от номинала резисторов делителя.

Lictor
Offline
Зарегистрирован: 01.10.2015

Datak пишет:

Цитата:
Благодарю за ответ, но скетч будет работать коректно? Насколько быстро выравнивается напряжение после открытия транзистора на аналоговом входе?

По поводу кода -

int zarya[2]; //переменная для хранения 3 последний значений напряжения

- это переменная для хранения двух последних значений, не трёх.

 

В остальном, вроде, пойдёт для начала.

Насчёт "успеет ли установиться" значение на аналоговом входе - так не скажу, придётся экспериментировать. Теоретически, время будет сильно зависеть от номинала резисторов делителя.

 

Ну я все таки настаиваю, что для 3-х. (правда я несколько напутал с q, теперь исправил). В zarya первое значение запишется в zarya[0]

Datak
Offline
Зарегистрирован: 09.10.2014

Andy пишет:
При закрытом транзисторе ток будет протекать через верхний резистор и защитный диод входа А2.

Точно, боюсь что так. :)

Тогда что, городить схему на паре транзисторов?

Datak
Offline
Зарегистрирован: 09.10.2014

Lictor пишет:
Ну я все таки настаиваю, что для 3-х. (правда я несколько напутал с q, теперь исправил). В zarya первое значение запишется в zarya[0]

А я настаиваю, что всё же двух. :)

Первое значение запишется в zarya[0], второе в zarya[1].
А в
zarya[2], при заданном размере, писать уже нельзя - вылезет за пределы выделенного массива.

Думаю что так. Точнее могу сказать, если покажете, программу после исправления.

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Datak пишет:
Тогда что, городить схему на паре транзисторов?
Можно на паре транзисторов, можно на оптопаре. Не ясно о каком аккуме идет речь. Может у него токи утечки и саморазряда в разы больше, чем ток через сопрот 2М, тогда нет и смысла городить.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Счас ещё выяснится, что ардуина питается от того же аккума через линейный стаб.   Экономим 5µA, расходуем на питание 10mA :-)

Als
Offline
Зарегистрирован: 17.05.2015

Lictor пишет:



  if (ms - ms2 > 1000) {
 
переменной ms2 не присвоено значение. Лучше не привыкать так делать. 
 
По поводу схемы: с реле работать будет. 
Чтобы рассчитать время переходных процессов нужно вычислить постоянную времени RC цепочки и умножить на 5, где С - ёмкость входа + ёмкость монтажа (можно взять 25pF, реальная ёмкость, скорее всего будет меньше). Для механического реле надо ещё прибавить 5 mS на дребезг контактов. Вместо механического реле лучше взять полевой транзистор. Схема с биполярным транзистором не рабочая.
Lictor
Offline
Зарегистрирован: 01.10.2015

Als пишет:

Lictor пишет:



  if (ms - ms2 > 1000) {
 
переменной ms2 не присвоено значение. Лучше не привыкать так делать. 
 
По поводу схемы: с реле работать будет. 
Чтобы рассчитать время переходных процессов нужно вычислить постоянную времени RC цепочки и умножить на 5, где С - ёмкость входа + ёмкость монтажа (можно взять 25pF, реальная ёмкость, скорее всего будет меньше). Для механического реле надо ещё прибавить 5 mS на дребезг контактов. Вместо механического реле лучше взять полевой транзистор. Схема с биполярным транзистором не рабочая.

 

Благодарю за подробный ответ. Только вопрос по 

[/quote]
 
переменной ms2 не присвоено значение. Лучше не привыкать так делать. 
[/quote]
что имеется ввиду? Что ей не присвоено значение на начало программы? Т.к. далее она приравнивается к таймеру.
Als
Offline
Зарегистрирован: 17.05.2015

Lictor пишет:



in
  ms = millis();
  if (ms - ms2 > 1000) {
    ms2 = ms;
 
 
ms2 уже используется, но значение не определено. В данном случае спасает то, что при перезагрузке контроллера в памяти данных будут нули. В другом случае такой способ программирования приведёт к многочасовым поискам ошибки.
zalias7
Offline
Зарегистрирован: 18.03.2015

Andy пишет:

Datak пишет:
Тогда что, городить схему на паре транзисторов?
Можно на паре транзисторов, можно на оптопаре. Не ясно о каком аккуме идет речь. Может у него токи утечки и саморазряда в разы больше, чем ток через сопрот 2М, тогда нет и смысла городить.

100% что так и будет :)
Автор читай:

http://jeelabs.org/2013/05/16/measuring-the-battery-without-draining-it/

Als
Offline
Зарегистрирован: 17.05.2015

Andy пишет:

 Может у него токи утечки и саморазряда в разы больше, чем ток через сопрот 2М, тогда нет и смысла городить.

Вроде бы входное сопротивление АЦП атмеги 150-300 кОм? Если это так, то чтобы обеспечить хоть какую-то приемлемую точность измерения напряжения, делитель должен быть порядка 1кОм. Утечки через делитель будут уже существенны. 
 
Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Als пишет:
Вроде бы входное сопротивление АЦП атмеги 150-300 кОм? Если это так, то чтобы обеспечить хоть какую-то приемлемую точность измерения напряжения, делитель должен быть порядка 1кОм. Утечки через делитель будут уже существенны.
Если без вроде бы, а взять из datasheet, то Analog Input Resistance 100 МОм

Als
Offline
Зарегистрирован: 17.05.2015

Действительно цифра такая в даташите есть. R входа АЦП 100Mом. Значит я со своими знаниями сильно отстал. Тогда с коммутацией можно не заморачиваться.

Lictor
Offline
Зарегистрирован: 01.10.2015

Als пишет:

Действительно цифра такая в даташите есть. R входа АЦП 100Mом. Значит я со своими знаниями сильно отстал. Тогда с коммутацией можно не заморачиваться.

 

Так тогда получится, что аккум постоянно замкнут на нагрузке в 2МОм, что тоже не способствует сохранению заряда.

Lictor
Offline
Зарегистрирован: 01.10.2015

zalias7 пишет:

Andy пишет:

Datak пишет:
Тогда что, городить схему на паре транзисторов?
Можно на паре транзисторов, можно на оптопаре. Не ясно о каком аккуме идет речь. Может у него токи утечки и саморазряда в разы больше, чем ток через сопрот 2М, тогда нет и смысла городить.

100% что так и будет :)
Автор читай:

http://jeelabs.org/2013/05/16/measuring-the-battery-without-draining-it/

 

Обязательно прочту. Атмега питается от своего источника, просто массы связаны. Читал, что такое допустимо.

 

Прочел. Попробую добавить кондер. 

Als
Offline
Зарегистрирован: 17.05.2015

Lictor пишет:

Так тогда получится, что аккум постоянно замкнут на нагрузке в 2МОм, что тоже не способствует сохранению заряда.

10V/2M=5uA - этим можно пренебречь.

Buldakov
Offline
Зарегистрирован: 17.01.2016

Опорное напряжение лучше использовать внешнее. Если использовать напряжение +5 в. то оно зависит от напряжения питания платы и может меняться в зависимости от нагрузки. Попробуйте в качестве внешнего опорника использовать что то типа TL431A.

По поводу связи напряжения питания и процента заряда есть программа для андроид. Там есть циферки зависимости.

http://4pda.ru/forum/index.php?showtopic=401883

 

Andry Smart
Offline
Зарегистрирован: 06.09.2016

как по мне то делитель на резисторах можно подключать простой записью в порт и настройкой пина. настроил на вход и все резисторы в воздухе. настроил на выход и выдал ноль (подключил к земле) выдал 1 (подключил к питанию..

только вот мне кажется смысла в такой экономии нет