Automatizarea utilizării dispozitivelor radio ASK

Pornind de la sistemul prezentat în proiectul “Convertor ASK USB” putem dezvolta o funcționalitate foarte simplă dar utilă în cazul utilizării mai multor dispozitive radio în bandă ISM de 433MHz modulație ASK – mai ales dacă vorbim de de dispozitive de la producători diverși, incompatibile nativ între ele. Această nouă funcționalitate a sistemului ne va permite să automatizăm diverse operații simple ca de exemplu: ”la declanșarea unui senzor de prezență sau de deschidere a ușii să se aprindă lumina într-o anumită cameră„ sau ”la declanșarea unui senzor de gaz să pornească alarma sistemului antiefracție„ etc. Sistemul nostru va face legătura între componente radio ce fac parte din dispozitive complet diferite și va putea fi utilizat indiferent indiferent dacă componentele respective mai fac sau nu mai fac parte din dispozitivele inițiale (senzorii și elementele de acționare vor funcționa cu sau fără componenta bază originală).

Vom utiliza aceleași componente ca și în lecția precedentă: placă de dezvoltare Arduino Pro Micro cu un microcontroler ATmega 32U4 la 16MHz / 5V, un transmițător radio și un receptor radio – ambele în bandă de 433MHz modulație ASK. Schema de interconectare este de asemenea la fel (transmițătorul conectat la pinul 10, receptorul la pinul 3):

2

Programul, dezvoltat și testat utilizând Arduino IDE 1.8.1, extensia Arduino AVR Boards 1.6.19 și bibilioteca rc-switch 2.6.2, este puțin diferit:

#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();

void setup() {

  while (!Serial);

  Serial.begin(115200);

  mySwitch.enableTransmit(10);

  mySwitch.setRepeatTransmit(3);

  mySwitch.enableReceive(0); }

void loop() {

   if (mySwitch.available()) {

     int value = mySwitch.getReceivedValue();

     if (value != 0) {

      switch (mySwitch.getReceivedValue()) {

        case 6083408:

          Serial.println(“ON command received.”);

          mySwitch.setProtocol(2);

          mySwitch.send(2474994176,32);

          break;

        case 6049984:

          Serial.println(“OFF command received.”);

          mySwitch.setProtocol(2);

          mySwitch.send(2743429632,32);

          break;

        default:

          Serial.print(“Unknown command, received “);

          Serial.print( mySwitch.getReceivedValue() );

          Serial.print(” / “);

          Serial.print( mySwitch.getReceivedBitlength() );

          Serial.print(“bit “);

          Serial.print(“Protocol: “);

          Serial.println( mySwitch.getReceivedProtocol() );

          break;

      }

    }

    mySwitch.resetAvailable();

  }

}

Se poate observa că în cadrul secțiunii loop() se execută o buclă infinită care așteaptă primirea unui cod radio. În funcție de codul radio primit (instrucțiunea switch(mySwitch.getReceivedValue())) se va trimite un alt cod radio ca efect al acțiunii dorite.

3

În cazul exemplului dat s-a utilizat un senzor de deschidere a ușii și o telecomandă radio (ambele făcând parte dintr-un sistem de securitate a locuinței) ca intrări și o priză Conrad RSL ca element de acționare. Pentru mai multe informații legate de diverse dispozitive radio de securitate se poate parcurge și proiectul ”HomeWatch” din cartea ”10(zece) proiecte cu Arduino” și pentru mai multe informații legate de dispozitivele din gama Conrad RSL se pot parcurge și materialele ”Cloud’s Lights” și ”Local Area Power Plugs”.

Codul 6083408 este transmis de senzorul de deschidere a ușii și declanșează deschiderea prizei – cod radio transmis 2474994176. Putem considera că priza alimentează o veioză, o sonerie sau o cameră video de securitate.

4

5

Codul 6049984 este transmis de butonul de armare al telecomenzii radio și va declanșa transmiterea codului radio 2743429632 de închidere a prizei. Orice alt cod radio, necunoscut, va avea ca efect afișarea în consola serială a mesajului Unknown command urmat de codul numeric propriu-zis, acest lucru permite aflarea codurilor ce dorim a fi introduse în program.

6

Funcționarea sistemului nu este limitată la dispozitive radio prefabricate. Putem cu ușurință să dezvoltăm sisteme simple de supraveghere a parametrilor de mediu sau sisteme de acționare pentru diverse sarcini casnice. Un bun exemplu este prezentat în cadrul proiectului ”HomeWatch” din cartea ”10(zece) proiecte cu Arduino” – este vorba de un senzor de bucătărie ce permite avertizarea în caz de inundație sau în cazul unor scurgeri de gaze. Senzorul se bazează pe o placă de dezvoltare Arduino Pro Mini, un modul senzor de gaz metan MQ4 și un transmițător radio 433MHz ASK.

Senzorul de bucătărie poate detecta două evenimente neplăcute ce pot apărea într-o locuință în zona bucătăriei: scurgeri de gaz, senzorul va trimite codul radio 3333310 la apariția acestui eveniment, și scurgeri de apă la nivelul podelei, senzorul va trimite codul radio 3333311 la apariția acestui eveniment. Acest sistem de tip senzor poate fi utilizat cu ușurință împreună cu sistemul de automatizare prezentat putând declanșa o alarmă sonoră sau, de ce nu, un sistem de deschidere a ferestrelor. Schema și codul necesar sunt prezentate în cele ce urmează.

7

Programul a fost testat utilizând Arduino IDE 1.8.1, extensia Arduino AVR Boards 1.6.19 și bibilioteca rc-switch 2.6.2.

#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();

volatile unsigned long alarma_apa = 0;

volatile unsigned long alarma_gaz = 0;

const unsigned long interval = 60000;

const unsigned int pin_rf = 10;

const unsigned int pin_gaz = A0;

const unsigned int pin_apa = A1;

const unsigned long cod_gaz = 3333310;

const unsigned long cod_apa = 3333311;

void setup() {

  mySwitch.enableTransmit(pin_rf);

  mySwitch.setRepeatTransmit(10);

  pinMode(pin_apa,INPUT_PULLUP); }

