Arduino Uno + SIM900

VaGrAm
Offline
Зарегистрирован: 11.12.2017

Добрый день коллеги,

Я в разработке проектов и приложений с/для Ардуино совсем новичок (с недельным стажем).

Просьба помочь советом/решением следующего примитивного (на первый взгляд) вопроса:

На Arduino Uno "надет" GSM shield SIM900. Переключатели TX/RX установлены в положении SW. При загрузке комплект устанавливает GPRS соеденение и шлет GET запрос на сервер. В ответ получает конкретные "текстовые" указания (1 или 0) на основе которых надо включить или отключить диодную лампочку. Установка соеденения, отправка запроса и прием проходит как запланировано (в логах веб-сервера виден запрос/ответ). Надо на основе "приема" включить/отключить лампу.  Нужна промежуточная "процедура" считывания и присвоения переменной ledcmd ответа выдаваемое в консоль после вызова AT+HTTPREAD (1 или 0). В "ручном" режиме (ручном вводе АТ комманд) после AT+HTTPREAD выдается результат:

+HTTPREAD:1
1
OK
 
Основной код програмы ниже.
 
#include "SIM900.h"
#include <SoftwareSerial.h>
 
int ledpin = 11;
char ledcmd;
 
void setup()
{
     pinMode(ledpin, OUTPUT);
     
     Serial.begin(9600);
     Serial.println("GSM Shield testing.");
     if (gsm.begin(9600)) Serial.println("\nstatus=READY");
     else Serial.println("\nstatus=IDLE");
     Serial.println("Setting up GPRS");
     gsm.SimpleRead();
     gsm.SimpleWriteln(("AT+SAPBR=3,1,\"Contype\",\"GPRS\""));
     delay(100);
     gsm.SimpleWriteln(("AT+SAPBR=3,1,\"APN\",\"internet.beeline.am\""));
     delay(100);
     gsm.SimpleWriteln(("AT+SAPBR =1,1"));
     delay(100);
     gsm.SimpleWriteln(("AT+HTTPINIT"));
     delay(100);
     gsm.SimpleWriteln(("AT+HTTPPARA=\"CID\",1"));
     delay(100);
     gsm.SimpleWriteln(("AT+HTTPPARA=\"URL\",\"http://www.mydomain.com/request.php\""));
     delay(100);
     gsm.SimpleWriteln(("AT+HTTPACTION=0"));
     delay(100);
     gsm.SimpleWriteln(("AT+HTTPREAD"));
};
 
 
void loop()
{
     if (ledcmd=="1")
     {
     digitalWrite(ledpin, HIGH);
     }
     else
     {
     digitalWrite(ledpin, LOW);
     }
     delay (2000);
}
 
На просторах интернета есть подобные задачи и решения, но уже который день тестирую их: ни с одним не удалось достичь результата.
 
Заранее спасибо за любую помошь и совет.
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А в чтении Вы тоже "совсем новичок (с недельным стажем)"? Или Вы просто не сочли нужным прочесть правила форума, прежде, чем в него писать?

VaGrAm
Offline
Зарегистрирован: 11.12.2017

В чтетии у меня "стаж" более 30 лет и прошу прощения если кого-то "обидел" своим необдуманным действием не ознакомившись до конца со всеми правилами. Ниже код в "приемлемом" формате (не нашел как отредактировать старое сообщение):

#include "SIM900.h"
#include <SoftwareSerial.h>
 
int ledpin = 11;
char ledcmd;
 
