Симметричный мультивибратор на Arduino nano Atmega328.
- Войдите на сайт для отправки комментариев
Друзья, здравствуйте. Такая штука: собрана приблуда для управления двумя соленоидами. Необходимо, чтобы при замыкании кнопки на землю включались сперва один симметричный мультивибратор, который будет давать сигал на включение реле 1 от первого соленоида на 12 В, далее через задержку включался второй мультивибратор для управления реле 2 от второго соленоида, а первый в этот момент выключался и т.д, т.е. попеременное включение и выключение соленоидов. Время задержки верхнего и нижнего фронта сигналов на вход блока реле регулируется от 500 до 100 мс при помощи потенциометра на 22кОм и значение выводится на LCD дисплей. Логику сделал на FLProg. Первая проблема заключается в том, что сперва блок реле начинает работать нормально, но через продолжительное время нажатия кнопки симметричность включения и выключения релюх нарушается и соленоиды начинают срабатывать хаотично. Запитано все это от компьютерного БП. +12 В на нагрузку и +5 В на контроллер, просадок напряжения нет. Также пробовал это делать на плате Mega уже без соленоида, происходит тоже самое, причем бывает момент, когда они начинают срабатывать асинхронно сразу же в момент нажатия кнопки, с чем это может быть связано и есть ли способы решения данного косяка? Вторая проблема заключается в отображаемой информации времени задержки на LCD дисплее. Постоянно шакалит последний разряд, плавает на + - 1. Возможно ли это как то стабилизировать и быть может это как раз и является причиной первой проблемы?
1) https://funkyimg.com/i/322Kw.jpg схема коммутации
2)https://funkyimg.com/i/322Kx.png схема в FLProg
3)https://funkyimg.com/i/322Kv.jpg блок реле
Использовал FLProg 4.0.0 и Arduino IDE 1.8.1
Код в arduino IDE:
#include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C _lcd1(0x3F, 16, 2); int _dispTempLength1=0; boolean _isNeedClearDisp1; int _disp2oldLength = 0; bool _tim1I = 0; bool _tim1O = 0; unsigned long _tim1P = 0UL; int _disp1oldLength = 0; bool _bounseInputD2S = 0; bool _bounseInputD2O = 0; unsigned long _bounseInputD2P = 0UL; bool _gen1I = 0; bool _gen1O = 0; unsigned long _gen1P = 0UL; bool _gen2I = 0; bool _gen2O = 0; unsigned long _gen2P = 0UL; void setup() { Wire.begin(); delay(10); pinMode(2, INPUT_PULLUP); pinMode(4, OUTPUT); pinMode(7, OUTPUT); _lcd1.init(); _lcd1.backlight(); _bounseInputD2O = digitalRead(2); } void loop() {if (_isNeedClearDisp1) {_lcd1.clear(); _isNeedClearDisp1= 0;} bool _bounceInputTmpD2 = (digitalRead (2)); if (_bounseInputD2S) { if (millis() >= (_bounseInputD2P + 40)) {_bounseInputD2O= _bounceInputTmpD2; _bounseInputD2S=0;} } else { if (_bounceInputTmpD2 != _bounseInputD2O ) {_bounseInputD2S=1; _bounseInputD2P = millis();} } //Плата:1 if (1) { _dispTempLength1 = (((String((map(( (analogRead (2))), (0), (1023), (100), (500))), DEC)))).length(); if (_disp1oldLength > _dispTempLength1) {_isNeedClearDisp1 = 1;} _disp1oldLength = _dispTempLength1; _lcd1.setCursor(int((16 - _dispTempLength1)/2), 0); _lcd1.print(((String((map(( (analogRead (2))), (0), (1023), (100), (500))), DEC)))); } else { if (_disp1oldLength > 0) {_isNeedClearDisp1 = 1; _disp1oldLength = 0;} } if (!(_bounseInputD2O)) { if (_tim1I) { if (_isTimer(_tim1P, (map(( (analogRead (2))), (0), (1023), (100), (500))))) {_tim1O = 1;}} else {_tim1I =1; _tim1P = millis();}} else {_tim1O = 0; _tim1I = 0;} if (_tim1O) { if (! _gen2I) { _gen2I = 1; _gen2O = 1; _gen2P = millis(); } } else { _gen2I = 0 ; _gen2O= 0;} if (_gen2I) { if ( _isTimer ( _gen2P , (map(( (analogRead (2))), (0), (1023), (100), (500))) )) { _gen2P = millis(); _gen2O = ! _gen2O;}} digitalWrite(7, !(_gen2O)); if (!(_bounseInputD2O)) { if (! _gen1I) { _gen1I = 1; _gen1O = 1; _gen1P = millis(); } } else { _gen1I = 0 ; _gen1O= 0;} if (_gen1I) { if ( _isTimer ( _gen1P , (map(( (analogRead (2))), (0), (1023), (100), (500))) )) { _gen1P = millis(); _gen1O = ! _gen1O;}} digitalWrite(4, !(_gen1O)); if (1) { _dispTempLength1 = ((String("Pulse time (ms)"))).length(); if (_disp2oldLength > _dispTempLength1) {_isNeedClearDisp1 = 1;} _disp2oldLength = _dispTempLength1; _lcd1.setCursor(int((16 - _dispTempLength1)/2), 1); _lcd1.print((String("Pulse time (ms)"))); } else { if (_disp2oldLength > 0) {_isNeedClearDisp1 = 1; _disp2oldLength = 0;} } } bool _isTimer(unsigned long startTime, unsigned long period ) { unsigned long currentTime; currentTime = millis(); if (currentTime>= startTime) {return (currentTime>=(startTime + period));} else {return (currentTime >=(4294967295-startTime+period));} }
С ФЛПрогом Вам здесь никто не поможет - не жалуют его тут.
Так что либо ищите форум по ФЛПрогу, либо (если Вам уже исполнилось хотя бы 10 лет) переходите на нормальный язык программирования.
Друзья, здравствуйте. Такая штука: собрана приблуда для управления двумя соленоидами. Необходимо, чтобы при замыкании кнопки на землю включались сперва один симметричный мультивибратор, который будет давать сигал на включение реле 1 от первого соленоида на 12 В, далее через задержку включался второй мультивибратор для управления реле 2 от второго соленоида, а первый в этот момент выключался и т.д, т.е. попеременное включение и выключение соленоидов. Время задержки верхнего и нижнего фронта сигналов на вход блока реле регулируется от 500 до 100 мс при помощи потенциометра на 22кОм и значение выводится на LCD дисплей. Логику сделал на FLProg. Первая проблема заключается в том, что сперва блок реле начинает работать нормально, но через продолжительное время нажатия кнопки симметричность включения и выключения релюх нарушается и соленоиды начинают срабатывать хаотично.
Про нормальный язык выше уже написали, там кода, без экрана, десять строчек и состоит он из analogRead, map, digitalWrite и простит меня бог, delay.
Бегающий разряд, это природное свойство потенциометра, странно, что только на единицу.
А вот тому хаду, который вас так кнопку научил включать, пургену в чай насыпьте.)))) (Не, виноват, там флпрога пуллапа вставила. Пурген отменяем. Хотя ведь могла и не вставить). Т.к. внутренний резистор весьма большого номинала, вполне может от срабатывания реле колбасить.
Ну а борьба с переполненным миллисом, как всегда, вне конкуренции.))))
Ну а борьба с переполненным миллисом, как всегда, вне конкуренции.))))
Это просто фирменная фишка FLProg - как песня "На речке, на речке ..." обязательно появляется во всех фильмах Данелия, так и эта борьба - во всех произведениях FLprog.
Господа, насколько я понял, Вы утверждаете, что написав правильно программу в среде IDE на С, используя функции analogRead, map, digitalWrite, delay и т.д. момент с рассинхроном срабатывания реле можно избежать?
Бегающий разряд удалось убрать подав 12 вольт на вход контроллера. Теперь отображает все четко без мерцания.
Другой момент. Решил запитать LCD дисплей 5 Вольтами с БП (не через стабилизатор с контроллера), чтобы лишний раз не нагружать Nano, в итоге сперва все отлично показывает, регулировка значений с потенциометра отображается корректно, но стоит нажать кнопку для начала работы реле, через 20 секунд вполне корректной работы контроллер зависает, оставляя открытым или закрытым один из реле. SCL SDA подтянул к +5 Вольт через резисторы 10кОм. Если подключать LCD к питанию с контроллера то иногда начинает мерцать подсветка.
насколько я понял, Вы утверждаете, что написав правильно программу в среде IDE на С, используя функции analogRead, map, digitalWrite, delay и т.д. момент с рассинхроном срабатывания реле можно избежать?
Нет.
Мы утверждаем, "что написав правильно программу" в любой среде с использованием любых функций, и собрав правильно схему, можно добиться, чтобы реле работали точнее швейцарских часов.
Что до второй части Вашего поста - запостите его на тот форум, на который Вы выкладывали схему. Там Вам смогут что-то разумное сказать. Здесь же - никак. Разве что, я вот заметил:
SCL SDA подтянул к +5 Вольт через резисторы 10кОм.
Много! См. п. 22.5.2 даташита и таблицу 29-14 там же.
Нет.
Мы утверждаем, "что написав правильно программу" в любой среде с использованием любых функций, и собрав правильно схему, можно добиться, чтобы реле работали точнее швейцарских часов.
Моё почтение, Вы меняя воодушевили на то, чтобы разбираться с кодом. Просто я склонялся в сторону аппаратной неисправности.
Если Вас не затруднит, не могли бы скинуть ссылку на даташит, на который Вы указали?
Так я имел в виду даташит на ATmega328P, которая стоит в унах, нанах и т.п. (только не говорите, что у Вас DUE - такое надо в первом посте писать! :-)
Большое спасибо! У меня именно такой чип, просто я в другом формате даташит скачал и соответственно не находил указанные Вами пункты) Попробую подтянуть на 1.5кОм.