avatar_UriBas

Моргалка на Arduino. Этюды для начинающих.

Автор UriBas, 08 Март 2017 в 16:08

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

Dunkel

Цитата: Dkin от 21 Март 2017 в 22:13
будет ли работать в вашем цикле уход на метку?

Не знаю, не пробовал.
А что за нужда выходить из цикла? Дождаться окончания цикла, и сделать все, что нужно.
Пара секунд никакой роли не сыграют. Мы же не пожар тушим.
Многофункциональная облачная моргалка/логгер:
https://morgalka78.wordpress.com/

Dkin

Это очень важно
К примеру, у нас установлено заряд 60 сек, пауза 20 сек
Первый раз напряжение коснется допустим 14,4В на 15 сек и уйдет в паузу
второй раз на 12
через 2 часа импульс заряда уже будет 4 секунды
через двое суток 0,5 сек
все условно конечно
Т.е. нужен обязательный уход в паузу при заданном напряжении

Dunkel

Т.е. в цикле нужно зафиксировать какое-то событие?
Делается просто, при фиксации события -  int flag=1;
По окончании цикла проверяем состояние флага и делаем выводы.
Многофункциональная облачная моргалка/логгер:
https://morgalka78.wordpress.com/

Dkin

#39
Отлично!
или как в моем примере,
// работа импульсов несущей частоты
  digitalWrite(13, HIGH);
  delay(impnes1 );                     
  digitalWrite(13, LOW);
  delay( pausenes1 );
измерение;
если напряжение превышает значение goto label1;
если нет goto label2;
label1;
пауза;
label2;

Получается, если напряжение превысило - пауза,
если нет - просто перепрыгиваем паузу

Dunkel

Не совсем понял, если в цикле заряда 60 сек напряжение стало 14,4В, то нужно сразу прервать заряд и уйти на паузу?
Или дождаться окончания 60сек заряда, понять что достигнуто 14,4В и уйти на паузу?
Я просто еще не достаточно точно представляю работу моргалки.
Многофункциональная облачная моргалка/логгер:
https://morgalka78.wordpress.com/

Dkin

Да, не важно на какой секунде при наступлении 14,4В сразу же прервать заряд и уйти на заданную паузу, потом вновь заряд.

Dkin

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

Спойлер

// Общие настройки - Несущая частота
float freq = 35.00; // частота в Гц (от 1 до 350)
float skv1 = 50.00; // коэффициент заполнения (от 1 до 99)

// 1 этап Модулирующие импульсы
long zar1 = 30; // время заряда в сек (от 1 сек)
long pauseosn1 = 10; // время паузы в сек (от 1 сек)

// 2 этап работа отсечки
long Uots = 690; // напряжение отсечки 690 - пока для примера (допустим 690 в пересчете с делителя напр. 14,4 В)
long pauseots1 = 60; // время паузы в сек (от 1 сек)

float impnes1 = 0.00;
float pausenes1 = 0.00;
long previousMillis = 0;
long Utek = 0;

void setup()
{
   pinMode(13, OUTPUT); // используем 13 выход для управления ключом, на нем также висит синий светодиод, располагающийся на плате, для наглядности
   PinMode(10, OUTPUT); // светодиод отсечка
   PinMode(12, OUTPUT); // светодиод заряд
   pinMode(0, INPUT); // вход A0 с делителя напряжения

   impnes1 = 10 * skv1 / freq; // расчет импульса заряда несущей частоты
   pausenes1 = 10 * (100 - skv1) / freq; // расчет паузы несущей частоты
}

void loop()
{
// расчет основного цикла заряд/пауза
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > zar1*1000) // если время заряда истекло
{
    digitalWrite(13, LOW); // выключаем ключ
    digitalWrite(12, LOW); // гасим светодиод заряд
    delay (pauseosn1*1000);
    currentMillis = millis();
    previousMillis = currentMillis;
}
// работа импульсов несущей частоты
  digitalWrite(12, HIGH); // включаем светодиод заряд
  digitalWrite(13, HIGH); // включаем ключ
  delay(impnes1 );                     
  Utek = analogRead(0); //измеряем напряжение на входе A0
  if (Utek > Uots) // если измеренное напряжение больше напряжения отсечки
{
goto label1; // перейти на паузу отсечки
}
  digitalWrite(13, LOW); // отключаем ключ
  delay( pausenes1 );
  goto label2; // пропустить паузу отсечки
label1:
    digitalWrite(13, LOW); // выключаем ключ
    digitalWrite(12, LOW); // гасим светодиод заряд
    digitalWrite(10, HIGH); // включаем светодиод отсечка
    delay (1000);
    digitalWrite(10, LOW); // гасим светодиод отсечка
    delay(pauseots1*1000 - 1000); пауза после отсечки минус 1 сек (горение светодиода отсечка)
    currentMillis = millis();
    previousMillis = currentMillis;