void setup()
{
     pinMode(ledpin, OUTPUT);
     
     Serial.begin(9600);
     Serial.println("GSM Shield testing.");
     if (gsm.begin(9600)) Serial.println("\nstatus=READY");
     else Serial.println("\nstatus=IDLE");
     Serial.println("Setting up GPRS");
     gsm.SimpleRead();
     gsm.SimpleWriteln(("AT+SAPBR=3,1,\"Contype\",\"GPRS\""));
     delay(100);
     gsm.SimpleWriteln(("AT+SAPBR=3,1,\"APN\",\"internet.beeline.am\""));
     delay(100);
     gsm.SimpleWriteln(("AT+SAPBR =1,1"));
     delay(100);
     gsm.SimpleWriteln(("AT+HTTPINIT"));
     delay(100);
     gsm.SimpleWriteln(("AT+HTTPPARA=\"CID\",1"));
     delay(100);
     gsm.SimpleWriteln(("AT+HTTPPARA=\"URL\",\"http://www.mydomain.com/request.php\""));
     delay(100);
     gsm.SimpleWriteln(("AT+HTTPACTION=0"));
     delay(100);
     gsm.SimpleWriteln(("AT+HTTPREAD"));
};
 
 
void loop()
{
     if (ledcmd=="1")
     {
     digitalWrite(ledpin, HIGH);
     }
     else
     {
     digitalWrite(ledpin, LOW);
     }
     delay (2000);
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

VaGrAm пишет:
Ниже код в "приемлемом" формате
Вы будете смеяться, но не в приемлемом.

Вот сами подумайте, ну вот захочу я сейчас сказать Вам где у Вас ошибка. И что мне говорить? В строке № .. эээ ... ХЗ?

Без номеров строк обсуждать невозможно. Вставьте как следует и привыкайте так вставлять.

VaGrAm
Offline
Зарегистрирован: 11.12.2017

Евгений, раз формат (функционал) портала (форума) позволяет мне постить код с специальной опцией "Убрать вертикальный выравниватель и номерацию строк" то речи быть не может о неприемлемости. Другое дело что указанный вами формат более удобен для указания конкретных ошибок (в общих случаях). С этим не спорю. В будущем (для более объемных задач) именно так и буду делать. Но в данном случае: не думаю что есть что указывать. Я тут не нерабочий код постил чтоб искать что где не работает. Это вырезка из рабочего кода с иллюстрацией как устанавливается соедение и как планирую "проверять" ответ с сервера. Мне нужно дописать процедуру типа readresponce() в которой ledcmd будет приписыватся 1 или 0. Но если указанный вами формат (с нумерацией) поможет решению моей проблемы: пожалуйста...

#include "SIM900.h"
#include <SoftwareSerial.h>
  
int ledpin = 11;
char ledcmd;
  
void setup()
{
     pinMode(ledpin, OUTPUT);
      
     Serial.begin(9600);
     Serial.println("GSM Shield testing.");
     if (gsm.begin(9600)) Serial.println("\nstatus=READY");
     else Serial.println("\nstatus=IDLE");
     Serial.println("Setting up GPRS");
     gsm.SimpleRead();
     gsm.SimpleWriteln(("AT+SAPBR=3,1,\"Contype\",\"GPRS\""));
     delay(100);
     gsm.SimpleWriteln(("AT+SAPBR=3,1,\"APN\",\"internet.beeline.am\""));
     delay(100);
     gsm.SimpleWriteln(("AT+SAPBR =1,1"));
     delay(100);
     gsm.SimpleWriteln(("AT+HTTPINIT"));
     delay(100);
     gsm.SimpleWriteln(("AT+HTTPPARA=\"CID\",1"));
     delay(100);
     gsm.SimpleWriteln(("AT+HTTPPARA=\"URL\",\"http://www.mydomain.com/request.php\""));
     delay(100);
     gsm.SimpleWriteln(("AT+HTTPACTION=0"));
     delay(100);
     gsm.SimpleWriteln(("AT+HTTPREAD"));
};
  
  
void loop()
{
     if (ledcmd=="1")
     {
     digitalWrite(ledpin, HIGH);
     }
     else
     {
     digitalWrite(ledpin, LOW);
     }
     delay (2000);
}

П.С. строка 27 содержит URL, который преобразовывается в линк на форуме. Может сразу и как боротся с этим подскажете? ;)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

VaGrAm пишет:

раз формат (функционал) портала (форума) позволяет мне постить код с специальной опцией "Убрать вертикальный выравниватель и номерацию строк" то речи быть не может о неприемлемости. 

Ну, раз собачки в парке какают и дероьмо валяется, то и речи быть не может, что в него не стоит вступать.

Я пытаюсь Вам помочь, сделать так, чтобы Ваш код кто-то прочитал и кто-то захотел посмотреть на суть дела. Если Вам это не нужно - я не настаиваю :)))))

VaGrAm
Offline
Зарегистрирован: 11.12.2017

Мне как раз это и нужно - чтоб кто-то помог. Но думаю если кто-то будет смотреть этот топик и по прошествии 5-7-и постов не увидит ничего дельного (кроме как указаний и соблюдений тех или иных правил и повторения того же кода в 3-х разных форматах) то шансов на решение куда меньше чем если осталось бы как есть и между строк (как совет) было бы выдано мне (как новичку форума) мол так писать намного удобнее. В любом случае, все еще надеюсь что кто нибудь вникнет в суть дела и даст дельный совет. И Вам спасибо Евгений, что помогли мне с советом как гулять в парках где много собак (да и с правилами форума ознакомили - это уже без иронии)...

b707
Offline
Зарегистрирован: 26.05.2017

VaGrAm пишет:

Мне как раз это и нужно - чтоб кто-то помог. Но думаю если кто-то будет смотреть этот топик и по прошествии 5-7-и постов не увидит ничего дельного (кроме как указаний и соблюдений тех или иных правил и повторения того же кода в 3-х разных форматах) то шансов на решение куда меньше

