Собрал Arduino Nano + SIM900 соединены rx tx и земля. Запрограммировал чтобы посылать команды Serial => Nano => Sim900 => Nano => Serial и считывать ответы на сервере. Как только подключаю к серверу (на Linux) то оно работает от часа до суток и зависает. Сначала подумал что наводки с проводов, тогда припаял к пинам здоровенные медные провода, но проблема никуда не делась, потом на сервере стал отслеживать зависания и просто перезапускать Serialport, какое-то время это работает, но в итоге через от дня до 4-х зависает наглухо и даже перезапуск Srialport не помогает. Запитано sim900 своим блоком питания, а Nano от usb порта.
Что это может быть? Наводки или програмный сбой?
Что это может быть? Наводки или програмный сбой?
main.cpp:
#include <Arduino.h>
#include <SoftwareSerial.h>
#define OS_BENCH // дефайн до подключения либы
#include <GyverOS.h>
#include <GParser.h>
#include <../lib/Matcher.h>
GyverOS<2> OS;
SoftwareSerial gsm(2, 3); // RX-3; TX-2;
void taskGSM();
void taskSerial();
uint8_t simRequest;
uint32_t savedtime = 0;
bool lockSend = false;
bool startup = true;
bool needSend = false;
char gsmString[128];
char phoneNumber[13];
char msgToSend[64];
char at_cmgs[24] = "AT+CMGS=\"000000000000\"\r";
char call_atd[21] = "ATD + 000000000000;\r";
uint16_t i = 0;
int ms;
void setup() {
gsm.begin(9600);
Serial.begin(115200);
Serial.setTimeout(250);
Serial.println( "start" );
OS.attach(0, taskSerial, 50);
OS.attach(1, taskGSM, 50);
lockSend = true;
startup = true;
simRequest = 0;
gsm.println( "AT + CREG? \r" );
delay(500);
}
void taskGSM() {
if (gsm.available()) {
Matcher mymatch( "+CMT:" );
memset(gsmString, 0, (int)(sizeof gsmString));
i = 0;
while (gsm.available()) {
char incoming = (char)gsm.read();
delay(2);
if ( i < 10 ) {
mymatch.isnew( incoming );
}
if ( !mymatch.getMatched() ) {
gsmString[i] = incoming;
} else {
Serial.print( incoming );
}
//Serial.print( incoming );
i++;
}
//Serial.print( gsmString );
if (mymatch.getMatched()) {
Serial.print( "|;" );
return;
} else if ( simRequest == 2 && strstr(gsmString, ">") != NULL ) {
gsm.println( msgToSend );
delay(50);
gsm.write(26);
simRequest = 3;
return;
} else if ( strstr(gsmString, "OK") != NULL ) {
switch (simRequest) {
case 0:
char str[4];
strncpy(str, gsmString + 2 + strcspn(gsmString, ":"), 3);
str[3] = 0;
if ( strcmp(str, "0,1") == 0 || strcmp(str, "1,1") == 0 ) {
if (needSend) {
simRequest = 2;
gsm.println( at_cmgs );
} else if (startup) {
simRequest = 1;
startup = false;
gsm.println( "AT + CMGF=1 \r" );
}
} else {
simRequest = 0;
gsm.println( "AT + CREG? \r" );
delay(1000);
}
break;
case 1:
simRequest = 4;
//lockSend = false;
gsm.println( "AT + CNMI = 2,2,0,0,0 \r" );
break;
case 3:
lockSend = false;
needSend = false;
simRequest = 5;
Serial.println( "sended" );
break;
case 4:
simRequest = 5;
lockSend = false;
Serial.println( "ready" );
break;
case 5:
lockSend = false;
Serial.print( "sr5||" );
Serial.println( gsmString );
break;
default:
lockSend = false;
break;
}
//Serial.println( (String) "true" );
} else if ( strstr(gsmString, "NO CARRIER") != NULL ) {
Serial.print( "called" );
lockSend = false;
return;
} else if ( strstr(gsmString, "ERROR") != NULL ) {
// Ошибка
if (needSend) {
simRequest = 0;
gsm.println( "AT + CREG? \r" );
} else {
Serial.print( "err||" );
Serial.println( gsmString );
lockSend = false;
}
}
}
}
void taskSerial() {
if (Serial.available()) {
char serialString[64];
int16_t amount = Serial.readBytes(serialString, 64);
serialString[amount] = NULL;
GParser data(serialString, '|');
int8_t am = data.split();
//Serial.println(data[0]);
//Serial.println(data[1]);
if (millis() - ms > 3000) {
//Serial.println( "unlock" );
lockSend = false;
}
if (lockSend ) {
Serial.println( "locked" );
} else if ( data.equals(0, "send") ) {
needSend = true;
lockSend = true;
ms = millis();
memset(phoneNumber, 0, (int)(sizeof phoneNumber));
strcpy(phoneNumber, data[1]);
memset(msgToSend, 0, (int)(sizeof msgToSend));
strcpy(msgToSend, data[2]);
strncpy( at_cmgs + 9, phoneNumber, 12 );
simRequest = 2;
gsm.println( at_cmgs );
} else if ( data.equals(0, "at") ) {
simRequest = 5;
lockSend = true;
ms = millis();
gsm.println( data[1] );
} else if ( data.equals(0, "call") ) {
lockSend = true;
ms = millis();
memset(phoneNumber, 0, (int)(sizeof phoneNumber));
strcpy(phoneNumber, data[1]);
strncpy( call_atd + 6, phoneNumber, 12 );
gsm.println( call_atd );
}
//*/
}
}
void loop() {
OS.tick();
}
Matcher.h:
#include <Arduino.h>
class Matcher {
private:
const char * _match;
uint16_t _i;
uint16_t _max;
bool _matched;
public:
Matcher(const char * match ) {
_match = match;
_matched = false;
_max = strlen(_match);
_i = 0;
}
char getChar(uint16_t n) {
return _match[n];
}
bool isnew ( char c ) {
if (c == _match[ _i ]) {
_i++;
if ( _i == _max) {
_matched = true;
}
} else {
_i = 0;
}
return getMatched();
}
bool getMatched() {
return _matched;
}
};