Нужен ли еще один последовательный порт для связи по UART
- Войдите на сайт для отправки комментариев
Втр, 15/05/2018 - 00:39
Пока идут компоненты, решил попробовать связать Arduino и Wemos по UART. И тут задумался, если RX-TX будут подключены к другой плате, то смогу ли я смотреть в монитор порта и отслеживать, что передается с Arduino в Wemos?
Смотря какой контроллер Ардуино Вы будете использовать.
Если у него 2-4 последовательных порта, то монитор подключается к одному, а Wemos - к другому.
Если только один, обычно используется SoftwareSerial.
Uno, что то забыл указать...)
Если только один, обычно используется SoftwareSerial.
Если еще захочу посмотреть, какие данные поступили на Wemos, то на нем тоже нужно использовать SoftwareSerial?
На одном - аппаратный, на другом - софтверный. Софтверный в один момент времени может работать только один.
Если нужно 3 порта или более - берите Мегу или DUE.
Если нужно 3 порта или более - берите Мегу или DUE.
Нет, мне достаточно два: один для просмотра монитора порта, а другой для связи по UART.
Я правильно понимаю, что для UART нужно использовать Софтверный?
Я правильно понимаю, что для UART нужно использовать Софтверный?
Не могли бы Вы как-то переформулировать вопрос?
Прошу прощения, слизал вашу фразу, видимо не в тему...) Насколько я понял, при помощи библиотеки SoftwareSerial, можно создать еще один программный последовательный порт, вы его назвали Софтверный(если я правильно вас понял..)), к примеру на 3-4 цифровых пинах. Получается для связи Arduino Uno и Wemos по UART, нужно использовать именно его, а не штатный на 0-1 цифровых пинах?
Использовать так, как Вам удобнее.
Собственно, аппаратный на Uno уже подключен к преобразователю USB-UART, поэтому логично именно его использовать для связи с компьютером по USB, а для связи с другим устройством, естественно, остается только программный. Но следует помнить, что программный имеет больше ограничений в использовании, в частности, не может работать на высоких частотах. Если это окажется критичным, то, возможно, окажется целесообразным пртивоположное решение: с компьютером связываться через SoftwareSerial при помощи внешнего USB-UART, а с другим устройством - через аппаратный, проигнорировав установленный на плате USB-UART.
Задачи бывают разные, и они требуют разных решений.
Понял, благодарю..) Не могу найти, какие можно использовать цифровые пины, для подключения с другими устройствами на Uno и Wemos D1 R2?
Если Вы про SoftwareSerial, то, насколько я помню, его можно повесить на любые пины Uno (разумеется, кроме А6 и А7, которых на оригинальном Uno нет).
Да, про него. У меня были не понятки с wemos, я думал что: d1 - это 1, d2 - это 2, для присвоения пина, сейчас вроде разобрался..)
Столкнулся с проблемой потери данных, я понимаю что косяк мой...), но не могу его решить... Ситуация следующая. С вемоса раз в две секунды передаются данные в ардуино:
void peredacha() //передаем данные в ардуино { //отправляем в последовательный порт mySerial mySerial.print("<tempRegAndroidD>"); //посылаем ориентировку на прием данных в ардуино mySerial.print(123); mySerial.print("</tempRegAndroidD>"); mySerial.print(" "); mySerial.print("<tempRegAndroidP>"); mySerial.print(68); mySerial.print("</tempRegAndroidP>"); //отправляем время mySerial.print("<Time>"); mySerial.print(sTime); mySerial.print("</Time>"); }В ардуино их принимаю только, если увижу вначале фразу: "<tempRegAndroidD>":
void priem() //принимаем данные от Wemos WIFI { if (mySerial.available()>0) { //проверка последовательного программного порта mySerial на наличие поступающих данных //в Wemos пакет(условно)передаваемых данных, начинается с фразы "<tempRegAndroidD>", поэтому наличие этой фразы //будет условием начала приема данных, иначе могут быть пропуски if (mySerial.find("<tempRegAndroidD>")) { //поиск ключевой фразы, после которой можно начать принимать //данные(задается на другой стороне-Wemos) sTempRegD = mySerial.parseInt(); //считывание целых данных без точки(считываются только цифры до первого //знака/буквы/пробела) Serial.print(sTempRegD); Serial.print(" "); if (mySerial.find("<tempRegAndroidP>")) { sTempRegP = mySerial.parseInt(); Serial.print(sTempRegP); Serial.print(" "); } if (mySerial.find("<Time>")) { sTime=mySerial.readStringUntil('<'); //принимаем строку до знака '<' Serial.println(sTime); } sFlag1 = 1; //данные получили, флаг того что теперь можно передавать } } }Далее по флагу sFlag1, передаю данные обратно в вемос:
void peredacha() //передаем данные в Wemos WIFI { if (sFlag1 == 1){ //передаем только тогда, когда данные получили, иначе программные порт не может нормально принять/передать!!! // delay(5); //обязательно ждем 1-5 милисекунд(можно больше) перед отправкой данных в Wemos, после приема данных с Wemos //отправляем в последовательный порт mySerial // len = sizeof(tempD); //можно узнать количество байт в числе и при надобности тоже отправить в порт. sTempD = 236.56; sTempRegD = 100; sTempRegP = 60; mySerial.print("<tempD>"); //посылаем ориентировку на прием данных в Wemos mySerial.print(sTempD); //температура духовки (обрезаем число до десятых: 36,6) // mySerial.print("</tempD>"); mySerial.print("<tempP>"); // float sTempP1 = round(sTempP*5000)/5000; //округляем до десятых mySerial.print(sTempP); //температура духовки (обрезаем число до десятых: 36,6) // mySerial.print("</tempP>"); mySerial.print("<tempRegD>"); mySerial.print(sTempRegD); //температура регулировки духовки // mySerial.print("</tempRegD>"); mySerial.print("<tempRegP>"); mySerial.print(sTempRegP); //температура регулировки продукта // mySerial.print("</tempRegP>"); mySerial.print("<sTimeReg>"); mySerial.print(sTimeReg); //время регулировки // mySerial.print("</sTimeReg>"); mySerial.print("<pr>"); mySerial.print(pr); //номер выбранной программы // mySerial.print("</pr>"); mySerial.print("<sPressUp>"); mySerial.print(sPressUp); //флаг закладки продуктов в духовку // mySerial.print("</sPressUp>"); // mySerial.print("<sDone>"); mySerial.print(sDone); //флаг завершения программы // mySerial.print("</sDone>"); int sRelayOn = digitalRead(sNull); //если равно 0, то значит выключено, и наоборот mySerial.print("<sRelayOn>"); mySerial.print(sRelayOn); //состояние реле вкл./выкл. // mySerial.print("</sRelayOn>"); mySerial.print("<sRelay>"); mySerial.print(sRelay); //флаг вышедшего реле из строя // mySerial.print("</sRelay>"); mySerial.print("<TimeA>"); mySerial.print(sTime); //отправляем обратно полученное время(для контроля зависания ардуино) mySerial.print("</TimeA>"); mySerial.print("<ledGreen>"); mySerial.print(ledGreen); //статус зеленого светодиода mySerial.println("</ledGreen>"); sFlag1 = 0; //обнуляем флаг о принятых данных } }В свою очередь в вемос их принимаю только, если увижу фразу:"<tempD>":
void priem() { //принимаем данные от ардуино if (mySerial.available()>0) { if (mySerial.find("<tempD>")) { sTempD = mySerial.parseFloat(); //считывание целых данных без точки(считываются только цифры //до первого знака/буквы/пробела) Serial.print("sTempD: "); Serial.print(sTempD); Serial.print(" "); if (mySerial.find("<tempP>")) { sTempP = mySerial.parseFloat(); Serial.print("sTempP: "); Serial.print(sTempP); Serial.print(" "); } if (mySerial.find("<tempRegD>")) { sTempRegD = mySerial.parseInt(); //считывание целых данных с плавающей точкой(считываются только //цифры с точкой до первого другого знака/буквы/пробела) Serial.print("sTempRegD: "); Serial.print(sTempRegD); Serial.print(" "); } if (mySerial.find("<tempRegP>")) { sTempRegP = mySerial.parseInt(); Serial.print("sTempRegP: "); Serial.print(sTempRegP); Serial.print(" "); } if (mySerial.find("<sTimeReg>")) { sTimeReg = mySerial.parseInt(); Serial.print("sTimeReg: "); Serial.print(sTimeReg); Serial.print(" "); } if (mySerial.find("<pr>")) { pr = mySerial.parseInt(); Serial.print("pr: "); Serial.print(pr); Serial.print(" "); } if (mySerial.find("<sPressUp>")) { sPressUp = mySerial.parseInt(); Serial.print("sPressUp: "); Serial.print(sPressUp); Serial.print(" "); } if (mySerial.find("<sDone>")) { sDone = mySerial.parseInt(); Serial.print("sDone: "); Serial.print(sDone); Serial.print(" "); } if (mySerial.find("<sRelayOn>")) { sRelayOn = mySerial.parseInt(); Serial.print("sRelayOn: "); Serial.print(sRelayOn); Serial.print(" "); } if (mySerial.find("<sRelay>")) { sRelay = mySerial.parseInt(); Serial.print("sRelay: "); Serial.print(sRelay); Serial.print(" "); } if (mySerial.find("<TimeA>")) { //принимаем время обратно с ардуино sTimeA=mySerial.readStringUntil('<'); //принимаем строку до знака '<' Serial.print("sTimeA: "); Serial.println(sTimeA); Serial.print(" "); } if (mySerial.find("<ledGreen>")) { //принимаем статус зеленого светодиода ledGreen = mySerial.parseInt(); Serial.print("ledGreen: "); Serial.println(ledGreen); } if (mySerial.find("</ledGreen>")) { Serial.println("OK"); } sFlag1 = 0; //обнуляем флаг о принятых данных } } }Но в мониторе порта вемоса не всегда корректные данные(то пропуски каких то переменных, то не правильные данные, то не находит несколько подряд идущих данных):
sana555, слишком много сущностей разом, так программы не отлаживают. Сделайте подробный вывод в сериал после первой передачи данных, убедитесь. что на этом этапе нет ошибок. Если все ОК - переходите к следующей, и отлаживайте каждую передачу в отдельности.
А как сделать подробный вывод?
А как сделать подробный вывод?
вот как вы на последнем этапе выводите - так в монитор порта и выводите значения АндроидП АндроидД и так далее. Только не просто выводите всю принятую строку целиком - а по отдельности значение каждого поля, чтобы видеть, что ваш разбор принимаемых данных работает правильно.
То есть так не достаточно:?
if (mySerial.find("<tempP>")) { sTempP = mySerial.parseFloat(); Serial.print("sTempP: "); Serial.print(sTempP); Serial.print(" "); }Нужно еще что то добавить, можете показать пример, а то я буксую...)
Так?
void priem() //принимаем данные от Wemos WIFI { if (mySerial.available()>0) { //проверка последовательного программного порта mySerial на наличие поступающих данных //в Wemos пакет(условно)передаваемых данных, начинается с фразы "<tempRegAndroidD>", поэтому наличие этой фразы //будет условием начала приема данных, иначе могут быть пропуски if (mySerial.find("<tempRegAndroidD>")) { //поиск ключевой фразы, после которой можно начать принимать //данные(задается на другой стороне-Wemos) sTempRegD = mySerial.parseInt(); //считывание целых данных без точки(считываются только цифры до первого //знака/буквы/пробела) Serial.print(sTempRegD); Serial.print(" "); if (mySerial.find("<tempRegAndroidP>")) { sTempRegP = mySerial.parseInt(); Serial.print(sTempRegP); Serial.print(" "); }else{ Serial.print("<tempRegAndroidP>"); Serial.print("NO"); } if (mySerial.find("<Time>")) { sTime=mySerial.readStringUntil('<'); //принимаем строку до знака '<' Serial.println(sTime); }else{ Serial.print("<Time>"); Serial.println("NO"); } sFlag1 = 1; //данные получили, флаг того что теперь можно передавать } } }Софтверный в один момент времени может работать только один.
Оказывается тот код, который я выложил, у меня все принимает нормально, без ошибок..) Я просто случайно(пробовал по разному) закоментировал свой флаг:
if(sFlag1 == 1){Этот флаг я сделал методом проб и тыка..) Но, до сих пор не понял, почему без него, данные шлются как попало(указывал выше), какую он играет роль? Ведь данные, которые посылает ардуино в вемос, никак не связыны с тем, что ардуино принимает с вемоса. Единственное, принятое время, но ведь оно записывается в переменную, и ардуино шлет его уже из этой переменной, я в ступоре...)