luni, 31 august 2015

Termostat cu control umiditate (higrostat) - partea a 2-a

   Fata de articolul precedent, in care am folosit un senzor combinat de umiditate si temperatura, de tipul AM2302 (sau notat DHT22, cand se vinde ca modul cu o rezistenta de 4k7 intre pinul de date si plus), acum o sa folosesc, 2 senzori separati, unul pentru temperatura si unul pentru umidtate.
   In prima faza, am pentru umiditate tot un senzor AM2302, iar pentru temperatura un DS18B20, schema devenind:
iar sketch-ul folosit este LCD1602_DHT22_18B20_thermostat_humidity_control_ver1m3a.ino.
   Fara modificari majore in sketch:
se poate inlocui si senzorul de umiditate cu DHT11, schema devenind:
   Urmatorul pas a fost acela in care am stocat datele folosite ca referinta (temperatura, interval de temperatura, umiditate, interval de umidtate, tip incalzire/racire, umidificator/dezumidificator) in memoria EEPROM a microcontrolerului de pe placa de dezvoltare Arduino.
   Pentru varianta cu DS18B20 si DHT22 (AM2302) se foloseste sketch-ul LCD1602_DHT22_18B20_thermostat_humidity_control_ver1m4.ino, iar pentru cu DS18B20 si DHT11 sketch-ul LCD1602_DHT11_18B20_thermostat_humidity_control_ver1m4.ino.
   In filmuletul termostat cu control umiditate folosind Arduino (6) se prezinta modul de functionare cu DHT22 (AM2302) si DS18B20:
iar in cel numit termostat cu control umiditate folosind Arduino (7) se foloseste un DHT11 si DS18B20:



vineri, 28 august 2015

Termostat cu control umiditate (higrostat)

   La solicitarea lui Mircea Craciun, am realizat un termostat, care mai are posibilitatea de a controla si umiditatea dintr-o incinta (higrostat).
   Senzorul pentru umiditate si temperatura este unul dedicat, AM2302 (cunoscut si ca DHT22 cand e montat pe un cablaj si are o rezistenta de 4k7 intre +5V si pinul de date).
   Precizia acestui senzor este destul de buna, la temperatura de +0,5 grade Celsius in domensiul de -40..+80 grade Celsius si pentru umidtatea relativa +2%RH in domensiul de 0..100%. 
   Schema de conectare este:
   Dupa cum se observa, am reprezentat cele doua variante de senzor, montandu-se doar una din ele..
   Am pus 2 led-uri pentru a avea o incatie, dar daca se inlocuiesc cu relee, ele pot comanda o centrala si un servomotor (sau electrovana) de eliminare umiditate, dupa cum sunt date comenzile din sketch-ul LCD1602_thermostat_humidity_ver1m0.ino.
   Din celel 3 butoane fara retinere se regleaza temperatura dorita, intervalul acceptat de scadere a temperaturii odata depasite (histerezis), umiditatea si intervalul acceptat de scadere al umiditatii odata depasite.
- reglaj temperatura:
 
- reglaj interval acceptat de scadere a temperaturii odata depasita (histerezis)
 
- reglaj umiditate:
 
reglaj interval acceptat de scadere a umiditatii odata depasite (histerezis)
 
   In graficul de mai jos se cele 3 cazuri: temperatura scazuta (BELOW), temperatura optima (OK) si temperatura prea mare (OVER):
  In timpul functionarii,pot fi mai multe stari (am simulat cateva):
- temperatura si umiditate in parametrii doriti (optim):
 
- temperatura scazuta si umiditate mai mica decat pragul admis:
- temperatura in parametrii, umiditate mai mica decat pragul admis (bun):
- temperatura in parametrii, umiditate prea mare:
- temperatura scazuta si umiditate prea mare:
- temperatura prea mare, umiditate crescuta:
 
   Am facut si 2 filmulete, care prezinta mai bine modul de reglaj al parametrilor:

27.05.2018
   Pentru a fi un adevarat termostat, am pus si parte de memorare date in EEPROM, sketck-ul fiind acum LCD1602_DHT22_thermostat_humidity_control_ver1m4x.ino

joi, 27 august 2015

Meniu personalizat pe ecran LCD 1602

   Pentru diverse sisteme de automatizare in care se doreste reglajul anumitor parametrii se folosesc meniuri mai simple sau mai complexe.
   In articolul Tutorial: manage menu and LCD display with Arduino este prezentat un meniu controlat cu 4 butoane fara retinere (selectie, renuntare, inainte/dreapta inapoi/stanga) in care se foloseste o libraria libraria MenuBackend modificata.
   In acel material se folosesc 4 butoane fara retinere cu contact intre pinii de intrare si plus, iar pinii sunt conectati prin rezistente la masa.