void loop() {

  if (analogRead(pin_gaz)>500)

  {   if (alarma_gaz == 0)

      {

         mySwitch.send(cod_gaz,24);

         delay(3000);

         alarma_gaz = millis();

      }

      else

        if ((millis() – alarma_gaz) > interval)

        {

          mySwitch.send(cod_gaz,24);

          delay(2000);

          alarma_gaz = millis();

        }

   }

   else

     if ((alarma_gaz != 0) && ((millis() – alarma_gaz) > interval) )

     {

       alarma_gaz = 0;

     }

   if (analogRead(pin_apa)<500)

   {

      if (alarma_apa == 0)

      {

         mySwitch.send(cod_apa,24);

         delay(3000);

         alarma_apa = millis();

      }

      else

        if ((millis() – alarma_apa) > interval)

        {

          mySwitch.send(cod_apa,24);

          delay(2000);

          alarma_apa = millis();

        }

   }

   else

     if ((alarma_apa != 0) && ((millis() – alarma_apa) > interval) )

     { alarma_apa = 0; }

}

Proiect Convertor ASK / USB

Multe dintre dispozitivele casnice fără fir funcționează prin comunicație radio în bandă ISM de 433MHz modulație ASK. Cele mai des întâlnite astfel de dispozitive sunt sistemele de securitate fără fir, prizele sau soclurile de bec comandate de la distanță și chiar sistemele meteo cu senzori fără fir. Toate aceste sisteme oferă dispozitive fără fir gata construite, ieftine și foarte ușor de folosit în sisteme de comandă personalizate. Dacă sistemul de comandă este bazat pe o placă de dezvoltare de tipul Arduino nu este nici un fel de problemă deoarece există module radio ASK în bandă de 433MHz cu un cost mic și ușor de folosit. Dacă sistemul de comandă are o complexitate mai mare și necesită utilizarea unui PC sau a unei plăci de tipul Raspberry Pi lucrurile se complică puțin. În cadrul acestui proiect ne propunem să realizăm un sistem ieftin și de mici dimensiuni care să realizeze legătura între comunicația radio în bandă de 433MHz modulație ASK și portul USB prezent în sistemele de calcul de uz general (PC-uri, laptop-uri, plăci de dezvoltare bazate pe microprocesoare). Astfel de dispozitive există deja dar au un preț destul de mare (a se vedea (*)).

Sistemul nostru se va baza pe o placă de dezvoltare Arduino Pro Micro cu un microcontroler ATmega 32U4 la 16MHz / 5V, un transmițător radio și un receptor radio – ambele în bandă de 433MHz modulație ASK. Componentele au fost alese astfel încât să asigure un cost total cât mai scăzut și posibilitatea de a fi integrate într-o carcasă de mici dimensiuni (aproximativ cât o baterie USB externă, imagine alăturată, astfel de carcase se găsesc de cumpărat pe Internet la prețuri de circa 2$).

2

Dispozitivul rezultat va fi văzut de sistemul de calcul în cadrul căruia va fi utilizat ca un dispozitiv serial ce va transmite către sistem codurile radio primite și va transmite radio codurile primite de la sistem – va fi realiza conversia dintre comunicația serială (over USB) și comunicația radio ASK în bandă de 433MHz.

 

Interconectarea componentelor

Interconectarea dintre placa de dezvoltare și cele două module radio este reprezentată în diagrama următoare:

3

Transmițătorul radio va avea linia de date conectată la pinul 10 al plăcii de dezvoltare iar receptorul radio va avea linia de date conectată la pinul 4 al plăcii de dezvoltare (pinul de întrerupere 0). Ambele module se vor alimenta la 5V prin intermediul pinilor VCC / GND ai plăcii de dezvoltare.

Pentru mai multe detalii despre instalarea și operarea plăcii Sparkfun Pro Micro se recomandă parcurgerea materialului ”Pro Micro & Fio V3 Hookup Guide” .

 

Programarea sistemului

Programul a fost dezvoltat și testat utilizând Arduino IDE 1.8.1 cu extensia Arduino AVR Boards 1.6.19 instalată și bibilioteca rc-switch 2.6.2.

 

#include <string.h>

#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();

void setup() {

  while (!Serial);

  Serial.begin(115200);

  mySwitch.enableTransmit(10);

  mySwitch.setRepeatTransmit(3);

  mySwitch.enableReceive(0);

}

void loop() {

  char inData[80];

  int index = 0;

  while(Serial.available() > 0)

  {

     char aChar = Serial.read();

     if(aChar == ‘\n’)

     {

        inData[index] = NULL;

        index = -1;

     }

     else

     {

        inData[index] = aChar;

        index++;

        inData[index] = ‘\0’;

     }

  }

  char * number;

  unsigned long number1, number2, number3;

  if (index==-1) {

    number = strtok(inData,”,”);

    number1 = atol(number);

    number = strtok(NULL,”,”);

    if(number!=NULL) { number2=atoi(number); }

    number = strtok(NULL,”,”);

    if(number!=NULL) { number3=atoi(number); mySwitch.setProtocol(number3);}

    mySwitch.send(number1,number2);

  }

  if (mySwitch.available()) {

     int value = mySwitch.getReceivedValue();

        if (value == 0) {

      Serial.print(“Unknown encoding”);

    } else {

      Serial.print( mySwitch.getReceivedValue() );

      Serial.print(“,”);

      Serial.print( mySwitch.getReceivedBitlength() );

      Serial.print(“,”);

      Serial.println( mySwitch.getReceivedProtocol() );

    }

    mySwitch.resetAvailable();

  }

}

Comunicația dintre sistemul de calcul și dispozitivul USB construit va avea mesajele de forma COD,DIMENSIUNE,VERSIUNEPROTOCOL .

De exemplu, în consola serială, apăsarea butoanelor unei telecomenzi radio ce face parte dintr-un sistem de securitate a locuinței va avea următorul efect (se observă codul butonului de dimensiune 24 biți, protocol radio versiunea 1).

4

5

Pentru mai multe informații legate de diverse dispozitive radio de securitate se poate parcurge și proiectul ”HomeWatch” din cartea ”10(zece) proiecte cu Arduino”.

În cazul în care dorim să dăm o comandă radio vom tasta în consola serială cei trei parametrii necesari transmisiei. De exemplu: 2474994176,32,2 (cod de deschidere pe 32 de biți, protocol versiunea 2, specific unei prize radio din gama Conrad RSL).

6

Pentru mai multe informații legate de dispozitivele din gama Conrad RSL se pot parcurge și materialele ”Cloud’s Lights” și ”Local Area Power Plugs”.

Bineînțeles, dispozitivul prezentat nu își găsește utilitatea majoră în comanda sau supravegherea manuală în consola serială. Utilizarea lui trebuie integrată într-o aplicație specifică platformei la care este conectat (o aplicație Windows sau un script de automatizare sub platforma Linux) și sub care pot fi predefinite codurile de comandă pentru diverse dispozitive cunoscute.

