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
}
}
}
fragment wywołania pomiaru: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
}