Вы правы, читать вашу перепалку с Евгением куда как интереснее, чем разбираться в скетче.

Что касается вопроса - на такие вопросы здесь отвечать не принято.  Почему? - потому что ваш вопрос предполагает, что кто-то возьмет и напишет вам недостающий код. А это неправильно.

На этом форуме принято отвечать на вопросы "Найдите ошибку?". а не "Помогите сделать?". Это предполагпет, что спрашивающий сначала сам попытается решить проблему, напишет код (пусть не работающий, но свой) - а на форум придет задавать вопросы о ошибках в коде, а не о том, как вообще это делается. Для ответов на вопрос "Как?" есть учебники и Гугль.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Вряд ли тебе здесь помогут. Раньше Квон таким как ты помогал, но сейчас ему, похоже, надоело.

А так здесь помогают тем, кто делает сам, т.е. тем, кто пишет что-то типа: "Я вот написал процедуру, но она в таких-то случаях неправильно работает, подскажите где накосячил".

А тем, кто сам не делает, а пишет

VaGrAm пишет:

Нужна промежуточная "процедура"

Здесь отвечают что-нибудь типа "всем нужна, иди в раздел "Ищу исполнителя" и заказывай на коммерческой основе".

Andrey12
Andrey12 аватар
Offline
Зарегистрирован: 26.12.2014

VaGrAm пишет:

Надо на основе "приема" включить/отключить лампу.  Нужна промежуточная "процедура" считывания и присвоения переменной ledcmd ответа выдаваемое в консоль после вызова AT+HTTPREAD (1 или 0). В "ручном" режиме (ручном вводе АТ комманд) после AT+HTTPREAD выдается результат:

+HTTPREAD:1
1
OK
 
 
На просторах интернета есть подобные задачи и решения, но уже который день тестирую их: ни с одним не удалось достичь результата.
 
Заранее спасибо за любую помошь и совет.

А что выдает программа? После команды 

 gsm.SimpleWriteln(("AT+HTTPREAD"));

Какой ответ получаете?

