Автоматическое отключение питания на Arduino

berkut229
Offline
Зарегистрирован: 22.05.2016

Доброго времени суток друзья! Нужна помощь. Нужно сделать устройство, которое будет отключать общее питание при отсутствии сигнала. Теперь подробно)) Имеем лазерный ЧПУ выжигатель, автономный контроллер им рулит через драйвера DRV8825, драйвера установлены на плате cnc shield. Суть вот в чем. Есть ардуино нано, так вот надо ее как то заставить отключать питание всего станка при выходе из строя любого драйвера на станке. Рассмотрим ситуацию. Перегорает каким то чудом драйвер оси Х, на которой находится лазер. Драйвер сгорел, двигатель стоит, а лазер шпарит. Тут и до пожара не далеко. Так вот нужно как то ардуино научить отключать питание общее при пропадании сигнала с выхода драйверов. 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Подозреваю (да и вы упомянули это), что надо садиться на выходы драйверов и смотреть сигнал - если нет какое-то время, то рубить питание. Как рубить? Да хоть через реле, хоть мосфетом. В чём конкретно проблемы - в схеме или в коде?

berkut229
Offline
Зарегистрирован: 22.05.2016

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

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Смотрите, как вариант: берёте конвертер уровней с али (искать по словам "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 - они зайдут в тему, думаю.

mag155
Offline
Зарегистрирован: 21.12.2017

Всем привет похожий вопрос. Нужно при пропадании сигнала с передатчика через сикунду отключать все реле приемника.

#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();
   }
   }

Все работает но когда удерживаю кнопку на передатчике реле клацает цыклично. В чем проблема подскажите? Буду оч благодарен.

Morroc
Offline
Зарегистрирован: 24.10.2016

Поставьте после

char val = radio.read();

вывод

Serial.println(val);

Serial.println(prevMillis);
 

и, возможно, сами увидите.

Удерживаете кнопку, отправляющую 4 или 5 ?

mag155
Offline
Зарегистрирован: 21.12.2017

Зделал вот так 

#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();
}
  }
}
 

Но работает только первое условие соответственно только одно релле. Голова уже дымит.??

mag155
Offline
Зарегистрирован: 21.12.2017

Постоянно перебераются цыфры (команды). Вы имеете в виду что сигнал есть постоянно ? Но все равно не пойму если сигнал есть то почему релле клацает ? Поясните если не сложно?

svm
Offline
Зарегистрирован: 06.11.2016

Ставьте датчики пламени и дыма, негорючее основание и систему пожаротушения. У меня сутки 3D принтер молотил на месте, заклинила ось Y , драйвера и шаговик исправны. А когда на лазерном гравере 2.5 Вт останавливается каретка, неважно от чего (может и механика заклинить и электроника ,и от зависания программы никто не застрахован) через 10-15 минут возгорание обеспечено.

Morroc
Offline
Зарегистрирован: 24.10.2016

>Но работает только первое условие соответственно только одно релле. Голова уже дымит.??

IF'ы позакрывайте. У вас где то сразу } стоит после digitalWrite, а где то внизу кода.

 

svm пишет:

Ставьте датчики пламени и дыма, негорючее основание и систему пожаротушения. У меня сутки 3D принтер молотил на месте, заклинила ось Y , драйвера и шаговик исправны. А когда на лазерном гравере 2.5 Вт останавливается каретка, неважно от чего (может и механика заклинить и электроника ,и от зависания программы никто не застрахован) через 10-15 минут возгорание обеспечено.

Может быть уже поздно :) Из извращений - акселерометр можно поставить на каретку и либо как то синхронизировать с УП либо тупо "1 минуту не двигаемся по X или по Y - выкл лазера".

mag155 пишет:

Постоянно перебераются цыфры (команды). Вы имеете в виду что сигнал есть постоянно ? Но все равно не пойму если сигнал есть то почему релле клацает ? Поясните если не сложно?

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

mag155
Offline
Зарегистрирован: 21.12.2017

В порту смотрел прилетают команды от не нажатых кнопок . Но почему 

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();

Не работает не пойму.?

Morroc
Offline
Зарегистрирован: 24.10.2016

== поменять на >

mag155
Offline
Зарегистрирован: 21.12.2017

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

#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 он должен гореть иначе тухнуть . Работает но горит в пол накала ???

Morroc
Offline
Зарегистрирован: 24.10.2016

