Построчный парсинг и SerialEvent
- Войдите на сайт для отправки комментариев
Еще раз доброе время суток всем!
Решил вынести свою проблему описанную здесь в отдельную тему, т.к. понял что чем дальше в лес тем толще партизаны. Вобщем, третий код, который казалось бы хоть как-то удовлетворяет мою хотелку, тоже работает через раз - то выдает нормально, то какую-то абракадабру, потом опять нормально и т.д.
Решил использовать прерывания в виде serialEvent(). Посмотрев пример вот что у меня получилось:
#include <SoftwareSerial.h> int sinhro = 0; String bufer = ""; String string2 = "ADSL link down\n"; String stringOne = "ADSL2/ADSL2+ connection\n"; char* AT_command_string = "admin"; //логин и пароль char* AT_command_string2 = "adsl info --show"; // команда String inputString = ""; boolean stringComplete = false; SoftwareSerial mySerial(10, 11); // RX, TX void setup() { Serial.begin(115200); mySerial.begin(9600); pinMode(8, INPUT_PULLUP); } void serialEvent() { while (Serial.available()) { // get the new byte: char inChar = (char)Serial.read(); // add it to the inputString: 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; // mySerial.println(inputString); } } } void loop() { // read_serial(); if (digitalRead(8) == LOW) { digitalWrite(13, HIGH); sinhro = 1; } if (sinhro == 1) { delay(1000); Serial.write(0x0A); // переход на новую строку (в некоторых модемах можно не выполнять) delay(2000); // ждем 2 сек. Serial.write(AT_command_string);// отправляем логин Serial.write(0x0A); // переход на новую строку delay(2000); // ждем Serial.write('\n');// отправляем пароль // Serial.write(0x0A); // переход на новую строку delay(2000); // ждем Serial.flush(); // очищаем буфер Serial.write(AT_command_string2); // отправляем команду Serial.write(0x0A); // переход на новую строку sinhro = 0; if (stringComplete) { mySerial.println(inputString); // очищаем строку: inputString = ""; stringComplete = false; } serialEvent(); } }
Пока пытаюсь просто разобрать прилетающую от модема в Serial информацию по строкам и вывести все это в softSerial. Моделирую в Proteuse через подключенный к com-порту ПК модем.
При нажатии кнопки вижу в виртуальном терминале Протеуса информацию которую выдает модем, а вот в виртуальном терминале "подключенном" к softSerial в это время пусто. Нажимаю второй раз кнопку, вижу опять инфу от модема и ... о чудо в softSerial выводится информация, но ... полученная при предыдущем нажатии кнопки. Нажимаю третий раз и стуация опять повторяется - в softSerial почему-то приходит инфа полученная в результате предыдущего запроса. Причем может выдать как нормально так и какие-то обрывки или через раз - то есть, то пусто, потом опять нормальная (полная).
Помогите разобраться где я накосячил
Вы не задумывались, что с модема может прилетать '\n' не вконце строки, а в начале ?
Вы не задумывались, что с модема может прилетать '\n' не вконце строки, а в начале ?
я запретил думать
О, великий Клапауций, прости засранца , но я не знал о твоем запрете и случайно взял и подумал. Вот лог снятый в Putty и открытый в Notepad++ с отображением всех символов
каждая строка у тебя оканчивается двумя символами - '\r', '\n'
в каждой строке '\n' идет последним? Так ведь и в коде идет проверка
и если условие выполняется то считается что строка принята. А '\r' , если я правильно понимаю, просто дописывается к содержимому строки. Но пока не пойму как это влияет на описанные косяки?
После небольшого перерыва опять достал с полки свой скетч и поэксперементирорав переделал его в очередной раз
Помогите все-таки разобраться почему
1. inputString выводится не построчно, а одной строкой. Вот результат вывода inputString.length()
2. Почему возникает задержка с выводом (такое впечатление что при первом нажатии кнопки инфа пишется в буфер, и только при втором нажатии считывается из него)
советую попробовать все это принять не софтверсериалом, а хардварным, и о результате собщите.
мне кажется софтвер и может косячить, то успевает то не успевает все принять.
и кстати скетч сколько памяти занимает? и поместится ли в буфер все, может банально не помещается?
А почему не использовать это?
А почему не использовать это?
кстати, еси бы кто подробно обьяснил недостатки такого способа вывоад инфы из стринг? с чем можно столкнуться?
Ребят, подскажите пожалуйста:
Будет ли работать функция SerialEvent с софтовым сериалом?
Аппаратный порт занят приемом данных с GPS, и использует эту (SerialEvent) функцию. А софтовым надо просто слушать другой порт и если придет команда (2 байта) = выполнить ряд действий (временно забив на данные с GPS) и все. Главное, не пропустить эту команду. Вот, думаю попробовать тоже использовать SerialEvent, для этой задачи.
Нет, не будет.
А софтовым надо просто слушать другой порт и если придет команда (2 байта) = выполнить ряд действий (временно забив на данные с GPS) и все.
а зачем обязательно SerialEvent ? - эта функция не делает ничего, что нельзя было бы сделать самому просто в loop()
Если вы принимаете данные с GPS постоянно, без перерывов - даже с функцией SerialEvent вы можете пропустить команду с другого Сериала, эта функция ничего не гарантирует
http://arduiniana.org/libraries/newsoftserial/
И нахрена эту какашку сюда притянул. А самому глянуть на то дерьмо что у них кодом зовется не? Просто людям советуем? Ну смотрим
И шо? А вот шо. Пока идет write прерывания cli(); - запрещены, а значить прием данных не производится. И если на Rx в этот момент начнет поступать нечто то оно будет пропущено или искажено. Каким образом внешнее устройство должно заподозрить что именно сейчас такое произойдет и не передавать что либо во избежании потерь? Правильный софтсириал должен уметь принять переданное им же. Т.е соединяем у контроллера Tx и Rx и приняли то что отправили. Сразу скажу - это возможно, но то дерьмо что ардуине суют такое не умеет.
Спасибо!
Да, тоже пришел к таким мыслям. Программа Принимает пакеты с GPS, снимает показания с датчиков, обрабатывает их и выплевывает в сериал вместе с данными GPS. Долго пытался отладить, чтобы не было пропусков, но получилось. Именно SerialEvent помог и более высокие скорости ком-порта.
Для софтового сделаю отдельную функцию, по типу SerialEvent.
Да, тоже пришел к таким мыслям. .............
SerialEvent помог и более высокие скорости ком-порта.
Не знаю, кому вы тут пишете, что "пришли к тем же мыслям" - но я-то вам написал совсем обратное - не нужен вам SerialEvent от слова "совсем" Вы явно заблуждаетесь насчет того, как работает эта функция - похоже вы думаете, что она выполняется в бекграунде, независимо от основной программы. Это абсолютная чушь. Обычный Serial.available() , размещенный в loop() - делает то же самое.
Вы не там ищете решение ваших проблем. Главное, что может помочь не терять ничего от входящего потока - это избавится от всез задержек в основном цикле программы. А если у вас основной код сидит в процедурах и функциях сотни миллисекунд - никакой SerialEvent вам не поможет И кстати, "более высокие скорости компорта" - это абсолютно неверно, на самом деле если вы не успеваете с обработкой - скорость порта надо снижать, а не повышать, это ж очевидно....
не знаю советовать или нет, классика из интернетов на кружевных Стрингах