И опять же после каждой из команд модему приходит ответ? Если вы не дожидаясь ответа отправляете следующую команду то результат будет непредсказуем :-( На время выполнения отводится 0,1 скеунда "delay(100)", я в настройках GPRS не силен, но вот если смс отправляю модем иногда и на 1-2 секунды задумывается. То есть сначала надо убедится что на все команды SIM900 реагирует как вам надо, а потом уже парсить тот ответ что вам нужен.

С ручным вводом все понятно, там вы ввели и ждете визуально ответ, а в скетче вы его не ждете, а думаете что за 0,1 сек придет ответ ОК для каждой из команд.

VaGrAm
Offline
Зарегистрирован: 11.12.2017

Коллеги, я специально не запостил десятки (без преувеличения) версии той процедуры которую написал/модифицировал и которая не дает результат а оставил место между setup и loop чтоб кто-то без мусора (в моем коде) помог написать эти 10 строк. Кстати, с которым думаю сталкивался практически любой начинающий разработчик связки Arduino/GSM Shield (коим я не являюсь и волей судьбы столкнулся с конкретной задачей) или же дал совет куда копать (пользоватся Гуглом тоже умею - не туда путь искал обращаясь сюда). Что до "спрашивающий сначала сам попытается решить проблему": уже неделю как столкнулся с этими платами именно над этим и тружусь (может вам и историю браузера выложить тут?) и по прошествии недели решил обратися к более опытным. Но даже и не думал что некоторые из них вместо того чтоб давать советы (если могут) будут гнатся за формальностями как в ЖКХ - бланки, бумаги, форматы и порядки постановки вопроса. Что до "Вряд ли тебе здесь помогут" и "на такие вопросы здесь отвечать не принято": не хочешь отвечать: пройди мимо. Кто-то может и поможет, буду благодарен. Сам найду ответ, выложу тут. Может кому-то как я понадобится. По крайней мере я не сижу сложа руки пока кто-то тут выложит код. Более того: из-за этой "перепалки с Евгением" к которой стягивается масса указывающих на образ жизни и так теряю достаточно времени которую мог бы потратить на что-то приближающее меня к решению задач.

Итог: не можешь помочь, не мешай...

b707
Offline
Зарегистрирован: 26.05.2017

VaGrAm пишет:

Сам найду ответ, выложу тут. Может кому-то как я понадобится.

Итог: не можешь помочь, не мешай...

Помогаю.

Вы правы насчет того, что с вашей проблемой сталкивается любой начинающий разработчик связки Arduino/GSM Shield.  И потому ваша задача разобрана в инете десятки раз. Каждый мало-мальский серьезный проектс с использованием ГСМ-модема содержит пример нужного вам кода.

VaGrAm
Offline
Зарегистрирован: 11.12.2017

Спасибо Андрей за ответ. Да, после каждой команды приходит ответ. delay (100) это один из этапов модификаций кода. На практике вплоть до 10сек задержку ставил именно предпалагаю что может быть опоздание ответа. В ручном режиме ответ выдается сразу же (может через секунду). Что получаю в консоли в ручном режиме: писал...

+HTTPREAD:1
1
OK
 
Мне нужно эту самую 2-ую строку запарсить. Разными способами присваиваю его переменным и далее вывожу их в консоль для контроля: получаю какие-то символы или же цифры. Такое впечатление что что-то с настройками serial-ов.
VaGrAm
Offline
Зарегистрирован: 11.12.2017

b707 пишет:

Помогаю.

Вы правы насчет того, что с вашей проблемой сталкивается любой начинающий разработчик связки Arduino/GSM Shield.  И потому ваша задача разобрана в инете десятки раз. Каждый мало-мальский серьезный проектс с использованием ГСМ-модема содержит пример нужного вам кода.

Вот и я об этом писал. В инете сотни РАЗНЫХ реализаций моей задачи. Неделю именно их и перебирал, модифицировал, делал свое на их основе. Результат всегда разный и какой-то не правильный (в прошлом сообщении написал: думаю что-то не то с serial привязкой). Поэтому и попросил тут помочь: чтоб кто-то предложил конкретно проверенный вариант и на основе его и продолжили общение (если самому не удастся подогнать его под себя).

b707
Offline
Зарегистрирован: 26.05.2017

VaGrAm пишет:

 
Мне нужно эту самую 2-ую строку запарсить. Разными способами присваиваю его переменным и далее вывожу их в консоль для контроля: получаю какие-то символы или же цифры. Такое впечатление что что-то с настройками serial-ов.

выкладывайте код, как "разными способами" присваивали переменной.

До вас никак не дойдет, что без вашего кода разговора не будет.

Andrey12
Andrey12 аватар
Offline
Зарегистрирован: 26.12.2014

VaGrAm пишет:

Спасибо Андрей за ответ. Да, после каждой команды приходит ответ. delay (100) это один из этапов модификаций кода. На практике вплоть до 10сек задержку ставил именно предпалагаю что может быть опоздание ответа. В ручном режиме ответ выдается сразу же (может через секунду). Что получаю в консоли в ручном режиме: писал...

+HTTPREAD:1
1
OK
 
Мне нужно эту самую 2-ую строку запарсить. Разными способами присваиваю его переменным и далее вывожу их в консоль для контроля: получаю какие-то символы или же цифры. Такое впечатление что что-то с настройками serial-ов.

Готового решения никто не предложит. Ваш код загрузил в IDE ну и соответственно ошибки полезли. Да это ладно. Все равно на работе SIM 900 нету.

Как вариант чтобы помогли надо привести код который компилируется. Ну и что выдаются какието цифры буквы но не те что надо. Тогда может кто либо и поможет как вам уже и выше писали. 
А готовое решение тут никто не выложит, времени нет разбираться и писать код, а комммерсы из "Ищу исполнителя" тоже не будут его писать по вполне понятным причинам. 
Так что будет один глумеж. Выход один выкладываете то что у вас выводит непонятные цифры буквы при парсинге, тогда может и будут разбираться.

VaGrAm
Offline
Зарегистрирован: 11.12.2017

Ниже полный код одного из версий попытки считывания. Давайте обсуждать его...

#include <SoftwareSerial.h>

SoftwareSerial gsmserial(2,3);
int ledpin = 11;
char responce[100];
int count=0;

 
void setup()
{
     pinMode(ledpin, OUTPUT);
     
     gsmserial.begin(9600);
     Serial.begin(9600);
     
     Serial.println("Setting up GPRS");
     
     gsmserial.println(("AT+SAPBR=3,1,\"Contype\",\"GPRS\""));
     delay(1000);
     serialread();
     clearbuffer();
     
     gsmserial.println(("AT+SAPBR=3,1,\"APN\",\"internet.beeline.am\""));
     delay(1000);
     serialread();
     clearbuffer();
     
     gsmserial.println(("AT+SAPBR =1,1"));
     delay(1000);
     serialread();
     clearbuffer();
     
     gsmserial.println(("AT+HTTPINIT"));
     delay(1000);
     serialread();
     clearbuffer();
     
     gsmserial.println(("AT+HTTPPARA=\"CID\",1"));
     delay(1000);
     serialread();
     clearbuffer();
     
     gsmserial.println(("AT+HTTPPARA=\"URL\",\"http://www.55tele.com/arduino.php?name=ALARM\""));
     delay(1000);
     serialread();
     clearbuffer();
     
     gsmserial.println(("AT+HTTPACTION=0"));
     delay(1000);
     serialread();
     clearbuffer();
     
     Serial.println("GPRS ready");
     
     gsmserial.println(("AT+HTTPREAD"));
     delay(1000);
     serialread();
};

void serialread()
{
     while(gsmserial.available())
     {
            responce[count++]=gsmserial.read();
            if(count == 100) break;
     }
     count = 0;
};

void clearbuffer()
{
    for (int i=0; i<count; i++)
    {
      responce[i]=(char)0;
    }
}

void loop()
{
     if (responce[0]=='1')
     {
     digitalWrite(ledpin, HIGH);
     }
     else
     {
     digitalWrite(ledpin, LOW);
     }
     Serial.println("Current buffer is:");
     Serial.println(responce);
     delay (2000);
}

В serialread() считываю порты.

В clearbuffer() сбрасываю то что считалось (обнуляю после каждой AT комманды кроме последней)

В loop-е помимо проверки для контроля вывожу то что считалось. По идее должно быть послений вывод (AT+HTTPREAD) но на выводе получается что-то из предпоследних (лобо что-то миксированное):

Current buffer is:
AT+HTTPREAD
 
OK
 
+HTTPACTION:0,200,1
rduino.php?name=ALARM
 
Просьба помочь разобратся: где что сделал не так.
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

clearbuffer  не работает никогда.

В конце serialread (в строке 67) Вы устанавливаете count d 0. Соответственно, цикл в строках 72-75 не выполняется ни разу, т.к. i (рвыное 0) с самого начала НЕ МЕНЬШЕ count, тоже равного 0.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

ТС, вам принципиально (только мое ИМХО) нужно менять логику: не пытаться вытащить ответы от модема и понять что он отвечает, а сделать некую таблицу (в голове / на бумаге, а потом уже в МК) - недавно обсуждали подобие "робот состояний".

Например:

команда Х может выдать ответы Y Z C, т.е. послали команду, в цикле посмоянно смотрите ответ его парсите и уже в зависимости от ответа делайте действия.

и так далее, не нужно надеяться что после некой команды придет ответ именно на нее, может придти ответ на предыдущую или первую команду....

b707
Offline
Зарегистрирован: 26.05.2017

andycat пишет:

не нужно надеяться что после некой команды придет ответ именно на нее, может придти ответ на предыдущую или нервую комнду....

Поддерживаю.

И в первую очередь не стоит рассчитывать, что на каждую вашу команду вы будете получать "ОК".

А вы сейчас в своем коде даже этого не проверяете - просто стираете ответ модема и идете дальше.

VaGrAm
Offline
Зарегистрирован: 11.12.2017

Спасибо Евгений за замечание. Это случилось после того как вынес очистку буфера отдельной процедурой.

Принудительно поменял

void clearbuffer()
{
    for (int i=0; i<100; i++)
    {
      responce[i]=(char)0;
    }
}
Ситуация изменилась но не так как требовалось.
 
Current buffer is:
AT+HTTPREAD
OK
+HTTPACTION:0,200,1
 
То есть выдает ответ предпосленей команды и не полностю то что нужно. В ручном режиме вывод такой:
+HTTPREAD:1
1
OK

 

Andrey12
Andrey12 аватар
Offline
Зарегистрирован: 26.12.2014

ЕвгенийП пишет:

clearbuffer  не работает никогда.

В конце serialread (в строке 67) Вы устанавливаете count d 0. Соответственно, цикл в строках 72-75 не выполняется ни разу, т.к. i (рвыное 0) с самого начала НЕ МЕНЬШЕ count, тоже равного 0.

Насколько я понимаю можно упростить
 

void clearbuffer()
{
      responce[0]=0;
}

Думаю так будет достаточно.

VaGrAm
Offline
Зарегистрирован: 11.12.2017

andycat пишет:

ТС, вам принципиально (только мое ИМХО) нужно менять логику: не пытаться вытащить ответы от модема и понять что он отвечает, а сделать некую таблицу (в голове / на бумаге, а потом уже в МК) - недавно обсуждали подобие "робот состояний".

Прежде чем строить какую-то логику мне пока нужно "вытащить ответы от модема". Я на этом этапе "застрял". Не могу вытащить то что нужно. А как дальше с ним обращатся: это уже другое дело (дело логики).

Andrey12
Andrey12 аватар
Offline
Зарегистрирован: 26.12.2014

andycat пишет:

и так далее, не нужно надеяться что после некой команды придет ответ именно на нее, может придти ответ на предыдущую или первую команду....

А что более непредсказуемо, может прийти звонок входящий или смс, тогда вообще путаница получится :)
И об этом тоже не надо забывать, я о том и писал что не delay(ххх) надо писать, а именно парсить ответ.

