Официальный сайт компании Arduino по адресу arduino.cc
MeGa WiFi RobotDyn передача из Serial в Serial3
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Добрый день! Нужна ваша помощь.
У меня логика такая: Есп берет из интернета данные,разбирает их и формирует строку вида : значение]значение2]значение3] и после этого, передает в сериал для меги, а мега уже разбирает эту строку и раздает задания на датчики. Значений может быть до 20 штук.
Вот строка которая формируется на есп:
a1]b18]c6]d55]e65]f0]g25]h28]i21]k24]l2019]m1]n16]o14]p36]r15]s18]t6]j18]q6]u0]v-63]w48680]
Влезает только вот это:
a1]b18]c6]d55]e65]f0]g25]h28]i21]k24]l2019]m1]n16]o14]p36]r15]s
63 символа.
Если выводить в сериал на есп, то выводится вся строка, все ок.
Предположение: Режется потому что, пока идет рид сериала на меге, есп посылает в сериал уже новую строку и старая обрубается... Хз как решить данную проблему =( Нужно что то вроде этого:
Пока мега делает рид сериал3, есп не может отслылать ничего в сериал...
Есп отсылает в сериал раз в 10 секунд, как бы делей достаточно большой... =(
код рида на меге:
String inString = ""; while (Serial3.available()) { // Чтение данных из порта Serial3 char inChar = Serial3.read(); // Вывод прочитанных данных в порт Serial Serial.write(inChar); // Поиск команды в полученных данных (команда должна быть в квадратных скобках) inString += inChar; }
код отправки на есп идет принтами:
Serial.print("a"); Serial.print(Arduino_active); Serial.print("]"); Serial.print("b"); Serial.print(properties.start); Serial.print("]"); Serial.print("c"); Serial.print(properties.stop); Serial.print("]");
код отправки идет принтами не "на" есп а "с" есп на сериал меги. Сорри за ошибку =)
эт скорее потому что буфер приема на 64 байта. надо ковырять файлы serial и увеличивать
Или организовать обмен не заполняя весь буфер
каким образом если есть 20-30 значений и их нужно все передать?
Да, скорее всего вы правы! Буду читать в эту сторону, спасибо!
каким образом если есть 20-30 значений и их нужно все передать?
Передавать значения в двоичном виде, а не строками, как у вас сейчас. Выкинуть разделители. Судя по виду вашей строчки, все это легко может поместится в 30-35 байт
Пока не нашел другого способа, сделаю так что бы двигаться дальше, но обязательно вернусь к этому вопросу что бы сделать "по человечески"
Перешел по C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial.h
там нашел строки
SERIAL_TX_BUFFER_SIZE 64
SERIAL_RX_BUFFER_SIZE 64
Поменял на 128, загрузил скетч на мегу+есп и все заработало. Спасибо
P.S. Это не особо правильный метод. Но я не на нобелевку делаю, а для себя, поэтому пойдет и так)))
Посмотрю на стибальность работы. Если будут зависания, либо не корректные данные в сериале то отпишу, что бы не учить плохому
Завтра попробую в двоичном виде! Спасибо
А вообще - абсолютно ничто не мешает вам разбить данные на несколько посылок...
Если вы за раз можете унести 4 коробки, а надо перетащить восемь - вы ж не ростите себе дополнительные руки, а просто перетаскиваете груз за два захода :)
Раз в 10 сек есп получает данные из инета и отправляет их на мегу.
Я отправляю пакет данных и жду несколько секунд и отправляю второй пакет? Просто Синхронизации между мегой и есп никакой нет, надеятся на везение - тоже не правильно.
По вашей логике это должно быть? так? :
ЕСП отправляет 1 пакет.
Мега при завершении обработки первого пакета отправляет обратно ответ и ЕСП посылает второй пакет?
b707 полностью с вами согласен! Логику я понял, а программно как мне понять что первая партия доставлена и пора вторую доставлять?)
И спасибо за совет =)
поставил delay(2000);
после каждых 5 значений. Всего 17 значений и 3 делея.
Вернул в хедере сериала со 128 до 64, вроде работает. Но не уверен что я правильно понял b707 о пакетных передачах =(
Поправьте меня если я не прав =)
b707 полностью с вами согласен! Логику я понял, а программно как мне понять что первая партия доставлена и пора вторую доставлять?)
а сейчас вы разве как-то заботитесь о том, дошло ли ваше сообщение? - или если один пакет данных потеряется, ничего страшного не произойдет? :) - если да - то в чем разница с таким вариантом?
Вообще, конечно, часто можно (и даже нужно) работать с подтверждением. Необходимость этого определяется тем, насколько критична доставка данных.
Вот у меня комнатный термометр шлет данные на сервер. Никакого подтверждения нет, поскольку даже если канал ляжет на несколько часов - мир не рухнет. А вот команды на компрессор я шлю с проверкой доставки. Если обратная сторона не ответила - пакет посылается снова и снова, а после пяти попыток выставляется ошибка
каким образом если есть 20-30 значений и их нужно все передать?
выложите весь код рида на меге. Сдается мне там задержка какая то есть. Потому что при этом коде
при появлении данных в буфере УАРТа они сразу должны оттуда вычитываться и буфер не будет успевать заполняться.
А если присутствует delay. и во время него от есп поступают данные, мега просто ждёт, буфер соответственно никто не вычитывает и он спокойно до конца заполняется. Поэтому строка не лезет полностью.
ПС. а лучше оба кода полностью.
каким образом если есть 20-30 значений и их нужно все передать?
а помоему лучше вычитывать во время из буфера на приёмной стороне и он не будет заполняться.
на стороне меги стоит делай (500)
он считывает моментально. Проблема вся в том чтто строка передается одним махом, а места нет. Если поставить в хедере на запись и чтение вместо 64 - 128 то все работает просто отлично!!!
Второй вариант - передавать несколькими порциями, я поделил на 3 порции по 7 значений и работает все отлично!!
он считывает моментально.
друг, а как вы думаете сколько времени займёт передача на этом канале 64 байт со скоростью 9600? это будет заметно меньше 500мс.
А считывает он конечно моментально, только вот это происходит, когда ваша программа на меге доберётся до цикла while. Но уже поздно, буфер то заполнился до конца. Ведь приём данных в буфер Serial не зависит от вашей программы, он на прерывании на сколько я знаю, поэтому когда вы простаиваете в delay, буфер спокойно и полностью заполняется.
проблема в том, что вы не спешите опустошать это место. С таким подходом вам и 128 может потом не хватить.
у меня стоит скорость 115200 с обеих сторон и со стороны меги пока нет ничего кроме проверки Serial.available() каждые 500мсек. Может конечно, я не так понимаю работу изнутри как вы! Я еще поковыряю код, т.к. день ушел только на то что бы это заработало, теперь осталось "прилизать" =)
спасибо большое за помощь!
у меня стоит скорость 115200 с обеих сторон и со стороны меги пока нет ничего кроме проверки Serial.available() каждые 500мсек. Может конечно, я не так понимаю работу изнутри как вы! Я еще поковыряю код, т.к. день ушел только на то что бы это заработало, теперь осталось "прилизать" =)
спасибо большое за помощь!
каждые 500 мсек с помощью delay? Блин я же вроде выше понятно объяснил почему у вас такой косяк. Сделайте свой delay через millis() без delay и все будет в порядке даже с 64кб буфером.
теперь понятно)))))) попробую и отпишу! Спасибо!!!
единственное нужно хотябы delay(2) в цикле while добавить, а то будет другая крайность - слишком быстрое чтение из буфера и будет вылетать из цикла while , дробя тем самым строку. Т.е. примерно так:
убрал delay и millis() вообще. Действительно. Зачем он нужен, сам не понимаю =(
поставил в while delay(2);
в общем, так же работает как и раньше. Завтра буду выкладывать код тогда сюда, видимо все проблемы в нем =(
Либо в платную часть напишу, за деньги сделать. А то я походу совсем баран =(
уберите delay (2), на скорости 115200 он вреден. Он нужен когда 9600.
также на передатчике рекомендую ввести маркер конца строки ,получив который на приёмнике , делать необходимые манипуляции со строкой inString , затем очищать её и выходить из цикла while.
передатчик
приёмник
А еще можно соеденить ЕСП с мегой дополниетльной линией готовности. И передавать данные только тогда, когда мега готова их принять.
также на передатчике рекомендую ввести маркер конца строки ,получив который на приёмнике , делать необходимые манипуляции со строкой inString , затем очищать её и выходить из цикла while.
передатчик
приёмник
ПОМОГЛО!!!! Спасибо тебе огромнейшее!!! Работает отлично. На передатчике данные передаются одним пакетом а на приемнике разбираются когда получает конец строки. Супер!!!!!
millis() работает лучше/легче/стабильнее чем delay?
А еще можно соеденить ЕСП с мегой дополниетльной линией готовности. И передавать данные только тогда, когда мега готова их принять.
Честно не понимаю о чем вы говорите. Можно попродробнее что это за линия такая?
Думаю мне это тоже будет интересно т.к. Сериал имеет таймаут а у меня в лупе кроме чтения сериала будет еще раздача заданий для датчиков и запись данных на сервер в интернете и боюсь что опять будут теряться данные т.к. время будет уходить на интернет отправку а в этому время сериал будет либо перезаполняться либо еще что нибудь...
просто во время delay программа останавливается и больше делать нчего не может, а когда вы делаете периодические действия через millis(), программа дальше спокойно крутится и может выполнять другие операции.
просто во время delay программа останавливается и больше делать нчего не может, а когда вы делаете периодические действия через millis(), программа дальше спокойно крутится и может выполнять другие операции.
Понял, спасибо!
Честно не понимаю о чем вы говорите. Можно попродробнее что это за линия такая?
Ну, в общем, можно сделать аналог CTS сигнала RS232. Соединяем свободный пин (цифровой вход) ЕСП со своббодным пином Ардуино (цифровой выход). Назовем его CTS. Когда Ардуино готово считывать данные из сериал, переводит CTS в HIGH (в стандарте RS232 наоборот, ну это не важно). ЕСП перед тем как передавать данные проверяет CTS если он LOW, то или ждет или идет чего другое делать. Если CTS HIGH, то начинает передачу порциями, проверяя CTS после каждой партии. Если он оказался LOW передачу тормозим.
Ардуино же, после того как приняла нужную информацию, ставит CTS в LOW и идет делать свои дела, зная что ничего ей передавать не будут, пока она CTS опять в HIGH не поставит.
Честно не понимаю о чем вы говорите. Можно попродробнее что это за линия такая?
Ну, в общем, можно сделать аналог CTS сигнала RS232. Соединяем свободный пин (цифровой вход) ЕСП со своббодным пином Ардуино (цифровой выход). Назовем его CTS. Когда Ардуино готово считывать данные из сериал, переводит CTS в HIGH (в стандарте RS232 наоборот, ну это не важно). ЕСП перед тем как передавать данные проверяет CTS если он LOW, то или ждет или идет чего другое делать. Если CTS HIGH, то начинает передачу порциями, проверяя CTS после каждой партии. Если он оказался LOW передачу тормозим.
Ардуино же, после того как приняла нужную информацию, ставит CTS в LOW и идет делать свои дела, зная что ничего ей передавать не будут, пока она CTS опять в HIGH не поставит.
Интересная идея! Спасибо!