Проблема передачи по серийному порту между двумя ардуино
- Войдите на сайт для отправки комментариев
Вс, 25/02/2018 - 23:40
Здравствуйте появилась проблема с передачей данных по серийному порту между двумя ардуино (Mega и Nano). Смысл в том, что одна ардуина отравляет пакета данных определенного количества байт, а другая будет считывать данные только тогда, когда будет то определенное количество байт. Но у меня появилась проблема что не всегда приходят данные ( то они приходят в нужном количестве, то не приходят вообще). Вот код первой принимающей ардуины:
void loop() { int FirstMass[4]; byte x = 0; int y = 0; Serial3.print("1"); // отправка флага чтобы отправляющая ардуина начала отправлять данные delay(100); // я думал что данные просто не успевают все перекинуться, поэтому поставил задержку if( Serial3.available() == sizeof(FirstMass) ) { // если пришло нужные данные in = Serial3.available(); // записываю количество байт которые пришли for(int i = 0; i < sizeof(FirstMass); i++) { // это я считываю данные из буфера, чтобы его очистить y = Serial3.read(); } } Serial.println(x);// вывод количества байт которые пришли delay(1000); }
Вот код отправляющей:
int FisrtMass[4] ={1,2,3,4,}; void loop() { if( Serial.available() > 0 ) { Serial.read(); for( int i = 0; i < 4; i++ ) { Serial.write(FirstMass[i]); } } delay(2000); }
В конце я поставил разные задержки чтобы с имитировать разные циклы программ
Не влетит .
Serial
.available() > 0
Не когда прилетел полностью пакет. А когда принят хоть один байт Вы просто пакет когда отправляете обрамляйте #XXXXX\n И тогда ясно что между # и \n есть информация.А можно поподробнее, а то я не понимаю
Serial
.available() > 0
Не когда прилетел полностью пакет.Вы имеете ввиду 4 строчку отправителя?
А отправка Serial.println(#packet);
Не влетит .
Serial
.available() > 0
Не когда прилетел полностью пакет. А когда принят хоть один байт Вы просто пакет когда отправляете обрамляйте #XXXXX\n И тогда ясно что между # и \n есть информация.Зачем?
Serial
.available()
возвращает количество пришедших байтов. У ТС именно это и проверяется. Задумано было всё хорошо, другое дело - как реализовано.У Вас проблема как с приёмником, так и с передатчиком.
В передатчике (строка 7) функция write отправляет 1 байт, а Вы пытаетесь пихать в неё число типа int. Т.е. Вы сразу же отправляете вдвое меньше информации, чем собирались.
В приёмнике вообще ничего не понятно. Вы код руками набирали? Не копипастили? Там написан некомпилируемый бред.
1) что за in в строке 9? Эта переменная 1) нигде не описана; 2) нигде больше не используется.
2) зачем чтение происходят в переменную y – она негде не используется.
3) зачем печатать x в стоке 15, если Вы ему нигде ничего не присваивали и он как был 0, так иостался?
Немного неправильно переписал со своео исходника, там просто был бред с названиями переменных. Переменная in это x, читал я в переменную y для очитски буфера, мне просто приходило вдвое ато и втрое больше байт чем нужно было, и я подумал что это изза того, что буфер не очищен. В 15 строке x - это количество байт которые пришли
неправильно переписал со своео исходника,
Вы уж пожалуйста копипастите. Я вот сидел, тратил время на рассматривание кода, который Вы "неправильно переписали". Вы не находите это .... странным? В общем, все пункты остаются в силе и про приёмник (особоенно) и про передатчик. Если Вы что-то не так переписали, давайте копипасту. Т.к. терять время, разглядывая неправильно переписанный код - идиотизм.
В передатчике (строка 7) функция write отправляет 1 байт, а Вы пытаетесь пихать в неё число типа int. Т.е. Вы сразу же отправляете вдвое меньше информации, чем собирались.
Я увидел где-то пример передачи данных по серийному порту через Seria.write(), и оно у меня работало, но из-за разной длины программ, не всегда нужные переменные приходили туда куда надо
Я увидел где-то пример передачи данных по серийному порту через Seria.write(), и оно у меня работало,
В примере скорее всего передавали массив байтов, а не целых чисел, как у Вас.
код отправителя остался таким же
Вы исправлять-то думаете?
Вот это код приемника
И что Вы в нём делаете?
В строках 11-13, Вы читаете 4 числа (только младшие байты, т.к. чисел целиком Вы не отправляли), по ходу каждого нового чтения, Вы затираете старый результат, который сидит в ina. А потом, в строке 21 Вы печатает in, который нигде ни разы не меняли, и который как был нулём в строке 4, так и остался. Ну, очевидно, 0 печатается, причём хренову гору раз - при каждом вызове loop.
То есть мне нужно в передатчике использовать serial.write с указанием количества байт которые я передаю
Serial.write(First mass[4], 2);
Так я буду отправлять все байты, а не только старший?
Конечно, нет. В такой записи - первый параметр - это адрес. Так что уж, как минимум, не "write(First mass[n], 2);", а "write(First mass+n, 2);". Возможно, ещё преобразование типа первого параметра к uint8_t * потребуется.
Я Вам второй раз говорю, третий раз говорить не буду. Если Вы хотите, чтобы кто-то тратил время на изучение Ваших кодов, будьте любезны публиковать их точно (копипастой) и полностью. Например, в Ваших нынешних кодах я не вижу как инициализируется Serial. Где Serial.begin? Своё мнение о том, какие коды нужны, а какие - нет, оставьте при себе - публикуйте полностью и точно.
Вот это полный код приемника void setup() { Serial.begin(9600); Serial3.begin(9600); } void loop() { int FirstMass[4]; byte SecondMass[4]; byte in = 0; int ina = 0; Serial3.print("1"); delay(100); if( Serial3.available() == sizeof(FirstMass) ) { in = Serial3.available(); for(int i = 0; i < sizeof(FirstMass); i++) { ina = Serial3.read(); } } Serial.println(in); delay(1000); }
А это полный код отправителя
Подключение: Arduino Mega через Serial3 подключен к Arduino Nano, и Mega подключена к компьютеру через usb
С такими учениками сопьёшься поневоле...
Т.е. передатчик Вы исправлять не хотите? Так и отправляете только моадшие быйты? Ну-ну... :)))
И кстати, в прошлом посте, я что-то не обратил внимание на второй параметр Вашего вызова write (на первом сконцентрировался). С чего там 2? Откуда взялось? Вы считаете, что размер массива .... Блин, ну надо Вам отправить массив, ну так и отправляйте его за раз целиком, сколько э можно мучать-то и его (массив), и себя, и меня заодно!
Почему я отправлял 2, переменная типа int - это два байта информации, я в цикле for я 4 раза отправлял переменные типа int, вместо того чтобы отправить весь массив. Я даже не знал что можно передать весь массив.
Только вопрос за что отвечает reinterpret_cast
За пробразование типа. Первый параметр должен иметь тип uint8_t *, а у Вас это массив целых.
То есть теперь массив отправляется полностью и сразу? Если да то приемник правильный?
Откуда мне знать, правильный он или нет. если Вы не объяснили что именно Вы хотите сделать?
Рискну предположить, что Вы хотите прочитать то, что пришло и сложить в масив FirstMass. Если так, то, конечно, нет.
Ну, вот что Вы там делаете?
Вот скажите, в какой именно из приведённых строк Вы хоть что-нибудь пытаетесь записать в массив FirstMass? В какой, номер строки можете назвать?
Или Вы не хотите ничего туда ( в массив FirstMass) записывать, тогда объясняйте чего Вы хотите.
Пока же я вижу, что Вы читаете байт за байтом в переменную ina (строка 16). Каждое новое прочитанное значение затирает предыдущее (так никуда и не использованное). А в конце (строка 20) Вы печатаете число 8, поскльку in не изменялось со строки 14, а в строке 14 available было равно именно 8, что Вы только что ( в строке 13) лично проверили. Какой смысл в этом коде я не понимаю, Вам виднее.
ПОчему Сусанин завел поляков на болото. Нет он не за царя это делал. Он разозлился на поляков. Поляки не внятно объснил куда им надо. А раз так, то будем кружить вокруг болота.
Поляки скажут конкретно. У меня проблема с передачей данных с Esp8266 на Arduino, попытался сам написать протокол передачи данных( передается температура команды, которые я храню в byte массиве), но данные либо приходили хаотично, т.е приходили не в те значения, либо не приходили вообще.
Я пытался сделать флаг, который отправляла бы Esp когда ей нужны данные с ардуино, но чето не получилось. Тесты я проводил между двумя ардуинками(Mega и Nano). То есть цель была сделать фсинхронный протокол передачи данных между двумя устройствами, но я начал копать с самых низов, этими низами оказалось то, в последовательный порт принимающей ардуино приходило то нужно количество байт, то ноль. И я решил в это разобраться.
Ну, за панов - ладно, нехрен было на GPS экономить, не утонули бы в болоте.
Вы со своим кодом приёмника разобрались?
Сделал вот такой код приемника
Только есть одна проблема, когда открываю мониториг, то первая строка приходит с нужными числами, но после приходит очень много всего непонятного
Евгений такой вопрос, лучше писать с комментариями?
Вопрос года...
Вопрос года...
Расчитываю на ответ века
Писать код лучше с умом, а если ума маловато в голове, то делаются заметочки на память- комментарии.
Не передавайте байтами информацию. У вас не такой сильный поток информации . Лучше ASC II . Тогда байт информации будет 2 байта в ASC II. Оставшие знаки будут банальной разметкой пакета.
То есть использовать функцию Serial.print();?
Вы наверно жопой читаете Serial.println(); Это команда в конце ставит \n - что сможете считать конец пакета
Хорошо, а как мне считать только данные без ид и адреса?
Считывай в как Си строку и переводи в байты. Просто без отметок начала и конца пакета у вас просто поток несвязаных байтов. Ни начала ни конца.
ПС: Пока не разберетесь что такое протокол и с чем его едят, то будете жевать одно и то же. http://uc.org.ru/node/20
лучше писать с комментариями?
Лучше всего начать с того, что подробно написать алгоритм по-русски (по-английски, по-китайски - кому что ближе).
Затем перед каждой строкой вставить "// ".
А затем между строчками вписывать нужные операторы языка программирования - реализацию этого алгоритма.
В результате у нас появится как раз код с комментариями.
Важно, что правильные комментарии пишутся не после написания кода, не одновременно с ним, а до кода.
andriano.Вот здесь вы напутали. Для правильного написания программы надо сделать 4 стадии. 1- составить полное ТЗ; 2- спроектировать программу; 3-написать код ;4 - залить скетч и отладить работу. Причем 1 и 2 этапы более важные чем 3 и даже 4. И комментарии до кода это просто эрзац планирование. Вроде хоть какое-то планирование,чем никакого вообще. Комментирование необходимо если вы берете объемную задачу и потом проектируете модули отдельно. И на полное составление уходит больше двух недель. Так что чего-то вы точно забудете. Но мелочь вы тупо забудете на следующий день. Вот и делаются пометки в виде комметариев. Сюда идем если эта ситуация и возвращаем это. А если то вот то и так.
ПС: обязательно комментировать отдельные функции , что делают, какие данные входные и что возвращают. Особенно если это в ваших личных библиотеках. Потому что информацию о вашей библиотеке гугл не найдет, если вы не напишите заранее и не выложите.
Я пытаюсь сделать обмен данными через println, но у меня остался вопрос по-поводу моего когда. Вот этого:
Это передатчик:
А это приемник:
andriano.Вот здесь вы напутали. Для правильного написания программы надо сделать 4 стадии. 1- составить полное ТЗ; 2- спроектировать программу; 3-написать код ;4 - залить скетч и отладить работу. Причем 1 и 2 этапы более важные чем 3 и даже 4. И комментарии до кода это просто эрзац планирование. Вроде хоть какое-то планирование,чем никакого вообще.
Отнюдь.
1. Я ничего не напутал.
2. По поводу 4-х стадий - на самом деле их больше: ВЫ опустили стадию тестирования. А она объемнее, чем все стадии до нее вместе взятые. Но пусть будеь так.
3. Я расписывал исключительно 3-ю стадию.
4. Алгоритм - это именно начало 3-й стадии. Он идет после 1-й и 2-й, но заменить их не может в принципе. Как алгоритм может заменить ТЗ или проект программы?
ChaNger. Вот смысл вам все это рассказывать. Все равно толку нет . Ваш пакет FirstMass состоит из 8 байт. Ну приняли 8 байт , потом 8 байт - и так дальше и должно быть . Но так не проиходит . Каким то образом вы принимает 9 байт . Но откуда лишний. Заняли у следующего за нима пакета . А следующий у за следующим за ним.
if
( Serial3.available() >=
sizeof
(FirstMass) )
Конструкция позволяет ловить и 9 и 10 байт
Сделал вот такой код приемника
Я сдаюсь :(
Во-первых, нахрена Вам в приёмнике delay? Чтобы пропустить все данные пока Вы в нём спите? В приёмниках задержек не делают, иначе они пропустят всё, что можно, и что нельзя. Занесите свою печать (стр. 16-20) под if и тогда печататься будет только когда реально считалось, а не на каждом проходе, как сейчас. А отправку "1" делайте как в "блинк без делэй".
Во-вторых, ну, вот что Вы опять сделали?
Serial.read читает 1 байт (прописью - "один"), а Вы заполняете им элемент массива int. Ну, блин, один байт он читает!
То, что Вам кажется, что
Я же Вам показал как делать передатчики ну, что Вам мешает сделать приёмник точно также?
delay сами убирайте, я Вам чтение из потока прописал. Заметьте, оно точно такое же, как была запись, кто Вам мешал так написать - чего мудрить-то было?
Огромное Вам спасибо!
Добрый день!
Подскажите пожалуйста как принять из UART в esp01s и итправить в esp?
Это ардуин отправляет в esp.
Это принимает esp из UART и отправляет пакет.
Это esp принимает пакет.
На выходе.
а должно быть data = 1023
если передавать с ардуина на ардуин по UART то число приходит
если в esp которая отправляет пакет в data записать число то напрямую c esp на esp оно приходит
подскажите что делать, а то мне чайнику ни как не разобраться.
а зачем вы под другим ником перерегистрировались? - вы же уже задавли этот вопрос неделю-две назад
вы думаете, вас так трудно узнать? - я ваш код с этими бредовыми reinterpret_cast отлично помню
вы уже тогда столкнулись с тем, что при передачи с Атмела на ЕСП нельзя использовать упрощенные типы вроде int. нужно писать точно - uint16_t, int32_t и так далее. Снова наступаем на те же грабли?
во, нашел предыдущую тему
http://arduino.ru/forum/programmirovanie/otpravka-dannykh-pokazaniya-datchika-dht11-iz-arduino-v-esp8266#comment-488618
и, что характерно - точно как там влезли в чужую тему со своим вопросом, вместо того чтоб начать новую
все говорит за то, что тамощний OFY и здешний aidtir - одно и тоже лицо
Ну, печати-то поставьте. Например, во втором скетче в строке №34 хотелось бы на data посмотреть.
Кроме того, какую именно Вы <WiFiUdp.h> используете? Если вот эту, то в ней просто нет метода write, принимающего только указатель на массив (без длины). А Вы в строке №39 передаёте именно так.
а меня еще и вот это смущает
Во-во. Поставить печать и всё видно будет.
Я не тот о ком вы подумали!
Объясните пожалуйста что мне делать я не понимаю.
Я смотрел тут переписки и у меня передача по UART с ардуино на ардуино работает а как записать прием в esp из UART правильно? Мне нужно просто принять число и отправить дальше пакетом.
Число будет изначально считываться ардуином из аналогово порта.
Объясните пожалуйста что мне делать я не понимаю.
Ну, Вам же уже подсказали.
1. Везде, вместо
int
FirstMass[2];
, напишитеint16_t
FirstMass[2];
.2. Поставьте печать во втором скетче, чтобы было видно, что принято
Я не тот о ком вы подумали!
Объясните пожалуйста что мне делать я не понимаю.
почитайте ветку по моей ссылке чуть выше, где ваш двойник задавал этот же вопрос с этим же кодом. Там и ответ есть.
насколько я вижу - тот ответ и вам должен решить проблему.