Ну тут бы пока разобраться с чтением UART.

VaGrAm
Offline
Зарегистрирован: 11.12.2017

Andrey12 пишет:

А что более непредсказуемо, может прийти звонок входящий или смс, тогда вообще путаница получится :)
И об этом тоже не надо забывать, я о том и писал что не delay(ххх) надо писать, а именно парсить ответ.

Ну тут бы пока разобраться с чтением UART.

Вот именно. Перебирать конечную модель с учетом всех погодных условий пока рано. Мне бы пока запарсить то что идет в serial-е (в ответ на последную AT команду) без каких-либо форс-мажорных обстоятельст (звонок, смс, ответ модема не OK и т.д.)

Andrey12
Andrey12 аватар
Offline
Зарегистрирован: 26.12.2014

Вот такая конструкция точно работать не будет

void serialread()
{
     while(gsmserial.available())
     {
            responce[count++]=gsmserial.read();
            if(count == 100) break;
     }
     count = 0;
};

по одной простой причине, UART может не успеть вам отдать всю строку сразу, и вы получите не все символы из ответа.
То есть gsmserial.available() возвращает количество символов в буфере на момент когда вы обратились там 1 символ вы его считали и вышли из while(gsmserial.available())  в буфере у вас 1 символ, а остальное пройдет мимо кассы. Отсюда и микс.