O aplicație utilă poate fi utilizarea dispozitivului în conjuncție cu o platfotmă de automatizare a locuinței, de exemplu OpenHAB. În acest scop se pot vedea și materialele ”Realizarea unui sistem de tip Home Automation” și ”Conectarea unor dispozitive antiefracție la platforma OpenHab”.

Proiect Termometru Simfonic

În cadrul proiectului de față vom prezenta o soluție de achiziție (ca exemplificare vom face achiziția temperaturii și umidității mediul ambiant) cu raportare IoT prin GPRS (rețea de telefonie mobilă). Soluția propusă este una simplă și vine în întâmpinarea unei probleme extrem de actuală: supravegherea de la distanță a unor parametrii de mediu în locații izolate unde nu dispunem de infrastructură de rețea Internet – în loc de temperatură și umiditate putem face achiziția unor parametrii ai solului (aplicații pentru agricultură inteligentă) sau achiziția unor parametrii de proximitate și integritate (aplicații de securitate).

Soluția propusă se bazează pe placa de dezvoltare Adafruit Feather 32U4 FONA, placă ce combină un microcontroler ATmega32U4 la 8MHz / 3.3V și un controler GSM SIM800 quad-band (850/900/1800/1900MHz). Placa necesită alimentarea de la un acumulator LiPo extern de minim 500mAh (se pot utiliza (*), (*), (*)) și o antenă GSM uFL.

2

Pentru achiziția parametrilor temperatură și umiditate vom utiliza un senzor digital I2C Si7021 ce are o precizie mare de măsurare și se poate interfața foarte ușor cu placa de dezvoltare utilizată.

3

Funcționarea sistemului necesită o cartelă GSM 2G cu capabilități de transfer de date. Pentru acest lucru vă propunem utilizarea unui SIM Simfony Mobile M2M – cartelă GSM ce oferă exclusiv servicii mobile de date.

4

Cartela este disponibilă gratuit prin comandă pe site-ul companiei Simfony Mobile SRL  sau împreună cu un produs din gama GSM pe site-ul Robofun. Cartela necesită înregistrarea și introducerea codului promoțional pentru activare și oferă gratuit 10MB de date mobile valabile 3 luni. Ulterior costurile de funcționare sunt de 0.25EURO, 0.5EURO, 1EURO pentru 1MB, 5MB respectiv 10MB trafic de date. Chiar dacă traficul inclus are valori modice pentru un sistem de raportare IoT este suficient iar costurile sunt rezonabile. O caracteristică importantă a cartelei SIM Simfony este indepența de un operator de telefonie anume, dispozitivul GSM ce utilizează cartela Simfony poate utiliza orice operator de telefonie mobilă în funcție de zona în care se află chiar și afara României.

 

Interconectarea componentelor

Interconectarea dintre senzorul Si7021 și placa Feather 32U4 FONA este reprezentată în diagrama următoare:

5

Pentru mai multe detalii despre operarea plăcii Adafruit Feather 32U4 FONA se recomandă parcurgerea materialului ”Adafruit Feather 32u4 FONA – Take your Feather anywhere in the world”.

 

Programarea sistemului

Pentru realizarea și testarea sistemului s-a utilizat Arduino IDE 1.8.1 cu extensia Adafruit AVR Boards 1.4.9 instalată precum și bibliotecile Adafruit FONA 1.3.2, Adafruit Si7021, Sleep_n0m1 1.1.1.

 

#include “Adafruit_FONA.h”

#define FONA_RX  9

#define FONA_TX  8

#define FONA_RST 4

#define FONA_RI  7

#define FONA_DTR 5

#define apn “internet.simfony.net”

#define apnusername “” 

#define apnpassword “” 

char replybuffer[255];

#include <SoftwareSerial.h>

SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);

SoftwareSerial *fonaSerial = &fonaSS;

Adafruit_FONA fona = Adafruit_FONA(FONA_RST);

uint8_t type;

#include <Sleep_n0m1.h>

Sleep sleep;

#include <Adafruit_Si7021.h>

Adafruit_Si7021 sensor = Adafruit_Si7021();

 

Dacă se dorește supravegherea funcționării sistemului pe serială se va adăuga următoarea linie, în funcționarea propriu-zisă nu este necesară:

 

#define debug

 

În cadrul secțiunii setup() se va realiza inițializarea modulului GSM și a senzorului Si7021:

 

void setup() {

  #ifdef debug

    while (!Serial);

    Serial.begin(115200);

    Serial.println(“Initializing…”);

  #endif

  digitalWrite(FONA_DTR,LOW);

  fonaSerial->begin(4800);

  if (! fona.begin(*fonaSerial)) {

    #ifdef debug

      Serial.println(F(“Couldn’t find FONA”));

    #endif

    delay(1);

    while (1);

  }

  #ifdef debug

    type = fona.type();

    Serial.println(F(“FONA is OK”));

    Serial.print(F(“Found “));

    switch (type) {

      case FONA800L:

        Serial.println(F(“FONA 800L”)); break;

      case FONA800H:

        Serial.println(F(“FONA 800H”)); break;

      case FONA808_V1:

        Serial.println(F(“FONA 808 (v1)”)); break;

      case FONA808_V2:

        Serial.println(F(“FONA 808 (v2)”)); break;

      case FONA3G_A:

        Serial.println(F(“FONA 3G (American)”)); break;

      case FONA3G_E:

        Serial.println(F(“FONA 3G (European)”)); break;

      default:

        Serial.println(F(“???”)); break;

    }

   #endif

  #ifdef debug

    char imei[15] = {0};

    uint8_t imeiLen = fona.getIMEI(imei);

    if (imeiLen > 0) {

      Serial.print(“Module IMEI: “); Serial.println(imei);

    }

  #endif

  fona.getSIMCCID(replybuffer); 

  #ifdef debug

    Serial.print(F(“SIM CCID = “));

Serial.println(replybuffer);

  #endif

  if (!fona.enableNetworkTimeSync(true)) {

     #ifdef debug

      Serial.println(F(“Failed to enable NTS”));

     #else

      ;

     #endif

  }

  delay(5000);

  fona.setGPRSNetworkSettings(F(apn),F(apnusername),F(apnpassword));

  uint8_t n=0;

  #ifdef debug

    Serial.print(“Connecting to network.”);

  #endif

  while (n!=5) {

    n = fona.getNetworkStatus();

    #ifdef debug

      Serial.print(“.”);

    #endif

    delay(1000);

  }

  #ifdef debug

    Serial.println(“OK”);

  #endif

  #ifdef debug

    n = fona.getRSSI();

    int8_t r;

    if (n == 0) r = -115;

    if (n == 1) r = -111;

    if (n == 31) r = -52;

    if ((n >= 2) && (n <= 30)) { r = map(n, 2, 30, -110, -54); }

    Serial.print(r); Serial.println(F(“dBm”));

  #endif

  sensor.begin();

  delay(5000);

}

 

