OK

Při poskytování služeb nám pomáhají soubory cookie. Používáním našich služeb vyjadřujete souhlas s naším používáním souborů cookie. Více informací

Úvodní stránka » GSM » Jak jednoduše na GSM - VI.díl - Ovládáme Arduinotech GSM Shield

Jak jednoduše na GSM - VI.díl - Ovládáme Arduinotech GSM Shield

V tomto díle se již konečně vrhneme na praktické příklady s Arduinotech GSM shieldem a ukážeme si, jak SMSkou vypnout a zapnout jeho relé a jak dostat informaci o tom, v jakém stavu máme vstupy nebo relátka. Zatím tedy využijeme 2 relé a 2 vstupních optočlenů. Pro začátek to bude jistě stačit, ovšem potenciál tohoto shieldu je daleko větší, to si ukážeme jistě v budoucnu také. Dnes si projdeme celkem 2 sketche - jeden je pouze pro otestování základního HW shieldu a druhý je již zmíněným praktickým příkladem.

Otestování HW Arduinotech GSM shieldu

Tento sketch vychází z již publikovaného terminálu pro SIM800 ze III.dílu mini seriálu a v podstatě je z něj patrná HW definice vůči Arduino UNO, pro které je tento shield primárně určen. Nebudu jej zde kopírovat celý, protože je jeho poměrně značná část věnována take otestování I2C sběrnice s OLED displejem, na který si posílám informace o jednotlivých stavech při testování. Pokud OLED displej nepoužíváte, pak funkci miniPrint() jednoduše nahraďte Serial.println(); nebo ji upravte takto a výpisy budou chodit na sériák:

void miniPrint(String text)
{
     Serial.println(text);
     return;
     /*
     zbytek věcí zakomentujte
     */
}

Celý sketch i s funkcemi pro OLED display (mimochodem s celkem povedeným terminálem pro výpis provozních stavů - právě tvořený funkcí miniPrint) je ke stažení zde.

K samotnému sketchi:


Definice všeho důležitého, vycházíme ze schématu z předchozího dílu. Do sketche je také přidána knihovna  U8glib.h, která obsluhuje OLED display, můžete ji tedy vynechat, pokud si zmodifikujete funkci miniPrint a OLED displej nebudete používat.


#include <SoftwareSerial.h>
#include <U8glib.h>

#define RESET 4
#define LED 7
#define RELE1 8
#define RELE2 9
#define IN1 5
#define IN2 6
#define RX 2
#define TX 3

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK); //U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_FAST); uint8_t lineCounter = 0; String lineTerminal[5]; SoftwareSerial SIM800(RX,TX); char g,s;

Zde nadefinujeme vstupy/výstupy a provedeme nějaké akce s LED a relátky. Upozorňuji, že pro přitažení relé je potřeba mít připojené napájení 12V do napájecího konektoru Arduino UNO. Jinak neuslyšíte přitažení - cvaknutí relé.


void setup() {

  SIM800.begin(9600);
  Serial.begin(9600);
  lineCounter = 0;
  u8g.setFont(u8g_font_7x14);
  miniPrint("GSM Shield Test");
  pinMode(LED, OUTPUT);
  pinMode(RESET, OUTPUT);
  pinMode(RELE1, OUTPUT);
  pinMode(RELE2, OUTPUT);
  pinMode(IN1,INPUT);
  pinMode(IN2,INPUT);
  digitalWrite(LED,HIGH);
  digitalWrite(RELE1, LOW);
  digitalWrite(RELE2, LOW);
  digitalWrite(RESET, LOW);
  miniPrint("Rele OFF");
  delay(500);
  miniPrint("SIM800 ON");
  digitalWrite(LED,LOW);
  digitalWrite(RESET, HIGH);
  digitalWrite(RELE1, HIGH);
  digitalWrite(RELE2, HIGH);
  miniPrint("Rele ON");
  delay(1000);
  digitalWrite(RELE1, LOW);
  digitalWrite(RELE2, LOW);
  digitalWrite(LED,HIGH);
  miniPrint("Rele OFF");
  
 }


Hlavní smyčku jsem tentokrát omezil pouze na 2 věci: sériový transparentní terminál tak, jak byl popsán ve III. díle a pak pravidelné čtení vstupů pro jejich otestování, obě procedury asi nepotřebují zvláštní komentář.


// the loop function runs over and over again forever
void loop() {
  if(Serial.available()>0)
  {
    g = Serial.read();
    SIM800.print(g);
  }
  if (SIM800.available()>0)
  {
    s = SIM800.read();
    Serial.print(s);
  }
  
  
  if ((digitalRead(IN1) == false) || (digitalRead(IN2) == false)) 
    {
        digitalWrite(LED,LOW);
        if ((digitalRead(IN1) == false)) miniPrint("IN1 LOW");
        if ((digitalRead(IN2) == false)) miniPrint("IN2 LOW");
        delay(200);
    }
  
  else digitalWrite(LED,HIGH);
}