iar meniul are 3 submeniuri, primul submeniu mai are 2 sub-submeniuri, al doilea submeniu are 3 sus-submeniuri, iar al treilea submeniu e fara sub-submeniuri.
   Eu am modificat sketch-ul pentru a elimina rezistentele, folosindu-ma de cele interne, pe care le pun in 1 logic (HIGH), deci am contact catre masa, schema devenind:
   Sketch-ul modificat este custommenu_ver1m0.ino si modul de functionare se vede in filmuletul menu cu submeniuri pe afisaj LCD 1602 folosind Arduino
si diverse faze se pot vedea in imaginile urmatoare:
- meniul principal
 
- primul submeniu
- al doilea submeniu
- al treilea submeniu
- sub-submeniurile de la submeniul 1:
 
- sub-submeniurile de la submeniul 2:
 
 
   Dupa cum am vazut cum functioneaza, am rescris sketch-ul (3menu_3submenu_each_ver2m0.ino) sa am cate 3 sub-submeniuri la fiecare submeniu, iar asta se vede in filmuletele:

marți, 25 august 2015

Afisaj matriceal din 8x8 leduri controlat de MAX7219 (2)

   In articolul precedent am prezentat modululele de afisare din 8x8 leduri controlate de MAX7219, folosind librariile Ledcontrol si apoi MaxMatrix
   Am realizat o varianta de ceas cu date meteo cu 4 module de afisare, la care se regleaza automat nivelul intensitatii luminoase a afisajului in functie de mediu si am folosit urmatoarele:
- modul cu DS3231 pentru partea de ceas si data (functioneaza fara modificari si DS1307)
- senzor DHT22 pentru temperatura si umiditate
- fotorezistenta montata intr-un divizor rezisitiv
   Montajul arata asa:
iar schema folosita a fost:
   In timpul experimentelor, am tot alimentat montajul ba din mufa usb, ba direct pe pinul +5V si GND si am observat ca uneori apar probleme la partea de ceas, aparand date eronate, asa ca am cautat solutii hard si soft si m-am oprit la una soft, de "curatire" a magistralei i2c, dupa cum am gasit in articolul Reliable Startup for I2C Battery Backed RTC Why the Arduino Wire library is not enough:
/**
 * I2C_ClearBus
 * (http://www.forward.com.au/pfod/ArduinoProgramming/I2C_ClearBus/index.html)
 * (c)2014 Forward Computing and Control Pty. Ltd.
 * NSW Australia, www.forward.com.au
 * This code may be freely used for both private and commerical use
 */

#include <Wire.h>

/**
 * This routine turns off the I2C bus and clears it
 * on return SCA and SCL pins are tri-state inputs.
 * You need to call Wire.begin() after this to re-enable I2C
 * This routine does NOT use the Wire library at all.
 *
 * returns 0 if bus cleared
 *         1 if SCL held low.
 *         2 if SDA held low by slave clock stretch for > 2sec
 *         3 if SDA held low after 20 clocks.
 */