Sistemul va raporta către serviciul IoT ThingSpeak valorile achiziționate (temperatură și umiditate) precum și voltajul și procentul de încărcare a acumulatorului ce alimentează sistemul. Secțiunea loop() implementează atât partea de achiziție cât și partea de transmisie de rețea prin intermediul comunicației mobile. În cadrul codului trebuie personalizată valoarea parametrului key ce se obține în urma înregistrării gratuite pe site-ul ThingSpeak. Achiziția și raportarea se realizează la un interval de o oră (3600000ms), în intervalul de inactivitate atât modulul GSM cât și microcontrolerul 32u4 se află în mod de consum redus.

 

void loop() {

while (!fona.enableGPRS(true)) {

#ifdef debug

Serial.println(F(“Failed to turn on GPRS”));

#endif

delay(5000);

}

uint16_t vbat;

uint16_t pbat;

#ifdef debug

if (fona.getBattVoltage(&vbat)) { Serial.print(F(“VBat = “)); Serial.print(vbat);

Serial.println(F(” mV”)); }

if (fona.getBattPercent(&pbat)) { Serial.print(F(“VPct = “)); Serial.print(pbat);

Serial.println(F(“%”));   }

Serial.println(“——————————————————“);

#else

fona.getBattVoltage(&vbat);

fona.getBattPercent(&pbat);

#endif

float temperature, humidity;

temperature = sensor.readTemperature();

humidity = sensor.readHumidity();

#ifdef debug

Serial.print(“Humidity:    “);

Serial.print(humidity, 2);

Serial.print(“\tTemperature: “);

Serial.println(temperature, 2);

#endif

String temp = “api.thingspeak.com/update?key=…&field1=” + String(vbat/1000.0F,2) + “&field2=” + String(pbat) + “&field3=” + String(temperature,2) + “&field4=” + String(humidity,2);

uint16_t statuscode;

int16_t length;

char url[100];

temp.toCharArray(url,temp.length()+1);

#ifdef debug

Serial.println(url);

if (!fona.HTTP_GET_start(url, &statuscode, (uint16_t *)&length)) Serial.println(“Failed

read HTTP!”);

#else

fona.HTTP_GET_start(url, &statuscode, (uint16_t *)&length);

#endif

while (length > 0) {

while (fona.available()) {

char c = fona.read();

#ifdef debug

Serial.write(c);

#endif

length–;

if (! length) break;

}

#ifdef debug

Serial.println();

#endif

break;

}

fona.HTTP_GET_end();

delay(100);

#ifdef debug

Serial.println(“——————————————————“);

if (!fona.enableGPRS(false)) Serial.println(F(“Failed to turn off GPRS”));

#else

fona.enableGPRS(false);

#endif

delay(100);

digitalWrite(FONA_DTR,HIGH);

#ifdef debug

delay(3600000);

#else

sleep.pwrDownMode();

sleep.sleepDelay(3600000);

#endif

digitalWrite(FONA_DTR,LOW);

delay(100);

}

 

Configurarea sistemului de raportare IoT

Sistemul nostru este un sistem tipic IoT ce utilizează platforma on-line ThingSpeak. Utilizarea platformei necesită înregistrare dar aceasta este gratuită.

6

Platforma ThingSpeak este una dintre cele mai cunoscute platforme IoT ce oferă servicii de stocare, prelucrare și vizualizare a datelor. Unul dintre avantajele majore ale platformei este posibilitatea de execuție de programe scrise în limbajul Matlab.

După înregistrare se va defini un nou canal înregistrare a datelor (My Channels / New Channel). Definirea canalului va genera și cheia (Write API Key) ce trebuie utilizată în program.

7

În cadrul acestui canal vom defini patru câmpuri Vbat, Vperc, Temperature și Humidity ce vor stoca efectiv datele trimise de dispozitivul nostru.

8

După punerea în funcțiune a sistemului se vor putea vedea și datele trimise de dispozitiv (secțiunea PrivateView).

9

Ce putem face cu datele înregistrate pe Robofun IoT?

Înregistrarea datelor în cloud este una dintre cele mai sigure metode de păstrare a datelor. Accesibilitatea acestora este, în același timp, un avantaj major în cazul vizualizării online. Serviciul cloud Robofun IoT oferă ambele avantaje permițând utilizatorilor să-și păstreze în siguranță datele provenite de la senzorii și sistemele de monitorizare electronică și să aibă disponibile informațiile de oriunde există o conexiune Internet. Dar, mai mult decât atât, datele stocate de serviciul Robofun IoT sunt disponibile pentru a fi preluate de alte servicii cloud și pot da naștere unor aplicații Internet colaborative de prelucrare și gestionare a informațiilor provenite de la dispozitivele IoT.

Datele stocate de serviciul Robofun IoT sunt disponibile utilizatorilor sub forma unei structuri JSON accesibile prin intermediul protocolului HTTP. Astfel, accesând URL-ul:

http://iot.robofun.ro/api/v1/senzor/[aici_introduceti_tokenul_senzorului]/data.json

vom putea vedea toate datele înregistrate de serviciu pentru un anume senzor.

2

Datele în format JSON pot fi preluate și introduse într-o bază de date locală pentru a deservi o aplicație web sau desktop proprie. Se poate vedea proiectul software „json-to-mysql” care permite salvarea unei structuri JSON într-o bază de date MySQL. Totuși, nu este nevoie scrierea unei aplicații proprii pentru a putea utiliza datele stocate în cadrul serviciului Robofun IoT.

O soluție foarte simplă este preluarea datelor într-un fișier Google Sheets. Această soluție este descrisă amănunțit în materialul „How to import JSON data into Google Spreadsheets in less than 5 minutes”. Pentru preluarea datelor se crează un fișier Google Sheets în Google Drive și în modul de editare se selectează Tools / Script editor… .

3

4

Se șterge codul implicit și se copiază codul de la adresa (5) în fișierul de script asociat fișierului Google Sheets. Fișierul de cod se redenumește  ImportJSON.gs și se salvează.

Întoarcându-ne în fișierul Google Sheets vom edita prima celulă din tabel și vom înscrie în aceasta:

