Данные через GPRS соединение (Arduino_Uno + GPRS_Shield)
- Войдите на сайт для отправки комментариев
Как указанно в заголовке есть связка Arduino_Uno + GPRS_Shield V1.2 .
Плюс пара кнопок - каждая посылающая свою команду в инет .
Команды передаем самым простым способом - в строке HTTP запроса .
gprsSerial.print("AT+HTTPINIT\r"); delay(500); gprsSerial.print("AT+HTTPPARA=\"CID\",1\r"); delay(500); gprsSerial.print("AT+HTTPPARA=\"URL\",\"СЕРВЕР.ru/proba.php?name=10\"\r"); delay(500); gprsSerial.print("AT+HTTPACTION=1\r"); delay(7000); gprsSerial.print("AT+HTTPTERM\r"); delay(500);
Работает все на ура , но уж очень медленно . Каждую команду приходится по 7 секунд ждать .
Понятно что все дело в /delay();/
Там где значение 500 стоит - там мы 'ОК' ответ от GPTRShield'a ждем . Пробовал меньше ставить значение - иногда не работает код . Как грамотно отследить что пришел ответ 'ОК' и можно следующую команду слать ?
Там где параметр 7000 - там помимо 'ОК' еще и соединения ждем (пока придет ответ '+HTTPACTION:1,200,104') - тут подбирать параметр delay вообще безсмысленно - то в 2 секунды соединяется , то по 10 ждать приходится .
Там где значение 500 стоит - там мы 'ОК' ответ от GPTRShield'a ждем . Пробовал меньше ставить значение - иногда не работает код . Как грамотно отследить что пришел ответ 'ОК' и можно следующую команду слать ?
Что значит "ответ от GPTRShield'a"? Он на экране высвечивается? Динамиком проговаривается? Или все же по Serial-каналу приходит?
Ну уж если по Serial, то после отправки любой команды, на которую ожидается ответ шилда "OK", можно не отсчитывать секунды, а в цикле ждать поступления чего-нибудь в приемный буфер:
Появился какой-то символ в приемном буфере - подождали еще 5-6 миллисекунд (чтобы не только "O", но и "K" успело прийти, ну и завершающие CR+LF (или только CR)), потерли буфер (чтобы на следующей команде все снова начиналось с ожидания, а не с проскока if'а) и приступили к отработке следующей команды.
Можно даже набраться наглости и не просто тереть буфер, а читать из него и анализировать прочитанное: вдруг там вместо ожидаемого "OK" какая-нибудь ересь пришла? Например, ваш шилд об ошибке что-нибудь лепечет...
Там где параметр 7000 - там помимо 'ОК' еще и соединения ждем (пока придет ответ '+HTTPACTION:1,200,104') - тут подбирать параметр delay вообще безсмысленно - то в 2 секунды соединяется , то по 10 ждать приходится .
И в этом случае ровно так же ждем поступления данных в приемный буфер. С той лишь разницей, что прийти их должно не 2 буквы + конец строки, а чуть-чуть больше (сами посчитаете?).
спасибо огромное !
вот так получилось . Всё работает
И все же, все же, все же...
Буфер чистить надо. Иначе при следующей проверке условие Serial.available() будет выполняться автоматически:
вот мой кусок программы
работает же ? С ардуино работаю не давно , въезжаю медленно .
Но - спасибо - перепишу .
работает же ? С ардуино работаю недавно, въезжаю медленно.
Ну, видно, delay(100) в данном конкретном случае помогают. Или переполнение буфера очень удачно к самой медлительной команде подоспело.
В общем, работает до поры до времени.
Поставив чтение из приемного буфера в пустоту (dummy=...), вполне можете сократить время ожидания раз в 10 (delay(10);). ну или в 8 (delay(12);)
думаю так пойдет ?
Serial.flush();
сейчас попробую - отпишусь
Да - получилось вот так
теперь правильно ?
сам спросил - сам ответил - не прокатило . передает данные через раз.
вот так вроде все стабильно
но объясните мне пожалуйста алгоритм.
gprsSerial.print("AT+HTTPACTION=1\r"); -тут отослали команду в шилд
while(gprsSerial.available()==0); - ждем пока хоть что то шилд пришлет в ответ (если ОК то ждем первую букву О)
delay(20); - даем время на прием всей информации от шилда (т.е. букву К)
while(gprsSerial.available()) - тут что ждем ???
dum=gprsSerial.read(); - зачем считывать что то в какую то переменную ? что это дает ?
Первые два предположения верны - в первом if'е ждем, пока не начнется передача ответа от шилда.
Затем даем некоторое время для того, чтобы весь ответ от шилда пришел в буфер приема (на скорости 9600 каждый символ передается примерно за миллисекунду. Так что если ожидается "OK", достаточно подождать 3-4 мсек, чтобы принять сами буквы плюс завершающие передаваемый пакет символы).
Ну а в последних двух строках (кстати, строки то две, а операция одна) читаем из входного буфера все те символы, что туда упали. Читаем до тех пор, пока в буфер не станет пуст, то есть очередной вызов Serial.available не вернет 0. Символы читаем и тут же забываем (поскольку сохраняем их в одной скалярной переменной). Этим добиваемся, что при подаче следующей команды наш if (тот, который ожидает поступления первого символа ответа от шилда) будет работать правильно
Если встанет задача не просто очистить буфер, а прочитать полученный ответ и проанализировать его, например, чтобы принять решение, что же делать дальше (т.е. когда логика программы станет чуть сложнее лома), придется освоить чтение этой информации из приемного буфера в строку.
Но это уже совсем другая история...
да хоть ты тресни - теперь совсем все висит .
Проблема может быть и в куску программы, отличном от вышеприведенного - лучше выложить (тестовый) скетч полностью (не забываем о кнопке [---]code).
вот вся программа
сим карту проверил - баланс ок , в гипертерминале все работает
Настройку скорости UART в последнее время не меняли?
Шилд точно на 19200 работает?
И зачем это вы программный Serial используете?
И зачем вешаете его на те же выводы, что и аппаратный Serial?
скорость никогда не менял
скорость сейчас поменяю на 9600
програмный - аппаратный сериал не понял вопроса .
програмный - аппаратный сериал не понял вопроса .
Это не вопрос, а указание на ошибку. Либо используйте обычный Serial, либо переносите свой gprsSerial на другие пины.
Как правило эти шилды имеют джампер. Куда подключится его RX,TX - либо на D0,D1 - тогда используем просто Serial, либо на какие-то другие пины (например D8,D9 - это уже в доках на шилд смотреть), тогда используем SoftwareSerial как у вас в коде.
Если решите использовать обычный Serial (это и есть "аппаратный", он меньше грузит проц), то что-бы не лопатить весь код, можете просто вместо строки
Написать
Тогда больше в коде ничего менять не прийдется
Немного не по теме , но всё же - Что за фигня такая ? Вот простейшая программа - каждая кнопка включает свой светодиод на 2 секунды. Почему после того как скетч записался в ардуино безо всяких нажатий кнопок загорается сначала один светодиод , потом второй ??? Напрягает ...
А по теме - поставил програмный сериал , скорость 9600 , толку ноль . Учу матчасть ...
Немного не по теме , но всё же - Что за фигня такая ? Вот простейшая программа - каждая кнопка включает свой светодиод на 2 секунды. Почему после того как скетч записался в ардуино безо всяких нажатий кнопок загорается сначала один светодиод , потом второй ??? Напрягает ...
Больше напрягает что вы ожидаете тут телепатов. Нужно догадыватся "что вы там наподключали". Скорее всего забыли про подтягивающие резисторы. Смотрите базовый пример, один из первых с которым нужно с дуиной знакомится http://arduino.ru/tutorials/button - как правильно подлючать кнопку.
И зачем все лепить в одну строчку? Что-бы труднее было заметить проблемы? В 12,13 строке, что у вас за чехарда со скобками на prevXXX=currkXXX?
А по теме - поставил програмный сериал , скорость 9600 , толку ноль . Учу матчасть ...
"Поставил програмный", всмысле джампером?
И откуда вы 9600 скорость взяли? Судя по wiki-шилда у него "родная скорость", таки 19200.
Поискал вверх по теме. Никто вам ставить 9600 - не советовал. Первый раз эта цифра упомнял step962. Причем со смыслом что "100 миллисекунд точно хватит и на скорости 9600 что бы успеть передать" (так что 500 - не нужно). Но это же не значит что "нужно ставить 9600 скорость" . Это значит что "для 19200" delay(100) - хватит с головой. А можно и меньше сделать.
И "ишо".
Раз вы все равно не пытаетесь парсить получаемые данные, то вместо delay() можно просто ждать пока из сериал прийдет перевод строки \n (или если там ожидается несколько строк ответа - считаем нужное количество переводов). Тогда не нужно будет "ждать лишнего".
Да не - в телепатов сам не верю :)
Говорю же - только начинаю изучать ардуино . Всегда везде все на Basic`е делал (Bascom - для прошивки в AVR , PureBasic для под винду программы и т.д.) а тут совершенно незнакомый язык...
Обязательным условием работы связки Arduino + GPRS-шилд является настройка и того и другого устройства на одинаковую скорость. А будет это 9600 или 19200 (либо какая еще) - не столь важно.
Хотя вру - для программного Serial важно. Чем выше скорость программного Serial, тем больше проблем с передачей данных. Поэтому, пока есть такая возможность, лучше работать с аппаратным.
По поводу непонятных скобок - все взято отсюда - такие исходники попались .
Ну так отформатируйте в приличный вид. Возможно в этом дело, раз резисторы на месте.
Можете проверить это сделав тестовый скетч с loop(){serial.println(analogRead(PIN_BUTTON);}
И посмотрите - стоит ли у вас ноль, как ожидается при отпущенной кнопке или нет. И появляется ли четкий 1, при этом.
По поводу непонятных скобок - все взято отсюда - такие исходники попались .
Ну так отформатируйте в приличный вид. Возможно в этом дело, раз резисторы на месте.
Нажмите в ArduinoIDE CTRL-T оно вам само отформатит.
Судя по всему - с кодом все нормально. Так что перепроверяйте подключение.
Огромное всем спасибо . Всё заработало .
Перепроверил соединения , заменил блок питания , общение с шилдом сделал через 7 и 8 пины , скорость для шилда включил 9600 (AT+IPR=9600) как и прописывал в скетче . Все заработало . Отправляет данные на сервер , принимает данные с сервера . Если интересно то видео будет завтра .
НО! :) а как же без но ?
На сервер данные передаются в строке адреса
сначала показалось так и проще и быстрее . На деле же на отсылку одной команды уходит 5-10 секунд . И , к тому же , если с платы нет команды на отсылку делается запрос на сервер - нет ли там команд на прием ? - это тоже 5-10 секунд. (задержка - это долгое соединение шилда с сервером)
Вобщем все очень долго работает .
Алгоритм отсылки команды :
1-задать адрес
2-соединиться
3-разъединиться
Подскажите - каким образом (протоколом) можно соединиться с сервером один раз и далее (проверяя наличие соединения ) отсылать и принимать команды дабы увеличить скорость обмена .