03-09-2017, 18:24
Witam
Stworzyłem projekt który wysyła temperaturę przez gsm (neoway m590 + arduino UNO) po wysłaniu komendy sms "tmp".Mam dziwny problem,po wysłaniu komendy "tmp" dostaję zwrotną wiadomość z aktualną temperaturą.Niby wszystko ok ale gdy wyśle następnego smsa,zamiast aktualnego pomiaru dostaję ten pierwszy pomiar.Kolejne smsy to samo.Wygląda to tak jakby czujnik mierzył tylko raz temperaturę.Poniżej wklejam kod oraz fragment kody gdzie wywołany jest pomiar.
fragment wywołania pomiaru:
Stworzyłem projekt który wysyła temperaturę przez gsm (neoway m590 + arduino UNO) po wysłaniu komendy sms "tmp".Mam dziwny problem,po wysłaniu komendy "tmp" dostaję zwrotną wiadomość z aktualną temperaturą.Niby wszystko ok ale gdy wyśle następnego smsa,zamiast aktualnego pomiaru dostaję ten pierwszy pomiar.Kolejne smsy to samo.Wygląda to tak jakby czujnik mierzył tylko raz temperaturę.Poniżej wklejam kod oraz fragment kody gdzie wywołany jest pomiar.
Kod:
#include <OneWire.h>
#include <DS18B20.h>
#include <AltSoftSerial.h>
#define ONEWIRE_PIN 5
float currentTemp;
// AltGSM always uses these pins:
//
// Board Transmit Receive PWM Unusable
// ----- -------- ------- ------------
// Arduino Uno 9 8 10
// Arduino Leonardo 5 13 (none)
// Arduino Mega 46 48 44, 45
byte address[8] = {0x28, 0xFF, 0xFC, 0xDA, 0x84, 0x16, 0x5, 0x50};
OneWire onewire(ONEWIRE_PIN);
DS18B20 sensors(&onewire);
AltSoftSerial GSM;
void setup() {
Serial.begin(9600);
while (!Serial) ; // wait for Arduino Serial Monitor to open
Serial.println("Test modułu GSM...");
GSM.begin(57600);
//GSM.print("ATE1\r");//ATE1 powoduje, że wszystko co wyślemy DO modułu będzie przez niego wysyłane do nas (echo)
GSM.print("ATE1\r");//ATE0 wyłącza powyższą funkcjonalność
delay(550);//czekamy nieco
sensors.begin(10);
sensors.request(address); //ustawienia do czujnika temperatury
}
//definiujemy zmienne pomocne przy odbiorze danych
char buffer[256];
byte field_begin[14];
int num=0;
//oraz zmienne kontrolujące odbiór danych, stałe do porównywania
const char SMS_REC[]="+CMGL: ";
const char OK[]="OK";
const char ERROR[]="ERROR";
const char accepted_nr[]="\"+48----------\"";
byte nr_correct=0;
enum states{IDLE,NEXT_TXT};
states stan=IDLE;
byte msg_id=0;
byte ok;
int j;
byte send_resp,wait_for_sending;
unsigned long old_millis=millis();
//pętla główna programu
void loop() {
if (sensors.available())
{
currentTemp = sensors.readTemperature(address);
Serial.print(currentTemp);
Serial.println(F(" 'C"));
delay(1000);
sensors.request(address);
}
char c;//zmienna pomocznicza
//ten blok pozwala nam przesyłać komendy do telefonu z terminala komputera
/*if(Serial.available()){
c=Serial.read();
GSM.print(c);
}*/
//ten blok co 5 sekund ustawia format wiadomości na tekstowy a następnie sprawdza listę wiadomości odebranych przez moduł
//i romimy to tylko wtedy gdy nie czekamy na nadanie wiadomości SMS
if(millis()-old_millis>5000&&wait_for_sending==0){
GSM.print("AT+CMGF=1\r");//ustaw format wiadomości na tekstowy
delay(550);
GSM.print("AT+CSCS=\"GSM\"\r");
delay(550);
GSM.print("AT+CMGL=\"ALL\"\r");//wyślij zapytanie o wyświetlenie wszystkich wiadomości
old_millis=millis();
}
if (GSM.available()) {//jeśli czeka na odbiór jakiś znak
c = GSM.read();//to odczytujemy go
Serial.print(c);//a tu możemy do celów debugowania wyświetlić na ekranie to co wysyła nam moduł - nie tylko nasze komunikaty
if(c=='\n'){//jeśli to znak zakończenia linii (koniec ramki) to przystępujemy do jej dekodowania
switch(stan){
case IDLE://normalny stan - sprawdzamy ramki pod kątem tego czego dotyczą
//-----------------------------------------------------------------------------------------------------------------------------------
//SMS przychodzący po poleceniu AT+CMGL... - dekodujemy początek wpisu
//-----------------------------------------------------------------------------------------------------------------------------------
ok=1;//zakładamy, ze to interesująca nas ramka
for(int i=0;i<6;i++){//w pętli porównujemy pierwsze znaki ramki ze wzorcem informacji o sms'ie
if(buffer[i]!=SMS_REC[i])ok=0;//jeśli jakiś znak się różni to to nie jest interesująca nas ramka
}
j=0;
if(ok){//jeśli mamy interesującą nas ramkę to możemy ją dekodować
for(int i=0;i<num;i++){//przeglądamy ją znak po znaku
if(buffer[i]==','){//jeśli trafiliśmy na przecinek
buffer[i]=0;//to zastępujemy go znakiem 0 - kończy on ciąg znaków
field_begin[j++]=i+1;//kolejny znak po przecinku to początek nowego pola - zapisujemy jego pozycję
if(j>5){//maksymalnie w tej ramce moze być 5 pól
j=0;
ok=0;
}
}else if(buffer[i]=='\r'||buffer[i]=='\n')buffer[i]=0;//znaki kończące ramkę też zastąpimy znakami zerowymi
}
}
if(ok){
//tu odczytuję z tekstu ID wiadomości
msg_id=atoi(&buffer[7]);
Serial.print("Wiadomosc nr: ");
Serial.println(msg_id);
Serial.print("Od numeru: ");
//następnie z pól odczytujemy numer telefonu wraz z "" w których jest zawarty
Serial.println(&buffer[field_begin[1]]);
//tu porównujemy ten ciąg z zapisanym w stałej na początku programu - nie chcemy by reklamy czy inne osoby coś mogły zrobić
if(strcmp(&buffer[field_begin[1]],accepted_nr)==0){
nr_correct=1;
Serial.println("NUMER ZGODNY");
}else{
nr_correct=0;
Serial.println("NUMER NIEOBSLUGIWANY");
}
stan=NEXT_TXT;//po tej ramce na pewno otrzymamy tekst sms'a, więc informujemy program, że kolejna linijka musi być dekodowana jako tekst a nie komenda
}
//-----------------------------------------------------------------------------------------------------------------------------------
//OK - komunikat poprawnego zakońvczenia wykonywania komendy
//-----------------------------------------------------------------------------------------------------------------------------------
ok=1;//zakładamy, ze to interesująca nas ramka
for(int i=0;i<2;i++){//w pętli porównujemy pierwsze znaki ramki ze wzorcem OK
if(buffer[i]!=OK[i])ok=0;//jeśli jakiś znak się różni to to nie jest interesująca nas ramka
}
if(ok){
wait_for_sending=0;//kasujemy blokadę wysyłania na czas nadawania sms'a
//jeśli odebrano jakąś wiadomość
if(msg_id!=0){
//to ją usuniemy
GSM.print("AT+CMGD=");
GSM.print(msg_id);
GSM.print("\r");
Serial.println("wiadomosc usunieta");
msg_id=0;
}else if(send_resp){//jeśli wiadomość zostałą usunięta i mamy nadać odpowiedź
send_resp=0;
GSM.print("AT+CMGS=\"+48---------\"\r");//to wysyłamy ją na ten numer
delay(550);
currentTemp = sensors.readTemperature(address);
Serial.println(currentTemp);
delay(300);
GSM.print("Temp:");//tu wpisujemy treść wiadomości (do 160 znaków)
delay(300);
GSM.print(currentTemp);
delay(300);
GSM.print((char)26);//a następnie zatwierdzamy wysłanie
Serial.println("Info wyslane");
wait_for_sending=1;//musimy zadbać, by zanim telefon potwierdzi nadanie wiadomości nie nadać nic do niego
}
}
//-----------------------------------------------------------------------------------------------------------------------------------
//ERROR
//-----------------------------------------------------------------------------------------------------------------------------------
ok=1;//zakładamy, ze to interesująca nas ramka
for(int i=0;i<5;i++){//w pętli porównujemy pierwsze znaki ramki ze wzorcem OK
if(buffer[i]!=ERROR[i])ok=0;//jeśli jakiś znak się różni to to nie jest interesująca nas ramka
}
if(ok){
wait_for_sending=0;//kasujemy blokadę wysyłania na czas nadawania sms'a
Serial.println("Huston, mamy problem...");
}
break;
//-----------------------------------------------------------------------------------------------------------------------------------
//Tekst wiadomości SMS
//-----------------------------------------------------------------------------------------------------------------------------------
case NEXT_TXT:
for(int i=0;i<num;i++){//przeglądamy ją znak po znaku
if(buffer[i]=='\r'||buffer[i]=='\n')buffer[i]=0;//znaki kończące ramkę też zastąpimy znakami zerowymi
}
Serial.print("Wiadomosc: ");
Serial.println(buffer);
//sprawdzamy czy to któreś z interesujących nas poleceń - możemy tu dodać własne polecenie, przesyłanie np. nastawy dla PWM itp.
if(nr_correct){//ale najpierw sprawdzamy czy numer był naszym numerem - nie chcemy, zeby irytująca reklama włączyła nam oświetlenie w domu :D // tu skasowałem część
if(strcmp(buffer,"tmp")==0){
send_resp=1;//poinformujemy, aby po zakończeniu nadawania wysłać informację do użytkownika
}
}
Serial.println();
stan=IDLE;
break;
}
num=0;
}else{//jeśli to inny znak niż zakończenie ramki to dopisujemy go do bufora
buffer[num++]=c;
buffer[num]=0;//ponadto zawsze kończymy zawartośc bufora znakiem 0 - koniec ciągu znaków
if(num>255)num=0;//i dodatkowo dbamy o to, żeby nie przepełnić bufora
}
}
}
Kod:
}else if(send_resp){//jeśli wiadomość zostałą usunięta i mamy nadać odpowiedź
send_resp=0;
GSM.print("AT+CMGS=\"+48-----------\"\r");//to wysyłamy ją na ten numer
delay(550);
currentTemp = sensors.readTemperature(address);
Serial.println(currentTemp);
delay(300);
GSM.print("Temp:");//tu wpisujemy treść wiadomości (do 160 znaków)
delay(300);
GSM.print(currentTemp);
delay(300);
GSM.print((char)26);//a następnie zatwierdzamy wysłanie
Serial.println("Info wyslane");
wait_for_sending=1;//musimy zadbać, by zanim telefon potwierdzi nadanie wiadomości nie nadać nic do niego
}