=ImportJSON(“http://iot.robofun.ro/api/v1/senzor/[aici_introduceti_tokenul_senzorului] /data.json”)

În mod automat tabelul va prelua la fiecare deschidere datele complete din serviciul Robofun IoT.

5

În momentul în care datele provenite de la senzori se regăsesc în fișierul Google Sheets aceste pot fi folosite ca intrări pentru alte servicii online. Un serviciu online foarte interesant ce oferă posibilitatea interconectării între diverse funcționalități Internet este Zapier.

6

Acesta oferă posibilitatea creării unui cont gratuit și pe baza acestuia este posibilă interconectarea de diverse servicii specifice Internet (email, rețele sociale, servicii de stocare cloud a fișierelor etc.). În cazul nostru vom crea două aplicații (Zaps) ce se vor baza pe informațiile din fișierul Google Sheets. Una dintre aplicații va transforma datele din tabelul Google Sheets într-un flux RSS iar cea de a doua va prelua fiecare linie nouă din tabel și o va transforma într-o postare Facebook.

7

Prima aplicație are ca scop transformarea datelor provenite de la senzor într-un flux RSS astfel încât să poată fi disponibile mai rapid în diverse aplicații de știri. Pentru această aplicație vom alege ca declanșator (Trigger App) Google Sheets – New Spreadsheet Row. Pentru ca serviciul Zapier să poată accesa fișierele de pe Google Drive este necesară acordarea unei permisiuni între cele două servicii. Ca acțiune asociată (Zapier Action) vom alege RSS – serviciu oferit intern de platforma Zapier. După configurarea opțiunilor specifice fluxului RSS și salvarea aplicației vom putea deja să vedem datele pe canalul RSS (datele postate de senzor).

8

Cea de a doua aplicație propusă ilustrează utilizarea datelor provenite de la senzor (via Robofun IoT și Google Sheets) pentru a construi o postare pe rețeaua de socializare Facebook. Vom utiliza același declanșator ca și în cazul precedent dar vom utiliza ca acțiune din secțiunea Facebook – Create Page Post. La fel ca și în cazul precedent este necesar să acordăm permisiunea serviciului Zapier pentru a posta pe pagina noastră de Facebook. După definitivarea configurației la fiecare nouă înregistrare de la senzorul nostru va apărea o postare pe Facebook.

9

Cele două aplicații date ca exemplu sunt doar pentru a vă stârni interesul. Posibilitățile oferite de serviciul Zapier sunt extrem de diverse și includ posibilitatea de interconectare cu alte rețele sociale (Twitter, LinkedIn, Instagram) și servicii Internet (email, Google Forms, servicii online de predicție a vremii, servicii de tipărire online, servicii de SMS online etc.). Aplicațiile pe care le puteți genera utilizând date IoT și servicii online sunt limitate ca diversitate doar de propria imaginație.

Pedometru IoT

Dispozitivele de tip pedometru (dispozitive ce contorizează numărul de pași) sunt din ce în ce mai populare. La acest lucru a condus pe de o parte scăderea prețului dispozitivelor electronice dar și necesitatea psihologică de a avea un ”martor” la eforturile personale de a ne menține în formă. Pedometrele variază ca funcționalitate de la simple dispozitive ce afișează pe un ecran numărul de pași până la dispozitive ce raportează prin protocoale fără fir către telefon sau tabletă numărul de pași permițând astfel generarea de rapoarte pe diverse intervale de timp și chiar clasamente între mai multe persoane.

În cadrul proiectului de față vă propunem implementarea unui dispozitiv de tip pedometru ce raportează numărul de pași prin Internet către serviciul cloud Robofun IoT. Serviciul cloud Robofun IoT este gratuit și permite înregitrarea și vizualizarea datelor prin intermediul unei interfețe web, pentru mai multe detalii puteți consulta documentația oficială a serviciului.

Există mai multe exemple de proiecte ce își propun implementarea funcționalității de pedometru dar nu și funcționalitatea de înregistrare online a datelor. Totuși, putem parcurg câteva astfel de proiecte pentru a înțelege diverse soluții de implementare: „Arduino Pedometer”, „Simple, Easy and Cheap DIY Pedometer With Arduino”, „Arduino Pedometer Watch, With Temperature, Altitude and Compass!”.

Dispozitivul prezentat va utiliza, pentru a putea sesiza fenomenul de ”pas”, un accelerometru digital ADXL345. Analiza fenomenelor fizice implicate (accelerații, recunoașterea tiparului generat de efectuarea unui pas) nu fac subiectul acestei lecții dar recomandăm parcurgerea suplimentară a următorului material: „Full-Featured Pedometer Design Realized with 3-Axis Digital Accelerometer”.

Partea de achiziție a datelor și de comunicație în rețea va fi asigurată de o placă de dezvoltare Sparkfun ESP32 Thing – placă echipată cu microprocesorul ESP32 de la Espressif ce asigură conectivitate WiFi și BLE (chiar dacă dispozitivul prezentat exemplifică doar partea de conectivitate WiFi asta nu înseamnă că acesta nu poate fi dezvoltat suplimentar pentru a putea asigura conectivitate BLE cu dispozitive mobile de tip telefon sau tabletă). Pe lângă puterea de procesare și conectivitatea WiFi placa de dezvoltare oferă avantajul de a funcționa alimentată de la un acumulator LiPo de 3.7V permițând astfel ca sistemul să fie portabil.

Schema de interconectare între placa de dezvoltare și accelerometru este următoarea (accelerometrul se va alimenta la 3.3V, pinul SDA se va conecta la pinul 21 al plăcii de dezvoltare iar SCL la pinul 22, pinul CS se va conecta la 3.3V iar SD0 la GND):

2

Pentru integrarea plăcii Sparkfun ESP32 Thing în mediul Arduino IDE este necesar să parcurgeți materialul „ESP32 Thing Hookup Guide” deoarece sunt necesare operații manuale de copiere și instalare a utilitarelor aferente.

Programul va utiliza, pentru detecția numărului de pași, bibliotecile Pedometer și Accelerometer_ADXL345 a celor de la Seeed-Studio.

Programul a fost dezvoltat și testa utilizând Arduino IDE 1.8.3. În program trebuie personalizate datele de conectare la rețeaua WiFi (networkName și networkPswd).

#include <WiFi.h>

#include “pedometer.h”

#include <ADXL345.h>

Pedometer pedometer;

#include <Wire.h>

const char * networkName = ““;

const char * networkPswd = ““;

const char * hostDomain = “iot.robofun.ro”;

const int hostPort = 80;

const int BUTTON_PIN = 0;

const int LED_PIN = 5;

În cadrul secțiunii setup() se vor realiza inițializările necesare. Placa de dezvoltare are integrate un led (pinul 5) și un buton (pinul 0). Ledul va indica (se va aprinde) activitățile de rețea din program (conectare AP, postare IoT) iar butonul va fi utilizat pentru a reseta numărul de pași efectuați.

void setup() {

  Serial.begin(115200);

  pinMode(BUTTON_PIN, INPUT_PULLUP);

  pinMode(LED_PIN, OUTPUT);

  digitalWrite(LED_PIN, HIGH);

  pedometer.init();

  connectToWiFi(networkName, networkPswd);

  digitalWrite(LED_PIN, LOW); }

Constanta INTERVAL va indica perioda de timp (în milisecunde) la care se va face transmiterea numărului de pași efectuați către serviciul IoT.

#define INTERVAL 60000

unsigned long lastPost = 0;

void loop() {

  if (digitalRead(BUTTON_PIN) == LOW)

pedometer.stepCount = 0;

  if((millis() – lastPost) > INTERVAL) {

    digitalWrite(LED_PIN, HIGH);

    if (WiFi.status() != WL_CONNECTED)

connectToWiFi(networkName, networkPswd);

    requestURL(hostDomain, hostPort);

    digitalWrite(LED_PIN, LOW);

    lastPost = millis();

  }

  delay(10);

}

Procedura connectToWiFi() este responsabilă cu conectarea la rețeaua WiFi.

void connectToWiFi(const char * ssid, const char * pwd)

{ int ledState = 0;

  Serial.println(“Connecting to WiFi network: ” + String(ssid));

  WiFi.begin(ssid, pwd);

  while (WiFi.status() != WL_CONNECTED)   {

    digitalWrite(LED_PIN, ledState);

    ledState = (ledState + 1) % 2;

    delay(500);

    Serial.print(“.”);

  }

  Serial.println();

  Serial.println(“WiFi connected!”);

  Serial.print(“IP address: “);

  Serial.println(WiFi.localIP());

}

Procedura requestURL() este responsabilă cu postarea către serviciul IoT. În cadrul acesteia trebuie completată valoarea cheii de autentificare (TOKEN) obținute în urma înregistrării în cadrul serviciului Robofun IoT.

void requestURL(const char * host, uint8_t port) {

  Serial.println(“Connecting to domain: ” + String(host));

  WiFiClient client;

  if (!client.connect(host, port))  {

    Serial.println(“connection failed”);

    return;

  }

  Serial.println(“Connected!”);

  pedometer.stepCalc();

client.print((String)”GET /api/v1/senzor/TOKEN/input?value=” + String(pedometer.stepCount) + “HTTP/1.1\r\n” +  “Host: ” + String(host) + “\r\n” +  “Connection: close\r\n\r\n”);

  unsigned long timeout = millis();

  while (client.available() == 0)

  {

    if (millis() – timeout > 5000)

    {

      Serial.println(“>>> Client Timeout !”);

      client.stop();

      return;

    }

  }

  while (client.available())  {

    String line = client.readStringUntil(‘\r’);

    Serial.print(line);

  }

  Serial.println();

  Serial.println(“closing connection”);

  client.stop();

}

Sistemul va posta în mod automat numărul de pași la un interval de 10 minute. În cazul în care ieșim din aria de acoperire WiFi sistemul va contoriza în continuarea numărul de pași efectuați și la reîntoarcere va realua raportarea. Astfel vom putea evalua numărul de pași efectuați și ”în casă” și afară. Resetarea numărului de pași se va face apăsând butonul de pe pinul 0 al plăcii de dezvoltare.

3

IoT Power Monitor

Măsurarea consumului echipamentelor electronice este o preocupare continuă în domeniul monitorizării utilizării energiei electrice. Evoluția sistemelor IoT a făcut posibilă apariției unor echipamente de monitorizare a consumului ce raportează datele măsurate prin intermediul rețelei Internet direct către un serviciu cloud. În cadrul acestui proiect vom prezenta construcția unui astfel de sistem IoT de monitorizare a puterii electrice consumate.

Sistemul se va baza pe placa de dezvoltare LinkIt Smart 7688 Duo ce oferă o combinație extrem de puternică (asemănătoare și compatibilă software cu placa de dezvoltare Arduino Yun) între un microprocesor MediaTek MT7688 ce rulează sistemul de operare OpenWRT și un microcontroler ATmega32U4.

2

Pentru a utiliza conectivitatea de rețea oferită de componenta MT7688 este nevoie de configurarea conexiunii WiFi. Configurarea conexiunii WiFi necesită conectarea la AP-ul (Access Point) LinkIt_Smart_7688_XXXXXX (XXXXXX este un identificator specific fiecărei plăci în parte) cu ajutorul unui laptop sau un terminal inteligent WiFi (telefon inteligent, tabletă). După conectare se deschide cu ajutorul unui client web (browser) adresa http://192.168.100.1 sau http://mylinkit.local ce permite accesul la interfața de administrare a componentei MT7688 / a sistemului de operare OpenWRT. La prima conectare se va stabili și parola utilizatorului root (utilizator cu drepturi de administrator).

3

Modificările necesare conectării plăcii LinkIt Smart 7688 Duo la Internet presupun trecerea componentei WiFi din mod AP în mod client (Station mode) și configurarea conectării la un AP ce oferă conectivitate Internet. Ambele modificări se fac din secțiunea Network a interfeței de administrare.

4

5

Atenție!!! Nu introduceți placa de dezvoltare într-o subrețea 192.168.100.0/24 deoarece chiar și în modul client interfața AP cu adresa 192.168.100.1 este activă și o altă adresă IP din aceiași subrețea va deruta mecanismul de rutare TCP/IP.

După configurare accesului la Internet, placa se poate accesa prin intermediul interfeței web prezentată anterior sau prin intermediul protocolului SSH, utilizând IP-ul oferit de AP-ul configurat. Utilizatorul necesar conectării este root și parola stabilită anterior. Pentru mai mult informații legate de configurarea plăcii LinkIt Smart 7688 Duo se poate consulta și „Get Started with the LinkIt Smart 7688 Duo Development Board”.

A doua operație de configurare, necesară pentru a utiliza biblioteca Bridge (bibliotecă specifică plăcii Arduino Yun) sub mediul Arduino IDE, necesită conectarea la consola plăcii de dezvoltare LinkIt Smart 7688 Duo prin intermediul unui client SSH (putty (3), de exemplu) și executarea următoarelor comenzi:

uci set yunbridge.config.disabled=’0′ 

uci commit 

reboot

Pentru măsurarea consumului vom utiliza senzorul de curent INA219 – senzor digital I2C ce permite măsurarea de tensiuni de până la 26V și curenți de până la 3.2A cu o precizie de 1%. Interconectarea cu placa de dezvoltare se va face prin intermediul magistralei I2C:

6

Senzorul se va alimenta la 3.3V iar pinii SCL și SDA se vor conecta la pinii D3 respectiv D2 ai plăcii de dezvoltare. Pentru a putea măsura curentul și tensiunea este necesar să trecem linia de alimentare a dispozitivului electronic monitorizat prin senzor. Acest lucru se poate face prin secționarea firului de alimentare sau prin conectarea unei perechi de mufe jack mamă – tată care să permită conectarea mufei de alimentare la senzor și senzorul la dispozitivul electronic. ATENȚIE!!! Inserarea senzorului se face pe linia de tensiune nu pe cea de masă.

Având în vedere scopul de monitorizare IoT a sistemului realizat în cadrul lecției de față vom utiliza cloud Robofun IoT. Pentru utilizarea acestui serviciu este necesară înregistrarea gratuită.

4

După înregistrare și conectare este necesară definirea unui senzor (Adauga senzor) pentru a putea înregistra puterea măsurată.

5

După definirea senzorului este necesar să copiem cheia de autentificare (Token) pentru a o utiliza în program.

3

Programul a fost realizat și testat utilizând Arduino IDE 1.8.3 cu extensia LinkIt Smart 7688 Duo 0.1.8 instalată și biblioteca Adafruit INA219 1.0.0.

#include <Bridge.h>

#include <HttpClient.h>

#include <Wire.h>

#include <Adafruit_INA219.h>

Adafruit_INA219 ina219;

Decomentarea directivei #define debug va permite supravegherea mesajelor de funcționare în consola serială.

//#define debug

void setup(void) {

  #ifdef debug

    SerialUSB.begin(115200);

    while (!SerialUSB);

  #endif

  ina219.begin();

  Bridge.begin();

}

În cadrul secțiunii loop() este necesară completarea valorii TOKEN obținută în procesul de înregistrare a senzorului în platforma Robofun IoT.

void loop(void) {

  float shuntvoltage = 0;

  float busvoltage = 0;

  float current_mA = 0;

  float loadvoltage = 0;

  float power = 0;

  shuntvoltage = ina219.getShuntVoltage_mV();

  busvoltage = ina219.getBusVoltage_V();

  current_mA = ina219.getCurrent_mA();

  loadvoltage = busvoltage + (shuntvoltage / 1000);

  power = loadvoltage * current_mA;

  #ifdef debug

    SerialUSB.print(“Bus Voltage:   “);

   SerialUSB.print(busvoltage);

   SerialUSB.println(” V”);

    SerialUSB.print(“Shunt Voltage: “);

    SerialUSB.print(shuntvoltage);

   SerialUSB.println(” mV”);

    SerialUSB.print(“Load Voltage:  “);

   SerialUSB.print(loadvoltage);

   SerialUSB.println(” V”);

    SerialUSB.print(“Current:       “);

   SerialUSB.print(current_mA); 

   SerialUSB.println(” mA”);

    SerialUSB.print(“Power:       “);

   SerialUSB.print(power);

   SerialUSB.println(” mW”);

    SerialUSB.println(“”);

  #endif

  HttpClient client;

  String temp = “http: ” + “//iot.robofun.ro/api/v1/senzor/TOKEN/input?value=” + String(power,2);

  client.get(temp);

  while (client.available()) {

    char c = client.read();

    #ifdef debug

      SerialUSB.print(c);

    #endif

  }

  #ifdef debug

    SerialUSB.println();

    SerialUSB.flush(); 

  #endif

  delay(60000);

}

Programul va trimite la un interval de 1 minut (60 secunde = 60000 milisecunde) valoarea calculată (puterea instantanee) pe baza curentului și tensiunii măsurate.

Testele au fost realizate monitorizând un dispozitiv de tip router WiFi HUAWEI HG8247H alimentat la 12V DC (curent continuu).

Graficul de valori înregistrate pe ultima zi (toate datele) – se poate observa un consum constant de minim 6600mW (6.6W):

7

Graficul de valori înregistrate pe ultima săptămână (cu mediere) – se poate observa o variație a consumului între 6619mW și 6800mW:

8

IoT UV Monitor

Razele ultraviolete din lumina solară reprezintă un factor de risc pentru om. Monitorizarea nivelului de radiații UV (UV index) se face pe o scară de la 1 la 10 (11 fiind deja un nivel extrem). Realizarea unui sistem electronic ce măsoară cu precizie indexul UV poate oferi informații utile pentru modul în care putem să ne protejăm (îmbrăcăminte, ochelari de protecție, creme de protecție etc.) în activitățile de zi cu zi.

În cadrul proiectului de față vom realiza un sistem care să măsoare indexul UV și să înregistreze datele măsurate pe serviciul cloud Robofun IoT. Pentru utilizarea acestui serviciu este necesară înregistrarea gratuită.

4

După înregistrare și conectare este necesară definirea unui senzor (Adauga senzor) pentru a putea înregistra valorile măsurate (UV index).

5

După definirea senzorului este necesar să copiem cheia de autentificare (Token) pentru a o utiliza în program.

3

Pentru implementarea hardware vom utiliza o placă de dezvoltare Adafruit Feather 32U4 FONA și senzorul digital I2C Si1145. Schema de interconectare între cele două componente este:

2.png

Senzorul se va alimenta de la pinul BAT al plăcii de dezvoltare. Pinul SDA al senzorului se va conecta la pinul 2 al plăcii de dezvoltare iar pinul SCK la pinul 3. Atenție!!! Placa Adafruit Feather 32U4 FONA necesită conectarea unui acumulator LiPo de 3.7V chiar dacă este alimentată prin intermediul cablului USB de programare. Componenta GSM FONA se alimentează direct din acumulator nu din alimentarea USB. Pentru mai multe detalii legate de funcționarea plăcii Adafruit Feather 32U4 FONA se poate parcurge materialul „Adafruit Feather 32u4 FONA – Take your Feather anywhere in the world”.

Funcționarea sistemului necesită o cartelă GSM 2G cu capabilități de transfer de date. Pentru acest lucru vă propunem utilizarea unui SIM Simfony Mobile M2M – cartelă GSM ce oferă exclusiv servicii mobile de date. Cartela este disponibilă gratuit prin comandă promoțională pe site-ul companiei Simfony Mobile SRL sau împreună cu un produs din gama GSM pe site-ul Robofun. Cartela necesită înregistrarea și introducerea codului promoțional pentru activare și oferă gratuit 10MB de date mobile valabile 3 luni. Ulterior costurile de funcționare sunt de 0.25EURO, 0.5EURO, 1EURO pentru 1MB, 5MB respectiv 10MB trafic de date. Chiar dacă traficul inclus are valori modice pentru un sistem de raportare IoT este suficient iar costurile sunt rezonabile. O caracteristică importantă a cartelei SIM Simfony este indepența de un operator de telefonie anume, dispozitivul GSM ce utilizează cartela Simfony poate utiliza orice operator de telefonie mobilă în funcție de zona în care se află chiar și afara României.

3

Programul a fost dezvoltat și testat utilizând Arduino IDE 1.8.3 cu extensia Adafruit AVR Boards 1.4.9 instalată și bibliotecile Adafruit FONA Library 1.3.2 (pentru partea de comunicație cu componenta GSM FONA) și Adafruit SI1145 1.0.0 (pentru comunicația cu senzorul Si1145). În program este necesară completarea cheii de autentiricare (Token) oferite de serviciul cloud (variabila temp).

#include “Adafruit_FONA.h”

#define FONA_RX  9

#define FONA_TX  8

#define FONA_RST 4

#define FONA_RI  7

#define FONA_DTR 5

#define apn “internet.simfony.net”

#define apnusername “” 

#define apnpassword “” 

char replybuffer[255];

#include <SoftwareSerial.h>

SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);