Pokud vše pracuje, jak má, pak po natažení sketche a správně připojeném napájení 12V se nejprve rozsvíti LED, vypnou se obě relé, pak za půl sekundy zhasne LEDka a na jednu sekundu přitáhnou obě relé, poté se rozvítí LED a vypnou obě relé. Od této chvíle můžete využít transparentní terminál pro AT příkazy a otestovat také vstupy - můžete uzemnit katodu LED diody jednotlivých optočlenů - zhasne LED dioda na shieldu.

Otestovali jsme HW a je-li vše OK, pak se můžeme rovnou vrhnout na slibovaný praktický příklad.

Ovládání Arduino GSM shieldu prakticky

Níže uvedený sketch používá stejné definice, jako sketch předchozí - testovací. Opět kvůli zjednodušení nebudu již uvádět a komentovat většinu pasáží, které jsou nutné pro správné fungování sketche a správnou interakci se shieldem, ale omezíme se na samotnou logiku hlavní smyčky. Podrobnosti o konstrukci sketche pro interakci se SIM800 naleznete ve IV. díle seriálu, kdy jsme SMSskou zhasli nebo rozsvítili LEDku.  Pochopitelně celý funkčí sketch se všemi nezbytnostmi je ke stažení zde. Vynechejme tedy vše, co již bylo řečeno a podívejme se rovnou na hlavní smyčku a funkce v ní:


void loop()
{

	//mrkni na příchod SMS
	checkSMS();
	//mrkni na vstupy
	checkInput();
	//opkuj co 1s
	delay(1000);

}

V hlavní smyčce tedy kontrolujeme 2 věci - zda došla nějaká SMSka s příkazem a nebo zda se nezměnily poměry na vstupech. Dále se již podíváme, na 3 jednotlivé funkce, resp. podrobněji pouze na 2 protože funkci checkSMS jsme si již objasnili ve IV. díle. V podstatě celá logika je jen ve 2 funkcích - parseSMS(), kterou po přečtení SMS ze SIM800 volá checkSMS() funkce a checkInput(), která po vyhodnocení stavu vstupů pošle SMS nebo-li zavolá funkci sendSMS(). 


 void SMSparser(String command)
{
	//ovládaní relé přes SMS
	if (command == "RELE1:ZAP")
	{
		digitalWrite(RELE1, HIGH);
		sendSMS(number, "RELE1 zapnuto!");
		rele1Status = true;
		return;
	}
	if (command == "RELE1:VYP")
	{
		digitalWrite(RELE1, LOW);
		sendSMS(number, "RELE1 vypnuto!");
		rele1Status = false;
		return;
	}
	if (command == "RELE2:ZAP")
	{
		digitalWrite(RELE2, HIGH);
		sendSMS(number, "RELE2 zapnuto!");
		rele2Status = true;
		return;
	}
	if (command == "RELE2:VYP")
	{
		digitalWrite(RELE2, LOW);
		sendSMS(number, "RELE2 vypnuto!");
		rele2Status = true;
		return;
	}
	//dotaz na stav Relé a vstupů
	if (command == "Info")
	{
		String tempMessage;
		tempMessage = "Rele1:";
		if (rele1Status == true) tempMessage += "ZAP";
		else tempMessage += "VYP";
		tempMessage += ",RELE2:";
		if (rele2Status == true) tempMessage += "ZAP";
		else tempMessage += "VYP";
		tempMessage += ",IN1:";
		if(digitalRead(IN1) == true) tempMessage += "1";
		else tempMessage += "0";
		tempMessage += ",IN2:";
		if (digitalRead(IN2) == true) tempMessage += "1";
		else tempMessage += "0";
		sendSMS(number, tempMessage);
		return;
	}
	Serial.println F("Neznamy prikaz!");

}

SMS parser je napsán pro obsluhu několika příkazů:

  • RELE1:ZAP a RELE1:VYP
  • RELE2:ZAP a RELE2:VYP
  • Info

K prvním dvěma příkazům asi není co dodat - pošlete SMSku s obsahem RELE1:ZAP - za cca 4 až 6 sekund (trvání odeslání a příjmu SMS) uslyšíte cvaknutí relátka. Doporučuji mít spuštěný sériový kanál a monitorovat, co na něj chodí. Pokud pošlete SMSku s obsahem RELE1:VYP - relé se vypne. O každé aktivitě vám bude odeslána SMSka zpět. Opět neřeším bezpečnost čísla, ale posílám SMSku tam, odkud jsem přijal povel.Na téma bezpečnost napíšu později určitě nějaký doplněk do sketche. Totéž funguje pro RELE2. Funguje-li vše, jak má, pak na sériovém monitoru objevíte toto:

Nova SMSka!!!!
Od:739822476
Obsah SMS:RELE1:ZAP
SMS pro:739822476
Obsah:RELE1 zapnuto!
SMS odeslana!
****************************************
SMS smazana z pameti.
****************************************
Nova SMSka!!!!
Od:739822476
Obsah SMS:RELE1:VYP
SMS pro:739822476
Obsah:RELE1 vypnuto!
SMS odeslana!
****************************************
SMS smazana z pameti.
****************************************