Вот тут есть небольшая статья как приянть строку из Srerial. То есть надо читать до символа конец строки ('\n'). И тогда у вас в буфере будет именно строка ответа, а не ее часть. Ну при условии что SIM900 завершает строку \r\n по сути это в установках по умолчанию.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

VaGrAm пишет:

Принудительно поменял

void clearbuffer()
{
    for (int i=0; i<100; i++)
    {
      responce[i]=(char)0;
    }
}
Ситуация изменилась но не так как требовалось.
 
Вы почему-то считаете, что мы бюрократы и "гноимся за формальностями", когда требуем от Вас публиковать вопросы правильно.
 
Вот хоть в этом случае. Откуда мне знать что Вы там поменяли, а именно: где и как Вы теперь сбрасываете Ваш count в 0? Или нигде? Публикойте код нормально и полностью, так ведь невозможно работать.
b707
Offline
Зарегистрирован: 26.05.2017

VaGrAm пишет:

Current buffer is:

AT+HTTPREAD
OK
+HTTPACTION:0,200,1
 
То есть выдает ответ предпосленей команды и не полностю то что нужно. В ручном режиме вывод такой:

Похоже все-таки не успевает. То есть к моменту подачи команды HTTPREAD модем еще только выдает ответ на HTTPACTION. Попробуйте после подачи всех команд читать ответ не один раз, как у вас в программе - а в в бесконечном цикле, выводя все полученное в Сериал.

VaGrAm
Offline
Зарегистрирован: 11.12.2017

ЕвгенийП пишет:

Вы почему-то считаете, что мы бюрократы и "гноимся за формальностями", когда требуем от Вас публиковать вопросы правильно.

Вот хоть в этом случае. Откуда мне знать что Вы там поменяли, а именно: где и как Вы теперь сбрасываете Ваш count в 0? Или нигде? Публикойте код нормально и полностью, так ведь невозможно работать.

Я поменял только то, что опубликовал (параметры в цикле for).

Но для верности вот полный код (посто не хотел раз за разом в топик заливать тот же длинный код)

#include <SoftwareSerial.h>

SoftwareSerial gsmserial(2,3);
int ledpin = 11;
char responce[100];
int count=0;

 
void setup()
{
     pinMode(ledpin, OUTPUT);
     
     gsmserial.begin(9600);
     Serial.begin(9600);
     
     Serial.println("Setting up GPRS");
     
     gsmserial.println(("AT+SAPBR=3,1,\"Contype\",\"GPRS\""));
     delay(1000);
     serialread();
     clearbuffer();
     
     gsmserial.println(("AT+SAPBR=3,1,\"APN\",\"internet.beeline.am\""));
     delay(1000);
     serialread();
     clearbuffer();
     
     gsmserial.println(("AT+SAPBR =1,1"));
     delay(1000);
     serialread();
     clearbuffer();
     /*
     gsmserial.println(("AT+HTTPINIT"));
     delay(1000);
     serialread();
     clearbuffer();
     
     gsmserial.println(("AT+HTTPPARA=\"CID\",1"));
     delay(1000);
     serialread();
     clearbuffer();
     */
     gsmserial.println(("AT+HTTPPARA=\"URL\",\"http://www.55tele.com/arduino.php?name=ALARM\""));
     delay(1000);
     serialread();
     clearbuffer();
     
     gsmserial.println(("AT+HTTPACTION=0"));
     delay(1000);
     serialread();
     clearbuffer();
     
     Serial.println("GPRS ready");
     
     gsmserial.println(("AT+HTTPREAD"));
     delay(1000);
     serialread();
};

