ABONAMENTE VIDEO REDACȚIA
RO
EN
×
▼ LISTĂ EDIȚII ▼
Numărul 103
Abonament PDF

Un termostat IoT - versiunea a II-a

Ovidiu Mățan
Fondator @ Today Software Magazine
PROGRAMARE


Am văzut în articolul precedent cum putem avea Un termostat IoT pe roți. Soluția inedită a fost aleasă în lipsa unui releu care să controleze centrala. În articolul de față expunem varianta în care vom folosi un releu real pentru controlul centralei. Îl vom utiliza într-o soluție inițială practică, după care o vom dezvolta pentru a avea un termostat complex ce va avea un senzor de temperatură performant, va afișa temperatura pe un ecran led și va putea fi controlat de la o telecomandă. Adăugăm că funcționarea centralei va fi semnalată de un semafor.

O soluție simplă

Probabil cea mai practică soluție, pe care chiar am aplicat-o în ultima lună, este să apeși pe un buton. Prin acest gest se pornește încălzirea la centrală, iar la o a doua apăsare aceasta se va opri. În condițiile iernii din acest an, acest mod de a controla declanșarea căldurii este foarte simplu. Termometrul suntem chiar noi iar când ne este frig pornim centrala.

Releul folosit a fost de 5V. În contextul folosirii unei plăci Arduino, un amănunt important este tensiunea aplicată pentru declanșarea releului. Cei 5V din specificații se referă la tensiunea necesară pentru a declanșa releul și închiderea circuitului. Circuitul extern poate avea și 220V, dar aceștia nu au o legătură cu cei 5V necesari operării releului.

Conectăm releul la placa Arduino astfel:

  1. Pini de control GND și VDD sunt conectați la masă, respectiv la o ieșire de 5V.

  2. Pinul EN este conectat la portul analogic A0.

Conectăm și butonul care va declanșa pornirea/oprirea centralei: VCC și GND vor fi conectați la porturile corespunzătoare de pe placă, iar pinul OUT la portul digital 7.

#define relay A0

bool heating=false;
int button=7;

 void setup(void) {
    pinMode(relay, OUTPUT);
    pinMode(button, INPUT);
}
  void loop(void) {

  if (digitalRead(button)){
    heating=!heating;
  }
  digitalWrite(relay,
   (heating)?HIGH:LOW);

  delay (200);
}

Logica din codul sursă este foarte simplă, în momentul în care se apasă butonul se inversează starea actuală și se pornește/oprește căldura.

Un termostat IoT

Dezvoltăm soluția simplă de mai sus într-o soluție în care profităm de senzorii IoT pe care îi avem. Temperatura limită a termostatului va putea fi controlată cu ajutorul unei telecomenzi. Vom citi și afișa temperatura din cameră. De asemenea, vom folosi un semafor pentru a afișa funcționarea centralei.

Începem prin instalarea unei plăci de expansiune Sensor Shield. Motivul principal este prezența pinilor de alimentare și masă pentru fiecare dintre pinii digitalii sau analogici. Vom instala în continuare componentele necesare:

Senzorul de temperatură

Vă recomand să folosiți un senzor de calitate suparioară pentru această măsurătoare. Este important să nu avem variații aleatorii, cum se poate întâmpla la cei entry-level. Am folosit un Sparkfun TMP117, iar rezultatele au fost foarte bune. De menționat faptul că acesta s-ar putea conecta printr-un conector Qwik direct la placa echivalentă Arduino de la Sparkfun. Soluția rezultată ar fi mai compactă în felul acesta.

Senzorul se va conecta prin interfața I2C. Aceasta permite conectarea unui număr mai mari de senzori în paralel. Din păcate, atât Arduino cât și placa de expansiune au doar câte un pin SDA, respectiv SCL. Deoarece și displayul folosește aceeași interfață a fost nevoie să folosim un bread board pentru a le conecta pe amândouă.

Telecomanda

Sistemul constă dintr-un receptor și un emițător. Senzorul receptor l-am conectat la pinul 11 de pe placa de expansiune Arduino. Acesta va decoda orice semnal infraroșu pe care îl primește. Puteți folosi din această perspectivă orice telecomandă doriți. Tot ceea ce trebuie să faceți este să afișați codul recepționat de senzor și să îl asociați unei comenzi în cazul în care este recepționat.

Displayul