Nyní zkuste odeslat SMS s obsahem Info. Parser tento příkaz vyhodnotí, mrkne v jakém stavu viděl naposledy relátka a přečte aktuální stav vstupů (je to jen příklad, chtělo by to čtení trochu více zrobustnit, ale nechci ten kód v příkladu dělat nepřehledný). Z těchto informací poskládá obsah SMSky a odešle. Je-li vše OK, pak obdržíte SMSku a na sériovém monitoru se objeví toto:

Nova SMSka!!!!
Od:739822476
Obsah SMS:Info
SMS pro:739822476
Obsah:Rele1:VYP,RELE2:ZAP,IN1:1,IN2:1
SMS odeslana!
****************************************
SMS smazana z pameti.
****************************************

Jak již bylo zmíněno ve IV.dílu - parser může být tak bohatý, jak si je napíšete a zařízení tedy může být tak vymakané, jak vymakaný budete mít parser. Takže neváhejte experimentovat a vymýšlejte své kombinace a příkazy.


void checkInput()

{
	String tempMessage;
	bool sendIt = false;
	tempMessage = "Zmena stavu";
	//při změně stavu vstupu odešli SMS
	if (digitalRead(IN1) != IN1Status)
	{
		tempMessage += " IN1:";
		//počkej 200ms a přečti ještě jednou - mohl to byt jen zákmit
		delay(200);
		if (digitalRead(IN1) != IN1Status)
		{
			if (IN1Status == true)
			{
				tempMessage += "0";
				IN1Status = false;
			}
			else
			{
				tempMessage += "1";
				IN1Status = true;
			}
			sendIt = true;

		}
		else
		{
			tempMessage = "Zmena stavu";
			sendIt = false;
		}
			

	}
	if (digitalRead(IN2) != IN2Status)
	{
		tempMessage += " IN2:";
		//počkej 200ms a přečti ještě jednou - mohl to byt jen zákmit
		delay(200);
		if (digitalRead(IN2) != IN2Status)
		{
			if (IN2Status == true)
			{
				tempMessage += "0";
				IN2Status = false;
			}
			else
			{
				tempMessage += "1";
				IN2Status = true;
			}
			sendIt = true;

		}
		else sendIt = false;

	}
	//pokud již modul pracoval s nějakým číslem, tak ho použij
	//pokud ne, pak použij definované číslo SERVIS_NUMBER
	if (sendIt == true)
	{
		sendIt = false;
		if (number.length() < 9) number = SERVIS_NUMBER;
		sendSMS(number, tempMessage);
	}
	
}

Funkce checkInput() bdí nad změnou stavů obou vstupů a jakmile by jeden z nich přešel z 1 na 0 nebo opačně, odešle o této skutečnosti SMSku. Pokud jste si již s SMSkami hráli, pak si do paměti uloží Vaše číslo, v opačném případě je potřeba do definice SERVICE_NUMBER zapsat číslo ručně, jinak budou chodit SMSky výlučně na mé číslo :-), pakliže začnete s testováním od vstupů a relátka necháte na později. Je-li vše OK, pak při "zatahání" za katodu diody v optočlenu se objeví na sériovém kanálu následující:

****************************************
SMS pro:739822476
Obsah:Zmena stavu IN2:0
SMS odeslana!
****************************************
SMS pro:739822476
Obsah:Zmena stavu IN2:1
SMS odeslana!
****************************************

A ve vašem telefonu přistanou dvě SMSky s obsahem Zmena stavu IN2:0 a Zmena stavu IN2:1.

S největší pravděpodobností vznikne pro Arduinotech GSM shield samostatná knihovna, kde budete ušetřeni podrobností s posíláním AT příkazů apod. a budou nejspíše zpřístupněny funkce typu sendSMS, checkSMS, inicializace pak přes nějaký shieldInit(), callNumber(), holdCall() apod. Mám to v plánu, ale pro účely podrobnějšího pohledu, jak to vlastně všechno vevnitř pracuje jistě není na škodu si takový sketch trochu rozebrat a pochopit, jak se věcí mají.

V příštím díle si rozeberem funkce s ovládáním relé pomocí prozvonění telefonu - koukal jsem, že tato zaízení jsou komerčně celkem hojně nabízená za cenu smartphone. Tak si takové zařízení s Arduinotech GSM shieldem rychle naprogramujeme za ani ne 1/3 ceny.

PF

Přidat komentář

Zvýrazněné položky jsou povinné.


TOP produkty

Arduino MEGA2560

Arduino MEGA2560
424 Kč s DPH

Arduino DUE

Arduino DUE
696 Kč s DPH

Kontakt

Ing. Petr Foltýn
Kunčice pod Ondřejníkem 814, 73913
TOPlist