работа с sim900
- Войдите на сайт для отправки комментариев
Втр, 26/04/2016 - 15:55
Добрый день. Я начинающий ардуино аматор. Знаю несколько ЯП но вот с СИ у меня проблемы. Пишу на ардуино взаимодействие gsm sim900 шилда с реле питания. Как на асперке про умную gsm розетку.
Столкнулся с проблемой приема смс.
#include <SoftwareSerial.h> SoftwareSerial GPRS(7, 8); // gsm power pin #define gsm_power 9 // пины, к которым подключены реле #define RELAY1 3 #define RELAY2 4 #define RELAY3 5 #define RELAY4 6 unsigned char buffer[64]; // buffer array for data recieve over serial port int count=0; // counter for buffer array #define phone "+37529XXXXXXX" #define msg "Sheeld started!" void setup() { //Старт консолек GPRS.begin(19200); // the GPRS baud rate Serial.begin(19200); // the Serial port of Arduino baud rate. // настраиваем пины реле в режим выхода, pinMode(RELAY1, OUTPUT);digitalWrite(RELAY1, HIGH); pinMode(RELAY2, OUTPUT);digitalWrite(RELAY2, HIGH); pinMode(RELAY3, OUTPUT);digitalWrite(RELAY3, HIGH); pinMode(RELAY4, OUTPUT);digitalWrite(RELAY4, HIGH); pinMode(gsm_power, OUTPUT); delay(500); // стартуем Шилд SIM900power(); sendsms(); } void loop() { Serial.println("Loop\n"); delay(1000); if (GPRS.available()) // if date is comming from softwareserial port ==> data is comming from gprs shield { while(GPRS.available()) // reading data into char array { buffer[count++]=GPRS.read(); // writing data into array if(count == 64)break; } Serial.write(buffer,count); // if no data transmission ends, write buffer to hardware serial port clearBufferArray(); // call clearBufferArray function to clear the storaged data from the array count = 0; // set counter of while loop to zero } if (Serial.available()) // if data is available on hardwareserial port ==> data is comming from PC or notebook GPRS.write(Serial.read()); // write it to the GPRS shield } void SIM900power() // software equivalent of pressing the GSM shield "power" button { // Стартуем GSM шилд Serial.println("Join to poweron sheeld\n"); digitalWrite(gsm_power, LOW); delay(1000); digitalWrite(gsm_power, HIGH); delay(2500); digitalWrite(gsm_power, LOW); delay(10000); // Инициализируем правильными командами симку Serial.println("Tuning SimCard\n"); GPRS.println("AT+CMGF=1\r"); delay(100); GPRS.println("AT+CSCS=\"GSM\""); delay(100); GPRS.println("AT+IFC=1,1"); delay(100); GPRS.println("AT+CNMI=1,2,2,1,0"); delay(100); } void sendsms() { Serial.println("Join to send SMS\n"); GPRS.print(F("AT+CMGS=\"")); delay(100); GPRS.print(phone); delay(100); GPRS.println("\""); delay(100); GPRS.print(msg); delay(100); GPRS.println((char)26); delay(100); GPRS.println(); } void clearBufferArray() // function to clear buffer array { for (int i=0; i<count;i++) { buffer[i]=NULL;} // clear all index of array with command NULL }
Включается ардуинка. Включается реле. Включается gsm шилд, коннектится к сети. СМС не шлет и не читает. Заливаю скетч где прямой вывод команд в шилд. Ввожу эти же команды руками. СМС отправляется. Подскажите что делаю не так? Как правильно сделать взаимодействие с gsm шилдом? Может готовая библиотека есть без такнцев с бубном?
Мне кажется, у Вас в строках 82-86 кавычек вокруг phone слишком много.
Я уже думал над этим. Вроде как правильно там все.
Я пробовал еще вот так передавать телефон:
Не помогает.
Я не это имел в виду, смотрите, вот текст рабочей функции отправки SMS, работает без кавычек :
UPD: Уточню, у меня Siemens TC35.
10000 после старта может быть маловато, лучше по-больше с запасом сделать (15000-30000), и потом команды по 100, тоже может быть мало, надо для пробы по-больше поставить (1000-5000), а чтобы по-точнее можно когда вручную отправляете команды посмотреть на какие сразу ответ приходит, там может по-меньше сделать задержку, а где по-дольше по-больше..., но вообще это, конечно, неправильно, надо именно ждать ответа, а не делать задержку с запасом, но это сложнее...
Попробовал с вашим вариантом pastebin
СМС не пришло. В консоли:
Join to poweron sheeld
Tuning SimCard
Sending SMS!
Loop
ЪЪЪЪ
RDY
+CFUN: 1
+CPIN: READY
AT+CMGF=1
OK
AT+CSLoop
Call Ready
Loop
Loop
Loop
Loop
Чтобы лучше видеть ответы модема, попробуйте этот скетч запустить (правил "вслепую", надеюсь, нигде не налажал)))
Извините за долгое отсутствие. Опробовал ваш пример:
Tuning SimCard
02552552552552552551310826889131013104367708578583249131013104367807378583282696568891310658443677771706149131310131079751310
658443678367836134718377341310131079751310
658443737067614944491310131079751310
65844367787773614944504450444944481310131079751310
Sending SMS!
6584436777718361435155535057495455495048551310131069828279821310
7310932115116971141161011003313102613
Loop
131067971081083282101971001211310
Loop
Loop
Loop
Нашел в чем ошибка отправки смс.
Не хватало закрывающей кавычки. СМС-ка была отправлена при включении. Продолжаем приключения. В ответ я отправил смс со своего телефона. В консоли выдало следующее:
Loop
Loop
+CMT: "+37529XXXXXXX","!5@359 /@5F","16/05/03,11:50Loop
Loop
Я понимаю, что произошло событие, которое было отображено в консоли. т.е. с номера XXXXXXX пришло сообщение. Но не отобразолось какое сообщение. Теперь если я верно понимаю нужно отслеживать буфер ответов. Если в буфере не пусто - вызывать цикл чтения/удаления сообщений.
Если у кого есть чтение сообщений на AT кодах - очень прошу поделиться. А то изобретать велосипед не весело.
Помогите пожалуйста с простым вопросом.
имеем:
char number[20];
далее по коду number заполняется данными и проверяем
sms.GetSMS(position, number, smsbuffer, 100);
Serial.print("\"");Serial.print(number);Serial.println("\"");
Serial.println(smsbuffer);
if ((number == "+375291111111") or (number == "+375442222222")) {
setRelay(number, smsbuffer);
} else {
Serial.println("Unregistered number!");
}
В консоли имеем:
"+375291111111"
Status
Unregistered number!
Почему проверку не проходит?
упростите код, и проверяйте кусками, вы хотите все сразу чтоб заработало, так не бывает.
Вместо
if ((number == "+375291111111") or (number == "+375442222222"))
// это НЕ будет работать для char number[20]
// Почему здесь "or", а не "||" ??
напишите
if ( (strstr(number, "+375291111111") != 0) || (strstr(number, "+375292222222") != 0) )
// это будет работать для char number[20]
кто может подсказать, а если к примру хочется иметь вариант:
не как: sendsms(
"+37529XXXXXXX"
,
"Im started!"
); а -
sendsms(
"phone"
,
"Im started!"
);
то нужно обьявлять не #define phone "+37529XXXXXXX" а int phone "+37529XXXXXXX" ?
или в первом варианте тоже будет работать, как поступать?
кто может подсказать, а если к примру хочется иметь вариант:
не как: sendsms(
"+37529XXXXXXX"
,
"Im started!"
); а -
sendsms(
"phone"
,
"Im started!"
);
то нужно обьявлять не #define phone "+37529XXXXXXX" а int phone "+37529XXXXXXX" ?
или в первом варианте тоже будет работать, как поступать?
int phone "+37529XXXXXXX" - это бессмыслица какая-то.
sendsms(
"phone"
,
"Im started!"
); - работает. Я так и делаю местами.
Только объявлять нужно #define phone "+37529XXXXXXX"
А вызывать sms.SendSMS(phone, "Im started!");
А еще можно просто sms.SendSMS("+375291111111", "Im started!"); и ничего выше не объявлять.
Araris
Проверять вхождение подстроки в строку... Я думал о таком варианте, но посчитал, что это не джедайский путь. Спасибо :)
Вроде все доделал. Работает. Заняло слишком много динамической памяти. Закоментил свои отладочные выводы. Сократил до 69%.
Скетч полностью рабочий. Сделал на библиотеке. Просто невнимательно сразу к либам относился и не понимал почему не работает. Сделал на BETA_GSM_GPRS_GPS_IDE100_v305. Желающие критиковать и понтоваться - могут идти лесом. Это первый опыт программирования на си.
Тем же кто по существу может подсказать как сделать лучше и надежнее - огромный респект и благодарность.
Отдельно хочу сказать спасибо Araris. Вы реально помогаете и несете добро и свет. Пусть ваш путь устилает наша благодарность и улыбки окружающих вас людей.
Максимально все коментировал что бы было понятнее что и где делается. В power шилде у меня все подключено на по умолчанию включенные клемики. Так нужно.
Что хотел бы доделать:
1. в loop хотелось бы сделать проверку ответов gsm шилда. Что бы не бросать в него тупо команды, а проверять в сети ли он и отвечает ли вообще. Не знаю на сколько он надежный но боюсь что будет летом перегреваться.
2. Было бы не плохо сделать какую-то оптимизацию в setRelay. Но мой опыт программирования пока не позволяет это сделать должным образом.
эээ смс будет иногда жестоко опаздывать. я бы по дтмф делал.
и в ответ не нужно смс слать которые обычно стоят доп. денег.
Извините за долгое отсутствие. Опробовал ваш пример:
Tuning SimCard
02552552552552552551310826889131013104367708578583249131013104367807378583282696568891310658443677771706149131310131079751310
658443678367836134718377341310131079751310
658443737067614944491310131079751310
65844367787773614944504450444944481310131079751310
Sending SMS!
6584436777718361435155535057495455495048551310131069828279821310
7310932115116971141161011003313102613
Loop
131067971081083282101971001211310
Loop
Loop
Loop
я тоже попробовал куски кода, так вот такой ответ почму то дает этот кусочек:
вот не вьеду - а почему ответ на это приходит куча цифр если должны быть ответы типа "ОК" ???.
если в терминалке этому же устройству давать ат команду, то модуль по прежнему "ОК" отвечает.
Не разгадал пока эту загадку, цифровые расширенные ответы?? а почему?
Попробуйте вместо
Serial
.print(GPRS.read());
поставитьSerial
.print((char)GPRS.read());
о, да, заработало, таки предыдущая команда на другом уровне инфу с порта вытаскивает, я так понял.
а кусочек интересный, им можно просматривать ответы при отладке.
в loop хотелось бы сделать проверку ответов gsm шилда. Что бы не бросать в него тупо команды, а проверять в сети ли он и отвечает ли вообще. Не знаю на сколько он надежный но боюсь что будет летом перегреваться.
В библиотеке SIM900 есть функция
char SendATCmdWaitResp (char const* AT_cmd_string, uint16_t start_comm_tmout, uint16_t max_interchar_tmout, char const* response_string,byte no_of_attempts)
Описание:
Sends an AT command passed as a parameter, controlling the time of timeout for the receipt of a response and between one character and another. After receiving the response, compares it with that expected, if different resends the command for the set number of times.The possible outputs are shown below, with the relative enumeration. AT_RESP_ERR_NO_RESP or -1: No response received.AT_RESP_ERR_DIF_RESP or 0: Response different from that expected.AT_RESP_OK or 1: The response contains the expected string.
Пример использования:
If (gsm.SendATCmdWaitResp (“AT”,500,50,”OK”,3) == AT_RESP_OK)
Serial.println(“OK”);
Если периодически посылать через неё, например, команду AT+CREG?, то очень даже контроль состояния шилда получится.
AT+CREG? — получить тип регистрации в сети.
Ответ : что-то вроде +CREG: 0,1
Где:
0, — нет сообщения о смене регистрации в сети.
1, — текущее состояние.