Am folosit un mic ecran OLED care, așa cum menționam mai sus , folosește tot interfața I2C. Conectăm masa și alimentare la Sensor Shield, iar pini SDA și SCL la porturile corespunzătoare extinse pe bread board. Așa cum veți putea vedea în codul de mai jos, se pot selecta fonturi, dimensiunea textului și poziția sa pe ecran prin folosirea librăriei U8g2.

Semaforul

Utilizăm un semafor pentru micro:bit, iar folosirea lui este simplă. Avem cei doi pini de alimentare și masă, iar pentru fiecare culoare avem un pin separat. Astfel, dacă vom transmite valoarea HIGH pinului verde, acesta se va aprinde.

Releul

Folosim același releu de 5V ca în exemplul de mai sus. Conectați cele două fire de la centrală pe porturile: NO respectiv COM.

Codul sursă

#include <Arduino.h>
#include <U8g2lib.h>
#include <SPI.h>
#include <Wire.h>            
#include <SparkFun_TMP117.h> 
#include "IRremote.h"
#define relay A0

U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0); 
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
TMP117 sensor; 

float tempSensor;
const long UP=16718055;
const long DOWN=16730805;
const long OK=16726215;
const float DELTA=1.0;
boolean showInfo=true;
char buff[10];
float reference_temp;
int ledGreen=5;
int ledYellow=6;
int ledRed=7;
int displayCount=0;
boolean heating=false;

void setup()
{
  pinMode(ledGreen, OUTPUT);
  pinMode(ledYellow, OUTPUT);
  pinMode(ledRed, OUTPUT);
  pinMode(relay, OUTPUT);
  Serial.begin(9600);
  u8g2.begin();
  Wire.begin();
  Wire.setClock(9600);   
  sensor.begin();
  show("Starting UP");
  irrecv.enableIRIn(); 
  reference_temp=readTemp();
  reference_temp=round(reference_temp)*1.0f-0.5;
}

void loop()
{
  if (displayCount%2==0 && sensor.dataReady() ) 
  {
    tempSensor = sensor.readTempC();
  } 

   if (displayCount>=0){
    show("Temp: ", tempSensor);
    if (displayCount>6){
      displayCount=-1;
    }
   }
  displayCount++;
  delay(500); 
  if (irrecv.decode()) {
   switch(irrecv.results.value){
    case UP: updateTempLimit(0.5);break;
    case DOWN: updateTempLimit(-0.5);break;
    case OK: showInfo=!showInfo; break;
  }
   irrecv.resume(); // Receive the next value
  }
  if ((tempSensor-DELTA )>reference_temp){
    heating=false;
   } else if (tempSensor>0 && 
       (tempSensor<reference_temp)){
      heating=true;
    }
    light((heating)?ledRed:ledGreen);
    digitalWrite(relay,(heating)?HIGH:LOW);
}

float readTemp(){
   if (sensor.dataReady()) {
    return sensor.readTempC();
  }
}

void updateTempLimit(float delta){
  reference_temp+=delta;
  showInfo=true;
  displayCount=-3;
  show("Limit:",reference_temp);
}

void closeLights(){
  digitalWrite(ledRed, LOW);
  digitalWrite(ledYellow, LOW);
  digitalWrite(ledGreen, LOW);
}

void light(int led){
if (showInfo){
  closeLights();
  digitalWrite(led, HIGH);
} else {
  closeLights();
 }
}

void show(const char *str, float tempC){
  char temp[5];
  char buff[5+sizeof(str)];
  dtostrf(tempC,2,1,temp);
  strcpy(buff,str);
  strcat(buff,temp);
  show(buff);
}

void show(const char *text){
  if (!showInfo){
    text="";
  }
   u8g2.clearBuffer();         
   u8g2.setFont(u8g2_font_logisoso16_tr);  
   u8g2.drawStr(8,30,text);
   u8g2.sendBuffer();
}

Am folosit o constantă DELTA care împreună cu valoarea de referință a temperaturii va defini un interval în care centrala va funcționa. Temperatura de referință va fi stabilită după pornire folosind tastele de săgeată de pe telecomandă. Tot de pe telecomandă, butonul Ok va închide afișajul și semaforul ca o măsură de protecție a acestora.

Concluzie

Cu toate că poate părea, la o primă vedere, relativ complicat, realizarea unui termostat așa cum ni-l dorim este simplu de realizat. Este un proiect de weekend care vă poate oferi multe satisfacții.

Conferință

VIDEO: NUMĂRULUI 110

Sponsori

  • Accenture
  • Bosch
  • ntt data
  • Betfair
  • FlowTraders
  • MHP
  • Connatix
  • Cognizant Softvision
  • BoatyardX
  • Colors in projects