SoftwareSerial и HC-06. Получение цельных данных
- Войдите на сайт для отправки комментариев
Пт, 26/01/2018 - 10:23
Добрый день, уважаемые форумчане!
Есть последовательность команд типа: $l123;d25;r7859;moff# ,где
$ - начало команд ; - разделитель между отдельными командами l,d,r,moff - типы команд 123,25,7859 - значение команды # - конец списка команд
Количество команд в последовательности не имеет жесткого ограничения. Необходимо получить последовательность целиком. В этом проблема.
Пытался двигаться в этом направлении:
void loop() { if(mySerial.available()>0){ symbol = mySerial.read(); incomingByte = symbol; if(incomingByte !=-1){ command = command + symbol; } } }
С двумя символами способ работает, но когда посылаю 3 символа, то последний не отображается. Если посылаю 4, то появляются кракозябры. Видимо, не успевает долетать информация или я её неправильно оргнизую. Подскажите пожалуйста, в каком направлении двигаться для решения это задачи? Использовать readBytes()?
Ну, по этому куску ничего не скажешь. Каких типов command , incomingByte и symbol ? Почему Вы нигде не проверяеете на конец посылки (#)? Что значит " посылаю 3 символа"? Символа или команды?
В общем, если хотите нормального обсуждения, делайте пример работающего скетча на десяток строк в котором Вы принимаете ntrcn и печатаете в сериал. Пишите что вводите в мониторе порта и что потом печатается (последнее копипастом). Тогда можно будет о чём-то говорить. Сейчас же ... хрустальные шары на этом форуме запрещены, так что ...
Можно этой штукой считать
Serial.readBytesUntil(character, buffer, length)
А можно просто в цикле читать и складывать в буфер пока не встретили #. Потом уже спокойно разбирать пакет (или обнаружить что это был и не пакет а что-то "искаженное").
ЕвгенийП, хотел проверить возможность получения трех символов(которые не относятся к поставленной задаче), но даже три символа нормально считать не удалось.
Penni, в readBytesUntil() необходимо указывать кол-во байтов, которые нужно считать, а это неизвестно.
Буду пробовать считывать до '#', хотя вчера вечером такое пытался релизовать, но программа не находила символ '#'. Скорее всего сам ошибку допустил. Буду смотреть.
Какой-то размер вы все равно будите для буфера приемного указывать, например, 30-50 байт, чтобы точно любой пакет влез. Вот это число и указывайте в readBytesUntil. Она прервется по любому из трех событий, встретили символ конца, прочитали всю длину либо вышел таймаут. В идеальном варианте она всегда будет прерываться по символу #
Если без всяких проверок на ошибки при приеме и прочего, то вот так, примерно
но даже три символа нормально считать не удалось.
Мой текст
Остаётся в силе.
Penni, спасибо большое! Изучил Ваш код, теперь всё работает.
Только если между (13 и 14) и (15 и 16) строчками в коде из сообщения #5 делаю вывод сообщения в порт через .println(), то появляются крокозябры в принятой команде.. Не знаю чем это можно объяснить. В моей программме нет необходимости в этих частях что-то выводить, но всё же особенность заинтересовала. Был бы благодарен, если кто-нибудь смог бы ткнуть меня носом в нужном направлении.
Пока что тестирую обработку принятой команды, поэтому часть кода Penni не использую. В качестве входных данных использую команду "u100". Получаю команду, записываю в inBuffer и вызываю функцию goMove(), которая занимается обработкой команды. Записываю char* pch в String command, потому что со String привык работать, а вот char* для меня дикий зверь.
Проблема в том, что не выполняется(видимо) код из строк 22, 26, 27. Пробовал ставить в разные места - результат не меняется: в ответ ничего не приходит и, соответственно, код в switch() не выполняется. Подскажите пожалуйста, в чём я допустил ошибку?
Во-первый: зачем Вы в 20 строке опять берете pch если у вас уже в 13 строке всё взято и дальше только со String можно работать. Заменяете в 20 строке pch[k] на command.charAt(k) и все будет хорошо.
Во-вторых: конструкции вида mySerial.println("charAt(): " + command.charAt(0)); не поддерживаются. Надо либо писать шаблон и выводить как в си через << либо заменять на print и println.
В-третьих: после каждого case надо ставить break; иначе будите выполнять все кейзы после верного.
Ну и PS: String Вам тут совсем не нужен, гуглите cstring и используйте. Плюс atoi.
Penni, большое спасибо! Теперь всё работает. Без Вас бы ничего у меня не получилось.