SoftwareSerial *fonaSerial = &fonaSS;

Adafruit_FONA fona = Adafruit_FONA(FONA_RST);

uint8_t type;

#include <Wire.h>

#include “Adafruit_SI1145.h”

Adafruit_SI1145 uv = Adafruit_SI1145();

Decomentarea directivei #define debug va permite urmărirea funcționării sistemului în consola serială.

//#define debug

void setup() {

  #ifdef debug

    while (!Serial);

    Serial.begin(115200);

    Serial.println(“Initializing…”);

  #endif

  if (! uv.begin()) {

    #ifdef debug

      Serial.println(“Didn’t find Si1145”);

    #endif

    while (1);

  }

  digitalWrite(FONA_DTR,LOW);

  fonaSerial->begin(4800);

  if (! fona.begin(*fonaSerial)) {

    #ifdef debug

      Serial.println(F(“Couldn’t find FONA”));

    #endif

    delay(1);

    while (1);

  }

  #ifdef debug

    type = fona.type();

    Serial.println(F(“FONA is OK”));

    Serial.print(F(“Found “));

    switch (type) {

      case FONA800L:

        Serial.println(F(“FONA 800L”)); break;

      case FONA800H:

        Serial.println(F(“FONA 800H”)); break;

      case FONA808_V1:

        Serial.println(F(“FONA 808 (v1)”)); break;

      case FONA808_V2:

        Serial.println(F(“FONA 808 (v2)”)); break;

      case FONA3G_A:

        Serial.println(F(“FONA 3G (American)”)); break;

      case FONA3G_E:

        Serial.println(F(“FONA 3G (European)”)); break;

      default:

        Serial.println(F(“???”)); break;

    }

   #endif

   #ifdef debug

   char imei[15] = {0};

   uint8_t imeiLen = fona.getIMEI(imei);

   if (imeiLen > 0) {

      Serial.print(“Module IMEI: “); Serial.println(imei);

    }

   #endif

   fona.getSIMCCID(replybuffer); 

  #ifdef debug

    Serial.print(F(“SIM CCID = “));

Serial.println(replybuffer);

  #endif

  if (!fona.enableNetworkTimeSync(true)) {

     #ifdef debug

      Serial.println(F(“Failed to enable NTS”));

     #else

      ;

     #endif

  }

  delay(5000);

  fona.setGPRSNetworkSettings(F(apn),F(apnusername),

F(apnpassword));

  uint8_t n=0;

  #ifdef debug

    Serial.print(“Connecting to network.”);

  #endif

  while (n!=5) {

    n = fona.getNetworkStatus();

    #ifdef debug

      Serial.print(“.”);

    #endif

    delay(1000);

  }

  #ifdef debug

    Serial.println(“OK”);

  #endif

  #ifdef debug

    n = fona.getRSSI();

    int8_t r;

    if (n == 0) r = -115;

    if (n == 1) r = -111;

    if (n == 31) r = -52;

    if ((n >= 2) && (n <= 30)) { r = map(n, 2, 30, -110, –

54); }

    Serial.print(r); Serial.println(F(“dBm”));

  #endif

  delay(5000);

}