void serialread()
{
     while(gsmserial.available())
     {
            responce[count++]=gsmserial.read();
            if(count == 100) break;
     }
     count = 0;
};

void clearbuffer()
{
    for (int i=0; i<100; i++)
    {
      responce[i]=(char)0;
    }
}

void loop()
{
     
     if (responce[0]=='1')
     {
     digitalWrite(ledpin, HIGH);
     }
     else
     {
     digitalWrite(ledpin, LOW);
     }
     
     Serial.println("Current buffer is:");
     Serial.println(responce);
     delay (2000);
}

 

VaGrAm
Offline
Зарегистрирован: 11.12.2017

b707 пишет:

Похоже все-таки не успевает. То есть к моменту подачи команды HTTPREAD модем еще только выдает ответ на HTTPACTION. Попробуйте после подачи всех команд читать ответ не один раз, как у вас в программе - а в в бесконечном цикле, выводя все полученное в Сериал.

Сейчас попробую как посоветовали. А может еще и delay после всех AT увеличить раз не успевает?

Кстати, увеличение скорости serial-ов до 19200 выдает вообще пустой результат.

Setting up GPRS
GPRS ready
Current buffer is:
 
Current buffer is:
 
Current buffer is:
 
А 4800: непонятную информацию (f⸮~`f⸮⸮⸮~⸮⸮⸮`). Скорость в мониторе менял :)
Но http запрос до сервера доходит (модем отвечает и на связи).
b707
Offline
Зарегистрирован: 26.05.2017

VaGrAm пишет:

Сейчас попробую как посоветовали. А может еще и delay после всех AT увеличить раз не успевает?

Нет, задержку увеличивать не надо - это неверный путь. Правильнее все-таки знать, какая строка должна придти в ответ - и парсить ответ от модема на предмет получение этой строки. Тогда у вас не будет ситуации, что вы на команду получаете отклик от предыдущей. Совет от Andrey12 ждать конца строки вам задает правильное направление , надо только учитывать, что у вас модем отвечает несколькими строчками и конец строки не всегда конец сообщения.

Andrey12
Andrey12 аватар
Offline
Зарегистрирован: 26.12.2014

VaGrAm пишет:

Сейчас попробую как посоветовали. А может еще и delay после всех AT увеличить раз не успевает?

Кстати, увеличение скорости serial-ов до 19200 выдает вообще пустой результат.

 
Дело не в delay, почитайте еще раз статью которую я привел в 25 посте.
Увеличение скорости выше 9600 у софтового UART у меня вообще не работает, ну в смысле нормально. Хотя на форуме писали, что стабильно работает до 38400.
 
А настройка скорости у SIM900 какая? Авто?
Andrey12
Andrey12 аватар
Offline
Зарегистрирован: 26.12.2014

b707 пишет:

Совет от Andrey12 ждать конца строки вам задает правильное направление , надо только учитывать, что у вас модем отвечает несколькими строчками и конец строки не всегда конец сообщения.

Это да, но дальше уже тема парсинга, а пока пытаемся прочитать правильно.

VaGrAm
Offline
Зарегистрирован: 11.12.2017

b707 пишет:

Нет, задержку увеличивать не надо - это неверный путь. 

Согласен, но установив везде delay в 5 секунд получил то что надо:

Current buffer is:
+HTTPREAD:1
1
OK
 
Значит Ваше предположение верное: что-то не успевает. Удалю delay-и пойдем другим путем: будем парсить до получения +HTTPREAD:1 и последующих...
VaGrAm
Offline
Зарегистрирован: 11.12.2017

Andrey12 пишет:

Дело не в delay, почитайте еще раз статью которую я привел в 25 посте.
Увеличение скорости выше 9600 у софтового UART у меня вообще не работает, ну в смысле нормально. Хотя на форуме писали, что стабильно работает до 38400.
 
А настройка скорости у SIM900 какая? Авто?

Именно delay и помог. Но как-то не комфортно так работать. Слишком долго ждать. Будем искать другой путь. Что до скорости модема: честно говоря не знаю. Как сказал только неделю назад волей судьбы пришлось столкнутся с Arduino+SIM900. Если подскажете где смотреть: посмотрю.

