Управление ардуиной второй ардуиной по UART

martinways
Offline
Зарегистрирован: 25.09.2020

Товарищи знатоки, подскажите почему не получается управлять ардуиной при помощи другой ардуины соединив их по RX-TX. Значит на первой ардуине залил скетч с функцией - нажатие кнопки1 в серийный порт идет сообщение  ON, при нажатии на кнопку2 выдает сообщение OFF, в сериал мониторе все работает. На второй ардуине залит нижеследующий скетч, может там я чето неправильно сделал, с компа при посылании сообщения ON через сериал монитор зажигается встроенный светодиод, а при сообщении OFF он гаснет, так как и задумано. Но при соединении двух ардуин накрест (RX1-TX2 и TX1-RX2) светодиод не зажигается, а только мигает светодиод RX, то есть сигнал идет, но управляемая ардуина не распознает его. Скорость на обеих платах выставлена 9600

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
   String value = Serial.readStringUntil('\n');
    if (value == "ON")  digitalWrite(LED_BUILTIN, HIGH);  
   else if (value == "OFF") digitalWrite(LED_BUILTIN, LOW);
}

 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

А почитайте ка Вы, мил человек, про сравнение строчных переменных. Или передавайте 1 символ.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Mykaida, это String, он так тоже работает. 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

DetSimen пишет:

Mykaida, это String, он так тоже работает. 

Точно? Счас в протеусе проверю.

martinways
Offline
Зарегистрирован: 25.09.2020

По одному символу только что попробовал работает, типа incomingByte == 'H', но вот надо именно по набору символов управлять, вот как?

sadman41
Offline
Зарегистрирован: 19.10.2016

Попробуй на меге... там хотя-бы больше сериалов - в один из них можно Debug выводить.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

У обьекта String определено несколько операторов ==, ему можно целые строки подсовывать, не обязательно один символ. 

martinways
Offline
Зарегистрирован: 25.09.2020

sadman41 пишет:

Попробуй на меге... там хотя-бы больше сериалов - в один из них можно Debug выводить.

Из-за особенностей проекта требуется именно NANку использовать и команды из набора символов.

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

Кода передатчика нет, потому разводим кофейную гущу и смотрим .... в восьмой строке замените '\n' на '\r' (это гуща так говорит, а хотите разумнее - давайте коды полностью).

sadman41
Offline
Зарегистрирован: 19.10.2016

martinways пишет:

sadman41 пишет:

Попробуй на меге... там хотя-бы больше сериалов - в один из них можно Debug выводить.

Из-за особенностей проекта требуется именно NANку использовать и команды из набора символов.

Отладишь и поменяешь хоть на Нано, хоть на мини про.

А так, наощупь что-то там отлаживать дураков нет.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

martinways, когда между собой общаются две программы, обеспечение человекочитаемости команд, как правило, требует совершенно неоправданного перерасхода ресурсов. Поэтому замените Ваши строки на однобайтовые (если их количество не превышает 256) или двухбайтовые числа. Избавитесь и от тех проблем, с которыми уже успели столкнуться, и с от тех, с которыми еще не успели.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

martinways пишет:

Из-за особенностей проекта требуется именно NANку использовать

А что, "особенности проекта" не позволяют попробовать на другом контроллере?

Цитата:

и команды из набора символов.

Т.е. исправлять ошибки, допущенные на стадии проектирования, Вы не хотите.
martinways
Offline
Зарегистрирован: 25.09.2020

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

#define BTN1 3
#define BTN2 2

#include "GyverButton.h"
GButton butt1(BTN1);
GButton butt2(BTN2);
void setup() {
  Serial.begin(9600);
}
void loop() {
  // тик в ручном режиме
  butt1.tick();
  butt2.tick();
  // проверяем одиночный клик
  if (butt1.isClick()) Serial.println("OFF");
  if (butt2.isClick()) Serial.println("ON");
}

 

martinways
Offline
Зарегистрирован: 25.09.2020

andriano пишет:

martinways пишет:

Из-за особенностей проекта требуется именно NANку использовать

А что, "особенности проекта" не позволяют попробовать на другом контроллере?

Цитата:

и команды из набора символов.

Т.е. исправлять ошибки, допущенные на стадии проектирования, Вы не хотите.

Да у меня просто как в песне - "Дайте, дайте сигарету... А нету, брат, а нету.."))  Нанок пучок с алишки и одна Унка

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

martinways пишет:

Так передатчик-то самый примитивный,

Ну, а то, что моя гуща подсказала попробовал?

Если не помогает, то в передатчике замените println на print, а конец строки руками подставьте.

По любому проблема в этом. Лучше бы конечно просто тупо посимвольно напечатать что приходит - сразу видно будет.

martinways
Offline
Зарегистрирован: 25.09.2020

ЕвгенийП пишет:

martinways пишет:

Так передатчик-то самый примитивный,

Ну, а то, что моя гуща подсказала попробовал?

Если не помогает, то в передатчике замените println на print, а конец строки руками подставьте.

По любому проблема в этом. Лучше бы конечно просто тупо посимвольно напечатать что приходит - сразу видно будет.

 

Если меняю n на r, то даже с компа перестает управляться. 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

martinways пишет:
Если меняю n на r, то даже с компа перестает управляться. 

martinways
Offline
Зарегистрирован: 25.09.2020

ЕвгенийП пишет:

martinways пишет:

Так передатчик-то самый примитивный,

