-
23.04.2018, 22:35 #31
- Регистрация
- 16.02.2015
- Сообщений
- 7,862
- Поблагодарили
- 2392
- Поблагодарил
- 449
Запускается и работает, но кое что не понятно.
В Serial1.println(send_data); убрал ln, иначе, пока нет данных, непрерывно гонит в порт 0D 0A...
Serial1.print(send_data); выдает ДВОЙНУЮ последовательность xyz
У меня данные приходят из другого порта, и в этом случае Serial1.println(send_data); выдает аж ЧЕТВЕРНУЮ последовательность xyz.
Почему, не пойму.
Ниже, то что у меня:
#include <AltSoftSerial.h>
AltSoftSerial altSerial;
/**
*
*/
const int SERIAL_DATA_DELAY = 5;
/**
* Startup events.
*/
void setup() {
init_serial();
}
/**
* Init serial port communication.
*/
void init_serial() {
Serial.begin(9600);
Serial1.begin(9600);
altSerial.begin(9600);
}
/**
* Main loop procedure.
*/
void loop() {
serial_forward();
}
/**
* Read data from serial port 0, parse string and send over serial 1.
*/
void serial_forward() {
String read_data;
String send_data;
int read_data_len;
while (altSerial.available() > 0) {
delay(SERIAL_DATA_DELAY);
char c = altSerial.read();
Serial.print(c);
read_data += c;
}
do {
read_data_len = read_data.length();
int endIndex = read_data.indexOf("C");
if (read_data.startsWith("A>B:") && endIndex >= 0) {
send_data = read_data.substring(4, endIndex);
read_data.remove(0, endIndex + 1);
}
Serial1.print(send_data);
Serial.print(send_data);
if (read_data_len == read_data.length()) {
read_data.remove(0, 1);
}
} while (read_data_len != read_data.length());
}
-
24.04.2018, 09:34 #32
- Регистрация
- 30.11.2012
- Возраст
- 52
- Сообщений
- 2,450
- Поблагодарили
- 1757
- Поблагодарил
- 1964
А зачем вам AltSoftSerial и три сериал порта
Код:void init_serial() { Serial.begin(9600); Serial1.begin(9600); altSerial.begin(9600); }
Код:while (altSerial.available() > 0) { delay(SERIAL_DATA_DELAY); char c = altSerial.read(); Serial.print(c); // Зачем вам это? read_data += c; }
Код:Serial1.print(send_data); Serial.print(send_data);
Андрей - YL2QN
-
24.04.2018, 09:54 #33
- Регистрация
- 30.11.2012
- Возраст
- 52
- Сообщений
- 2,450
- Поблагодарили
- 1757
- Поблагодарил
- 1964
Лучше не надо так делать....
Тем более, что вы сами делаете перевод в цифру
Ваш код можно дописать, но он не предусматривает,
1. Обработку, если в буфере будет два или три нужных вам стринга
2. Обработку, если в буфере будет "мусор"
Скорее всего Serial.print(c);
или оберните отправку проверкой на наличее данных (хотя дико сомневаюсь, что это там)
Код:if (send_data.length() > 0) { Serial1.println(send_data); }
Андрей - YL2QN
-
24.04.2018, 19:24 #34
- Регистрация
- 16.02.2015
- Сообщений
- 7,862
- Поблагодарили
- 2392
- Поблагодарил
- 449
- Почему AltSoftSerial? - так сложилось, раньше писал для UNO, а там нет Serial1 2, 3. Если это принципиально то уберу, заменю на Serial2
- Нужны данные только на железных портах и в этом смысле просто Serial не подходитэ
- Serial.print везде добавил чтобы посмотреть, что идет в этих местах. Когда заработает - конечно уберу.
- С портами пока вроде не запутался.
Скорее всего Serial.print(c);
или оберните отправку проверкой на наличее данных
Serial1.print(send_data);
Serial.print(send_data);
Или нет? Как сделать?
Думаю( может не прав), что вы не видите бесконечное 0D 0A потому что Serial монитор IDE не показывает, а Serial1 - железный и терминал видит.
Но это мне не так страшно, плохо, что идёт дублирование.
...Есть подозрение, что исходная A>B:xyzC на самом деле может на конце иметь 0D 0A или 0D 0A 0D 0A. Проверю.Последний раз редактировалось R3DE; 24.04.2018 в 19:50.
-
24.04.2018, 20:36 #35
- Регистрация
- 30.11.2012
- Возраст
- 52
- Сообщений
- 2,450
- Поблагодарили
- 1757
- Поблагодарил
- 1964
Ну на самом деле я ничего вообще не вижу, так как написал этот код в слепую и не проверял его. Я об этом написал в самом начале.
Если я не ошибаюсь, Mega имеет 4 UART порта: Serial, Serial1, Serial2, Serial3. Используя AltSoftSerial вы можете сделать ещё на свободных пинах эмуляцию дополнительных портов. Но лучше использовать готовые UART.
Согласно вашему коду, вы слушаете altSerial и побайтно транслируете, то что получаете в Serial.
Потом парсите данные (вырезаете лишнее) и шлёте данные в Serial и Serial1.
Вопрос: какой порт вы мониторите? Если Serial, то там и будет двойной набор данных.
Если бы в конце были бы получены 0D 0A - то парсер их как раз должен был бы вырезать. Скорее всего, это какие-то служебные символы. Их мониторинг (отображение) зависит от настроек COM PORT терминала, которым вы смотрите данные.
P.S. Ещё в терминале может быть включено echo, тогда вы будете тоже видеть двойной набор данных.Андрей - YL2QN
-
24.04.2018, 21:10 #36
- Регистрация
- 30.11.2012
- Возраст
- 52
- Сообщений
- 2,450
- Поблагодарили
- 1757
- Поблагодарил
- 1964
Нет, не обернули.
Двойная отправка, на самом деле, мой косяк - там do-while делает ещё один проход после отправки, а send_data не обнуляется. Извините.
Вот так будет правильно:
Код:/** * */ const int SERIAL_DATA_DELAY = 5; /** * Startup events. */ void setup() { init_serial(); } /** * Init serial port communication. */ void init_serial() { Serial.begin(9600); Serial1.begin(9600); } /** * Main loop procedure. */ void loop() { serial_forward(); } /** * Read data from serial port 0, parse string and send over serial 1. */ void serial_forward() { String read_data; String send_data; int read_data_len; while (Serial.available() > 0) { delay(SERIAL_DATA_DELAY); char c = Serial.read(); read_data += c; } do { read_data_len = read_data.length(); int endIndex = read_data.indexOf("C"); if (read_data.startsWith("A>B:") && endIndex >= 0) { send_data = read_data.substring(4, endIndex); read_data.remove(0, endIndex + 1); } if (send_data.length() > 0) { Serial1.print(send_data); send_data = ""; } if (read_data_len == read_data.length()) { read_data.remove(0, 1); } } while (read_data_len != read_data.length()); }
Последний раз редактировалось YL2QN; 24.04.2018 в 21:30.
Андрей - YL2QN
-
24.04.2018, 21:35 #37
- Регистрация
- 16.02.2015
- Сообщений
- 7,862
- Поблагодарили
- 2392
- Поблагодарил
- 449
Ok, спасибо , шас попробую.
И еще. Как обычно изменились условия. Действительно реально последовательность оказалась с 0D 0A на конце. И именно это надо также обрезать, а С оставить. То есть на входе (на altSerial) A>B:xyzC.. (где две точки это 0D 0A), а на выход( с Serial1) должно уйти xyzC
Как это прописать... видимо в int endIndex = read_data.indexOf("С"); ?Последний раз редактировалось R3DE; 24.04.2018 в 21:46.
-
24.04.2018, 22:01 #38
- Регистрация
- 30.11.2012
- Возраст
- 52
- Сообщений
- 2,450
- Поблагодарили
- 1757
- Поблагодарил
- 1964
Простейший вариант да, заменить C на нужную вам последовательность символов окончания. Должно работать, правда не оптимально, так как парсер сделает дополнительно несколько прогонов do-while по количеству символов. Но в вашем случае, это не будет являться проблемой, если, конечно, траффик по com port не сильно большой (десятки сообщений в секунду).
Лучше подправьте ещё одну строчку:
было: read_data.remove(0, endIndex + 1);
надо: read_data.remove(0, endIndex + 4);
Т.е. увеличили длину конечного стринга.Андрей - YL2QN
-
24.04.2018, 22:27 #39
- Регистрация
- 16.02.2015
- Сообщений
- 7,862
- Поблагодарили
- 2392
- Поблагодарил
- 449
Последний раз редактировалось R3DE; 24.04.2018 в 22:33.
-
25.04.2018, 10:33 #40
- Регистрация
- 30.11.2012
- Возраст
- 52
- Сообщений
- 2,450
- Поблагодарили
- 1757
- Поблагодарил
- 1964
Социальные закладки