GSM A6 вопрос про RING
- Войдите на сайт для отправки комментариев
Пнд, 26/09/2016 - 21:02
Заказал потестить GSM модуль A6 такой. Пказался очень достойной заменой M590. При не на много большей цене - больше функционал и меньше энергопотребление.
Пока едет, подробнее полистал доступные доки - не нашел есть ли в нем аналог ноги RING в M590? Т.е. GSM модуль работает автономно, а при получении SMS или входящем звонке будит МК дергая ногу RING.
Только получил пару A6C, сейчас разбираюсь. И похоже один дохлый. Что мешает будить МК от COM порта.
Только получил пару A6C, сейчас разбираюсь. И похоже один дохлый. Что мешает будить МК от COM порта.
Точняк)) Мешает разве что религия воспитанная спец ногой на М590)))
A6C - это который с камерой? А, если не сложно, поделитесь доками про него. С пол пинка сейчас не нашел.
Здесь про все http://www.electrodragon.com/w/GSM_GPRS_A6_Module
А есть готовые библиотеки под этот модуль?
Там ни к чему библиотека. Он управляется АТ командами в духе:
Serial.println("AT+CLIP=1"); //включаем АОНСписок поддерживаемых команд есть в приведенной выше ссылке (спасибо!).
Что он нам отвечает тоже ловим с сериала, и разбираем в соответствии с задачами.
Спасибо, придет - буду разбираться.
Разбираюсь с этим модулем и не могу разобраться с чтением смс. Ранее стоял МС35 там все работало.
суть вопроса. отравляю несколько смс на модуль.
модуль принимает но не сохраняет их.
вот к примеру три подряд полученных смс:
+CIEV: "MESSAGE",1
+CMT: "+790********",,"2016/10/31,19:46:29+03
test1
+CIEV: "MESSAGE",1
+CMT: "+790********",,"2016/10/31,19:46:32+03
test2
+CIEV: "MESSAGE",1
+CMT: "+790********",,"2016/10/31,19:46:34+03
test3
везде смс в ячейке 1....
при попытке чтения выдает ошибку.
at+cmgr=1
+CMS ERROR:321
и так по любой ячейке..... никто не разбирался?
Разбираюсь с этим модулем и не могу разобраться с чтением смс. Ранее стоял МС35 там все работало.
суть вопроса. отравляю несколько смс на модуль.
модуль принимает но не сохраняет их.
вот к примеру три подряд полученных смс:
+CIEV: "MESSAGE",1
+CMT: "+790********",,"2016/10/31,19:46:29+03
test1
+CIEV: "MESSAGE",1
+CMT: "+790********",,"2016/10/31,19:46:32+03
test2
+CIEV: "MESSAGE",1
+CMT: "+790********",,"2016/10/31,19:46:34+03
test3
везде смс в ячейке 1....
при попытке чтения выдает ошибку.
at+cmgr=1
+CMS ERROR:321
и так по любой ячейке..... никто не разбирался?
У меня то же самое, только ошибка +CME ERROR: 58. Причем эту ошибку он выдает на любую команду, даже просто на АТ. Хотя звонить с модуля на другой телефон получается без проблем.
У меня причина все-таки в коде. Уважаемые гуру, подскажите, пожалуйста, где ошибка?
#include <SoftwareSerial.h> SoftwareSerial mySerial(2, 3); // RX, TX int ch = 0; int led = 13; String val = ""; void setup() { delay(2000); //время на инициализацию модуля pinMode(led, OUTPUT); digitalWrite(led, LOW); Serial.begin(9600); //скорость порта Serial.println("GSM tester v1.0"); mySerial.begin(9600); mySerial.println("AT+IPR=9600"); //устанавливаем скорость шилда delay(100); mySerial.println("AT+CLIP=1"); //включаем АОН delay(100); mySerial.println("AT+CMGF=1"); //режим кодировки СМС - обычный (для англ.) delay(100); mySerial.println("AT+CSCS=\"GSM\""); //режим кодировки текста delay(100); } void loop() { if (mySerial.available()) { //если GSM модуль что-то послал нам, то while (mySerial.available()) { //сохраняем входную строку в переменную val ch = mySerial.read(); val += char(ch); delay(10); } if (val.indexOf("RING") > -1) { //если звонок обнаружен, то проверяем номер if (val.indexOf("79000000000") > -1) { //если номер звонящего наш. Укажите свой номер без "+" Serial.println("--- MASTER RING DETECTED ---"); mySerial.println("ATH0"); //разрываем связь digitalWrite(led, HIGH); //включаем светодиод на 3 сек delay(3000); digitalWrite(led, LOW); //выключаем реле } } else Serial.println(val); //печатаем в монитор порта пришедшую строку val = ""; } if (Serial.available()) { //если в мониторе порта ввели что-то while (Serial.available()) { //сохраняем строку в переменную val ch = Serial.read(); val += char(ch); delay(10); } mySerial.println(val); //передача всех команд, набранных в мониторе порта в GSM модуль if (val.indexOf("sendsms") > -1) { //если увидели команду отправки СМС sms(String("hello world"), String("+7900000000")); //отправляем СМС на номер +71234567890 } val = ""; //очищаем } } void sms(String text, String phone) //процедура отправки СМС { Serial.println("SMS send started"); mySerial.println("AT+CMGS=\"" + phone + "\""); delay(500); mySerial.print(text); delay(500); mySerial.print((char)26); delay(500); Serial.println("SMS send complete"); delay(2000); }Команды в setup отрабатываются с ответом ОК, но при вводе команд в мониторе порта выдается ошибка +CME ERROR:58.
Звонок с моего телефона проходит, но не сбрасывается и диод не моргает.
Если закомментить строку 49, то смс мне отправляются без ошибок, но тогда команды в шилд не отправляются.
Модуль А6, плата UNO R3. Модуль подключен Tx на 2, Rx на 3, по другому модуль не отзывался. Питание на модуль подал через USB от телефонной зарядки 1,6а. Земли соединил.
У меня тоже косяки перли ри попытке работать с софтовым сериал и хардовым одновременно. потому сделал проще подключил еще один адаптер FTDI им смотрел что там происходит в обмене между модемом и ардуиной.
У меня логика работы другая я жду извещения о приходе смс и потом читаю из ячейки содержимое.
придется переделывать.
Здравствуйте! Как работает модуль, зависаний нет? Интересно, как вы его запитывали и как согласовали уровни портов? Ведь судя по ссылке, вы взяли голый модуль практически без обвязки...
Я предполагаю всё-так вместо гасящего диода по питанию использовать DC-DC конвертер на 4В, а вот с Rx/Tx портами, под вопросом. Ведь в модуле на входах Стоят ограничительные диоды, как я понимаю на 2,8В, а с Ардуинки приходят уровни 3,3В. В более дорогих модулях на А6, например в том, что ниже на фото, мы видим предобразователь уровней на МАХ232, явно не зря они его ставят? Может поставить на порты внешние стабилитроны на 2,8В дополнительно? Вопрос в том, насколько надежно Ардуинка будет воспринимать уровни 2,8В?
>> может кто дальше продвинулся?
alexlord, ага
там текст в семибитной кодировке
Всем привет, проконсультируйте пожалуйста, требуется в офисе поднять gsm шлюз с 10-20 номерами, вот сижу и ломаю голову, удастся ли подключить 10-20 модулей a6 к arduino. Прошу сильно не пинать, я новичек в этом и хочу разобраться с arduino ну и по возможности поднять данную задумку. Заранее благодарен за консультацию.
А можно сделать в 16bit UCS2, тогда и русские символы будут доступны
AT+CSCS="HEX"
OK
AT+CUSD=1,*100#,15
OK
+CUSD: 2, "00310030002E003000300440002E000A0416043C04380020002A00320034003000230
0200020041F043E043B044304470438002000350030003000300440002E002004370430002004320
43D0438043C043004420435043B044C043D043E04410442044C002000200028003300300440002F0
031003000200434043D0029" ,72
Расшифровка: "10.00р.
Жми *240# Получи 5000р. за внимательность (30р/10 дн)"
Это вывод непосредственно с терминала, модуль подключен к компу напрямую
А дальше либо PDU Converter, вводим в окно "USSD Entry/Display" и ставим "UCS2"
либо ручками Таблица кодировки UCS2 для СМС
сутки тестовой работы с отправкой данных каждые 6 минут на narodmon.ru
отравляю несколько смс на модуль.
модуль принимает но не сохраняет их.
при попытке чтения выдает ошибку.
at+cmgr=1
+CMS ERROR:321
и так по любой ячейке..... никто не разбирался?
В этом модуле по умолчанию не задана настройка куда сохранять входящие СМС, т.е. по умолчанию он их вообще нигде не хранит, ни в памяти ни на СИМ-карте, 3й параметр пустой:
Для того чтобы сохранялись на СИМ-карте нужно дать комманду:
.
>> может кто дальше продвинулся?
alexlord, ага
там текст в семибитной кодировке
Поделитесь пожалуста полным кодом.
...
Поделитесь пожалуста полным кодом.
И я за. Можете оформить в виде функции Decode7bit, у которой на вход два параметра: 1-й ссылка на входной буфер, 2-й ссылка на выходной буфер. Можно и третий - размер выходного буфера, чтобы по памяти не побежать.
Вот моя функция перекодировки.
void Decode7bit(String &instr, String &outstr) { byte reminder = 0; int bitstate = 7; for(int i=0; i<instr.length(); i++) { byte b = instr[i]; byte bb = b << (7 - bitstate); char c = (bb + reminder) & 0x7F; outstr += c; reminder = b >> bitstate; bitstate--; if(bitstate == 0) { char c = reminder; outstr += c; reminder = 0; bitstate = 7; } } }Как пользоваться
//ответ на USSD запрос AT+CUSD=1,#111#,15 if(inputstr.indexOf(F("+CUSD:"))>-1) { //анализируем строку int p1 = inputstr.indexOf(F("\"")); //начало строки int p2 = inputstr.lastIndexOf(F("\"")); //конец строки inputstr = inputstr.substring(p1+1,p2); Serial.println(""); Serial.println("Input string:"); Serial.println(inputstr); String decodestr; Decode7bit(inputstr, decodestr); Serial.println(""); Serial.println("Decode string:"); Serial.println(decodestr); }А вот что получил в терминале
Так вот у меня вопрос что обозначает первый параметр в возвращаемом сообщении (1 или 2)?
Вот моя функция перекодировки.
Большое спасибо. Но у меня в терминале ничего не выходит. можете показать весь код пожалусто , либо хотябы ту часть где идет запрос на USSD , и void Setup ?
Большое спасибо. Но у меня в терминале ничего не выходит. можете показать весь код пожалусто , либо хотябы ту часть где идет запрос на USSD , и void Setup ?
SoftwareSerial gsm(2, 3); // RX, TX String inputstr; void setup() { Serial.begin(9600); //Скорость порта для связи Arduino с компьютером Serial.println("Start module"); gsm.begin(9600); //Скорость порта для связи Arduino с GSM модулем Serial.print("Wait connect to GSM..."); while( !waitConnect( 10000 ) ) { Serial.println("timeout"); Serial.print("Wait connect to GSM..."); } Serial.println("ok"); Serial.print("Wait registration in net..."); while( !waitRegistration( 10000 ) ) { Serial.println("timeout"); Serial.print("Wait registration in net..."); } Serial.println("ok"); gsm.println("AT+CLIP=1"); delay(200); // даём время на усваивание команды gsm.println("AT+CMGF=1"); delay(200); // даём время на усваивание команды gsm.println("AT+CNMI=2,2"); delay(200); // даём время на усваивание команды gsm.println("AT+CUSD=1,#121#,15"); delay(200); // даём время на усваивание команды inputstr = ""; }И цикл программы
void loop() { while(gsm.available()) { char ch=gsm.read(); if( ch == '\r' ) { //ответ на USSD запрос AT+CUSD=1,#111#,15 if(inputstr.indexOf(F("+CUSD:"))>-1) { //анализируем строку int p1 = inputstr.indexOf(F("\"")); //начало строки int p2 = inputstr.lastIndexOf(F("\"")); //конец строки inputstr = inputstr.substring(p1+1,p2); Serial.println(""); Serial.println("Input string:"); Serial.println(inputstr); String decodestr; Decode7bit(inputstr, decodestr); Serial.println(""); Serial.println("Decode string:"); Serial.println(decodestr); } inputstr = ""; } else { inputstr+=ch; } Serial.write(ch); } if (Serial.available()) gsm.write(Serial.read()); }Функции waitConnect и waitRegistration, это ожидание конекта с GSM-модулем, и ожидание регистрации в сети соответственно. Если нужны скину код, но это простой цикл отправки и ожидания ответа опредкоманд.
Функции waitConnect и waitRegistration, это ожидание конекта с GSM-модулем, и ожидание регистрации в сети соответственно. Если нужны скину код, но это простой цикл отправки и ожидания ответа опредкоманд.
Большое спасибо. Очень помогло. Ваш код работает. Единственное добавил переход на скорость 9600. т.к.SoftwareSerial я так понял не особо любит эту скорость. Но почемуто не получается заставить работать по событию например проверять состояние счета при наличии входящего звонка. В сериал летят сплошные иероглифы. Не подскажите в чем проблема?
#include <SoftwareSerial.h> SoftwareSerial gsm(2, 3); // RX, TX String inputstr; boolean ok = false; String str = ""; void setup() { Serial.begin(9600); do { gsm.begin(115200); delay(100); gsm.println(F("ATZ+IPR=9600")); delay(500); gsm.end(); delay(100); gsm.begin(9600); delay(100); gsm.println(F("ATE 0"));//отключаем эхо delay(100); gsm.println(F("AT")); delay(100); str = ""; while (gsm.available()) { char ch1 = gsm.read(); str += ch1; delay(10); } if (str.indexOf(F("OK")) > -1) { ok = true; Serial.println("IPR:9600 OK"); } else { gsm.end(); delay(500); ok = false; Serial.println("IPR not 9600"); } } while (!ok); gsm.println("AT+CLIP=1"); delay(200); // даём время на усваивание команды gsm.println("AT+CMGF=1"); delay(200); // даём время на усваивание команды gsm.println("AT+CNMI=2,2"); delay(200); // даём время на усваивание команды inputstr = ""; Serial.println("Start module"); } void loop() { if (gsm.find("RING")) { gsm.println("ATH"); delay(200); gsm.println("AT+CLIP=0"); delay(200); gsm.println("AT+CUSD=1,#101#,15"); delay(200); while (gsm.available()) { char ch = gsm.read(); if ( ch == '\r' ) { //ответ на USSD запрос AT+CUSD=1,#111#,15 if (inputstr.indexOf(F("+CUSD:")) > -1) { //анализируем строку int p1 = inputstr.indexOf(F("\"")); //начало строки int p2 = inputstr.lastIndexOf(F("\"")); //конец строки inputstr = inputstr.substring(p1 + 1, p2); Serial.println(""); Serial.println("Input string:"); Serial.println(inputstr); String decodestr; Decode7bit(inputstr, decodestr); Serial.println(""); Serial.println("Decode string:"); Serial.println(decodestr); } inputstr = ""; } else { inputstr += ch; } Serial.write(ch); } if (Serial.available()) gsm.write(Serial.read()); } } void Decode7bit(String &instr, String &outstr) { byte reminder = 0; int bitstate = 7; for (int i = 0; i < instr.length(); i++) { byte b = instr[i]; byte bb = b << (7 - bitstate); char c = (bb + reminder) & 0x7F; outstr += c; reminder = b >> bitstate; bitstate--; if (bitstate == 0) { char c = reminder; outstr += c; reminder = 0; bitstate = 7; } } }Надеюсь у тебя GSM модуль A6? Так вот у него автоматическая подстройка частоты сериала, нужно только несколько раз в секунду подать простую команду AT и дождаться на неё OK, при этом посылка команду установки скорости (ATZ+IPR=9600) явно не нужна. Это у меня выполняет функция waitConnect, вот её код:
bool waitConnect(long timeout) { int countok = 0; String str; uint32_t tstart = millis(); while(countok<5) //ждём пять ОК { uint32_t ms = millis(); if( ( ms - tstart) > timeout ) return false; // Событие срабатывающее каждые 500 мс if( ( ms - msAT ) > 500|| ms < msAT ) { msAT = ms; //посылаем команду gsm.println("AT"); str = ""; delay(100); //Ждём ответа while(gsm.available()) { char ch=gsm.read(); str+=ch; } if(str.indexOf(F("OK"))>-1) countok++; else countok = 0; } } return true; }После этого идёт ожидание регистрации в сети. Ответ на команду должен прийти 1,1. Вот код
bool waitRegistration( long timeout ) { bool ok = false; String str; uint32_t tstart = millis(); while(!ok) { uint32_t ms = millis(); if( ( ms - tstart) > timeout ) return false; // Событие срабатывающее каждые 500 мс if( ( ms - msAT ) > 500|| ms < msAT ) { msAT = ms; //посылаем команду gsm.println("AT+CREG?"); delay(100); //Ждём ответа str = ""; while(gsm.available()) { char ch=gsm.read(); str+=ch; } int p = str.indexOf(F("+CREG: ")); int a = 0; int b = 0; if( p > -1 ) { p += 7; str = str.substring(p); a = str.toInt(); p = str.indexOf(F(",")); if( p > -1 ) { p += 1; str = str.substring(p); b = str.toInt(); } } Serial.print(a); Serial.print(","); Serial.print(b); Serial.print(" "); if(a==1 and b==1) ok = true; } } return true; }И только после этого можно отсылать команды настройки, такие как
AT+CLIP=1
AT+CMGF=1
void loop() { while(gsm.available()) { char ch=gsm.read(); if( ch == '\r' ) { //сдесь анализ целой входящей строки //входящий вызов if(inputstr.indexOf(F("RING"))>-1) { countring++; Serial.println(countring); } //ответ на USSD запрос AT+CUSD=1,#111#,15 if(inputstr.indexOf(F("+CUSD:"))>-1) { //анализируем строку int p1 = inputstr.indexOf(F("\"")); //начало строки int p2 = inputstr.lastIndexOf(F("\"")); //конец строки inputstr = inputstr.substring(p1+1,p2); Serial.println(""); Serial.println("Input string:"); Serial.println(inputstr); String decodestr; Decode7bit(inputstr, decodestr); Serial.println(""); Serial.println("Decode string:"); Serial.println(decodestr); } //если хотим ещё что то ловить, то дописываем сдесь // // //после анализа строки очищаем её inputstr = ""; } else { inputstr+=ch; } Serial.write(ch); } if (Serial.available()) //передадим команды из терминала в модуль gsm.write(Serial.read()); if(countring==6) //после 6 входящих RING { countring = 0; //отбить вызов gsm.println("ATH"); delay(100); //Ждём ответа char text[48]; //послать смс статус strcpy(text,"STATUS"); sendTextMessage(text); //посылка sms } }Большое спасибо, за совет. Исправил, все заработало.
Здравствуйте! А кто нибудь запитывал этот модуль от акб 18650 минуя встроенный стабилизатор?
Доброе утро!
Помогите новичку! Заказал GSM модуль A6 mini https://geardx.com/ru/p/gprs-a6-mini-Серийный-gprs-gsm-модуль-ядра-developemnt-совет-для-arduino-443770 , после чего обратил внимание, что у нет примеров подключения. На данной модели 16 контактов, а у большенства моделей - 24. Подскажите - для чего контакты HTX, HRX, IO14, NET, MIC2_P. Если правильно понял, то URX и UNX для подключения к компу или ардуино.
Сравните с другими моделями и с доками, пост #3. URX и UTX сериал порт.
Сравнивал.. пока не понятно... Может это для меня и лишние навороты, но интересно все же... Во всех элементарных примерах просто подключают через urx-utx и довольны... Ничего более полного пока не нашел...
Если названия выводов на плате не соответствуют названию в доках надо прозвонить от модема к пинам, ну и китайца пнуть на предмет описания. Из наворотов мне интересна камера, из за неё и брал. Это модель A6C.
Камера то же интересна, но это другой проект... Я заказал 590 для телеметрии и А6 - друг попросил дисковый сотовый телефон сделать для подарка товарищу... Я так понимаю, то же из Ростова будете?
Ну если дисковый сотовый с камерой вообще круто будет:) Из Ростова н/Д.
Круто.... но тогда еще экран приделать надо... и вайбер поставить.... Главное чтоб полифония была цветная ?-) Кстати - звонок оставляю родной.... А аппарат железный... с горгазовой аварийки, кажется... киллограм 5-6 весит :-)
Приехало и мне такое чудо. Вроде даже на АТ отвечает после доработок по опыту камрадов myxaz и novak. За что им спасиба, ибо на 115200 одни краказябы были. Код для старта так
#include <SoftwareSerial.h> SoftwareSerial mySerial(2,3); void setup() { Serial.begin(9600); mySerial.begin(9600); }; int ww=20; void loop() { if (mySerial.available()) { Serial.write(mySerial.read()); } else { if(ww) { mySerial.println(F("ATI")); delay(100); ww--; } } if (Serial.available()) { mySerial.write(Serial.read()); } }Почитал по ссылке #3, и его первоисточник http://smart-prototyping.com/image/data/9_Modules/101756%20Wireless%20A6C/A6_A7_A6C_datasheet-EN.pdf почитал.
А девайс вобще от 5В нормально работает? Обосную вопрос цитатой "Working voltage : 3.3V-4.2V;" Заодно отвечу Iguana "А кто нибудь запитывал этот модуль от акб 18650 минуя встроенный стабилизатор? ", судя по диапазону он как раз на такое и заточен.
ПС. Думаю что ответ про 5В нашел на плате в виде стабилизатора. Т.е сам А6 - железная коробочка не расчитан на 5В, но продаваемая плата с А6 (которую называют А6_mini или тоже просто А6)))) уже с стабилизатором и может держать 5В и наверно даже несколько выше. Я верно понимаю?
Дело движется, но результат не получен.
скетч
#include <SoftwareSerial.h> SoftwareSerial mySerial(2,3); void setup() { Serial.begin(9600); mySerial.begin(9600); }; int ww; void loop() { int t=millis(); if (mySerial.available()) { Serial.write(mySerial.read()); } else { if(ww<10) { mySerial.println(F("AT")); delay(80); ww++; } else { static int tt; static byte Q; if(t-tt>100) { tt=t; if(Q) Q--; else { switch(ww) { case 10: Q=50;break; case 11: mySerial.println(F("ati"));Q=2;break; case 12: mySerial.println(F("at+ccid"));Q=5;break; case 13: mySerial.println(F("AT+CPOF=?"));Q=5;break; default: ww--; } ww++; } } } } if (Serial.available()) { mySerial.write(Serial.read()); } }Выдает
На карте деньги есть? У меня иногда регистрация в сети проходила даже больше минуты.
У меня один модуль на 5В 0.5А не запустился, думал что убитый. Второй заработал, но были сбои. От 1А БП оба заработали.
Несмотря на:
1. БП 5В 2А
2. электролит 3300мкФ
оно упрямствует :(
При этом в процессе включения статус регистрации последовательно, секунд за 30-40 проходит состояния
Ха! Кажется загадка решена. В списке сетей, а его я только что получил командой at+cops=? секунд за 20. Среди 3-х обнаруженых операторов напроч отсутствует мой. Тут я вспомнил "мелочь", он стандарта wcdma. А что с этим делом у A6? Ща почитаю.
Наигрался я этим А6. Не плох вроде. Сложноватый конечно набор команд, но терпимо. Стабилен, но без аппаратного ресета бывают неприятности с автоопределением скорости. Модем занимается чем то долгим, МК ребутнулся, пытается достучатся до модема, а он молчит да еще и на нетой скорости:) А потом чего выплевывает непонятное.
Код.
#include <SoftwareSerial.h> #include "SSD1306.h" SoftwareSerial mySerial(2,3); #define OLED_SCL_PIN 6 #define OLED_SDA_PIN 7 ssd1306_i2c(OLED_SCL_PIN, OLED_SDA_PIN, myOLED) ; typedef void (*pFn)(char* p); typedef boolean (*pFnb)(char* p); typedef struct sEventsMap { const char* Name; pFn Event; }; bool NevSpeed; void ReciveAT_OK(char* p){ NevSpeed=true;}; bool ActivAT; pFn EventOk=ReciveAT_OK; void ReciveOK(char* p){digitalWrite(13,LOW);ActivAT=false; if(EventOk) EventOk(p); }; void SendAT(const __FlashStringHelper* at) { //Serial.print(">>AT>>"); //Serial.println(at); digitalWrite(13,HIGH); ActivAT=true; mySerial.println(at); } char InpStr[100]; void SerialOut(char* p=InpStr){ Serial.println(p);} void ReciveRING(char* p){ SerialOut(); myOLED.clrScr();myOLED.drawString(6,2,"R I N G");SendAT(F("AT+CLCC"));}; pFn EventERROR; void ReciveERROR(char* p){digitalWrite(13,LOW); ActivAT=false; if(EventERROR) EventERROR(p); else SerialOut();}; byte ConnectMode=0; pFn EventChngReg; void ChngReg(char* p) { byte r=(*(p+3))-'0'; if(r!=ConnectMode) if(EventChngReg) { ConnectMode=r; EventChngReg(p); } ConnectMode=r; } void DravString(byte str, byte row, char *p) { char *a; for(a=p;*a>=' ';a++) {}; *a=0; myOLED.drawString(str,row,p); } void ReciveCOPS(char* p) { p++; SerialOut(p); if((*p)!='(') //список всех сетей { DravString(0,7,p); return; } myOLED.clrScr(); byte n=1; for(char *a=p, *b=p;*a!=0;a++) { if((*a==')') && (*(a+1)!='"')) //life - козлы!!! { a++; *a=0; myOLED.drawString(0,n,b); n++; b=a+1; } } } void ReciveSMS(char* p) { Serial.println("SMS"); SerialOut(); myOLED.clrScr(); myOLED.drawString(7,3,"S M S"); SendAT(F("AT+CMGF=1")); SendAT(F("AT+CMGR=1")); } void ReadSMS(char* p){ Serial.println("Text"); SerialOut();} void SignalQuality(char* p){ myOLED.drawString(10,0,"sign:");DravString(15,0,p);Serial.println("Sig:"); SerialOut();} void ReadICCID(char* p) { char *a=p; for(;*a>=' ';a++) { if(!(((int)a)&3)) *a='*'; } *a=0; myOLED.drawString(0,5,p); Serial.println("ICCID:"); SerialOut(p); } void EndCALL(char* p){DravString(4,7,p);} void DetaleRING(char* p) { char *a=p;for(;*a!='"';a++); *a=0; DravString(3,4,p); *a='"';*(a+4)='*';*(a+7)='*';*(a+9)='*';*(a+11)='*'; DravString(1,5,a); } sEventsMap EventsMap[]={ {"OK", ReciveOK}, {"RING", ReciveRING}, {" ERROR:", ReciveERROR}, {"+CME", ReciveERROR}, {"+CIEV:", EndCALL}, {"+CREG:", ChngReg}, {"+COPS:", ReciveCOPS}, {"^CINIT:", SerialOut}, {"+CMTI", ReciveSMS}, {"+CMGR", ReadSMS}, {"+CSQ:", SignalQuality}, {"+CCID:", ReadICCID}, {"+CLCC:", DetaleRING} }; boolean ReciveATE_OK(char* p){SendAT(F("ati"));return true;}; boolean ReciveATI_OK(char* p) { SerialOut(p); myOLED.clrScr(); myOLED.setFont( SSD1306::FONT_SIZE_1); byte n=0; char *b=p; for(char *a=p;*a!=0;a++) { if(*a<' ') { *a=0; myOLED.drawString(0,n,b); n++; a++; b=a+1; } } *b='@'; myOLED.drawString(0,n,b); SendAT(F("at+ccid")); myOLED.drawString(0,4,"маскированый ICCID:"); return true; }; boolean ReciveAT_CCID_OK(char* p){ SendAT(F("at+creg?")); return true;}; boolean ReciveAT_CREG_OK(char* p) { if(ConnectMode!=1) { SendAT(F("at+creg?")); return false; //повторим эту команду } EventChngReg=ReciveInit_ERROR; //т.к. не стартует при незавершенной регистрации то перезапустим по её завершению myOLED.drawString(5,7,"Поиск сетей..."); SendAT(F("at+cops=?"));return true; }; boolean ReciveAT_COPS_OK(char* p){ EventChngReg=0; SerialOut();SendAT(F("at+cops?"));;return true;}; boolean ReciveAT_COPS_sel_OK(char* p){ EventChngReg=0; SerialOut();SendAT(F("at+csq"));return true;}; boolean InitEnd; boolean ReciveAT_QSQ_OK(char* p){ EventERROR=0; SerialOut();EventOk=SerialOut;InitEnd=true;return true;}; pFnb InitProc[]={ ReciveATE_OK, ReciveATI_OK, ReciveAT_CCID_OK, ReciveAT_CREG_OK, ReciveAT_COPS_OK, ReciveAT_COPS_sel_OK, ReciveAT_QSQ_OK, }; byte InitID; void ReciveInit_OK(char* p) { // p[strlen(p)-6]=0; //удаляем ОК if(InitID<sizeof(InitProc)/sizeof(InitProc[0])) { if(InitProc[InitID](p)) InitID++; } }; void ReciveInit_ERROR(char* p) { InitProc[InitID-1](p); } pFn OK_Fn=ReciveAT_OK; void setup() { Serial.begin(9600); mySerial.begin(9600); pinMode(13, OUTPUT); myOLED.begin(); myOLED.clrScr(); myOLED.setFont( SSD1306::FONT_SIZE_2); myOLED.drawString(1,1,"Пейджер"); myOLED.drawString(0,3,"ардуинщика"); delay(2000); }; int ww; void loop() { int T=millis(); if (mySerial.available()) { static byte StrEnd; static char* pInpStr=InpStr; static char* pNewStr=InpStr; byte r=mySerial.read(); if(r==10) StrEnd|=1; else if(r==13) StrEnd|=2; else StrEnd=0; *pInpStr=r; if(pInpStr<(InpStr+sizeof(InpStr)-1)) pInpStr++; // char s[10];itoa(r,s+2,16);s[0]=r;s[1]='-'; Serial.println(s); if((StrEnd==3) && ((pInpStr-InpStr)==2)) { StrEnd=0; pInpStr=InpStr; } if(StrEnd==3) { // Serial.println(InpStr); *pInpStr=0; bool FlPresent; FlPresent=false; for(byte i=0;i<sizeof(EventsMap)/sizeof(EventsMap[0]);i++) { if(!memcmp(EventsMap[i].Name,pNewStr,strlen(EventsMap[i].Name))) { if(EventsMap[i].Event) { char *p=InpStr; if(!i) *pNewStr=0; //если ОК - удаляем его else p+=strlen(EventsMap[i].Name); EventsMap[i].Event(p); } FlPresent=true; break; } } // Serial.println(InpStr); if(FlPresent) { pInpStr=InpStr; StrEnd=0; } pNewStr=pInpStr; } } else { if(!NevSpeed) { SendAT(F("AT")); digitalWrite(13,ww&1); delay(24); } else { static bool FlInit; if(!FlInit) { FlInit=true; EventOk=ReciveInit_OK; EventERROR=ReciveInit_ERROR; SendAT(F("ate 0")); } } } static int TimeCSQ; if(ActivAT || !InitEnd) TimeCSQ=T; else if(T-TimeCSQ>3000)z { TimeCSQ=T; // SendAT(F("AT+CPMS?")); // SendAT(F("AT+CMGR=1")); // SendAT(F("AT+CMGF=1")); // SendAT(F("AT+CMGL=4")); SendAT(F("at+csq")); } if(InitEnd) if (Serial.available()) { mySerial.write(Serial.read()); } }синематограф. https://youtu.be/cx0dIHB1zH8
Звонки принимает, номера определяет. А с СМС не так просто. Видать его настроить надо, а то он даже не сохраняет их. Я попробовал парочку прислать. Выдает кучу ошибок, а принятой не появляется в памяти. Я и плюнул.
....
А с СМС не так просто. Видать его настроить надо, а то он даже не сохраняет их. Я попробовал парочку прислать. Выдает кучу ошибок, а принятой не появляется в памяти. Я и плюнул.
Нужно подать команду куда сохранять СМС. По умолчанию она сразу приходит в терминал. Формат вывода тоже настраивается AT-командами. Разберись сначало с латинскими. Для руских букв особый формат.
Я как раз разбираюсь с USSD-запросами, там разбор тоже особый. Хочу баланс получать.
СМС. По умолчанию она сразу приходит в терминал.
Так вот что мне валилось в сириал! А я смотрю - странные какието ошибки большим потоком, а то наверно SMS была в PDU.
Я вобще не сильно уверен в востребованости функционала SMS. Для обмена данными TCP по GPRS явно предпочтительный. На крайняк если есть причины не держать его постоянно, можна по входящему звонку без ответа на него подымать TCP.
ПС. Пациент с вчерашнего вечера в сети, ни ребутов ни сбоев. ОК. Да на видео упомянут электролит по питанию на 3300мкФ. Без него включается, начинает работать но поиск сетей не проходит. Питание от USB через ардуино нано. Так что к питанию требователен.
Продолбавшись с SMS начал замечать некоторые странности в данных поступающих с A6. После исключения всех возможных факторов и экспериментов с разными скоростями взглянул на реализацию софтового сириала в SoftwareSerial.cpp.
Я много херни видел за жизнь в *.cpp, но такого пи...ватизма не припоминаю даже у джуниора.
Вот так,
inline void SoftwareSerial::handle_interrupt() { if (active_object) { active_object->recv(); ............................................. потом так void SoftwareSerial::recv() { ............................ for (uint8_t i=0x1; i; i <<= 1) { tunedDelay(_rx_delay_intrabit); ................. } tunedDelay(_rx_delay_intrabit); ...................... шахимат в одном пакете /* static */ inline void SoftwareSerial::tunedDelay(uint16_t delay) { uint8_t tmp=0; asm volatile("sbiw %0, 0x01 \n\t" "ldi %1, 0xFF \n\t" "cpi %A0, 0xFF \n\t" "cpc %B0, %1 \n\t" "brne .-10 \n\t" : "+r" (delay), "+a" (tmp) : "0" (delay) ); }Итого: МК уходит в прерывание и висит в нем все время пока не приймет стоповый. А это значить что при сплошном потоке данных у скетча времени на обработку принятого практически нет. Короткие паузы между стопом и стартом успешно забирает прерывание системного таймера. И на практике именно так выглядит ситуация. При приеме более 64 байт буфер софтового сириала заканчивается. А выбирать данные из него МК просто не успевает, он все время занят выполнением tunedDelay. И внутри прерывания. У остального кода нет шансов. Причем понижение скорости только ухудшает ситуацию.
Я счтитаю, что авторы такого кода должны быть известны каждому, чтоб услышав о них каждый мог плюнуть и обходить стороной все, к чему прикасались эти жопоруки.
Вот они, безславные ублюдки, выродки рода разработчиков. Будте прокляты в веках.
ladyada (http://ladyada.net)
Mikal Hart (http://www.arduiniana.org)
Я не строю атомные реакторы. Не умею и может й..нуть. Но я писал софтверный сириал и не раз, и на ассемблере для пиков и т.д. Прерывание пина и таймер легко решают задачу, пусть не для высоких скоростей но решает. Почему ублюдки-авторы берутся делать то, чего не умеют? Они надеются на свой фарт, что их не долбанет за их говнокод? А я думаю и надеюсь долбанет, и сильно.
ПС. Я Вам рассказал о своем последнем случае использования SoftwareSerial. И Вам не советую.
Да, там буфер 64 байта по умолчанию. Измени переменную отвечающую за буфер, советуют менять на 180.
Я отлаживаюсь на софтсериале, потом переключаюсь на аппаратное.
Я отлаживаюсь на софтсериале, потом переключаюсь на аппаратное.
Это для тех плат, где аппаратное одно? Те на меге можно сразу на аппаратном пробывать или есть другие причины?
Gprs никто ещё не юзал???, поделитесь если есть кодом.
Гммм.. ну как бы раз ТСР юзаю, наверно по GPRS. Код выше. Но вобщето актуальней АТ командами делится. Продолжаю здесь http://arduino.ru/forum/apparatnye-voprosy/gsm-modem-a6-v-rezhime-tcp т.к. к рингу это явно не относится.