Автоматическое отключение питания на Arduino
- Войдите на сайт для отправки комментариев
Вс, 22/05/2016 - 18:57
Доброго времени суток друзья! Нужна помощь. Нужно сделать устройство, которое будет отключать общее питание при отсутствии сигнала. Теперь подробно)) Имеем лазерный ЧПУ выжигатель, автономный контроллер им рулит через драйвера DRV8825, драйвера установлены на плате cnc shield. Суть вот в чем. Есть ардуино нано, так вот надо ее как то заставить отключать питание всего станка при выходе из строя любого драйвера на станке. Рассмотрим ситуацию. Перегорает каким то чудом драйвер оси Х, на которой находится лазер. Драйвер сгорел, двигатель стоит, а лазер шпарит. Тут и до пожара не далеко. Так вот нужно как то ардуино научить отключать питание общее при пропадании сигнала с выхода драйверов.
Подозреваю (да и вы упомянули это), что надо садиться на выходы драйверов и смотреть сигнал - если нет какое-то время, то рубить питание. Как рубить? Да хоть через реле, хоть мосфетом. В чём конкретно проблемы - в схеме или в коде?
Да на выход драйвера)) там два сигнала. Один сигнал идет на обмотку двигателя для удержания, а второй отвечает за вращение. На обоих 12 вольт. Проблема и в схеме и коде). Для меня сам станок собрать не проблема, а все эти прошивки и схемы как то не дано))
Смотрите, как вариант: берёте конвертер уровней с али (искать по словам "logic level converter"), подключаете один его вход к сигналу с драйверов, противоположный выход - на пин ардуины. В коде отслеживаете время последнего получения сигнала, что-то типо такого:
unsigned long lastSignalTime = 0; const int inPin = 10; // на каком пине сигнал const int powerPin = 9; // на каком пине управляем питанием void setup() { pinMode(inPin, INPUT); pinMode(powerPin, OUTPUT); digitalWrite(powerPin,HIGH); } void loop() { if(digitalRead(inPin) == HIGH) // если есть сигнал { lastSignalTime = millis(); } if(millis() - lastSignalTime > 10000) // если сигнала нет больше 10 секунд { // отрубаем питание digitalWrite(powerPin,LOW); } }К пину управления цепляем либо затвор мощного мосфета, либо - сигнал для модуля реле. Если юзается мосфет, то нагрузку вешаете в цепь стока, если реле - к выходам реле. Примеров использования и того, и другого, с рисунками - масса.
Естественно, код, который привёл - лишь набросок. По аппаратной части более правильно подскажут опытные товарищи, вроде axill - они зайдут в тему, думаю.
Всем привет похожий вопрос. Нужно при пропадании сигнала с передатчика через сикунду отключать все реле приемника.
#include <SoftwareSerial.h> SoftwareSerial radio(6, 7); // RX, TX void setup() { Serial.begin(9600); radio.begin(9600); pinMode(13, OUTPUT); pinMode(8, OUTPUT); pinMode(9, OUTPUT); char val = radio.read(0); } void loop() { static unsigned long prevMillis; if (millis() - prevMillis == 2000 ) { // если с приема предыдущей команды прошло больше 2 сек digitalWrite( 14, 0); // выключаем диод digitalWrite( 8, 0); digitalWrite( 13, 0); prevMillis = millis(); char val = radio.read(); switch (val) { case 'A': digitalWrite(8,0); break; case '1': digitalWrite(8, 0); break; } char val1 = radio.read(); switch (val) { case '4': digitalWrite(13, 1); break; case '3': digitalWrite(13, 0); break; } char val2 = radio.read(); switch (val) { case '5': digitalWrite(9, 1); break; case '6': digitalWrite(9, 0); break; prevMillis = millis(); } }Все работает но когда удерживаю кнопку на передатчике реле клацает цыклично. В чем проблема подскажите? Буду оч благодарен.
Поставьте после
char val = radio.read();
вывод
Serial.println(val);
Serial.println(prevMillis);
и, возможно, сами увидите.
Удерживаете кнопку, отправляющую 4 или 5 ?
Зделал вот так
#include <SoftwareSerial.h> SoftwareSerial radio(6, 7); // RX, TX void setup() { Serial.begin(9600); radio.begin(9600); pinMode(13, OUTPUT); pinMode(8, OUTPUT); pinMode(9, OUTPUT); } void loop() { static unsigned long prevMillis; if (millis() - prevMillis == 1000 ) { // если с приема предыдущей команды прошло больше 2 сек digitalWrite( 9, 1); // выключаем диод digitalWrite( 8, 1); digitalWrite( 13, 1); prevMillis = millis(); } char val = radio.read(); if( val== '4' ) { digitalWrite(9,1); } if( val== '3' ) { digitalWrite(9, 0); if( val== '6' ) { digitalWrite(9,1); } if( val== '5' ) { digitalWrite(9, 0); if( val== '1' ) { digitalWrite(13,1); } if( val== '2' ) { digitalWrite(13, 0); } prevMillis = millis(); } } }Но работает только первое условие соответственно только одно релле. Голова уже дымит.??
Постоянно перебераются цыфры (команды). Вы имеете в виду что сигнал есть постоянно ? Но все равно не пойму если сигнал есть то почему релле клацает ? Поясните если не сложно?
Ставьте датчики пламени и дыма, негорючее основание и систему пожаротушения. У меня сутки 3D принтер молотил на месте, заклинила ось Y , драйвера и шаговик исправны. А когда на лазерном гравере 2.5 Вт останавливается каретка, неважно от чего (может и механика заклинить и электроника ,и от зависания программы никто не застрахован) через 10-15 минут возгорание обеспечено.
>Но работает только первое условие соответственно только одно релле. Голова уже дымит.??
IF'ы позакрывайте. У вас где то сразу } стоит после digitalWrite, а где то внизу кода.
Ставьте датчики пламени и дыма, негорючее основание и систему пожаротушения. У меня сутки 3D принтер молотил на месте, заклинила ось Y , драйвера и шаговик исправны. А когда на лазерном гравере 2.5 Вт останавливается каретка, неважно от чего (может и механика заклинить и электроника ,и от зависания программы никто не застрахован) через 10-15 минут возгорание обеспечено.
Может быть уже поздно :) Из извращений - акселерометр можно поставить на каретку и либо как то синхронизировать с УП либо тупо "1 минуту не двигаемся по X или по Y - выкл лазера".
Постоянно перебераются цыфры (команды). Вы имеете в виду что сигнал есть постоянно ? Но все равно не пойму если сигнал есть то почему релле клацает ? Поясните если не сложно?
Да, подозреваю, что прилетают постоянно какие то команды если держать кнопку. Но лучше не гадать и сделать вывод в порт.
В порту смотрел прилетают команды от не нажатых кнопок . Но почему
static unsigned long prevMillis; 17 if (millis() - prevMillis == 1000 ) { // если с приема предыдущей команды прошло больше 2 сек 18 digitalWrite( 9, 1); // выключаем диод 19 digitalWrite( 8, 1); 20 digitalWrite( 13, 1); 21 prevMillis = millis();Не работает не пойму.?
== поменять на >
Простое выражение но диод загорается в пол накала подскажите почему ?
#include <SoftwareSerial.h> SoftwareSerial radio(6, 7); // RX, TX int led = 9; void setup() { Serial.begin(9600); radio.begin(9600); pinMode(13, OUTPUT); pinMode(8, OUTPUT); pinMode(9, OUTPUT); } void loop(){ char val = radio.read(); if( val== '3' ) { digitalWrite(9,0); } else { digitalWrite(9,1); } }Тоесть когда приходит 3 он должен гореть иначе тухнуть . Работает но горит в пол накала ???
Вам нужно совершать действия в определенные моменты времени. Например, когда пришла команда '3' - включить светодиод, а у вас сейчас получается цикл проверки постоянно крутится независимо от того пришла команда или нет, вы это не проверяете и ориентируетесь каждый раз на val, хотя там может быть старое значение или что то еще. Это с модулями nrf24 штуковина ? Надо вывести val в serial и глянуть, что получается когда отпускаете кнопку пульта.
Имеем лазерный ЧПУ выжигатель, автономный контроллер Рассмотрим ситуацию. Перегорает каким то чудом драйвер оси Х, на которой находится лазер. Драйвер сгорел, двигатель стоит, а лазер шпарит. Тут и до пожара не далеко. Так вот нужно как то ардуино научить отключать питание общее при пропадании сигнала с выхода драйверов.
Вероятность выхода из строя драйверов, если они правильно настроены - невелика. Гораздо выше вероятность механических неисправностей. ЧПУ выжигатели -работают на достаточно высоких скоростях и длительное время измеряемое десятками часов испытывая при этом значительные динамические нагрузки и вибрацию. Откуда более вероятно откручивание шкивов на валу ШД, просто раскручивание резьбовых соединений или просто обрыв провода на одну из обмоток шаговика или попадание пыли в подшипник из за чего ось может встать . При этом на шаговик будут поступать нормальные сигналы с драйвера, которому все равно стоит шаговик или крутится в холостую. Следить лучше за перемещением ремней или паразитных роликов, поставив на них оптические или магнитные датчики. А еще лучше за световым пятном лазера. При этом не обязательно знать его положение, а просто фиксировать, что световая картинка долго не меняется. Но это только один из возможных вариантов. Я немного игрался с лазерным гравером и тоже думал о проблеме возгорания, особенно когда пытался вырезать фигурки из бумаги. Возгорания происходили достаточно часто, особенно если встречались мелкие детали. Поэтому ни разу не оставлял выжигатель без присмотра. Хотя- бы раз в 10 минут проверял его. Так-что вопрос довольно актуальный.
Нет с другими модулями завтра напишу модель.
Модули HC 12.
Зделал вот так
char val = radio.read(); Serial.println(); if( val== '3' ) { digitalWrite(9,0); } else { digitalWrite(9,1); } if( val== '4' ) { digitalWrite(8,0); } else { digitalWrite(8,1);Тоесть пришла команда 3 мреле вкл.Нет команды выкл . Но когда несколько релле и их нужно вкл одновременно то команды передаются по очереди соответственно релле клацаю по очереди . Есть идеи ?
У вас получилось, что если команда 3 - включается реле, а если любая другая - выключается. Нужно или в один if ... else if ... завернуть (а не отдельными if) или switch / case как было выше постами. Посмотрели что возвращает radio.read() при отсутствии команд ? Что то ведь возвращает - это важно.
В смысле одной командой релле включать а второй отключать?
А... это же serial. Тогда сначала нужно проверить пришло что то вообще или нет if (radio.available() > 0) {} и только в этом случае читать radio.read() и щелкать реле.
Надо то как ? Чтобы реле включались командами, а выключались сами через 1-2 сек ?
Сейчас возврвщает просто кубики какието а если нажать кнопку передатчика то цыфру если две кнопки то переберает цыфры
Получается так есть передача например 3ки релле вкл нет передачи реле остается вкл пока не появится передача . Получается чтоб релле отпало передатчик должен послать команду а это значит что при отпущенной кнопке передаттчик все время посылает команды.
У вас digitalWrite(9,0); включает реле или выключает ? Выключаться реле должны тоже какой то командой или сами по себе ? По вашим последним вариантам непонятно, по тому, где case, вроде как сами по себе, но не команадами.
char val = radio.read(); 02 Serial.println(); 03 04 05 if( val== '3' ) { 06 digitalWrite(9,0); 07 } 08 09 else { 10 11 digitalWrite(9,1); 12 } 13 14 if( val== '4' ) { 15 digitalWrite(8,0); 16 } 17 18 else { 19 20 digitalWrite(8,1);Блок релле у меня вкл отрицательной полярностью . То есть ноль это релле вкл. Оно командой включается а отклю чается если команда отсутствует например еслиприемник потерял связь с передатчиком. Но если передавать две команды то они передаются по очереди соответственно релле клацает.
В принципе вариант "выключить через секунду" нормальный если это устраивает. Выключать именно то реле, по которому нет команды на включение 1 сек - типа так ? Если надо быстро выключать - лучше передавать отдельно команды на вкл и выкл, а уж по потере связи отдельно отключать через 1 сек.
Вот так не клацает ? Только включается ?
if (radio.available() > 0) { char val = radio.read(); Serial.println(); if( val== '3' ) { digitalWrite(9,0); } else if( val== '4' ) { digitalWrite(8,0); }; }Да .Отключатся ж условия нет.
Зато не клацает :) Теперь можно и выключать. Так работает ? Вместе выключать нельзя - получится что отсутствие любой из команд выключит все реле.
static unsigned long prevMillis8; static unsigned long prevMillis9; if ((digitalRead(9)==0)&&(millis() - prevMillis9 > 1000)) { // если с приема предыдущей команды прошло больше 1 сек digitalWrite(9, 1); } if ((digitalRead(8)==0)&&(millis() - prevMillis8 > 1000)) { // если с приема предыдущей команды прошло больше 1 сек digitalWrite(8, 1); } if (radio.available() > 0) { char val = radio.read(); if( val== '3' ) { digitalWrite(9,0); prevMillis9 = millis(); } else if( val== '4' ) { digitalWrite(8,0); prevMillis8 = millis(); }; }поправил radio.read
Благодарю за идею. Работает.
А зашифровать как ? Просто умножать наверно не то ?
Команды ? В простейшем случае можно и умножить, только не просто на одно число, а, к примеру, придумать один ключ типа '2146237656593986657' для приемника и передатчика и каждую следующую команду умножать на следующую цифру, с последней перейти на первую, в приемнике соответственно синхронно делить. Как в этом случае защититься от пропуска... двусторонний обмен с перезапросом(чтобы все команды доходили), какое то контрольное число передавать и если контроль не прошел - рестарт ключа с 1й цифры (снижает стойкость) или подобрать цифру в ключе, дающую правильный результат (снижает надежность передачи). Черт его знает... проще ничего в голову не приходит, только сложнее. А оно точно надо ? Там внутри и так сложный протокол, если кто то умудрится влезть в обмен блютус - ваши ардуинские шифровальные поделки от него не помогут :)
И то верно.
Не подскажите радио модули на 433 . Более мощные ?
И 13 строке получается не нужна ?
Наверное без нее работать будет, но лучше оставить - если это условие не выполняется, то вы считываете из порта непонятно что.
А я думал это блютус модули по аналогии с hc-05 / 06 :) У вас вроде и так неплохие модули, можно на si4432 попробовать. Поищите с усилителем/нормальной антенной (если есть возможность - с направленной, будет лучше в разы) или попробуйте такие если высокая скорость передачи не нужна:
https://www.cooking-hacks.com/documentation/tutorials/extreme-range-lora-sx1272-module-shield-arduino-raspberry-pi-intel-galileo/
http://www.hoperf.com/rf_transceiver/lora/
Наверно лучше к этим усилитель какой-то сваять.
Получается что можно передавать сигнал и по одному проводу.Где в программе прописано кто rx. а кто tx ?
Разобрался
radio.print('3');Вот так реализовал задержку при передаче .
if (digitalRead(buttonPin) != 1) buttononTime = millis(); if(millis() - buttononTime > 1000) { radio.print('3'); }Откретикуйте .
Не понял зачем она.
Допустим нажали кнопку а релле должно включится после интервала в одну секунду. Типа релле времени.
Допустим нажали кнопку а релле должно включится после интервала в одну секунду. Типа релле времени.
Если ваш вариант допилить, то получится "держать кнопку 1 сек". Если надо именно так - нужно исправить косяки, а если нужна просто задержка срабатывания - можно сделать и в приемнике после получения команды.
Просто задержка срабатывания. Можно и в приемнике согласен. Чё то написал в передатчика.
Если хотите в передатчике, то можно как то так:
if (digitalRead(buttonPin) != 1) { delay(20); //антидребезг if (digitalRead(buttonPin) != 1) { buttononTime3 = millis(); } } if ((buttononTime3 != 0)&&(millis() - buttononTime3 > 1000)) { radio.print('3'); buttononTime3 = 0; }т.е. разделить события нажатия кнопки и отправки команды
А так как у меня не правильно ?
Надо сделать так чтобы не повторялись постоянно команды после выполнения условия >1000. Вы же отвязали команду от кнопки и как только >1000 - оно начнет спамить постоянно командами.
if(millis() - buttononTime > 1000) { radio.print('3'); }Слушайте, mag155 - это раздел "Проекты", не надо его засорять тупыми "новечковыми" темами.
И еще - вы когда хоть что-нибудь прочитаете по программированию?
ААААА понятно спасибо.
Тоесть в вашем случае условие
Полностью завист от нажатия кнопки ?
У меня одновременно и старт отсчета и признак наличия "отложенной" команды. В таком виде отсчет начинается после отпускания кнопки, а когда заканчивается - сбрасываем её в 0 чтобы больше не реагировать (до следующего нажатия) на условие (millis() - buttononTime3 > 1000) даже если оно выполняется.