Вам нужно совершать действия в определенные моменты времени. Например, когда пришла команда '3' - включить светодиод, а у вас сейчас получается цикл проверки постоянно крутится независимо от того пришла команда или нет, вы это не проверяете и ориентируетесь каждый раз на val, хотя там может быть старое значение или что то еще. Это с модулями nrf24 штуковина ? Надо вывести val в serial и глянуть, что получается когда отпускаете кнопку пульта.

svm
Offline
Зарегистрирован: 06.11.2016

berkut229 пишет:

 Имеем лазерный ЧПУ выжигатель, автономный контроллер  Рассмотрим ситуацию. Перегорает каким то чудом драйвер оси Х, на которой находится лазер. Драйвер сгорел, двигатель стоит, а лазер шпарит. Тут и до пожара не далеко. Так вот нужно как то ардуино научить отключать питание общее при пропадании сигнала с выхода драйверов. 

Вероятность выхода из строя драйверов, если они правильно настроены - невелика. Гораздо выше вероятность механических неисправностей. ЧПУ выжигатели -работают на достаточно высоких скоростях и длительное время измеряемое десятками часов испытывая при этом значительные динамические нагрузки и вибрацию. Откуда более вероятно откручивание шкивов на валу ШД, просто раскручивание резьбовых соединений или просто обрыв провода на одну из обмоток шаговика или попадание пыли в подшипник из за чего ось может встать . При этом на шаговик будут поступать нормальные сигналы с драйвера, которому все равно стоит шаговик или крутится в холостую. Следить лучше за перемещением ремней или паразитных роликов, поставив на них оптические или магнитные датчики. А еще лучше за световым пятном лазера. При этом не обязательно знать его положение, а просто фиксировать, что световая картинка долго не меняется. Но это только один из возможных вариантов. Я немного игрался с лазерным гравером и тоже думал о проблеме возгорания, особенно когда пытался вырезать фигурки из бумаги. Возгорания происходили достаточно часто, особенно если встречались мелкие детали. Поэтому ни разу не оставлял выжигатель без присмотра. Хотя- бы раз в 10 минут проверял его. Так-что вопрос довольно актуальный.

mag155
Offline
Зарегистрирован: 21.12.2017

Нет с другими модулями завтра напишу модель.

mag155
Offline
Зарегистрирован: 21.12.2017

Модули HC 12.

mag155
Offline
Зарегистрирован: 21.12.2017

Зделал вот так 

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 мреле вкл.Нет команды выкл . Но когда несколько релле и их нужно вкл одновременно то команды передаются по очереди соответственно релле клацаю по очереди . Есть идеи ?

Morroc
Offline
Зарегистрирован: 24.10.2016

У вас получилось, что если команда 3 - включается реле, а если любая другая - выключается. Нужно или в один if ... else if ... завернуть (а не отдельными if) или switch / case как было выше постами. Посмотрели что возвращает radio.read() при отсутствии команд ? Что то ведь возвращает - это важно.

 

mag155
Offline
Зарегистрирован: 21.12.2017

В смысле одной командой релле включать а второй отключать?

Morroc
Offline
Зарегистрирован: 24.10.2016

А... это же serial. Тогда сначала нужно проверить пришло что то вообще или нет if (radio.available() > 0) {} и только в этом случае читать radio.read() и щелкать реле.

Надо то как ? Чтобы реле включались командами, а выключались сами через 1-2 сек ?

mag155
Offline
Зарегистрирован: 21.12.2017

Сейчас возврвщает просто кубики какието а если нажать кнопку передатчика то цыфру если две кнопки то переберает цыфры

mag155
Offline
Зарегистрирован: 21.12.2017

Получается так есть передача например 3ки релле вкл нет передачи реле остается вкл пока не появится передача . Получается чтоб релле отпало передатчик должен послать команду а это значит что при отпущенной кнопке передаттчик все время посылает команды.

Morroc
Offline
Зарегистрирован: 24.10.2016

У вас  digitalWrite(9,0); включает реле или выключает ? Выключаться реле должны тоже какой то командой или сами по себе ? По вашим последним вариантам непонятно, по тому, где case, вроде как сами по себе, но не команадами.

mag155
Offline
Зарегистрирован: 21.12.2017
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);

Блок релле у меня вкл отрицательной полярностью . То есть ноль это релле вкл. Оно командой включается а отклю чается если команда отсутствует например еслиприемник потерял связь с передатчиком. Но если передавать две команды то они передаются по очереди соответственно релле клацает.

Morroc
Offline
Зарегистрирован: 24.10.2016

В принципе вариант "выключить через секунду" нормальный если это устраивает. Выключать именно то реле, по которому нет команды на включение 1 сек - типа так ? Если надо быстро выключать - лучше передавать отдельно команды на вкл и выкл, а уж по потере связи отдельно отключать через 1 сек.