label2:
}

Алгоритм:

заряд - 30 сек
пауза - 10 сек

несущая частота 35Гц с коэффициентом заполнения 50%.

при достижении напряжения на АКБ 14,4В - отключение заряда и пауза 60 сек.

UriBas

#43
Цитата: Dunkel от 21 Март 2017 в 21:52Вряд ли АКБ хуже зарядится из-за использования delay. 
delay - останавливает АЦП и мы не сможем мерить напряжение на АКБ в паузе, а нам его придется мерить.. если хотим заряжать, а не просто моргать.    Зачем мерить в паузе?  Чтобы потом определять длину паузы - по падению напряжения, таким образом, программа будет подбирать оптимальный режим заряда.  Например пауза рассчитывается  по скорости падения напряжения = от 2 до 7мВ/сек, смотря на какой стадии заряда находится АКБ.
Цитата: Dunkel от 21 Март 2017 в 22:19А что за нужда выходить из цикла? Дождаться окончания цикла, и сделать все, что нужно.  Пара секунд никакой роли не сыграют. Мы же не пожар тушим. 
Пара секунд - для заряда импульсным током в 10-20А почти "вечность".. за эти пару секунд напряжение может взлететь гораздо выше 14,4В и электролит будет сильно кипеть..  при сильном кипении начинается терморазгон (нагрев), разрушение активной массы в АКБ и другие вредные процессы..  Для чего вообще нужно моргать?.. именно для того, чтобы за время пауз электролит смог остывать, а также еще есть такое понятие как поляризация электрического слоя, которая препятствует дальнейшему заряду..  нельзя слишком долго давать импульс заряда, потому что тогда происходит эта поляризация,  поэтому еще, надо давать необходимую паузу, чтобы поляризация рассосалась..  - вот в чем смысл импульсного заряда.   Так шта километр" сюда, километр" туда - здесь не подходит.  Все решают миллисекунды и милливольты!   
Восточная мудрость - "Шакал воет - караван идет"  Эл.вел. 350Вт.   Верую в Иисуса Христа, НЛО.  тема "продвинутой моргалки" https://electrotransport.ru/index.php?msg=1669651

UriBas

#44
Цитата: Dkin от 22 Март 2017 в 00:40
Алгоритм: заряд - 30 сек  пауза - 10 сек
несущая частота 35Гц с коэффициентом заполнения 50%.
при достижении напряжения на АКБ 14,4В - отключение заряда и пауза 60 сек.
О! У блинка" появился порог в 14,4В..  это уже хорошо!  Но.. в заряде АКБ существует такое понятие как "добивка"..  потому что, когда напр достигло 14,4В АКБ еще не заряжен полностью..  т.е. заряжен всего на 70-80% и то, это если АКБ не засульфатирован, т.е. новый, свежий..  Так вот, даже если мы будем заряжать новый и хороший АКБ, то такой режим будет приводить к недозаряду и к сульфатации АКБ..  Да вот.. есть эти злосчастные сульфаты, которые с одной стороны участвуют в заряде и разряде..  и без них никуда,  с другой эти сульфаты в виде белого порошка - налета, оседают на пластинах и препятствуют заряду..  А растворить их можно только зарядив АКБ полностью на 100%..   Вот такие дела...  НЕДОЗАРЯД ВЫЗЫВАЕТ СУЛЬФАТАЦИЮ И ДЕГРАДАЦИЮ АКБ!!!

Так шта этот режим не пойдет!  Пауза в 60секунд после 14,4В  слишком большая..   НО! Если ее сделать скажем 7 секунд или меньше, то тоже, могут быть проблемы - если к примеру АКБ уже зарядится.  Что будет?.. А будет то, что АКБ будет всегда находится в пределах 14,0-14,4В .. и это будет вызывать опять же..  да, кипячение!..   Так как же быть? Какую паузу делать? .. 2-7-10-20 или более секунд??  Ответ уже написал выше,

[b-b]самое правильное делать АДАПТИВНУЮ ПАУЗУ[/b-b]..  т.е. паузу, которая бы подходила во всех случаях и опытным путем уже определена - Пауза должна прерываться при скорости от 2 до 7мВ/сек.   К примеру если напр достигло 14,4В  пауза должна быть длиннее и скорость можно снизить до 2-4мВ/сек.   

[b-b]То же самое касается и длительности импульса[/b-b], там тоже нужно обрывать импульс по достижению [b-b]дельты[/b-b]" в 0,2-0,6В..  тогда это будет более или менее уже нормальный заряд.   Расчет ведется так - вначале мерится НРЦ (напряжение на АКБ без подключения зарядного или разрядного тока), запоминается, затем включается заряд и во время заряда мерим напряжение, если напряжение на АКБ превышает НРЦ +0,4В - то импульс прекращается.   Вот попробуйте реализовать такой алгоритм.

