Официальный сайт компании Arduino по адресу arduino.cc
Не работает Stream->readString()
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Пт, 07/06/2019 - 15:45
Добрый день!
Что-то третий день уже ковыряюсь и не могу понять в чем дело. Имеем ардуину, к ней через программный последовательный порт подключен SIM800L. В последствии с программного переедет на аппаратный, когда все заработает как надо. Имеется объект, в котором реализую функции работы с модемом. В конструктор передается указатель типа Stream на объект SoftwareSerial. Только вот не получается с него данные в виде строки получить.
String _resp = ""; if (serialPort->available()) { Serial.print(serialPort->available()); //показывает что в буфере что-то накопилось while (serialPort->available()) { // пробовал так вот //char symbol = ' '; //symbol=(char) serialPort->read(); //_resp.concat(symbol); //пробовал и так _resp.concat((char)serialPort->read()); //delay(10); Это тоже пробовал ставить //так выводит все в другой порт в нормальном виде //Serial.print((char) serialPort->read()); //вот это не работает, казалось бы то что надо //_resp = serialPort->readString(); } Serial.print("readString: "); Serial.print(_resp); Serial.println(":"); } }
Что я не так делаю?
А что возвращает вызов concat? Должен при успешной операции true вертать.
Можт этот ваш SIM800 строку не терминирует \n или шлёт более одной секунды свой реплай?
Ноль возвращает. Вот так проверял:
Ноль возвращает. Вот так проверял:
Значит, false возвращает. Я обычно просто оператором сложения пользуюсь:
Проблем никогда не замечал. Надо смотреть в исходниках, шо там конкретно. Щас гляну.
Посмотрел исходники, оператор суммирования неявно вызывает concat, всё с concat нормально в коде. Проблема, как вариант, с памятью, или ещё с чем.
Запускается на меге168, может и не хватает памяти... Наверно придется от всех объектов избавляться. пока вот:
В последствии мега328 будет
Но когда памяти не хватает он же должен зависнуть? А оно работает.
Запускается на меге168, может и не хватает памяти... Наверно придется от всех объектов избавляться. пока вот:
В последствии мега328 будет
Но когда памяти не хватает он же должен зависнуть? А оно работает.
Если вы посмотрите исходники WString.cpp - то увидите, как String работает с памятью: пока объект жив - внутренний буфер, выделенный на куче - занят. Буфер переаллоцируется, если не хватает места. Следовательно, неумеючи можно легко одним глобальным объектом String усрать всю оперативку ;)
вон оно что... придется попробовать другие методы...
спасибо за помощь!
В последствии с программного переедет на аппаратный, когда все заработает как надо.
оно и на програмном uart нормально написанный код работает.
переходите на буфер char, и вручную обрабатывайте каждый входящий байт из UART и не будет никаких переполнений String
Вообще-то скетч неполный. Не видно ни как работаетсте со стрингов, ни как передаёте поток, сделайте минимальный (по размерам) но полный скетч, на котором проявляется проблема. Тогда разговор будет предметным.
В качестве основы брал код из этих статей http://codius.ru/articles/GSM_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8C_SIM800L_%D1%87%D0%B0%D1%81%D1%82%D1%8C_1, только в классы решил обернуть для удобства. Весь код разбит на кучу файлов, все работает, осталось вот только модем заставить работать.
Вот описание класса
Работаем с ним так:
Ну, по-прежнему, нет короткого полного кода, который я мог бы запустить у себя и посмотреть.
Вот код, компилируется
Так лучше.
Во-первых, если Вы хотите в строках №№ 97-99 вычитывать всё, что пришло, то в строке №97 должен быть while, а не if.
Во-вторых, в конце цикла (перед строкой №99) нужна задержка. На скорости 9600 байты приходят медленно и они просто не будут успевать прийти, как Вы уже перестанете читать.
Для начала поставьте какую-нибудь "бешеную" задержку типа 100мс.
После этих двух исправлений, у Вас всё должно заработать (у меня заработало). Потом подберёте разумную задержку, НО ... очень не советую делать так.
Лучше воспользоваться тем, что строка от модема имеет явный признак конца (возврат каретки). Вот и читайте пока не прочитаете этот символ. Ждите сколько надо.
--------------------
Ну и ещё ряд замечаний, которые прямо не влияют на данную проблему, но в глаза бросились:
Спасибо большое!
по поводу 9600 - может увеличить скорость просто? Я как-то сталкивался с плохой работой программного последовательного порта на низкой скорости. Это имеет значение?
Касательно пункта 6 - функция не дописана просто. В этом коде много чего нету.
Большое спасибо за помощь, я все учту!
Ну, хоть заработало-то? А скорость - не знаю, смотрите сами. В любом случае лучше ждать терминального символа, чем играться с задержками.
Нет, не заработало ;(
Терминального символа ждать не могу - модем отправляет данные как ему удобно, часто несколькими строками.
Вот эта штука работает прозрачно:
Значит данные ходят туда-сюда.
Показывает что байты в буфере есть, Readstring() не читает их, хотя буфер опустошается. (char)modemPort->read() не читает тоже. Сейчас хочу попробовать сделать буфер из char и работать без String, но не хочется фиксированный буфер иметь. Хотя планирую команды не больше 64 байт длинной и вроде на ответы модема это тоже хватит...
По-правде расстраивает то что везде в инете примеры работают, а у меня - нет. Как так-то?
У меня появилось ощущение, что Вы меня троллите.
Ваш код из поста #13 отлично работает с теми правками, что я написал. Но! В нём (в коде из #13) нет никакого readString!
Вы показываете мне один код, а говорите о другом?
Я не троллю, я не клапануций сотоварищи. У меня не работает очевидный код, а я не понимаю почему. В общем разбираюсь, экспериментирую. Почему-то работа с последовательным портом у меня все время сопряжена с каким-то гимором...
Я не троллю
Тогда откуда в коде вообще взялся readString, если его там нет?
В самом первом посте я перечислял как пробовал. За основу брал такой код из примеров:
Он не заработал сходу и я стал пробовать читать разными способами.
а read() данные хоть и читает, но они недоступны. Я так понимаю он возвращает тип byte, т.е. бинарные данные как они есть. В случае перенаправления из порта в порт все происходит как надо. Но в моем случае нужна строка, а значит преобразовывать это дело в строку. Я делаю _resp.concat ((char)modemPort->read()), количество байт в буфере уменьшается, но на выходе ничего.
...а read() данные хоть и читает, но они недоступны. Я так понимаю он возвращает тип byte, т.е. бинарные данные как они есть. В случае перенаправления из порта в порт все происходит как надо...
Это как так? Например, на запрос "AT\r\n" что получаешь - 4F 4B 0D 0A?
Это как так? Например, на запрос "AT\r\n" что получаешь - 4F 4B 0D 0A?
и что в этом удивительного? - это одно и то же
а read() данные хоть и читает, но они недоступны. Я так понимаю он возвращает тип byte, т.е. бинарные данные как они есть. В случае перенаправления из порта в порт все происходит как надо. Но в моем случае нужна строка, а значит преобразовывать это дело в строку. Я делаю _resp.concat ((char)modemPort->read()), количество байт в буфере уменьшается, но на выходе ничего.
Вам уже несколько раз сказали - бросьте String, . concat у всех работает, а у вас нет - вероятно проблема не в нем,
переходите на массивы символов (char*) Команда read() как раз читает из буфера один символ
и что в этом удивительного? - это одно и то же
Видимо ТС этого не понимает.
В самом первом посте я перечислял как пробовал. За основу брал такой код из примеров:
Причём тут Ваш первый пост?
давайте восстановим последовательность. Я попросил Вас дать мне полный, короткий код, чтобы я мог увидеть проблему (посты #10 и #12). Вы мне его дали в посте #13. Никаких readString там не было и в помине.
Я потратил время на то, чтобы запустить, найти ошибки и описать их Вам. А теперь выяснилось, что это совсем не тот код, в котором проблема, а проблема в другом коде из примера! Вы сами себя слышите?
А на что я тратил время? Если Вы считаете. что не троллите, значит издеваетесь, хрен редьки не слаще. Вы заставили меня запускать и отлаживать код, который Вам, оказывается нахрен не нужен!
Я сегодня чрезвычайно добрый и потому не буду Вас посылать сразу, а дам ещё один шанс. дайте мне, мля, тот код с которым у Вас проблема (тот самый, а не какой-то другой!!!). Постарайтесь сделать его как можно короче. Опишите в чём именно проблема, и я его посмотрю. Но если опять выяснится. что это не тот код, уж извините, Вы будете помещены в список идиотов, с которыми общаться нельзя.
ЕвгенийП, уважаемый, я Вас делать и отлаживать ничего не заставлял, это ваше решение. Я благодарен Вам за помощь, но совершенно не понимаю такого отношения ко мне. Если Вам угодно, можете смело добавлять меня в свой список идиотов. Но все же это технический форум, а не место выяснения отношений
Понятно, то есть дать код и задать по нему интересующий Вас вопрос, чтобы Вам могли ответить, Вы не в состоянии? Понять, что дав мне не тот код, который Вас на самом деле интересует, Вы просто смыли в унитаз час моего времени, Вы тоже не в состоянии? Хорошо, добавляю.
Я благодарен Вам за помощь, но совершенно не понимаю такого отношения ко мне.
А что там понимать-то? Вы просили помощи - вам сделали код, отладили его - а вы даже не удосужились его проверить.
А теперь имеете наглость снова задавать этот же вопрос?
Понятно, то есть дать код и задать по нему интересующий Вас вопрос, чтобы Вам могли ответить, Вы не в состоянии? Понять, что дав мне не тот код, который Вас на самом деле интересует, Вы просто смыли в унитаз час моего времени, Вы тоже не в состоянии? Хорошо, добавляю.
Код, который Вы просите в полном виде разбит на десяток файлов, там куча классов с взаимодействием между ними. Я урезал код по-максимуму и дал его Вам. У Вас он заработал. У меня - нет. Я не уверен что у вас такое же окружение. Такой же модем. Такой же контроллер и подключен так же. У меня он работает на внутреннем генератора 8 МГц. Я не просил решать задачу за меня. Я просил указать направление, мысли, идеи, которых у местных завсегдатаев точно больше чем у меня.
А про ваше потраченное время могу лишь напомнить: Вы делали это добровольно. Я не требовал. Обвинять меня в том что вы по своей воле потратили время по-моему как-то странно. Я вполне бы согласился оплатить Ваши консультации и помощь в разработке. При условии, конечно, большего взаимного уважения.
Я благодарен Вам за помощь, но совершенно не понимаю такого отношения ко мне.
А что там понимать-то? Вы просили помощи - вам сделали код, отладили его - а вы даже не удосужились его проверить.
А теперь имеете наглость снова задавать этот же вопрос?
а вы, уважаемый, по теме вообще ничего не сказали. Я проверил код сегодня утром. Что не так? Неужели вы настолько изголодались по ругани и спорам? К чему весь этот срач?
Код, который Вы просите в полном виде разбит на десяток файлов, там куча классов с взаимодействием между ними. Я урезал код по-максимуму и дал его Вам.
зачем вам код с десятком исходных файлов, если у вас элементарное не работает? Напишите взаимодействие с Сериал коротким куском, строк в 20-30 - без всяких десяти уровней классов - и сначала отладте его. А уж потом добавляйте в свой мега-проект.
Именно такой код, самодостаточный и короткий - у вас и просили.