void loop() {

  while (!fona.enableGPRS(true)) {

    #ifdef debug

      Serial.println(F(“Failed to turn on GPRS”));

    #endif

    delay(5000);

  }

#ifdef debug

  uint16_t vbat;

  uint16_t pbat;

  if (fona.getBattVoltage(&vbat)) {

Serial.print(F(“VBat = “));

Serial.print(vbat); Serial.println(F(” mV”)); }

  if (fona.getBattPercent(&pbat)) {

Serial.print(F(“VPct = “));

Serial.print(pbat); Serial.println(F(“%”));   }

    Serial.println(“—————————“);

#endif

float UVindex = uv.readUV();

UVindex /= 100.0; 

#ifdef debug

    int light = uv.readVisible();

    Serial.print(“Vis: “); Serial.println(light);

    Serial.print(“UV: “);  Serial.println(UVindex);

#endif

String temp = “http” + “://iot.robofun.ro/api/v1/senzor/TOKEN/input?value=” + String(UVindex,2);

uint16_t statuscode;

int16_t length;

char url[100];

temp.toCharArray(url,temp.length()+1);

#ifdef debug

    Serial.println(url);

    if (!fona.HTTP_GET_start(url, &statuscode, (uint16_t*)&length)) Serial.println(“Failed read HTTP!”);

#else

    fona.HTTP_GET_start(url, &statuscode, (uint16_t*)&length);

#endif

while (length > 0) {

          while (fona.available()) {

            char c = fona.read();

            #ifdef debug

              Serial.write(c);

            #endif

            length–;

            if (! length) break;

          }

          #ifdef debug

            Serial.println();

          #endif

          break;

fona.HTTP_GET_end();

delay(100);

#ifdef debug

    Serial.println(“—————————-“);

    if (!fona.enableGPRS(false))

Serial.println(F(“Failed to turn off GPRS”));

#else

    fona.enableGPRS(false);

#endif

delay(100);

digitalWrite(FONA_DTR,HIGH);

delay(600000);

digitalWrite(FONA_DTR,LOW);

}

Programul va citi valorile indexului UV și va înregistra datele on-line la un interval de 10 minute (60 secunde = 60000 milisecunde). Intervalul de măsurare poate fi modificat în funcție de dinamica monitorizării dorite. Graficul de supraveghere va arăta în felul următor (se poate observa că, într-o zi însorită, indexul UV poate ajunge la valori periculoase în intervalul 15:00-17:00 iar într-o zi noroasă / cu ploaie rămâne la valori subunitare):

4