П.С.  Это конечно еще не все (по алгоритму) Надо будет потом разбить весь процесс заряда на три (можно больше) этапа:   первый - это этап раскачки АКБ.  Второй - основной заряд.  Третий - добивка..   у каждого есть свои особенности, частично уже сказал о добивке. 
Также нам потребуется вся мощь процессора - быстродействие АЦП  чтобы можно было делать за короткое время максимальное количество выборок, а потом делать усреднение.. в конечном итоге получим около 15 усредненных значений в секунду.
Для этого хорошо почитать статью http://robotosha.ru/arduino/analog-measurements-arduino.html - "Аналоговые измерения с Arduino"
Восточная мудрость - "Шакал воет - караван идет"  Эл.вел. 350Вт.   Верую в Иисуса Христа, НЛО.  тема "продвинутой моргалки" https://electrotransport.ru/index.php?msg=1669651

Dunkel

Цитата: UstAlexei от 22 Март 2017 в 07:56
Arduino хороша для поиграться, либо быстро сделать сиюминутную задачу, но не более.

Ардуино замечательно подходит для обучения, в нашем случае для понимания алгоритма работы моргалки.
А уже когда будет понимание алгоритма - можно реализовывать на чем угодно.
Многофункциональная облачная моргалка/логгер:
https://morgalka78.wordpress.com/

Dkin

#46
Цитата: UriBas от 22 Март 2017 в 04:24
самое правильное делать АДАПТИВНУЮ ПАУЗУ..  т.е. паузу, которая бы подходила во всех случаях и опытным путем уже определена - Пауза должна прерываться при скорости от 2 до 7мВ/сек.   

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

Dkin

Пример 10 измерений подряд с усреднением

s=0;
for (int i = 0; i <10; i ++)  s+=analogRead(A0);
utek=s/10;

Dkin

Время выполнения команд на ардуино, для информации

запись байта в память - 2 такта
запись 2 байтов       - 4 такта
запись 4 байтов       - 8 тактов
цикл int (long)       - 6 тактов
int                         - 6-7 тактов
long             - 15-17 тактов
float              - 200-220 тактов
millis                - 2 мкс
digitalWrite          - 6-8 мкс
digitalRead           - 4-6 мкс
analogRead            - 111-112 мкс


UstAlexei

Цитата: Dkin от 22 Март 2017 в 09:07
Пример 10 измерений подряд с усреднением
[b-b]for (int i = 0; i <10; i ++)  [/b-b]
s+=analogRead(A0); внутри процедуры analogRead(A0) происходит передача номера входа А0 (в цикле 10 раз одна и та же) для считывания, и задержка (в цикле 10 раз одна и та же) для успокоения входа АЦП после переключения входа, поэтому функцию по получению данных АЦП надо переписать. Сделать передачу входа на мультиплексор один раз (возможно вообще один раз в функции setup, вы же один вход меряете), и собственно избавиться от задержки аналогичным образом.
[b-b]utek=s/10; [/b-b]
Процедура деления гораздо затратнее (в аппаратном смысле) чем процедура сдвига, поэтому стоит выбрать число кратное 2n, а после сделать сдвиг вправо на n, эквивалентно [b-b]S/n[/b-b], но выполняется в разы быстрее и отнимает меньше памяти. [b-b]А потом задуматься, а нужно ли вообще деление? суммировали 10 значений, ну и работайте с ними, задавая уставку по напряжению в 10 раз больше.[/b-b]

Dkin


Dunkel

А для чего вся эта оптимизация?
У нас в алгоритме сплошные паузы - сделаем их поменьше, если процессору нужно больше времени.
Многофункциональная облачная моргалка/логгер:
https://morgalka78.wordpress.com/

Alex_Soroka

Цитата: Dkin от 21 Март 2017 в 21:56
Скорее всего, измерения будут вносить дополнительное время задержки.
6_6
если вы используете delay() функцию из стандартной библиотеки, и используете прерывания, то делай не будет никогда считать точно, потому что прерывания тоже отнимают процессорное время, а делай просто тупо "nop" крутит в цикле или подобное.
Надо делать измерения времени на таймере, или сидеть с секундомером и высчитывать "время задержки" по реальному устройству.

Dkin

Цитата: Alex_Soroka от 22 Март 2017 в 10:04
Надо делать измерения времени на таймере, или сидеть с секундомером и высчитывать "время задержки" по реальному устройству.

Будем вносить корректировки по реальным измерениям.