Отправка нулей через SoftwareSerial.
- Войдите на сайт для отправки комментариев
Сб, 14/01/2017 - 17:33
Здравстввуйте!
Плата Adruino Uno и Mini.
Требуется считать пакет в виде "1f 00 00 00 00 43 56" из Serial порта платы номер 1 и передать через SoftwareSerial на плату номер 2. На плате на, на приеме получается только "1f",
Если отправлять пакет вида "1f 00 12 00 32 43 56", то он приходит целиком. Но как только 2 байта с нулями идут подряд, перед ними обрываются данные.
Пробовал через Serial.readString и переменную string, Serial.readBytes в массив char[]. Результат одинаковый.
Подскажите, как решить данную задачу?
На всякий случай проверьте, на каких частотах работают резонаторы на разных платах. Возможно, разница достигает процентов и из-за этого на некоторых битовых комбинациях теряется синхронизация.
У меня такое было с MIDI устройством. Пришлось вместо стандартной частоты 31250 прописывать в скетче 31500.
На всякий случай проверьте, на каких частотах работают резонаторы на разных платах. Возможно, разница достигает процентов и из-за этого на некоторых битовых комбинациях теряется синхронизация.
У меня такое было с MIDI устройством. Пришлось вместо стандартной частоты 31250 прописывать в скетче 31500.
можно тактировать контроллеры от одного кварца
Не уверен но что если не принт а врайт? http://arduino.ru/Reference/Serial/Write
Не уверен но что если не принт а врайт? http://arduino.ru/Reference/Serial/Write
какая в жопу разница?
Один ... а другой дразнится.
size_t Print::print(const String &s) { return write(s.c_str(), s.length()); }Я думаю, что стандартный принт интерпретирует 0-й байт как символ окончания строки, обычно С строка всегда заканчиватся 0-ём.
Подскажите, как решить данную задачу?
А скетч не судьба показать?
А скетч не судьба показать?
я запретил.
Простите за сумбурный вопрос.
Снова добрался до задачи.
2 платы.
На одной обычный softwareserial из примера, для сбора данных и отправки дальше.
#include <SoftwareSerial.h> SoftwareSerial mySerial(10, 11); // RX, TX void setup() { Serial.begin(19200); mySerial.begin(19200); } void loop() { // run over and over if (mySerial.available()) { Serial.write(mySerial.read()); } if (Serial.available()) { mySerial.write(Serial.read()); } }На второй PubSubClient, опять же из примера. Он соеденятся с mqtt брокером moqsuitto и отсылает ему данные в виде char.
if (Serial.available()) { String stringVar=Serial.readString(); char charVar[sizeof(stringVar)]; stringVar.toCharArray(charVar, sizeof(charVar)); mqtt.publish(serial_in, charVar );Я запутался в преобразованиях данных. Мне нужно что бы вход с UART отправлялся в виде CHAR "как есть", без преобразования в ASCII.
Тоесть в "сыром" виде. Но преобразования данных подрозумевают что на входе будет ASCII. Соответственно нули и отбрасываются. т.к. в аски ноль это 0x30.
Задача - преобразовать hex в ascii, что бы оно выглядело как первоначальный пакет. Так наверное. Запутался уже.
Да Вы тут много в чём запутались.
Для начала, размер массива charVar Вы указали
sizeof(stringVar). И чему это по-вашему равно? Напечатайте - узнаете.А если Вам не надо преобразовывать, так зачем Вы преобразовываете? Зачем String приплели? У Вас же в врехнем скетче всё нормально написано. Ну и делайте также в нижнем.
Выбросьте кашу из головы и делайте то, что нужно Вам, а не то, что Вы где-то увидели.
Евгений, спасибо за ответ.
String для чтения из потра данных. Потом преобразование из string в char, т.к. pubsub со стрингом не работает.
Если читать сразу в char, то выход для пакета ABCDEA принимает такой вид:
Это в терминале смотрю.
Если читать в string, потом в char преобразовывать, то вид нормальный, что пишу то и принимаю. Но на нулях обрывается передача.
Ну, я Вам ещё раз говорю, выбросьте кашу из головы. То Вы говорите, что Вам не надо преобразовывать, а то оказывается надо в читабельный вид - разберитесь чего Вы хотите.
вид нормальный
Нормальный - это какой?
И не забудьте про sizeof (я Вам писал) - Вы зря думаете, что в нём сидит длина Вашей строки.
Пробовал размер менять, без особых изменений.
Я вижу выход таким образом - преобразовать исходные данные в ascii.
Т.е. пакет вида ABCDEA0000 каким то образом должен принять вид
"0х41 0х42 0х43 0х44 0х45 0х41 0х30 0х30 0х30 0х30"
И уже его отсылать дальше.
Пока не знаю как это провернуть.
Вкратце, нужно действие аналогично Serial.println(char, HEX), только без вывода в порт, а с сохранением в виде char.
Что Вы там пробовали менять? sizeof не имеет никакого отношения к длине строки.
ПАо поводу проеобразований, Вы её еще на бумагу напечатайте и руками вводите.
Скажите чётко что Вам надо? Как пришло, так и отправлять или что?
Ставил фиксированную длинну (64), потом поменял на stringVar.length(). В итоге убрал вообще это преобразование.
Медотом экспериментов пришел к тому, что нужно из пришедшие на Serial байты преобразовывать в ASCII и отправлять дальше.
Попробую обьяснить, не ругайтесь сильно.
Смысл такой. С порта забрать байты и преобразовать их в ASCII с хранением в типе char.
То есть, забрать из порта последовательность вида "ABCDEA0000" и сохранить в типе char её же, но в виде ASCII.
Т.е. char должен содержать в себе информацию типа "41424344454130303030", для отправки ее дальше. Т.к. pubsubclient работает только с ascii, и если я буду пересылать напрямую с порта после чтения в char сразу, то pubsubclient отправит данные "как есть", т.е. "ABCDEA0000". На нулях посылка оборвется, и все что будет после нулей не придет.
Ну, если надо преобразовывать, так преобразовывайте, но не стринг же ради этого притягивать
Т.е. считывать в char? А потом что с ним делать не совсем понимаю. Serial.Println(char, HEX) отрабатывает все как надо, но выводит в порт только. Можно как нибудь сохранить этот вывод?
Вдруг кому понадобится рабочий вариант того, что от меня требовалось.
if (Serial.available() > 0) { str1= Serial.readString(); char buffer[2*sizeof(str1)]; char* buffPtr = buffer; for(byte i = 0; i < sizeof(str1) - 1; i++){ itoa((uint8_t)str1[i],buffPtr,16); buffPtr += strlen(buffPtr); *buffPtr = ' '; buffPtr++; } buffPtr--; *buffPtr = '\0'; Serial.println(buffer); }Тип char buffer хранит в себе аски коды того, что пришло на входе порта. Как то так. Это решение волне работает с передачей данных через PubSubClient.
Вы находите, что две приведенный ниже цитаты исключают друг друга?
Т.е. пакет вида ABCDEA0000 каким то образом должен принять вид
"0х41 0х42 0х43 0х44 0х45 0х41 0х30 0х30 0х30 0х30"
Т.е. char должен содержать в себе информацию типа "41424344454130303030"
И еще. ASCII - американский телеграфный код. Что Вы подразумевате под
преобразовать исходные данные в ascii.
понимаете только Вы.
ASCII - это способ кодировки текста. "ABCDEA0000" - это УЖЕ текст, а потому это УЖЕ ASCII. Куда его дальше преобразовывать?
В чем я не прав?
ABCDEA0000 после преобразования имеет вид "41424344454130303030". Для более удобного восприятия я написал с нулями и пробелами. Тут согласен, мог запутать кого.
Я использую данные с порта в "сыром" виде. Не через терминал, который из УЖЕ в ASCII шлет.
Например модбас-пакет. О каком аски или тексте там речь может идти?
Для того, чтобы выяснить, в чем Вы не правы, нужно:
1. Понять, что именно Вам нужно.
2. Узнать, что Вы для этого делавете.
3. Выяснить, чем первое отличается от второго.
Я, честно говоря, забуксовал уже на первом пункте.
Насколько я понял (пункт 2), Вы берете текст (в частности "ABCDEA0000"), зачем-то рассмиатриваете его как бинарные данные и записываете их снова в виде текста в hex-формате. Либо я не правильно понял, что именно Вы делаете, либо совершенно не могу взять в толк, зачем это нужно. Зачем с текстом делать какие-то еще преобразования?
Для того, чтобы выяснить, в чем Вы не правы, нужно:
1. Понять, что именно Вам нужно.
2. Узнать, что Вы для этого делавете.
3. Выяснить, чем первое отличается от второго.
Я, честно говоря, забуксовал уже на первом пункте.
Насколько я понял (пункт 2), Вы берете текст (в частности "ABCDEA0000"), зачем-то рассмиатриваете его как бинарные данные и записываете их снова в виде текста в hex-формате. Либо я не правильно понял, что именно Вы делаете, либо совершенно не могу взять в толк, зачем это нужно. Зачем с текстом делать какие-то еще преобразования?
ABCDEA0000 это не текст, а бинарные данные с порта. Устройство-передатчик не совместимо с ascii и не умеет впринципе текст передавать. itoa() - как раз для этиц целей.
Устройство-передатчик не совместимо с ascii и не умеет впринципе текст передавать. itoa() - как раз для этиц целей.
Простите, но Вы бредите. Текст - это такие же байты (числа) как и нетекст. Текстом они становятся только в человеческой голове. Компьютер или любое другое техническое устройство никак не отличает текст от нетекста - для него это просто числа.
Снчала я не понял чего Вам надо, теперь вот коллега тоже не понял. А по Вашему посту я вижу, что Вы сами не понимаете - и проблема именно в этом.
Постарайтесь понять сами и тогда обяснить нам.
Все решено уже и сделано. Код выше запостил.