Ну, а то, что моя гуща подсказала попробовал?

Если не помогает, то в передатчике замените println на print, а конец строки руками подставьте.

По любому проблема в этом. Лучше бы конечно просто тупо посимвольно напечатать что приходит - сразу видно будет.

Ну, дружище, помогли! Поменял на Print и конец строки поставил \n и все заработало, Вы - мозг! Благодарю!

martinways
Offline
Зарегистрирован: 25.09.2020

DetSimen пишет:

martinways пишет:
Если меняю n на r, то даже с компа перестает управляться. 

Ну что посоветовали, то и сделал)) 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

так видимо в конце строки два символа прилетало, возврат каретки и перевод строки )))

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

Таки да, а с \r не работало потому, что \n там и оставался - его никто не выедал. Говорю же, надо было печатать посимвольно - сразу никаких вопросов.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

Таки да, а с \r не работало потому, что \n там и оставался - его никто не выедал. Говорю же, надо было печатать посимвольно - сразу никаких вопросов.

да, дополнив восьмую строку, всё бы заработало

martinways
Offline
Зарегистрирован: 25.09.2020

Если не трудно, подскажите чем надо дополнить 8-ю строку, чтобы не дописывать в каждую команду \n ?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

martinways пишет:

Если не трудно, подскажите чем надо дополнить 8-ю строку, чтобы не дописывать в каждую команду \n ?

так Вы так и не поняли,  Евгений Петрович подсказал "\r\n" - или 0x0D, 0x0A в шестнадцатеричном, там два символа, вычитывать их надо полностью, println как раз эти символы и добавляет

MaksVV
Offline
Зарегистрирован: 06.08.2015

приемник 

char currStr[25];   // буфер для принятия команд (не более 24 символов)

void uartRead()
{
   if (!Serial.available()) return;
    char currSymb[2] = {0};
    currSymb[0] = Serial.read();
    static bool stringEnd = 0; 
 if (currSymb[0] == '\r' || stringEnd == 1)
       { 
               if (strcmp(currStr, "ON") ==0)   {digitalWrite (13, HIGH);}
          else if (strcmp(currStr, "OFF")==0)   {digitalWrite (13, LOW); }
          currStr[0] = 0; stringEnd = 0;
       } 
 
    else if (currSymb[0] != '\n')  strcat (currStr,currSymb);
    if (strlen(currStr)>24) stringEnd = 1;
}

void setup() 
{
Serial.begin (9600);
pinMode (13, OUTPUT);
}

void loop() 

{
uartRead();  // функция принятия команд
//остальной код
}


передатчик, так,  для теста

void setup() 
{
Serial.begin (9600);
}

void loop() 
{
Serial.println("ON");
delay (2000); 
Serial.println("OFF");
delay (2000); 
}

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

ТС, спросите зачем такой сложный скетч приёмника. Объясняю. Во-первых, ваш скетч из нулевого поста, все время тормозит loop() на время Timeout (по умолчанию 1 сек) функции readStringUntil(). Т.е. считайте что типа  delay (1000) добавили в loop.   Чтобы этого не происходило нужно писать так 

if (Serial.available()) 
  {
  String value= Serial.readStringUntil('\n');
  // бла бла
  }

но даже в этом случае, если по какой либо причине во время приёма информации от оппонента в конце строки скетч не дождётся \n будет опять задержка в 1 сек. Я уж не говорю про использование String, что считается моветон.  Поэтому мой скетч предпочтительней. 

martinways
Offline
Зарегистрирован: 25.09.2020

MaksVV пишет:

ТС, спросите зачем такой сложный скетч приёмника. Объясняю. Во-первых, ваш скетч из нулевого поста, все время тормозит loop() на время Timeout (по умолчанию 1 сек) функции readStringUntil(). Т.е. считайте что типа  delay (1000) добавили в loop.   Чтобы этого не происходило нужно писать так 

if (Serial.available()) 
  {
  String value= Serial.readStringUntil('\n');
  // бла бла
  }

но даже в этом случае, если по какой либо причине во время приёма информации от оппонента в конце строки скетч не дождётся \n будет опять задержка в 1 сек. Я уж не говорю про использование String, что считается моветон.  Поэтому мой скетч предпочтительней. 

Спасибо, попробуем и Ваш вариант. Конкретно в моем исполнительном устройстве задержка в 1 сек будет некритична, но в других вариантах возможно очень даже.

MaksVV
Offline
Зарегистрирован: 06.08.2015

martinways пишет:

Если не трудно, подскажите чем надо дополнить 8-ю строку, чтобы не дописывать в каждую команду \n ?

а надо не дополнить 8 строку, а проверять полученные данные  правильно. (В передатчике ставить println .)

        if (value.indexOf("ON") !=-1) digitalWrite(LED_BUILTIN, HIGH); 
   else if (value.indexOf("OFF")!=-1) digitalWrite(LED_BUILTIN, LOW);

т.е. ваш вариант приёмника примерно такой 

void setup() 
{
Serial.begin (9600);
pinMode (13, OUTPUT);
}

void loop() 

{
if (Serial.available()) 
  {
  String value= Serial.readStringUntil('\n');
        if (value.indexOf("ON") !=-1) {digitalWrite(LED_BUILTIN, HIGH); }
   else if (value.indexOf("OFF")!=-1) {digitalWrite(LED_BUILTIN, LOW);  }
  }
}