Andrey12
Andrey12 аватар
Offline
Зарегистрирован: 26.12.2014

VaGrAm пишет:

Согласен, но установив везде delay в 5 секунд получил то что надо:

Current buffer is:
+HTTPREAD:1
1
OK
 
Значит Ваше предположение верное: что-то не успевает. Удалю delay-и пойдем другим путем: будем парсить до получения +HTTPREAD:1 и последующих...

Как вариант с костылем попробуйте

void serialread()
{
     while(gsmserial.available())
     {
            responce[count++]=gsmserial.read();
            delay(10);
            if(count == 100) break;
     }
     count = 0;
};

про скорость

команда 
AT+IPR?
ответ 
+IPR: 0
OK
 
Скорость порта:
0 – автоматически
1200
2400
4800
9600
19200
38400
57600
115200
VaGrAm
Offline
Зарегистрирован: 11.12.2017

Andrey12 пишет:

Как вариант с костылем попробуйте

void serialread()
{
     while(gsmserial.available())
     {
            responce[count++]=gsmserial.read();
            delay(10);
            if(count == 100) break;
     }
     count = 0;
};

не помогло...

Andrey12 пишет:

про скорость

команда 
AT+IPR?
ответ 
+IPR: 0
OK

Получается +IPR: 9600
А если попробовать его увеличить может модем успевать за AT командами?
b707
Offline
Зарегистрирован: 26.05.2017

VaGrAm пишет:

А если попробовать его увеличить может модем успевать за AT командами?

это все равно "костыль".

Парсинг ответов - единственный правильный путь.

Andrey12
Andrey12 аватар
Offline
Зарегистрирован: 26.12.2014

VaGrAm пишет:

не помогло...

Получается +IPR: 9600

А если попробовать его увеличить может модем успевать за AT командами?

Ну костыли на то и костыли что помогают не всегда. 
У меня стоит 0, то есть автоопределение скорости, работает пока нормально.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

b707 пишет:

Парсинг ответов - единственный правильный путь.

+100500!

И если не терять время на костыли, то его давно уже можно было сделать.

VaGrAm
Offline
Зарегистрирован: 11.12.2017

Спасибо всем за советы. Сегодня попробую сделать парсинг до требуемой строки. На стороне сервера могу сделать так же чтоб вместо 0 или 1 выдавал что-то определенное с ключем: типа LED:0 или LED:1. Буду искать слово LED в ответах. По ходу буду отписыватся...

kostyamat
Offline
Зарегистрирован: 16.11.2017
bool SendAT(String _str, String _answer, uint8_t _try, unsigned long _time) {
  String _val;
  unsigned long starttime, endtime;
  starttime = millis();
  do {
    endtime = millis();
    GSMmodem.println(_str);
    digitalWrite(RLed, HIGH);
    delay(_time / _try);
    while (GSMmodem.available()) {  //сохраняем входную строку в переменную val
      ch = GSMmodem.read();
      _val += char(ch);
      delay(0);
      if (_val.indexOf(_answer) > -1) {
        digitalWrite(RLed, LOW);
        delay(50);
        digitalWrite(RLed, HIGH);
        delay(50);
        digitalWrite(RLed, RLedState);
        return true;
        break;

      }
    }
    digitalWrite(RLed, LOW);
  } while ((endtime - starttime) <= _time);
  return false;
}

Вот, для себя делал функцию для парсинга ответа модема.

Пользоваться примерно вот так

  while (!SendAT("AT", "OK", 5, 500)) {
    Serial.print(F("."));
  }

 

Первый параметр - команда, которую шлем

Второй - какой ответ ожидаем

Третий - столько раз шлем команду за тот период времени, который указан в четвертом параметре.

Четвертый параметр -  максимальный срок ожидания корректноего ответа. То-есть, вы можете задать период ожидания скажем 2000 миллисекунд, но модем ответил правильно через 200, значит и функция завершится сразу посде получения ожидаемого ответа, возвращая true.

Но, если ответ модема не тот, что мы ожидаем, то функция будет продолжать ожидать до конца строка и завершится через 2000 миллисекунд, возвращаю false.

Если вам не нравится поведение функции, вы вольны менять ее по своему усмотрению. ))

Фактически, третий параметр, нормально, должен быть равен 1, но повторная отправка команды несколько раз, за некий период времени, иногда бывает полезна, как в случае команды AT, когда модем в режиме автоматического выбора скорости. Вверху как раз такой случай.

Или вот:

if (SendAT("AT+CREG?", ",1", 1, 500) {

   Serial.println(F("Modem ready for voice calls."));

}

ПС. К гуру: Да, это быдлокод, да, я тоже еще только учусь. ))