int I2C_ClearBus() {
  TWCR &= ~(_BV(TWEN)); //Disable the Atmel 2-Wire interface so we can control the SDA and SCL pins directly

  pinMode(SDA, INPUT_PULLUP); // Make SDA (data) and SCL (clock) pins Inputs with pullup.
  pinMode(SCL, INPUT_PULLUP);

  delay(2500);  // Wait 2.5 secs. This is strictly only necessary on the first power
  // up of the DS3231 module to allow it to initialize properly,
  // but is also assists in reliable programming of FioV3 boards as it gives the
  // IDE a chance to start uploaded the program
  // before existing sketch confuses the IDE by sending Serial data.

  boolean SCL_LOW = (digitalRead(SCL) == LOW); // Check is SCL is Low.
  if (SCL_LOW) { //If it is held low Arduno cannot become the I2C master. 
    return 1; //I2C bus error. Could not clear SCL clock line held low
  }

  boolean SDA_LOW = (digitalRead(SDA) == LOW);  // vi. Check SDA input.
  int clockCount = 20; // > 2x9 clock

  while (SDA_LOW && (clockCount > 0)) { //  vii. If SDA is Low,
    clockCount--;
  // Note: I2C bus is open collector so do NOT drive SCL or SDA high.
    pinMode(SCL, INPUT); // release SCL pullup so that when made output it will be LOW
    pinMode(SCL, OUTPUT); // then clock SCL Low
    delayMicroseconds(10); //  for >5uS
    pinMode(SCL, INPUT); // release SCL LOW
    pinMode(SCL, INPUT_PULLUP); // turn on pullup resistors again
    // do not force high as slave may be holding it low for clock stretching.
    delayMicroseconds(10); //  for >5uS
    // The >5uS is so that even the slowest I2C devices are handled.
    SCL_LOW = (digitalRead(SCL) == LOW); // Check if SCL is Low.
    int counter = 20;
    while (SCL_LOW && (counter > 0)) {  //  loop waiting for SCL to become High only wait 2sec.
      counter--;
      delay(100);
      SCL_LOW = (digitalRead(SCL) == LOW);
    }
    if (SCL_LOW) { // still low after 2 sec error
      return 2; // I2C bus error. Could not clear. SCL clock line held low by slave clock stretch for >2sec
    }
    SDA_LOW = (digitalRead(SDA) == LOW); //   and check SDA input again and loop
  }
  if (SDA_LOW) { // still low
    return 3; // I2C bus error. Could not clear. SDA data line held low
  }

  // else pull SDA line low for Start or Repeated Start
  pinMode(SDA, INPUT); // remove pullup.
  pinMode(SDA, OUTPUT);  // and then make it LOW i.e. send an I2C Start or Repeated start control.
  // When there is only one I2C master a Start or Repeat Start has the same function as a Stop and clears the bus.
  /// A Repeat Start is a Start occurring after a Start with no intervening Stop.
  delayMicroseconds(10); // wait >5uS
  pinMode(SDA, INPUT); // remove output low
  pinMode(SDA, INPUT_PULLUP); // and make SDA high i.e. send I2C STOP control.
  delayMicroseconds(10); // x. wait >5uS
  pinMode(SDA, INPUT); // and reset pins as tri-state inputs which is the default state on reset
  pinMode(SCL, INPUT);
  return 0; // all ok
}


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  int rtn = I2C_ClearBus(); // clear the I2C bus first before calling Wire.begin()
  if (rtn != 0) {
    Serial.println(F("I2C bus error. Could not clear"));
    if (rtn == 1) {
      Serial.println(F("SCL clock line held low"));
    } else if (rtn == 2) {
      Serial.println(F("SCL clock line held low by slave clock stretch"));
    } else if (rtn == 3) {
      Serial.println(F("SDA data line held low"));
    }
  } else { // bus clear
    // re-enable Wire
    // now can start Wire Arduino master
    Wire.begin();
  }
  Serial.println("setup finished");
}

void loop() {
  // put your main code here, to run repeatedly:
  // do Wire RTC stuff here.
}
   Sketch-ul meu, adaptat acestei solutii este maxmatrix_DS3231_clear_DHT22_4digit_ver6m0.ino !!!
   Ulterior, m-am gandit ca in locul senzorului DHT22 sa folosesc un sensor DHT11 pentru date de umiditate, avand in vedere ca precizia este suficienta, iar pentru temperatura sa folosesc un senzor DS18B20.
   Pentru a folosi doar un DHT11 in locul lui DHT22, se fac modificari minore in sketch:
in
   Daca se doreste si o temperatura cu precizie buna, se poate folosi partea de citirea unui senzor DS18B20 cum e prezentata in materialul de la http://arduinoprojects.ru/ (in care pinul de date este la D8) si astfel sketch-ul devine maxmatrix_ds18b20_dht_4module_ver7m0.ino.
   Schema se modifica foarte putin, dupa cum se observa:
iar montajul arata asa:
 
 
   Am facut si un filmulet numit statie meteo si ceas cu data pe afisaj led de 32x8 leduri (4) in care prezint modificarile si cum apar informatiile pe afisajul compus din cele 4 module:
   Am adaugat si partea de a putea alege rezolutia de la 9 la 12 biti, dupa cum se vede in sketch-ul maxmatrix_ds18b20_dht_4module_ver7m1.ino.

luni, 24 august 2015

Transmitere date prin bluetooth de la un Arduino catre alt periferic

   Anumite date care sunt prelucrate de o placa Arduino pot fi trimise prin bluetooth catre un telefon, tableta sau alt periferic cu sistem de operare Android sau, mai rar, un calculator cu alt sistem de operare Windows, Linux etc care are conectat un modul ("dongle") bluetooth.
   Cautand informatii pe net, am gasit putine data, pana am dat de articolul Arduino – making a simple BlueTooth data logger, care prezinta modul de trimitere prin bluetooth a datelor (temperatura si umiditatea) de la senzorul nepretentios DHT11 catre un periferic, folosind un un modul HC-05.
   Am reprodus si eu experimentul, folosind o clona Arduino Nano:
si un telefon cu sistem de operare Android in care am instalat programul "BT terminal":
   Am facut repede un filmulet, numit trimitere date prin bluetooth folosind Arduino din care se constatata ca legatura intre modulul HC-05 conectat la Arduino si telefon se tot intrerupe.
   Sketch-ul folosit acolo, este foarte asemanator cu cel din articolul din care m-am inspirat, doar am schimbat viteza de transmisie a datelor in 9600.
   Schema de conectare rezulta din sketch:
   Tot cautand pe net si conectand diverse telefoane, am realizat ca pot mari timeout-ul (timpul de lipsa raspuns de la celalalt periferic) la 5 sau chiar 10 secunde si nu mai apar probleme, dupa cum se vede in filmuletul trimitere date prin bluetooth folosind Arduino (3) in care am folosit sketch-ul BT_datalogger_2b.ino:
   Am modificat un pic sketch-ul, in care se numarul si de date trimise de la conectare, acesta devenind BT_datalogger_2b2b.ino si am facut un alt filmulet numit trimitere date prin bluetooth folosind Arduino (4)
si o varianta in engleza, numita bluetooth data logger using Arduino

miercuri, 19 august 2015

Modul GPRS cu M590 (3)

   In articolele anterioare, am facut facut teste de trimitere si receptie sms-uri cu modulul GPRS cu M590 de la Neoway.
   In timpul testelor, am incercat controlul acestui modul cu Arduino Uno, prin folosirea librariei SoftwareSerial, cum era prezentat si in articolul Tutorial: Control AC outlets via SMS, dar nu am reusit sa trimit sau sa receptionez comenzi, eventual niste semne ciudate, asa ca am folosit un Arduino Mega si am conectat comunicatia la Rx2 si Tx2 prin intermediul convertorului de nivel logic de 5V la 3,3V.
   Repetand experimentele, am constatat desi schema de conectare cu Uno e corecta, in ecranul de monitorizare seriala apar caractere ciudate si, am banuit, ca-s problenme cu viteza de transfer de 115200bps, desi in documentatia de pe site-ul Arduino zice ca functioneaza si la aceasta (vedeti articolul SoftwareSerial: begin(speed), dar intr-un material de la https://github.com/arduino/Arduino/issues/2019 apare ca-s probleme la viteza asta..
   De data asta, "am venit cu lectia invatata" si am refacut schema de conectare cu Arduino Mega si schimbat viteza de transfer (baud rate) cu comanda AT+IPR=9600...folosindu-ma de sketch-ul M590_mega_serialtest2.ino
si am schimbat si in sketch la 9600 in loc de 115200 si am dat comenzile AT:
si e in regula, doar ca trebuie date comenzi mai rar...
   Am realizat schema de conectare la Arduino Uno (un VISduino Uno, in cazul de fata) si am dat comenzi AT de verificare, dupa ce am incarcat sketch-ul M590_softwareserial.ino:
   Am completat schema cu cele 4 leduri inseriate cu rezistente si, dupa ce am incarcat un sketch modificat, in sensul de a introduce niste intarzieri intre comenzi de 2,5 secunde, am facut teste:
- am dat comand apentru aprinderea celor 4 leduri:
- am dat comanda sa fie aprinse cele 2 leduri din mijloc 
- am dat comanda sa fie aprinse cele 2 leduri din exterior:
   Pentru a fi mai convingator, am facut 2 filmulete:
SMS control 4 leds using M590 GPRS module and Arduino (2)
20.08.2015
   Am deconectat placa Arduino de la calculator si am alimentat-o din sursa externa de 4,2V in conectorul unde este inscriptionat 5V si am reluat testele... functioneaza fara probleme, in plus, este ca un modul independent, in locul led-urilor se pot pune relee, care comanda becuri, motoare, ventilatoare, camere, etc sau prin optocuploare (pentru a proteja montajele si utilizatorii) se pot comanda triace/tiristoare, care la randul lor aprind becuri, alimenteaza motoare de la retea...
   Am facut inca 2 filmulete, pentru a fi mai clar:
   In locul convertorului de nivel logic, de-l folosesc eu, se poate folosi schema din manualul tehnic de utilizare:
in care VCCI) (pinul 6 al lui M590) este o tensiunea de referinta de 2,85V pentru comenzile logice. RXD_GPRS este pinul 7 de la M590, iar TXD_GPRS este pinul 8 de la M590.
   MCU_TXD si MCU_RXD sunt pinii de receptie, respectiv transmisie date ale microcontorlerului sau placii de dezvoltare Arduino, in cazul nostru.

Atentie: Tensiunea sursei externe de alimentare este de +4,6V nu de +4,2V deoarece modulul chinezesc arata cu 0,3-0,4V mai putin decat tensiunea reala !!!