GSM A6 зависание.
- Войдите на сайт для отправки комментариев
Пнд, 15/05/2017 - 11:43
Всем приве! Собрал скетч для управление реле по смс.
Скетч на основе того что выкладывали в форуме. Текущая проблема:
Либо после отправки смс или ussd кода модем перестает отвечать. Смс не доходит. Помогает включить выключить несколько раз. Вообщем никакой стабильности. Битр рейт выставил низкий из-за того что иногда приходят кракозяблы
Сам скетч
#include <AltSoftSerial.h> //8,9 rx,tx #include <SoftwareSerial.h> #include <Arduino.h> // First we include the libraries #include <OneWire.h> #include <DallasTemperature.h> /********************************************************************/ // Data wire is plugged into pin 2 on the Arduino #define ONE_WIRE_BUS 3 #define DEBUG struct RelayCmd { int pin; String name; }; const RelayCmd relay1 = {10, "relay1"}; const RelayCmd relay2 = {11, "relay2"}; const RelayCmd relay3 = {12, "relay3"}; const RelayCmd relay4 = {13, "relay4"}; const RelayCmd relayCmds[] = { relay1, relay2, relay3, relay4 }; const int count = 4; #define ON "on" #define OFF "off" #define STATUS "status" #define END_SMS "#" /********************************************************************/ // Setup a oneWire instance to communicate with any OneWire devices // (not just Maxim/Dallas temperature ICs) OneWire oneWire(ONE_WIRE_BUS); /********************************************************************/ // Pass our oneWire reference to Dallas Temperature. DallasTemperature sensors(&oneWire); char number[] = "+7XXXXXXXXX"; const char balanceRequest[] = "AT+CUSD=1,#102#,15"; String val = ""; String currStr = ""; String str = ""; String temp = ""; boolean ok = false; unsigned int rate = 2400; uint32_t msAT=0; //////////////////////////// unsigned long delayPing = 0; boolean boolPing = true; AltSoftSerial altSerial; void setup() { Serial.begin(9600); altSerial.begin(rate); Serial.print("Start load"); 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"); do { Serial.print("."); delay(2000); Serial.print("."); altSerial.println("ATZ+IPR=" + rate); delay(500); altSerial.begin(rate); delay(200); Serial.print("."); altSerial.println("ATE0"); //отключаем эхо delay(200); Serial.print("."); altSerial.println("AT"); delay(200); str = ""; while (altSerial.available()) { char ch = altSerial.read(); Serial.print(ch); str += ch; delay(5); } if (str.indexOf("OK") > -1) { ok = true; Serial.print("."); delay(200); //altSerial.println("AT+CPIN=2113"); //Pin sim карты altSerial.println("AT+CNMI=2,2"); Serial.print("."); delay(200); altSerial.println("AT+CMGF=1"); Serial.print("."); delay(200); altSerial.println("AT+CSCS=GSM"); Serial.print("."); delay(200); Serial.println("OK"); } else { altSerial.end(); delay(500); ok = false; Serial.print("-"); } } while (ok == false); for (int i = 0; i < count; i++) { RelayCmd relay = relayCmds[i]; pinMode(relay.pin, OUTPUT); digitalWrite(relay.pin, HIGH); Serial.print("Setup relay "); Serial.println(relay.name); } sensors.begin(); delay(5000); } void loop() { ///если что то пришло, читаем if (altSerial.available()) { delay(5); char ch = altSerial.read(); Serial.print(ch); val += char(ch); } if (val.indexOf("+CUSD:")>-1 && val.indexOf(",15")>-1) { resendMasage(); val = ""; } if (val.indexOf(number) > -1 && val.indexOf(END_SMS)>-1) { if (val.indexOf(STATUS) > -1) { Serial.println("income status"); val = "echo"; } if (val.indexOf("balance") > -1) { Serial.println("income balance"); altSerial.println("AT+CUSD=1,#102#,15"); delay(300); } else { for (int i = 0; i < count; i++) { RelayCmd relay = relayCmds[i]; if (val.indexOf(relay.name)>-1) { if (val.indexOf(ON)>-1) { Serial.print("Income on "); Serial.println(relay.name); digitalWrite(relay.pin, LOW); } if (val.indexOf(OFF)>-1) { Serial.print("Income off "); Serial.println(relay.name); digitalWrite(relay.pin, HIGH); } } } } checkAndSendEchoSms(); val = ""; } ///////////////////////////////////// //затираем переменную после отправки смс//// if (val.indexOf("CMGS:") > -1) { val = ""; } //оживляем модуль, если он уснул //////////////////////////////////////////////////////// if (millis() - delayPing > 900000) { if (boolPing == true) { altSerial.println("AT"); boolPing = false; } if (val.indexOf("OK") > -1) { boolPing = true; delayPing = millis(); val = ""; } } if (millis() - delayPing > 905000) { altSerial.end(); altSerial.begin(rate); altSerial.println("AT"); boolPing = true; } } ///////////////////////////////////////////////////////////////////// void smsSend(char tel[12], String text) { altSerial.print("AT+CMGS=\""); delay(200); for (int i = 0; i < 12; i++)altSerial.write(tel[i]); delay(300); altSerial.print(char(34)); delay(200); altSerial.write(0x0D); delay(500); altSerial.print(text + "\x1a"); delay(600); // altSerial.println(char(26)); Serial.println("sms sended"); } void checkAndSendEchoSms() { Serial.println(val); if (val.indexOf("echo") > -1) { sensors.requestTemperatures(); temp = String(sensors.getTempCByIndex(0)); String text = "ECHO: "; for (int i = 0; i < count; i++) { RelayCmd relay = relayCmds[i]; text += relay.name + (digitalRead(relay.pin) == LOW ? " ON " : " OFF "); } text += " T: " + String(temp); Serial.println(text); smsSend(number, text); } val = ""; } 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; } } } void printResponse() { while (altSerial.available()) { char ch = altSerial.read(); Serial.print(ch); delay(5); } } void resendMasage() { int p1 = val.indexOf(F("\"")); //начало строки int p2 = val.lastIndexOf(F("\"")); //конец строки val = val.substring(p1 + 1, p2); String decodestr; decode7bit(val, decodestr); Serial.println(decodestr); smsSend(number,decodestr); } 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; //посылаем команду altSerial.println("AT"); str = ""; delay(100); //Ждём ответа while(altSerial.available()) { char ch=altSerial.read(); Serial.print(ch); str+=ch; } if(str.indexOf(F("OK"))>-1) countok++; else countok = 0; } } return true; } 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; //посылаем команду altSerial.println("AT+CREG?"); delay(100); //Ждём ответа str = ""; while(altSerial.available()) { char ch=altSerial.read(); Serial.print(ch); 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; }
panason2008@y удалось побороть зависания?
4 к 1, что не хватает питания.
должно хватать. на уно приходит 9 вольт, 3.5 А.
хотя может вы и правы. сейчас подтянул ногу 5 вольт к gpio1. прочитал в соседней ветке. буду смотреть.
должно хватать. на уно приходит 9 вольт, 3.5 А.
Мне кажется. я это (именно этими словами) уже читал.
Очевидно, что вы питаете модем А6 через Уно. В этом случае не имеет ни малейшего значения, какие там амперы на входе - хоть 3.5А, хоть 333А. Все равно модем получит ровно столько. сколько может выдать регулятор напряжения Уно - а он на лригинальной плате дает 0.8А (которые расходуются на все. что подключено к Уно, а не только на модем). Если же Уно китайская. то скорее всего и 800 мА там не будет.
Вообще. почему-то почти все новички питают свои поделки высоким напряжением - 9В, 12В и тд. Зачем вам это? У вас есть в системе компоненты, которым нужно 9в? Номинальное напряжение Уно - 5в, модема А6 - либо 4-4.2в, либо 5в. Берите БП 5в 2А и от него питайте и ардуину и модем параллельно
уно не китайская. описаный мною блок питания шел в комплекте. мысль я вашу понял. спасибо.
уно не китайская. описаный мною блок питания шел в комплекте. мысль я вашу понял. спасибо.
А можно уточнить как зависает модем? И точно ли дело в модеме?
Я тоже долго искал проблемы и думал что проблема в A6, оказалось нет:
1 скорость порта
2 переход на аппаратный uart
3 следить за переполнению памяти, особенно при использовании soft serial
В итоге уже неделя полет нормальный
Ещё у себя добавил перезагрузку модема при неответе в течении 30 секунд и watchdog на 8 секунд для самого контроллера.
следить за переполнению памяти, особенно при использовании soft serial
а можно уточнить, как именно следите? В смысле - при написании программы или прямо в рантайме как-то отслеживаете свободную память?
Нет конечно, такие тонкие материи мне не по силам)
Долго вылавливал пару странных поведений программы, в итоге нашёл ошибки в скетч - выход за выделенный кусок памяти, из-за чего было вообще не понятно что виновато, то ли модем то ли МК - не адекватное поведение.
ок, понял
Кстати даже сейчас какие то странности)
Все работает, все хорошо, устройство команды обрабатывает и отвечает корректно, а LCD 1602 выдаёт какую то хрень - иероглифы, ну и фиг с ним - на работу не влияет. Иногда просто гаснет.
Я так думаю моя китайская совсем УНО плата глючит.
в моем случае А6 обеспечивает связь с mqtt брокером. я удаленно получаю данные с датчика температуры и управляю реле. во время работы происходит обрыв связи. причем это происходило рандомно. иногда менее часа, а иногда сутки. выручал резет уно. чтобы разобраться в причине, подключил все к компу и открыл монитор порта, дополнительно при подключении к брокеру загорается светодиод. при разрыве связи с брокером светодиод гаснет. предусмотрена возможность переподключения к брокеру. так вот, через некоторое время я увидел погасший диод, а в монитор порта циклическую попытку подключится к брокеру. из чего я сделал вывод о зависании (засыпании или еще чего) модема.
как то так. пинайте.
Ключевая фраза - помогает сброс уно - т е вы не уверены что дело в модеме.
Ну и советую что уже писал - аппаратный serial, сброс модема при не ответе, WDT на сам МК.
И да, я например не вижу смысла в готовом устройстве оставлять код, выдающий какую-то информацию отладочную в консоль - лишняя задержка и нагрузка на МК.
Как вариант например светодиоды, сигналищирующие об ошибках, lcd самый дешёвый, тут где то я выкладывал приемник отдельный uart на attiny85 и т д, вариантов масса сигнализировать о проблемах.
Хотя бы несколько суток пройдёт тогда можно считать что все гуд
это точно. буду ждать.
t19.31u8d18h
Температура и аптайм реального устройства, правда на другом модеме.