Ви не увійшли.
помогите пожалуйста, с компьютера на ардуино поступают команды в таком виде: "Rele 1", "Rele 2", "Rele 3" (изменить их нельзя)
написал такой код:
if (Serial.available() > 0)
{
char str = Serial.read();
if (str == 'Rele 1') digitalWrite(led11, HIGH);
if (str == 'Rele 2') digitalWrite(led12, HIGH);
if (str == 'Rele 3') digitalWrite(led13, HIGH);
}
но не работает, что делаю не так ?
заранее признателен за помощь !
Неактивний
вы делаете вычитку по байту
и байт сравниваете со строкой
Вам нужно читать строки
https://www.arduino.cc/en/Serial/ReadString
либо самому собирать строку
несколько вариантов в ответах
http://stackoverflow.com/questions/1119 … on-arduino
Неактивний
вы делаете вычитку по байту
и байт сравниваете со строкой
Вам нужно читать строки
https://www.arduino.cc/en/Serial/ReadString
либо самому собирать строкунесколько вариантов в ответах
http://stackoverflow.com/questions/1119 … on-arduino
по последней ссылке нашел похожий пример, ну что то опять не хочет работать, что опять не так делаю ?
int x;
String str;
void setup(){
Serial.begin(9600);
}
if (Serial.available() > 0)
{
str = Serial.readStringUntil('\n');
x = Serial.parseInt();
if (x == 'Rele 1') digitalWrite(led11, HIGH);
if (x == 'Rele 2') digitalWrite(led12, HIGH);
if (x == 'Rele 3') digitalWrite(led13, HIGH);
}
Остання редакція ardnew (2016-03-02 19:09:47)
Неактивний
char input[20];
void setup(){
Serial.begin(9600);
}
void loop()
{
if (Serial.available() > 0)
{
Serial.readBytes( input, 20 );
String str= (String) input;
if (str == "Rele 1") digitalWrite(led11, HIGH);
if (str == "Rele 2"') digitalWrite(led12, HIGH);
if (str == "Rele 3") digitalWrite(led13, HIGH);
}
}
может где то так
Неактивний
if (x == 1) digitalWrite(led11, HIGH);
if (x == 2) digitalWrite(led12, HIGH);
if (x == 3) digitalWrite(led13, HIGH);
??
и это не нравится,
if (Serial.available() > 0)
есть ли проверка на строку?
Остання редакція NoName (2016-03-02 20:38:27)
Неактивний
Nefreemen, что то я чую, что логическую бомбу заложили )
кто спец по либам, обьясните
предположим пришло 4 байта, разрыв в потоке, бывает, это ведь асинхронный поток
if (Serial.available() > 0)
4 больше нуля, поехали дальше
Serial.readBytes( input, 20 );
читаем 20 байт, но если их нет то по таймауту отдаем сколько есть и очищаем буфер, я бы так делал
т.е. если набивать ручками управляющие команды то будет кака? или как эта либа работает?
Неактивний
NoName, да поток асинхронный, таймаут по умолчанию 1000мс ( и его всегда можно изменить ). Даже при скорости 9600 бод сколько байт придет, или может прийти учитывая какие то паузы? Правильно намного больше нежели 20 байт . Для простых задач, типа этой, этого вполне достаточно. Если вести речь о передаче больших объемов например файла, то алгоритм ясное дело другой, это может быть проверка на полноту полученной информации по контрольной суме или другие "фантазии" программиста. Не мне Вам рассказывать . А для передачи управляющей команды это надо? Ну получит раз на тысячу в буфере вместо "Relay 1" что то типа Rela или Pelay . Реактивный двигатель не запуститься и спутник упадет ? А новичку само то, и "аппетит" не испортить, и в очень сложные дебри пока не влезать (всему свое время). Я как и Вы понимаю, что в идеале можно замутить типа контроль по int как признак окончания передачи ( поскольку в передаче нельзя ничего изменить, добавить что то типа % или }). Можно читать по байтам в строку и контролировать длину. И мало что можно придумать . Новичок сам когда то придет к этому но в других задачах .
Неактивний
Да к стати, о Serial и двух вечерах убитого времени. Задача банальная. Передаю ISON строку из Arduino 2560 в ESP все путем. Возвращаю ее с изменениями обратно, и тут облом, приходит только часть. Причем обрывается по разному, увеличиваю буфер ISON - не идет. Возился долго, нудно пока не сделал подсчет байтов и тут "сюприз" - 63 байта хоть тресни. Лезу в библиотеку Serial смотрю вроде все ОК при разных объемах остатка флеша разный кольцевой буфер. Но черт возьми при загрузке в 15% Atmega2560 у меня получается 64 . Ставлю ручками 256 байт и все начало бегать как дети в школу. Вот такие бывают "сюрпризы" в библиотеках .
Неактивний
возьмет кто то такой пример - а не работает, и будет Nefreemenу икаться ) ибо вспоминать будут незлым, тихим, словом )
учится нужно на правильных алгоритмах, трудноуловимые глюки - бичЪ программиста )
Неактивний
Идеального не существует в природе априори . Стремится надо Что и делаем . Примеров в сети вагон, и тоже с кучей недостатков. Что же придется сесть с другими авторами и икать . NoName, я не против если Вы предложите более совершенный и простой понятный алгоритм, даже приму участие .
Неактивний
https://www.arduino.cc/en/Tutorial/SerialEvent
пойдем по более привычному пути
условие, у запроса footer = '\n'
change #5
/*
Serial Event example
When new serial data arrives, this sketch adds it to a String.
When a newline is received, the loop prints the string and
clears it.
A good test for this is to try it with a GPS receiver
that sends out NMEA 0183 sentences.
Created 9 May 2011
by Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/SerialEvent
*/
#define max_length 200
String inputString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
boolean string_error = false; // whether the string is overflow
void setup() {
// initialize serial:
Serial.begin(9600);
// reserve 200 bytes for the inputString:
inputString.reserve(max_length);
}
void loop() {
// print the string when a newline arrives:
if (stringComplete) {
// change #5 Serial.println("R1");
if (inputString == "Rele 1") { Serial.println("R1"); digitalWrite(led11, HIGH); }
else if (inputString == "Rele 2") { Serial.println("R2"); digitalWrite(led12, HIGH); }
else if (inputString == "Rele 3") { Serial.println("R3"); digitalWrite(led13, HIGH); }
// add change #3
else {
Serial.print("err: ");
Serial.println(inputString);
}
// clear the string:
inputString = "";
stringComplete = false;
}
else if ( string_error == true )
{
// while (1); achtung!!!! wtf?
string_error = false;
// clear the string:
inputString = "";
stringComplete = false;
// но я бы сделал анализ по циклическому буферу от последнего байта :)
// забил бы на achtung), и отказался бы от стринга, ибо непривычно )
}
}
/*
SerialEvent occurs whenever a new data comes in the
hardware serial RX. This routine is run between each
time loop() runs, so using delay inside loop can delay
response. Multiple bytes of data may be available.
*/
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
// add change #4
if (inChar >= 0x20 )
{
inputString += inChar;
}
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == '\n') {
stringComplete = true;
}
else
if ( inputString.length() >= (max_length-1))
{ string_error = true; }
}
}
кто проверит?, ЭТО работает или нет? )
Остання редакція NoName (2016-03-03 17:44:59)
Неактивний
Неа...не компилится. Компилятор ругается на if ( strlen (inputString) >= max_length ) такими матюками er:57: error: cannot convert 'String' to 'const char*' for argument '1' to 'size_t strlen(const char*)'
cannot convert 'String' to 'const char*' for argument '1' to 'size_t strlen(const char*)'
Неактивний
логично, но мало ли , я ж не знаю насколько он strict ) а то вольностей пообещали )
помогайте ) нужно вместо strlen ( да и header не включил я) ) функция определения длины строки
заменить на местное для работы со стрингом
inputString.length есть такое?
if ( inputString.length >= max_length )
ладно вечером почитаем )
и вместо сравнения нужно compare сделать
add
заменить на
if ( inputString.length() >= (max_length-1))
// скушаем 1 байт от буфера )
Остання редакція NoName (2016-03-03 15:18:25)
Неактивний
Угу. Я тут ставлю Гипертерминал на 10 пытаюсь проверить. Не работает зараза, в inputString то что ввел через терминал, а оно зараза не работает ( а должно ) и тут открываю глаза...Мама моя... я долблю ему "Relay 1" надо "Rele 1" Но все равно что то не так. К стати я не вычитал конечный байт...Может из за этого.
Неактивний
нет, гипертерминал отправляет \r\n
и строки не равны, нужно не equ ( == ) делать а сравнение по содержимому, я еще не читал что доступно для стринга в ардуино (
эхо принятой строки отправляйте обратно )
add change #3
Остання редакція NoName (2016-03-03 16:31:35)
Неактивний
void loop() {
// print the string when a newline arrives:
if (stringComplete) {
Тут inputString все Ок, а дальше в if не работает.
if (inputString == "Rele 1") digitalWrite(led11, HIGH);
if (inputString == "Rele 2") digitalWrite(led12, HIGH);
Неактивний
Nefreemen, самое смешное что ardnew уже получил что нужно и тему не читает )
читаю, и очень внимательно !
и получил как бы не совсем то, вернее то, но реле как то включаются через раз
какую либо статистику не собрать
и еще, никак не могу сообразить, у меня 8 реле, нужно сделать так что бы по сигналу включалось только одно реле, а остальные выключались,
например, пришел сигнал "Rele 2" включилось реле 2, пришел сигнал "Rele 5" включилось бы реле 5, а реле 2 выключилось,
короче, всегда может быть включено только одно реле из восьми.
Остання редакція ardnew (2016-03-03 17:49:36)
Неактивний
это просто см change 5
добавлен лог выполнения
если правильно понял..
вот это работает четко if (x == 1) digitalWrite(led11, HIGH);
если с терминала даю один байт, типа 1, 2, или 3, но у меня текстовая строка, и вот в этом вся проблема
Неактивний