Увеличение буфера UART более 128 байт.
- Войдите на сайт для отправки комментариев
Втр, 24/01/2012 - 21:43
Arduino UNO. Связь через UART (пинRX(0), пинTX(1)) с модемом Siemens MC35i.
Столкнулся с проблемой приёма данных по UART (RX, TX) больше чем размер буфера в 128 байт. Я думаю что упираюсь именно в ёмкость буфера, так как в стрковую переменную данные записываются не полностью. Во всей строчке около 70-75 букв, в я получаю что-то около 65 :(
Уже второй день бъюсь головой об стол - ничего не помогает. Ну не принимает зараза больше и всё!
Serial.println("AT+CMGL=?"); // Отправляем апрос модему // Читаем ответ от модема while (Serial.available() > 0) { char inChar = Serial.read(); txtMsg += inChar; } // Обработка принятых данных, проверка, действие. txtMsg = ""; // обнуляем строку //в начало цикла loop
Подскажите, как можно обойти это ограничение и принимать всё что нужно до конца?
Есть подозрение, что проблема прямо противоположная - вы читаете быстрее, чем модем успевает присылать информацию. В какой-то момент условие Serial.available()>0 перестает выполняться, хотя модем готов слать еще и еще (программа выбрала/обработала последний успевший поступить в буфер символ, снова пришла на проверку условия и прочитала там 0 - очередной байт еще только поступает, принято, например, 6-7 битов, но не целый байт).
Попробуйте либо в уже в имеющийся цикл впихнуть задержку в миллисекунду (на 9600 общаетесь?) или меньше (при более высокой скорости), либо сдублировать цикл (в смысле copy&paste) и вставить между первым и вторым циклами задержку в 10-20 мсек.
Задержки ставил и по правде сказать мне это самое первое что пришло в голову, и скажу Вам не работает - и в цикл внутрь вставлял и снаружи и разные задержки от 50мсек и до 2 сек, но вот по поводу сдублировать цикл приёма это нужно попробовать, спасибо. Завтра с утра обязательно попробую и отпишусь.
Отпишитесь, ибо у меня та же проблема похоже
И дайте посмотреть, что отправляется и что принимается - т.е. хочется взглянуть что и где теряется.
Опять же - интересно узнать параметры связи, прежде всего скорость. Вы проверяли - с обоих сторон настройки одинаковые?
step962 прав, проблема в коде отправителя, я отправляю пакетом по 800 байт и никаких переполнений нет
Может я и не прав, у меня Carduino Nano Duo, у него USB мост на FTDI
у меня тоже на ftdi. Код дома, вечером точно выложу. Но суть:
Надо отправлять 16*48 байт /8бит = 96 байт
доходит 10*48 / 8 = 60 байт, далее потеря serial.avariable видимо
попробую задержку..
да, скорость пробовал 9600, 56700,115200
Кстати, почему не работает
никогда?
А сивол новой строки точно передается? Может быть, только возврат каретки ('\r')?
да черт его знает.. ))
http://my.jetscreenshot.com/1474/20120125-q5bs-116kb
Попробуй альтернативную библиотеку.
спасибо, попробую
Ребят, очень сорри что потерялся - работы просто вагон и маленькая тележка.
Под рукой проекта нет, он на работе остался - завтра думаю займусь в плотную, но пока объясню - да, пробовал разные скорости и пока остановился на 9600 для надёжности и USB мост на FTDI.
Отправляю в модем команду AT+CMGL=?
Ответ должен быть такой:
+CMGL : ("REC UNREAD", "REC READ", "STO UNSENT", "STO SENT", "ALL")
OK
----------------------------------------------------------------------------------------------
Только вот приходит : +CMGL : ("REC UNREAD", "REC READ", "STO UNSENT", "STO SENT", "ALL
Как видно в строчке теряются кавычки, скобка, возврат каретки, перенос строки и ОК.
Это один из вариантов обработки входных данных с порта, но сути это не меняет - все варианты дают один и тотже результат. Завтра буду пробовать дублировать цикл в цикле и писать другую строковую переменную и если там не достающая часть буду объеденять переменные. Пока думаю так, а там видно будет. В любом случае отпишусь.
Скетч вот в таком виде:
возвращает всю строку +CMGL : ("REC UNREAD", "REC READ", "STO UNSENT", "STO SENT", "ALL"). Чему я, собс-но, не удивляюсь, ибо всегда без проблем слушаю порт подобным образом. Установка delay(1) в цикле чтения не изменила поведения программы.
А в том виде, что у вас (с обработчиком serialEvent) вообще ничего не выдает (Arduino IDE ver 0022).
Строка подавалась через Serial monitor с установленным терминатором строки "new line" (выпадающий список внизу справа - левее списка выбора скорости передачи)
Спасибо, завтра попробую и отпишусь по пунктам что куда отсылается и как принимается!
Итак, отписываюсь - всё по прежнему! Строка принимается не полностью, но в ходе моих попыток, я заметил, что если подавать через сериал монитор по примеру step962, то всё принимается замечательно любой длинны, а вот с модема никак и меня осенило - когда модем даёт ответы, то сигнатура его обычно сводится к определённой очерёдности, а именно:
1. символ возврата каретки (ASCII 13, или '\r'), символ новой линии (ASCII 10, или '\n')
2. данные
3. символ возврата каретки (ASCII 13, или '\r'), символ новой линии (ASCII 10, или '\n')
4. OK
5. символ возврата каретки (ASCII 13, или '\r') и символ новой линии (ASCII 10, или '\n')
-----------------------------------
AT+CMGL=?
+CMGL: ("REC UNREAD","REC READ","STO UNSENT","STO SENT","ALL")
OK
_ <- Здесь мигает курсор
-----------------------------------
Я думаю, что из-за этого кода:
выход из условия производится не корректно и нужно как-то ковырять строковую переменную от модема игнорируя всё лишнее кроме последнего "ОК".
Может есть у кого какие мысли? Как быть?
Как быть? Ну вы все расписали)
Это конечно, но как реализовать на практике, я не знаю.
Целый день пытался обработать строку с помощью .endsWith() и .indexOf(), но никак не получается....
Функция trim() почему-то не работает.
Я еще таким не занимался к сожалению, строки в МК вообще ненавижу...
Всем добрый вечер!
Столкнулся с аналогичной проблемой не хватки размера буфера.
Не влазит часть строки от SIM900.
Возможно ли как то увеличить размер буфера?
HardwareSerial.cpp
#define SERIAL_BUFFER_SIZE
Но это изменит размер буфера для всех скетчей - можно помоему до килобайта
HardwareSerial.cpp
#define SERIAL_BUFFER_SIZE
Но это изменит размер буфера для всех скетчей - можно помоему до килобайта
а если увеличивать буфер то какое из двух значений увеличивать? в файле написаны две константы
Вчера сам столкнулся с аналогичной проблемой при чтении USSD ответа от GSM модуля.
Этот код разбивает считываемую строку на несколько частей:
А вот этот считывает полностью:
Тестовая строка - около 160 символов.
delay(1) замедляет чтение из буфера, предотвращая его опустошение. Справедливо для скорости 9600. Для более высоких надо задержку уменьшать чтоб не столкнуться с переполнением буфера длинной строкой.
А если не думать и просто попробывать
str = Serial.readString();
PS.
Хотя это не очень красиво. Я думаю она будет стоять на конце блока данных,
пока не кончится TimeOut (Serial.setTimeout()...) но зато получаем целую строку,
со всякими chr(13), chr(10) внутри. А в ответе модемов и GSM, по моему, нет конца строки ...
Решили задачу?
Не могу вешить подубную, нужно считать с прибора 71 байт данных. Получается считать только 63.
Говорят можно в библиотеке поменять размер буфера, пока не получилось. Подскажите где именно.
Плата UNO R3
Решили задачу?
Не могу вешить подубную, нужно считать с прибора 71 байт данных. Получается считать только 63.
Говорят можно в библиотеке поменять размер буфера, пока не получилось. Подскажите где именно.
Плата UNO R3
https://www.google.com/search?q=arduino+uard+buffer
Спасибо. Все получилось, УРА. Все заработало после установки новой версии IDE