Управленеи реле через ком порт

Max_Ness
Offline
Зарегистрирован: 04.11.2018

Доброго времени суток.

Пишу пытаюсь управлять RGB светодиодной лентой c помощью реле через СОМ-порт. 

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

int i=0;
char buffer_out[35];
int _R = 2;
int _G = 3;
int _B = 4;

void setup()
{
  Serial.begin(9600);  //USB порт arduino
  pinMode(_R, OUTPUT);
  pinMode(_G, OUTPUT);
  pinMode(_B, OUTPUT);
  digitalWrite(_R, HIGH);
  digitalWrite(_G, HIGH);
  digitalWrite(_B, HIGH);

}
void loop()
{
  if(Serial.available())
     {
       delay(100);
       //загоняем прочитанное в буфер
       while(Serial.available() && i< 10)
         {
           buffer_out[i++] = Serial.read();
         }
       buffer_out[i++]='\0'; //закрываем массив
       String needComand = buffer_out;
       needComand = needComand.substring(0,i-1); //Обрезаю конец строк
       Serial.println(needComand);
       
       if (needComand == "ON")
       {
        digitalWrite(_R, LOW);
        digitalWrite(_G, LOW);
        digitalWrite(_B, LOW);
       }
       if (needComand == "OFF")
       {
        digitalWrite(_R, HIGH);
        digitalWrite(_G, HIGH);
        digitalWrite(_B, HIGH);
       }
       if (needComand == "BUSY")
       {
        digitalWrite(_R, LOW);
        digitalWrite(_G, LOW);
        digitalWrite(_B, HIGH);
       }
       if (needComand == "FREE")
       {
        digitalWrite(_R, HIGH);
        digitalWrite(_G, LOW);
        digitalWrite(_B, HIGH);
       }
        if (needComand == "ERR") //Моргать красным светодиодом.
       {
        digitalWrite(_G, LOW);
        digitalWrite(_B, LOW);
        digitalWrite(_R, LOW);
        delay(1000);
        digitalWrite(_R, HIGH);
        delay(1000);
       }
       i=0;
    }        
}

Если вместо: while (needComand == "ERR") пишу while (needComand == "ERR") то лента моргает, но при этом ардуина не риагирует на другие команды.

Подскажите что не так?

 

Max_Ness
Offline
Зарегистрирован: 04.11.2018

Ошибся

Max_Ness пишет:

Если вместо: if (needComand == "ERR") пишу while (needComand == "ERR") то лента моргает, но при этом ардуина не риагирует на другие команды.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А где у Вас моргание-то?

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

Max_Ness
Offline
Зарегистрирован: 04.11.2018

К ардуине подключено реле и digitalWrite LOW это Включить реле.

Строки 59-61 включают реле.

А вопрос как-раз и есть как застави "моргать" краным цветом. (белый->краный->белый->краный-> и т.д.)

В данном варианте кода он просто включился и выключился, если пишу цикл while (needComand == "ERR") то переключение цветов происходит, но ардуина не реагирует на команды и не выходит из цикла.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Так, у Вас вопрос поменялся? Раньше Вы спрашивали

Max_Ness пишет:

Подскажите что не так?

а теперь спрашиваете

Max_Ness пишет:

А вопрос как-раз и есть как застави "моргать" краным цветом

На вопрос, "что не так" я Вам написал - у Вас вообще не написано моргание, Вы включаете красный один раз, через секунду гасите и всё. С чего бы ему моргать?

А насчёт "как застави "моргать" краным цветом",  думайте. Попробуйте написать моргание, Вы ведь даже не попытались.

Max_Ness
Offline
Зарегистрирован: 04.11.2018

Я же говорю что при:

if (needComand == "ERR") //Моргать красным светодиодом.
       {
        digitalWrite(_G, LOW);
        digitalWrite(_B, LOW);
        digitalWrite(_R, LOW);
        delay(1000);
        digitalWrite(_R, HIGH);
        delay(1000);
       }

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

если я пишу:

while (needComand == "ERR") //Моргать красным светодиодом.
       {
        digitalWrite(_G, LOW);
        digitalWrite(_B, LOW);
        digitalWrite(_R, LOW);
        delay(1000);
        digitalWrite(_R, HIGH);
        delay(1000);
       }

Он будет моргать, но при поступление другой команды в ком порт он не выходит из циклв.

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

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Освойте "blink без delay", в условие с millis() введите булеву переменную, которую будете приводить в true при ERR и в false при иных командах.

Max_Ness
Offline
Зарегистрирован: 04.11.2018

В ардуино в цикле выполняется все, что находится в

void loop()
{
...
}

так же как и

if(Serial.available())
     {
       delay(100);
       //загоняем прочитанное в буфер
       while(Serial.available() && i< 10)
         {
           buffer_out[i++] = Serial.read();
         }
       buffer_out[i++]='\0'; //закрываем массив
       String needComand = buffer_out;
       needComand = needComand.substring(0,i-1); //Обрезаю конец строк
       Serial.println(needComand);

       if (needComand == "ON")
       {
        digitalWrite(_R, LOW);
        digitalWrite(_G, LOW);
        digitalWrite(_B, LOW);
       }
...
       i=0;
}

Ардуина получила команду в ком порт, выполнила условие и вышла в ожидание новой команды, если я в if (needComand == "ERR") напишу код используя millis() он всеравно не будет работать в цикле или, а если его не ограничить, то никогда с него не выйдет.

А решение моего вопроса банальное, нужно вынести условия if (needComand == "...") за  if(Serial.available()) и всебудет работать как надо.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Вы даже не пытались понять, что я вам написал. Да и бох с вами.

b707
Offline
Зарегистрирован: 26.05.2017

Max_Ness пишет:

А решение моего вопроса банальное, нужно вынести условия if (needComand == "...") за  if(Serial.available()) и всебудет работать как надо.

И что, получилось? Работает как надо?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Max_Ness пишет:

А решение моего вопроса банальное, нужно вынести условия if (needComand == "...") за  if(Serial.available()) и всебудет работать как надо.

Ну, если ешё и "String needComand" в глобальные вынести. Только это не решение. Это костыль, направленный на маскировку (а не исправление) проблемы.

Max_Ness
Offline
Зарегистрирован: 04.11.2018

Все что нужно вынес в глобальные, если не выносить то работать не будет. Это первое.

А вынес if (needComand == "...") за  if(Serial.available()) поотму,  что если внутри if(Serial.available()) будет выполнятся какая-то задача в цикле то до ее завершения я не смогу считать информацию с ком-порта. Ограничение цикла приведет к преждевременному завершению или будут пропущены команды.

Вот и получаем if(Serial.available()) {...} служит для считывания данных с ком порта и запись переменных (к тому же с порта я получаю не одну переменную, а строку которую еще нужно разбивать и присвоить переменным их значения).

А if (needComand == "...") я заменил на кейсы, писать полсотни ифов будет неправильго. А все события вынес отдельно и вызываю их из кейсов.

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

Max_Ness
Offline
Зарегистрирован: 04.11.2018

Вынес необходимые переменные в глобальные, поправли код и все заработало. Правда когда подключил ленту оказалось что я неправльно написал последовательность включения/отключения цветов, но это мелочи.

Max_Ness
Offline
Зарегистрирован: 04.11.2018

Я прекрано понял, что вы мне написали, и я написал с использованием millis(), но проблему мою это не решило.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Max_Ness пишет:

Только чтобы это понять, я взял и почитал матчасть.

Я потратил час на форум и мне никто не сказал,

Каковы мерзавцы!

wdrakula
wdrakula аватар
Онлайн
Зарегистрирован: 15.03.2016

Max_Ness пишет:

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

Гляди ж ты! А селедка-то, похоже, начинает действовать! (с) - Старый анекдот.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Max_Ness пишет:

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

Вообще-то целью отетовздесь и было, чтобы Вы почитали матчасть и чему-то научились. Так что цельдостигнута.

Только, почитайте матчасть ещё. Вы как бы решили проблему, но наихудшим из всех возможных способов и ненадолго.