Morroc
Offline
Зарегистрирован: 24.10.2016

Вот так не клацает ? Только включается ?

if (radio.available() > 0) {  
char val = radio.read();
Serial.println();

  if( val== '3' ) {
    digitalWrite(9,0);
  } else 
      if( val== '4' ) {
        digitalWrite(8,0);
      };
}

 

mag155
Offline
Зарегистрирован: 21.12.2017

Да .Отключатся ж условия нет.

Morroc
Offline
Зарегистрирован: 24.10.2016

Зато не клацает :) Теперь можно и выключать. Так работает ? Вместе выключать нельзя - получится что отсутствие любой из команд выключит все реле.

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

mag155
Offline
Зарегистрирован: 21.12.2017

Благодарю за идею. Работает.

mag155
Offline
Зарегистрирован: 21.12.2017

А зашифровать как ? Просто умножать наверно не то ?

Morroc
Offline
Зарегистрирован: 24.10.2016

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

mag155
Offline
Зарегистрирован: 21.12.2017

И то верно.

mag155
Offline
Зарегистрирован: 21.12.2017

Не подскажите радио модули на 433 . Более мощные ?

mag155
Offline
Зарегистрирован: 21.12.2017

И 13 строке получается не нужна ?

Morroc
Offline
Зарегистрирован: 24.10.2016

Наверное без нее работать будет, но лучше оставить - если это условие не выполняется, то вы считываете из порта непонятно что.

А я думал это блютус модули по аналогии с 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/

mag155
Offline
Зарегистрирован: 21.12.2017

Наверно лучше к этим усилитель какой-то сваять.

mag155
Offline
Зарегистрирован: 21.12.2017

Получается что можно передавать сигнал и по одному проводу.Где в программе прописано кто rx.  а кто tx ?

mag155
Offline
Зарегистрирован: 21.12.2017

Разобрался 


    radio.print('3');

 

mag155
Offline
Зарегистрирован: 21.12.2017

Вот так реализовал задержку при передаче .

 if (digitalRead(buttonPin) != 1) 
   buttononTime = millis();
      if(millis() - buttononTime > 1000) {
       radio.print('3');
      }

Откретикуйте .

Morroc
Offline
Зарегистрирован: 24.10.2016

Не понял зачем она.

mag155
Offline
Зарегистрирован: 21.12.2017

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

Morroc
Offline
Зарегистрирован: 24.10.2016

mag155 пишет:

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

Если ваш вариант допилить, то получится "держать кнопку 1 сек". Если надо именно так - нужно исправить косяки, а если нужна просто задержка срабатывания - можно сделать и в приемнике после получения команды.

mag155
Offline
Зарегистрирован: 21.12.2017

Просто задержка срабатывания. Можно и в приемнике согласен. Чё то написал в передатчика.

Morroc
Offline
Зарегистрирован: 24.10.2016

Если хотите в передатчике, то можно как то так:

if (digitalRead(buttonPin) != 1) {
  delay(20); //антидребезг
  if (digitalRead(buttonPin) != 1) {
    buttononTime3 = millis();
  }
}

if ((buttononTime3 != 0)&&(millis() - buttononTime3 > 1000)) {
  radio.print('3');
  buttononTime3 = 0;
}

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

mag155
Offline
Зарегистрирован: 21.12.2017

А так как у меня не правильно ?

Morroc
Offline
Зарегистрирован: 24.10.2016

Надо сделать так чтобы не повторялись постоянно команды после выполнения условия >1000. Вы же отвязали команду от кнопки и как только >1000 - оно начнет спамить постоянно командами.

if(millis() - buttononTime > 1000) {
 radio.print('3');
}

 

b707
Онлайн
Зарегистрирован: 26.05.2017

Слушайте, mag155 - это раздел "Проекты", не надо его засорять тупыми "новечковыми" темами.

И еще - вы когда хоть что-нибудь прочитаете по программированию?

mag155
Offline
Зарегистрирован: 21.12.2017

ААААА понятно спасибо.

mag155
Offline
Зарегистрирован: 21.12.2017

Тоесть в вашем случае условие 

 buttononTime3

Полностью завист от нажатия кнопки ?

Morroc
Offline
Зарегистрирован: 24.10.2016

У меня одновременно и старт отсчета и признак наличия "отложенной" команды. В таком виде отсчет начинается после отпускания кнопки, а когда заканчивается - сбрасываем её в 0 чтобы больше не реагировать (до следующего нажатия) на условие (millis() - buttononTime3 > 1000) даже если оно выполняется.