Se afișează postările cu eticheta temperatura. Afișați toate postările
Se afișează postările cu eticheta temperatura. Afișați toate postările

luni, 6 iulie 2015

Afisaj OLED de 0,96" (2,4cm) cu rezolutie de 128x64 pixeli (3)

   Am primit un afisaj OLED cu driver SSD1306, dar nu e identic cu cel dinainte, acesta are 7 pini (5 pini comanda + 2 alimentare)
nu ca celalalt care se conecteaza pe i2c s are 4 pini (2 pini comanda + 2 alimentare)
   Mi-am adus aminte ca exemplele de la libraria Adafruit SSD1306 exista un sketch si pentru versiunea de conectare SPI, asa ca am realizat schema conform exemplului (DO/CLK = D10, DI/MOSI = D9, RST/RESET = D13, DC = 11, CS = 13)
rezultatul este bun:
   Am incercat si libraria u8glib, care am mai folosit-o la alte afisaje, dar a functionat doar daca am pus pinul de RESET la D2. dupa cum am citit pe forumul Arduino, apoi am configurat restul pinilor cum am dorit eu: 
iar schema de conectare devine:
   Incarcand exemplul cu grafica librariei u8glib, pe ecran apar diverse imagini de grafica si text:
 
 
   Partea de configurare a sketch-ului cu libraria Adrafruit SSD1306 devine:
   In articolul http://nicuflorica.blogspot.ro/2015/06/afisaj-oled-de-096-24cm-cu-rezolutie-de_22.html am prezentat un ceas mai deosebit, asa ca am modificat sketch-ul,devenind ro_DHT_RTC_adjust_ver6m0.ino, iar schema arata asa:
 
   Fata de sketch-ul pentru i2c am introdus cateva linii de configurare:
dar se poate folosi si afisajul I2c, daca se anuleaza aceste linii si reactivarea celor initiale:
   Am facut un filmulet numit statie meteo si ceas cu alarma pe afisaj OLED (3)

  Am adaptat si celalalt sketch, cu pisica, prezentat initial pe www.instructables.com, devenind ro_Pusheen_Generic_ro3.ino:

29.7.2015
   Am gasit si o librarie pentru text, desi se pot face si niste grafice din liniute, dar partea importanta e ca ocupa spatiu putin; aceasta librarie se numeste SSD1306_text !!!

marți, 16 iunie 2015

Statie meteo cu ceas pe afisaj de Nokia 5110

   O statie meteo cu ceas si date meteo prezentate pe un afisaj de Nokia 5110 se gasesc in articolul Afisajul folosit la telefoanele Nokia 5110/3310 si Arduino (III); montajul prezentat acolo are in componenta sa: 
- o placa compatibila Arduino Uno
- un ceas cu DS1307
- temperatura si umiditate cu DHT11
- afisaj de Nokia 5110 (controler PCD8544)
iar schema de conectare este:
   Acum am schimbat senzorul de temperatura si umiditate cu unul mai bun, DHT22, care este mult mai precis, dupa cum am prezentat si in articolul Ceas RTC cu DS1307 si date mediu cu DHT22 pe afisaj alfanumeric LCD1602 folosind Arduino.
   Cum am scris si acolo, senzorul DTH22 se vinde ca modul cu 3 pini sau ca piesa cu 4 pini, avand cod AM2302, care necesita o rezistenta de 4k7 intre iesire (OUT/DATAS) si plus (VDD/5V):
   Schema de conectare este identica:
   Adaptorul de afisaj la care fac referire are schema (fundalul se poate aprinde fie punand conectorul "background" la masa, fie la +5V, depinde de schema de conectare al ledurilor de pe modul)
   Sketch-ul este foarte putin modificat, modificare consta in anularea liniei cu DHT11 si introducerea uneia in care este scris DHT22:
   Sketch-ul se gaseste pe https://github.com/tehniq3 !!
   Am facut cateva poze cu montajul si datele de pe afisaj:
   In mod normal, in sketch, ceasul de timp real cu DS1307 ia data de la calculator, daca nu este niciuna inscrisa:
iar daca vrem sa reglam ceasul (ora de vara/iarna, etc), activam linia:
incarcam scketch-ul, apoi anulam linia (cum a fost initial) si reincarcam sketch-ul..

PS: Avand in vedere ca senzorul DHT22 ofera informatii mai detalite despre temperatura, am pus si cifra dupa virgula:
sketch-ul versiunea 1.8b se gaseste pe https://github.com/tehniq3.

PS2: Am facut si poze cu un aparat de fotografiat:
 
 
   Am facut si un scurt filmulet numit Statie meteo cu ceas pe afisaj de Nokia 5110 in care se vede modul de afisare si ce componente are montajul.

miercuri, 14 ianuarie 2015

Modul de afisare cu 8 cifre LED din 7 segmente fiecare controlate de MAX7219 (VI)

   Fata de articolele anterioare, unde aveam reglaj complet la ceasul RTC cu DS1307 dintr-un encoder (folosindu-ma de informatiile de la http://andydoz.blogspot.com/) acum am 3 taste...
   Schema de conectare este similara, deoarece am pastrat conexiunile principale, punand chiat si tastele ca la encoder):
   In modul obisnuit, pe ecranul apar ciclic informatii despre:
- ora:
- data:
- temperatura si umiditate:
   Daca apas scurt pe tasta MENU/NEXT apare pe ecran ID-ul meu "niq_ro":
   Daca apas lung (mai mult de 3 secunde) se intra in modul de reglaj:
- an:
- luna:
- zi:
- ora:
- minut:
   Am facut si 2 filmulete:
   Sketch-ul folosit de mine este:
// adapted sketch by niq_ro from http://arduinotehniq.blogspot.com
// and http://nicuflorica.blogspot.ro
// version 1.0 in 6.11.2014, Craiova - Romanaia
// curent version in 12.1.2015
// source for LEDControl: http://embedded-lab.com/blog/?p=6862
#include "LedControl.h" 
/*
 Now we need a LedControl to work with.
 ***** These pin numbers will probably not work with your hardware *****
 pin 12 is connected to the DataIn 
 pin 11 is connected to the CLK 
 pin 10 is connected to LOAD 
 We have only a single MAX72XX.
 */
LedControl lc=LedControl(12,11,10,1);

// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain
#include "DHT.h"
#define DHTPIN A1     // what pin we're connected to A1
// Uncomment whatever type you're using!
#define DHTTYPE DHT11   // DHT 11 
//#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// if is just sensor:
// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

DHT dht(DHTPIN, DHTTYPE);

// declaration for type of value
int t, h;

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
// original sketck from http://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/
// add part with SQW=1Hz from http://tronixstuff.wordpress.com/2010/10/20/tutorial-arduino-and-the-i2c-bus/

// Dawn & Dusk controller. http://andydoz.blogspot.ro/2014_08_01_archive.html
// 16th August 2014 - (C) A.G.Doswell 2014

#include <Wire.h>
#include "RTClib.h" // from https://github.com/adafruit/RTClib
#include <LiquidCrystal.h>
//#include <Encoder.h> // from http://www.pjrc.com/teensy/td_libs_Encoder.html

RTC_DS1307 RTC; // Tells the RTC library that we're using a DS1307 RTC
///Encoder knob(2, 3); //encoder connected to pins 2 and 3 (and ground)

//the variables provide the holding values for the set clock routine
int setyeartemp; 
int setmonthtemp;
int setdaytemp;
int sethourstemp;
int setminstemp;
int setsecs = 0;
int maxday; // maximum number of days in the given month
int TimeOut = 10;
int TimeOutCounter;

// These variables are for the push button routine
int buttonstate = 0; //flag to see if the button has been pressed, used internal on the subroutine only
int pushlengthset = 3000; // value for a long push in mS
int pushlength = pushlengthset; // set default pushlength
int pushstart = 0;// sets default push value for the button going low
int pushstop = 0;// sets the default value for when the button goes back high

int knobval; // value for the rotation of the knob
boolean buttonflag = false; // default value for the button flag

byte SW1 = 2;  // switch for down
byte SW2 = 3;  // switch for up

void setup()
{
// Initialize MAX7219 device
lc.shutdown(0,false); // Enable display 
lc.setIntensity(0,3); // Set brightness level (0 is min, 15 is max) 
lc.clearDisplay(0); // Clear display register 
 
// Initialize HTD sensor
dht.begin();

    Wire.begin();
    RTC.begin();
//  if (! RTC.isrunning()) {
    //Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
// }
// part code from http://tronixstuff.wordpress.com/
Wire.beginTransmission(0x68);
Wire.write(0x07); // move pointer to SQW address
//Wire.write(0x10); // sends 0x10 (hex) 00010000 (binary) to control register - turns on square wave
Wire.write(0x13); // sends 0x13 (hex) 00010011 (binary) to control register - turns on square wave at 32kHz
Wire.endTransmission();
// end part code from http://tronixstuff.wordpress.com/

pinMode(A0,INPUT);//push button on encoder connected to A0 (and GND) or MENU/NEXT
digitalWrite(A0,HIGH); //Pull A0 high

 pinMode(SW1, INPUT);  // N.O. push button switch
 pinMode(SW2, INPUT);  // N.O. push button switch

 digitalWrite(SW1, HIGH);
 digitalWrite(SW2, HIGH);

/*
 Serial.begin(9600);
 Serial.println("test for niq_ro");
 Serial.println("------------------");
*/
}

void loop()
{
 // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
h = dht.readHumidity();
// t = dht.readTemperature(); 
  
/* test part  
// test humidity value
h = 37;
// test temperature value
t = 19;
*/

// 
lc.clearDisplay(0); // Clear display register 

for(int j=0; j<300; j++){
temperatura (t);
umiditate (h);

    pushlength = pushlengthset;
    pushlength = getpushlength ();
    delay (10);
    if (pushlength <pushlengthset) {
      ShortPush ();   
    }
       //This runs the setclock routine if the knob is pushed for a long time
       if (pushlength >pushlengthset) {
       lc.clearDisplay(0); // Clear display register 
         DateTime now = RTC.now();
         setyeartemp=now.year(),DEC;
         setmonthtemp=now.month(),DEC;
         setdaytemp=now.day(),DEC;
         sethourstemp=now.hour(),DEC;
         setminstemp=now.minute(),DEC;
         setclock();
         pushlength = pushlengthset;
       };

}


//delay(3000);

lc.clearDisplay(0); // Clear display register 
for(int j=0; j<300; j++){
DateTime now = RTC.now();
int ora0 = now.hour();
int minut0 = now.minute();
int second0 = now.second();
/*
// serial monitor
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  Serial.print(now.minute(), DEC);
  Serial.print(":");
  Serial.print(now.second(), DEC);
  Serial.print(" -> ");
  Serial.print(ora1);
  Serial.println(":");
  Serial.print(minut1);
  Serial.print(":");
  Serial.print(second1);
  Serial.println("------------------");
*/
ora (ora0, minut0, second0);

    pushlength = pushlengthset;
    pushlength = getpushlength ();
    delay (10);
    if (pushlength <pushlengthset) {
      ShortPush ();   
    }
       //This runs the setclock routine if the knob is pushed for a long time
       if (pushlength >pushlengthset) {
         lc.clearDisplay(0); // Clear display register 
         DateTime now = RTC.now();
         setyeartemp=now.year(),DEC;
         setmonthtemp=now.month(),DEC;
         setdaytemp=now.day(),DEC;
         sethourstemp=now.hour(),DEC;
         setminstemp=now.minute(),DEC;
         setclock();
         pushlength = pushlengthset;
       };



//delay (900);
}

t = dht.readTemperature(); // read data for temperature

lc.clearDisplay(0); // Clear display register 
for(int j=0; j<300; j++){
DateTime now = RTC.now();
int ziua0 = now.day();
int luna0 = now.month();
int anul0 = now.year();
/*
// serial monitor
  Serial.print(now.day(), DEC);
  Serial.print(":");
  Serial.print(now.month(), DEC);
  Serial.print(":");
  Serial.print(now.year(), DEC);
  Serial.print(" -> ");
  Serial.print(ziua0);
  Serial.println(".");
  Serial.print(luna0);
  Serial.print(".");
  Serial.print(anul0);
  Serial.println("------------------");
*/
data (ziua0, luna0, anul0);



    pushlength = pushlengthset;
    pushlength = getpushlength ();
    delay (10);
    if (pushlength <pushlengthset) {
      ShortPush ();   
    }
       //This runs the setclock routine if the knob is pushed for a long time
       if (pushlength >pushlengthset) {
         lc.clearDisplay(0); // Clear display register 
         DateTime now = RTC.now();
         setyeartemp=now.year(),DEC;
         setmonthtemp=now.month(),DEC;
         setdaytemp=now.day(),DEC;
         sethourstemp=now.hour(),DEC;
         setminstemp=now.minute(),DEC;
         setclock();
         pushlength = pushlengthset;
       };



//delay (900);
}



}


void umiditate (int umidit)
{
int zu = int(umidit/10); // determin cifra zecilor
int uu = umidit - 10*zu; // determin cifra unitatilor
  
lc.setDigit(0,2,zu, false); // afisez un 5 pe coloana 2
lc.setDigit(0,1,uu, false); // afisez un 0 pe coloana 1
lc.setRow(0,0,B0110111);  // afisez litera "H"
}


void temperatura (int temper)
{
int zt = int(temper/10); // determin cifra zecilor
int ut = temper - 10*zt; // determin cifra unitatilor
  
lc.setDigit(0,7,zt, false); // afisez un 5 pe coloana 7
lc.setDigit(0,6,ut, false); // afisez un 0 pe coloana 1
lc.setRow(0,5,B1100011); // afisez un semn de grad pe coloana 5
lc.setRow(0,4,B1001110); // afisez un C pe coloana 4
}

void ora (int ora1, int minut1, int second1) 
{
// hour
int zo = int(ora1/10); // determin cifra zecilor
int uo = ora1 - 10*zo; // determin cifra unitatilor
if (zo >= 1) lc.setDigit(0,7,zo, false); // afisez zecile de ore pe coloana 7 (in stanga)
lc.setDigit(0,6,uo, false); // afisez unitatile de ore pe coloana 6
lc.setRow(0,5,B0000001);  // afisez o liniuta pe coloana 5
// minutes
int zm = int(minut1/10); // determin cifra zecilor
int um = minut1 - 10*zm; // determin cifra unitatilor
lc.setDigit(0,4,zm, false); // afisez zecile de minute pe coloana 4
lc.setDigit(0,3,um, false); // afisez unitatile de minute pe coloana 3
lc.setRow(0,2,B0000001);  // afisez o liniuta pe coloana 2
// seconds
int zs = int(second1/10); // determin cifra zecilor
int us = second1 - 10*zs; // determin cifra unitatilor
lc.setDigit(0,1,zs, false); // afisez zecile de secunde pe coloana 1
lc.setDigit(0,0,us, false); // afisez unitatile de minute pe coloana 0 (dreapta) 
}

void data (int ziua1, int luna1, int anul1) 
{
// ziua (day)
int zz = int(ziua1/10); // determin cifra zecilor
int uz = ziua1 - 10*zz; // determin cifra unitatilor
if (zz >= 1) lc.setDigit(0,7,zz, false); // afisez zecile de ore pe coloana 7 (in stanga)
lc.setDigit(0,6,uz, true); // afisez unitatile de ore pe coloana 6
//lc.setRow(0,5,B0000001);  // afisez o liniuta pe coloana 5

// luna (mounth)
int zl = int(luna1/10); // determin cifra zecilor
int ul = luna1 - 10*zl; // determin cifra unitatilor
lc.setDigit(0,5,zl, false); // afisez zecile de minute pe coloana 5
lc.setDigit(0,4,ul, true); // afisez unitatile de minute pe coloana 4
//lc.setRow(0,2,B0000001);  // afisez o liniuta pe coloana 2

// anul (year)
int ma = int(anul1/1000); // determin cifra miilor
int rsa = anul1 - 1000*ma; // determin restul sutelor
int sa = int(rsa/100); // determin cifra sutelor
int rza = rsa - 100*sa; // determin restul zecilor
int za = int(rza/10); // determin cifra zecilor
int ua = rza - 10*za; // determin cifra anilor

lc.setDigit(0,3,ma, false); // afisez zecile de secunde pe coloana 3
lc.setDigit(0,2,sa, false); // afisez unitatile de minute pe coloana 2  
lc.setDigit(0,1,za, false); // afisez zecile de secunde pe coloana 1
lc.setDigit(0,0,ua, false); // afisez unitatile de minute pe coloana 0 (dreapta) 
}


//sets the clock
void setclock (){
   setyear ();
lc.clearDisplay(0); // Clear display register 
   setmonth ();
lc.clearDisplay(0); // Clear display register 
   setday ();
lc.clearDisplay(0); // Clear display register 
   sethours ();
lc.clearDisplay(0); // Clear display register 
   setmins ();
lc.clearDisplay(0); // Clear display register 
   
   RTC.adjust(DateTime(setyeartemp,setmonthtemp,setdaytemp,sethourstemp,setminstemp,setsecs));

   delay (1000);
   
}

// subroutine to return the length of the button push.
int getpushlength () {
  buttonstate = digitalRead(A0);  
       if(buttonstate == LOW && buttonflag==false) {     
              pushstart = millis();
              buttonflag = true;
          };
          
       if (buttonstate == HIGH && buttonflag==true) {
         pushstop = millis ();
         pushlength = pushstop - pushstart;
         buttonflag = false;
       };
       return pushlength;
}
// The following subroutines set the individual clock parameters
int setyear () {
//lcd.clear();
//lc.clearDisplay(0); // Clear display register 
//    lcd.print ("Set Year");
lc.setRow(0,7,B0111011);  // afisez litera "y" pe coloane 7 (in stanga de tot)
lc.setRow(0,6,B1101111);  // afisez litera "e" pe coloane 6
lc.setRow(0,5,B1111101);  // afisez litera "a" pe coloane 5
//lc.setRow(0,4,B0000101);  // afisez litera "r" pe coloane 4
lc.setRow(0,4,B10000101);  // afisez litera "r" cu punct jos

    pushlength = pushlengthset;
    pushlength = getpushlength ();
    if (pushlength != pushlengthset) {
      return setyeartemp;
    }

//lc.clearDisplay(0); // Clear display register
    if (!digitalRead(SW1)) { //bit of software de-bounce
      knobval = -1;
       delay(150);
          setyeartemp=setyeartemp + knobval;
    if (setyeartemp < 2014) { //Year can't be older than currently, it's not a time machine.
      setyeartemp = 2014;
    }
    }
    if (!digitalRead(SW2)) {
      knobval = 1;  
       delay(150);
          setyeartemp=setyeartemp + knobval;
    if (setyeartemp < 2014) { //Year can't be older than currently, it's not a time machine.
      setyeartemp = 2014;
    }
    }
 //   setyeartemp=setyeartemp + knobval;
 //   if (setyeartemp < 2014) { //Year can't be older than currently, it's not a time machine.
 //     setyeartemp = 2014;
 //   }
//    lcd.print (setyeartemp);
int zua = setyeartemp - 2000;  // aflu ultimele 2 cifre din an
int za = zua / 10;  // aflu cifra zecilor din an
int ua = zua - 10*za; // aflu cifra unitatilor din an
lc.setDigit(0,3,2, false); // afisez cifra "2" din an pe coloana 3
lc.setDigit(0,2,0, false); // afisez cifra "0" din an pe coloana 2
lc.setDigit(0,1,za, false); // afisez cifra zecilor din an pe coloana 1
lc.setDigit(0,0,ua, false); // afisez cifra unitatilor din an pe coloana 0 (dreapta de tot)
    setyear();
//    delay(150);
}

  
int setmonth () {
//lcd.clear();
//lcd.print ("Set Month");
lc.setRow(0,7,B0110111);  // afisez litera "H" (in loc de "m") pe coloane 7 (in stanga de tot)
//lc.setRow(0,7,B1001111);  // afisez litera "E" (in loc de "m") pe coloane 7 (in stanga de tot)
lc.setRow(0,6,B0011101);  // afisez litera "o" pe coloane 6
lc.setRow(0,5,B0010101);  // afisez litera "n" pe coloane 5
lc.setRow(0,4,B0001111);  // afisez litera "t" pe coloane 4
lc.setRow(0,3,B0010111);  // afisez litera "h" pe coloane 3

    pushlength = pushlengthset;
    pushlength = getpushlength ();
    if (pushlength != pushlengthset) {
      return setmonthtemp;
    }

//    lcd.setCursor (0,1);
   if (!digitalRead(SW1)) { //bit of software de-bounce
      knobval = -1;
      delay(150);
        setmonthtemp=setmonthtemp + knobval;
    if (setmonthtemp < 1) {// month must be between 1 and 12
      setmonthtemp = 1;
    }
    }
    if (!digitalRead(SW2)) {
      knobval = 1;
      delay(150);
      setmonthtemp=setmonthtemp + knobval;
    if (setmonthtemp > 12) {
      setmonthtemp=12;
    }  
    }  
  
 //   lcd.print (setmonthtemp);
 //   lcd.print("  ");
int zl = setmonthtemp / 10;  // aflu cifra zecilor din luna
int ul = setmonthtemp - 10*zl; // aflu cifra unitatilor din luna
lc.setDigit(0,1,zl, false); // afisez cifra zecilor din luna pe coloana 1
lc.setDigit(0,0,ul, false); // afisez cifra unitatilor din luna pe coloana 0 (dreapta de tot)
     setmonth();
}

int setday () {
  if (setmonthtemp == 4 || setmonthtemp == 6 || setmonthtemp == 9 || setmonthtemp == 11) { //30 days hath September, April June and November
    maxday = 30;
  }
  else {
  maxday = 31; //... all the others have 31
  }
  if (setmonthtemp ==2 && setyeartemp % 4 ==0) { //... Except February alone, and that has 28 days clear, and 29 in a leap year.
    maxday = 29;
  }
  if (setmonthtemp ==2 && setyeartemp % 4 !=0) {
    maxday = 28;
  }
//lcd.clear();  
//    lcd.print ("Set Day");
lc.setRow(0,7,B0111101);  // afisez litera "d" pe coloane 7
lc.setRow(0,6,B1111101);  // afisez litera "a" pe coloane 6
lc.setRow(0,5,B0111011);  // afisez litera "y" pe coloane 5

    pushlength = pushlengthset;
    pushlength = getpushlength ();
    if (pushlength != pushlengthset) {
      return setdaytemp;
    }

 //   lcd.setCursor (0,1);
    if (!digitalRead(SW1)) { //bit of software de-bounce
      knobval = -1;
      delay(150);
        setdaytemp=setdaytemp+ knobval;
    if (setdaytemp < 1) {
      setdaytemp = 1;
    }
    }
    if (!digitalRead(SW2)) {
      knobval = 1;  
      delay(150);
        setdaytemp=setdaytemp+ knobval;
    if (setdaytemp > maxday) {
      setdaytemp = maxday;
    }
    } 
  
//    lcd.print (setdaytemp);
//    lcd.print("  "); 
int zz = setdaytemp / 10;  // aflu cifra zecilor din zi
int uz = setdaytemp - 10*zz; // aflu cifra unitatilor din zi
lc.setDigit(0,1,zz, false); // afisez cifra zecilor din zi pe coloana 1
lc.setDigit(0,0,uz, false); // afisez cifra unitatilor din zi pe coloana 0 (dreapta de tot)
    setday();
}

int sethours () {
//lcd.clear();
//    lcd.setCursor (0,0);
//    lcd.print ("Set Hours");
lc.setRow(0,7,B0010111);  // afisez litera "h" pe coloane 7
lc.setRow(0,6,B0011101);  // afisez litera "o" pe coloane 6
lc.setRow(0,5,B0011100);  // afisez litera "u" pe coloane 5
lc.setRow(0,4,B0000101);  // afisez litera "r" pe coloane 4

    pushlength = pushlengthset;
    pushlength = getpushlength ();
    if (pushlength != pushlengthset) {
      return sethourstemp;
    }

//    lcd.setCursor (0,1);
    if (!digitalRead(SW1)) { //bit of software de-bounce
      knobval = -1;
       delay(150);
        sethourstemp=sethourstemp + knobval;
    if (sethourstemp < 0) {
      sethourstemp = 0;
    }
    }
    if (!digitalRead(SW2)) {
      knobval = 1;
     delay(150);  
    sethourstemp=sethourstemp + knobval;
    if (sethourstemp > 23) {
      sethourstemp=23;
    }
    }
//    lcd.print (sethourstemp);
//    lcd.print("  "); 
int zo = sethourstemp / 10;  // aflu cifra zecilor de ore
int uo = sethourstemp - 10*zo; // aflu cifra unitatilor de ore
lc.setDigit(0,1,zo, false); // afisez cifra zecilor de ora pe coloana 1
lc.setDigit(0,0,uo, false); // afisez cifra unitatilor de ora pe coloana 0 (dreapta de tot)
    sethours();
}

int setmins () {
//lcd.clear();
//   lcd.setCursor (0,0);
//    lcd.print ("Set Mins");
lc.setRow(0,7,B0110111);  // afisez litera "H" (in loc de "m") pe coloane 7 (in stanga de tot)
//lc.setRow(0,7,B1001111);  // afisez litera "E" (in loc de "m") pe coloane 7 (in stanga de tot)    
lc.setRow(0,6,B0010000);  // afisez litera "i" pe coloane 6
lc.setRow(0,5,B0010101);  // afisez litera "n" pe coloane 5
lc.setRow(0,4,B0011100);  // afisez litera "u" pe coloane 4
lc.setRow(0,3,B0001111);  // afisez litera "t" pe coloane 3
//lc.setChar(0,2,'e',true);
lc.setRow(0,2,B11101111);  // afisez litera "e" cu punct jos


    pushlength = pushlengthset;
    pushlength = getpushlength ();
    if (pushlength != pushlengthset) {
      return setminstemp;
    }

//    lcd.setCursor (0,1);
   if (!digitalRead(SW1)) { //bit of software de-bounce
      knobval = -1;
       delay(150);  
         setminstemp=setminstemp + knobval;
    if (setminstemp < 0) {
      setminstemp = 0;
    }
    }
    if (!digitalRead(SW2)) {
      knobval = 1;  
       delay(150);   
    setminstemp=setminstemp + knobval;
    if (setminstemp > 59) {
      setminstemp=59;
    }
    }
//    lcd.print (setminstemp);
//    lcd.print("  ");
int zm = setminstemp / 10;  // aflu cifra zecilor de minute
int um = setminstemp - 10*zm; // aflu cifra unitatilor de minute
lc.setDigit(0,1,zm, false); // afisez cifra zecilor de minute pe coloana 1
lc.setDigit(0,0,um, false); // afisez cifra unitatilor de minute pe coloana 0 (dreapta de tot)
    setmins();
}


void ShortPush () {
  //This displays show something
lc.clearDisplay(0); // Clear display register
for (long Counter = 0; Counter < 10 ; Counter ++) { //returns to the main loop if it's been run 604 times 
                                                 
//  lcd.setCursor (2,0);
//  lcd.print ("Hi, niq_ro!");
lc.setRow(0,6,B1100010);  // afisez litera "n" pe coloane 6
lc.setRow(0,5,B0100000);  // afisez litera "i" pe coloane 5
lc.setRow(0,4,B1110011);  // afisez litera "q" pe coloane 4
lc.setRow(0,3,B0000001);  // afisez semnul "-" pe coloane 3
lc.setRow(0,2,B1000010);  // afisez litera "r" pe coloane 2
lc.setRow(0,1,B1100011);  // afisez litera "o" pe coloane 1
delay(200);
}
lc.clearDisplay(0); // Clear display register
}
   

sâmbătă, 10 ianuarie 2015

Ceas RTC cu DS1307 si date mediu cu DHT11 pe afisaj alfanumeric LCD1602 folosind Arduino (2)

   Am gasit articolul Arduino Astronomical Clock (or Arduino Pond Pump Controller!) care are un ceas pe baza integratului DS1307, pe care l-am folosit si eu, dar are 2 facilitati interesante: reglajul orei si datei din encoderul rotativ + calcul perioadei cat soarele este pe cer (rasarit si apus soare).
   Am reprodus si eu experimentul pentru a intelege modul de schimbare al orei si datei, mai putin releul...
   Daca se apasa pentru scurt timp se afiseaza orele de rasarit si de apus ale soarelui.
iar la o noua apasare, se alege modul de actionare la unui releu: AUTO (pe durata zilei, mereu actionat contact sau permanent decuplat contact), asta deoarece se folosea pentru alimentarea pe timpul zilei a unei fantani arteziene.
   Daca se apasa lung (mai mult de 3 secunde) se intra in modul de reglaj:
- an:
- luna:
- zi:
- ora:
- minute:
   Pentru a putea calcula perioada cat soarele este pe cer se foloseste o librarie speciala, TimeLord.h (se poate descarca si de la aici), care necesita introducerea in sketch a coordonatelor GPS alel localitatii si a orei locale fata cea de baza:
   Pentru verificarea datelor, am cautat si, evident, gasit orele de rasarit si apus ale soarelui pentru ziua respectiva:
si se observa ca eroare este doar de cateva minute, rasaritul de soare este calculat de Arduino ca fiind la 7:59, iar pe site am gasit ca a fost 8:00, respectiv apusul soarelui a fost calculat ca fiind la 17:02, iar pe site este 17:04.
   Am facut un film, numit ceas cu DS1307 reglat cu encoder rotativ si date despre soare (rasarit si apus) pentru a se vedea mai usor modul de "actiune":
   Revenind la partea care m-a interesat in mod deosebit, am adaugat si un modul cu senzor DHT11 pentru a pune si umiditatea si temperatura, conectand pinul de date la A1:
   Sketch-ul folosit de mine este:
// Dawn & Dusk controller. http://andydoz.blogspot.ro/2014_08_01_archive.html
// 16th August 2014.
// (C) A.G.Doswell 2014
// adapted sketch by niq_ro from http://nicuflorica.blogspot.ro & http://arduinotehniq.blogspot.com/
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
//
// Designed to control a relay connected to pin A3. Pin goes low during daylight hours and high during night. Relay uses active low, so is
// "On" during the day. This is connected to the fountain pump in my garden.
//
// Time is set using a rotary encoder with integral push button. The Encoder is connected to interrupt pins D2 & D3 (and GND), 
// and the push button to pin analogue 0 (and GND)
// The RTC is connections are: Analogue pin 4 to SDA. Connect analogue pin 5 to SCL.
// A 2 x 16 LCD display is connected as follows (NOTE. This is NOT conventional, as interrupt pins are required for the encoder)
//  Arduino LCD  
//  D4      DB7
//  D5      DB6
//  D6      DB5
//  D7      DB4
//  D12     RS
//  D13     E
// 
// Use: Pressing and holding the button will enter the clock set mode (on release of the button). Clock is set using the rotary encoder. 
// The clock must be set to UTC.
// Pressing and releasing the button quickly will display the current sun rise and sun set times. Pressing the button again will enter the mode select menu. 
// Modes are AUTO: On when the sun rises, off when it sets.
//           ON: Permanently ON
//           OFF: Permanently OFF (Who'd have guessed it?)
//
// Change the LATTITUDE and LONGITUDE constant to your location.

#include <Wire.h>
#include "RTClib.h" // from https://github.com/adafruit/RTClib
#include <LiquidCrystal.h>
#include <Encoder.h> // from http://www.pjrc.com/teensy/td_libs_Encoder.html
#include <TimeLord.h> // from http://swfltek.com/arduino/timelord.html. When adding it to your IDE, rename the file, removing the "-depreciated" 
// http://www.timeanddate.com/sun/romania/craiova - for control sun time

RTC_DS1307 RTC; // Tells the RTC library that we're using a DS1307 RTC
Encoder knob(2, 3); //encoder connected to pins 2 and 3 (and ground)
LiquidCrystal lcd(12, 13, 7, 6, 5, 4); // I used an odd pin combination because I need pin 2 and 3 for the interrupts.

//the variables provide the holding values for the set clock routine
int setyeartemp; 
int setmonthtemp;
int setdaytemp;
int sethourstemp;
int setminstemp;
int setsecs = 0;
int maxday; // maximum number of days in the given month
int TimeMins; // number of seconds since midnight
int TimerMode = 2; //mode 0=Off 1=On 2=Auto
int TimeOut = 10;
int TimeOutCounter;

// These variables are for the push button routine
int buttonstate = 0; //flag to see if the button has been pressed, used internal on the subroutine only
int pushlengthset = 3000; // value for a long push in mS
int pushlength = pushlengthset; // set default pushlength
int pushstart = 0;// sets default push value for the button going low
int pushstop = 0;// sets the default value for when the button goes back high

int knobval; // value for the rotation of the knob
boolean buttonflag = false; // default value for the button flag


//const int TIMEZONE = 0; //UTC
const int TIMEZONE = 2; //UTC Craiova (Romania) - http://www.worldtimebuddy.com/utc-to-romania-craiova
//const float LATITUDE = 51.89, LONGITUDE = -2.04; // set YOUR position here 
const float LATITUDE =  44.3167, LONGITUDE = 23.8; // Craiova GPS position
int Sunrise, Sunset; //sunrise and sunset expressed as minute of day (0-1439)
TimeLord myLord; // TimeLord Object, Global variable
byte sunTime[]  = {0, 0, 0, 1, 1, 13}; // 17 Oct 2013
int SunriseHour, SunriseMin, SunsetHour, SunsetMin; //Variables used to make a decent display of our sunset and sunrise time.


// http://arduino.cc/en/Reference/LiquidCrystalCreateChar
byte grad[8] = {
  B01100,
  B10010,
  B10010,
  B01100,
  B00000,
  B00000,
  B00000,
};

#include <DHT.h>
#define DHTPIN A1     // what pin we're connected DHT11/22
#define DHTTYPE DHT11   // DHT 11 
//#define DHTTYPE DHT22   // DHT 22

DHT dht(DHTPIN, DHTTYPE);
float t1;


void setup () {
    //Serial.begin(57600); //start debug serial interface
    Wire.begin(); //start I2C interface
    RTC.begin(); //start RTC interface
  dht.begin();  // DHT init 
  lcd.createChar(0, grad);  // create custom symbol
    lcd.begin(16,2); //Start LCD (defined as 16 x 2 characters)
    lcd.clear(); 
    pinMode(A0,INPUT);//push button on encoder connected to A0 (and GND)
    digitalWrite(A0,HIGH); //Pull A0 high
    pinMode(A3,OUTPUT); //Relay connected to A3
    digitalWrite (A3, HIGH); //sets relay off (default condition)
    
    //Checks to see if the RTC is runnning, and if not, sets the time to the time this sketch was compiled.
    if (! RTC.isrunning()) {
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
 
 
    //Timelord initialisation
    myLord.TimeZone(TIMEZONE * 60);
    myLord.Position(LATITUDE, LONGITUDE);
    CalcSun ();
}
           

void loop () {

  int h = dht.readHumidity();
   float t = dht.readTemperature();
   lcd.setCursor(11, 1);
  // lcd.print("t=");
 if (t < 0) 
 {t1=-t;}
 else t1=t;
  
    if ( t1 < 10)
   {
     lcd.print(" "); 
   }
   if (t>0) lcd.print("+"); 
   if (t==0) lcd.print(" "); 
   if (t<0) lcd.print("-");
   lcd.print(t1,0);
   //lcd.print(",0");
//   lcd.write(0b11011111);
   lcd.write(byte(0));
   lcd.print("C");
    

   lcd.setCursor(11, 0);
  // lcd.print("H=");
   lcd.print(h);
   lcd.print("%RH"); 
   
    DateTime now = RTC.now(); //get time from RTC
    //Display current time
    lcd.setCursor (0,0);
    lcd.print(now.day(), DEC);
    lcd.print('/');
    lcd.print(now.month());
    lcd.print('/');
    lcd.print(now.year(), DEC);
    lcd.print(" ");
    lcd.setCursor (0,1);
    lcd.print(now.hour(), DEC);
    lcd.print(':');
    if (now.minute() <10) 
      {
        lcd.print("0");
      }
    lcd.print(now.minute(), DEC);
    lcd.print(':');
    if (now.second() <10) 
      {
        lcd.print("0");
      }
    lcd.print(now.second());
//    lcd.print("     ");
    
    //current time in minutes since midnight (used to check against sunrise/sunset easily)
    TimeMins = (now.hour() * 60) + now.minute();
    
    // Calculate sun times once a day at a minute past midnight
    if (TimeMins == 1) {
      CalcSun ();
    }
    if (TimerMode ==2) {
      if (TimeMins >= Sunrise && TimeMins <=Sunset-1) { //If it's after sunrise and before sunset, switch our relay on
          digitalWrite (A3, LOW);
          lcd.setCursor (9,1);
          lcd.print ("*");
        }
        else {  //otherwise switch it off
          digitalWrite (A3, HIGH);
          lcd.setCursor (9,1);
          lcd.print ("!");
        }
      }
       if (TimerMode ==0) {
         digitalWrite (A3, HIGH);
         lcd.setCursor (9,1);
         lcd.print ("!");
       }
     
       if (TimerMode ==1) {
         digitalWrite (A3, LOW);
         lcd.setCursor (9,1);
         lcd.print ("*");
       }
    
    pushlength = pushlengthset;
    pushlength = getpushlength ();
    delay (10);
    
    if (pushlength <pushlengthset) {
     
      ShortPush ();   
    }
    
       
       //This runs the setclock routine if the knob is pushed for a long time
       if (pushlength >pushlengthset) {
         lcd.clear();
         DateTime now = RTC.now();
         setyeartemp=now.year(),DEC;
         setmonthtemp=now.month(),DEC;
         setdaytemp=now.day(),DEC;
         sethourstemp=now.hour(),DEC;
         setminstemp=now.minute(),DEC;
         setclock();
         pushlength = pushlengthset;
       };
}

//sets the clock
void setclock (){
   setyear ();
   lcd.clear ();
   setmonth ();
   lcd.clear ();
   setday ();
   lcd.clear ();
   sethours ();
   lcd.clear ();
   setmins ();
   lcd.clear();
   
   RTC.adjust(DateTime(setyeartemp,setmonthtemp,setdaytemp,sethourstemp,setminstemp,setsecs));
   CalcSun ();
   delay (1000);
   
}

// subroutine to return the length of the button push.
int getpushlength () {
  buttonstate = digitalRead(A0);  
       if(buttonstate == LOW && buttonflag==false) {     
              pushstart = millis();
              buttonflag = true;
          };
          
       if (buttonstate == HIGH && buttonflag==true) {
         pushstop = millis ();
         pushlength = pushstop - pushstart;
         buttonflag = false;
       };
       return pushlength;
}
// The following subroutines set the individual clock parameters
int setyear () {
//lcd.clear();
    lcd.setCursor (0,0);
    lcd.print ("Set Year");
    pushlength = pushlengthset;
    pushlength = getpushlength ();
    if (pushlength != pushlengthset) {
      return setyeartemp;
    }

    lcd.setCursor (0,1);
    knob.write(0);
    delay (50);
    knobval=knob.read();
    if (knobval < -1) { //bit of software de-bounce
      knobval = -1;
    }
    if (knobval > 1) {
      knobval = 1;
    }
    setyeartemp=setyeartemp + knobval;
    if (setyeartemp < 2014) { //Year can't be older than currently, it's not a time machine.
      setyeartemp = 2014;
    }
    lcd.print (setyeartemp);
    lcd.print("  "); 
    setyear();
}
  
int setmonth () {
//lcd.clear();
   lcd.setCursor (0,0);
    lcd.print ("Set Month");
    pushlength = pushlengthset;
    pushlength = getpushlength ();
    if (pushlength != pushlengthset) {
      return setmonthtemp;
    }

    lcd.setCursor (0,1);
    knob.write(0);
    delay (50);
    knobval=knob.read();
    if (knobval < -1) {
      knobval = -1;
    }
    if (knobval > 1) {
      knobval = 1;
    }
    setmonthtemp=setmonthtemp + knobval;
    if (setmonthtemp < 1) {// month must be between 1 and 12
      setmonthtemp = 1;
    }
    if (setmonthtemp > 12) {
      setmonthtemp=12;
    }
    lcd.print (setmonthtemp);
    lcd.print("  "); 
    setmonth();
}

int setday () {
  if (setmonthtemp == 4 || setmonthtemp == 5 || setmonthtemp == 9 || setmonthtemp == 11) { //30 days hath September, April June and November
    maxday = 30;
  }
  else {
  maxday = 31; //... all the others have 31
  }
  if (setmonthtemp ==2 && setyeartemp % 4 ==0) { //... Except February alone, and that has 28 days clear, and 29 in a leap year.
    maxday = 29;
  }
  if (setmonthtemp ==2 && setyeartemp % 4 !=0) {
    maxday = 28;
  }
//lcd.clear();  
   lcd.setCursor (0,0);
    lcd.print ("Set Day");
    pushlength = pushlengthset;
    pushlength = getpushlength ();
    if (pushlength != pushlengthset) {
      return setdaytemp;
    }

    lcd.setCursor (0,1);
    knob.write(0);
    delay (50);
    knobval=knob.read();
    if (knobval < -1) {
      knobval = -1;
    }
    if (knobval > 1) {
      knobval = 1;
    }
    setdaytemp=setdaytemp+ knobval;
    if (setdaytemp < 1) {
      setdaytemp = 1;
    }
    if (setdaytemp > maxday) {
      setdaytemp = maxday;
    }
    lcd.print (setdaytemp);
    lcd.print("  "); 
    setday();
}

int sethours () {
//lcd.clear();
    lcd.setCursor (0,0);
    lcd.print ("Set Hours");
    pushlength = pushlengthset;
    pushlength = getpushlength ();
    if (pushlength != pushlengthset) {
      return sethourstemp;
    }

    lcd.setCursor (0,1);
    knob.write(0);
    delay (50);
    knobval=knob.read();
    if (knobval < -1) {
      knobval = -1;
    }
    if (knobval > 1) {
      knobval = 1;
    }
    sethourstemp=sethourstemp + knobval;
    if (sethourstemp < 1) {
      sethourstemp = 1;
    }
    if (sethourstemp > 23) {
      sethourstemp=23;
    }
    lcd.print (sethourstemp);
    lcd.print("  "); 
    sethours();
}

int setmins () {
//lcd.clear();
   lcd.setCursor (0,0);
    lcd.print ("Set Mins");
    pushlength = pushlengthset;
    pushlength = getpushlength ();
    if (pushlength != pushlengthset) {
      return setminstemp;
    }

    lcd.setCursor (0,1);
    knob.write(0);
    delay (50);
    knobval=knob.read();
    if (knobval < -1) {
      knobval = -1;
    }
    if (knobval > 1) {
      knobval = 1;
    }
    setminstemp=setminstemp + knobval;
    if (setminstemp < 0) {
      setminstemp = 0;
    }
    if (setminstemp > 59) {
      setminstemp=59;
    }
    lcd.print (setminstemp);
    lcd.print("  "); 
    setmins();
}

int setmode () { //Sets the mode of the timer. Auto, On or Off
//lcd.clear();
    lcd.setCursor (0,0);
    lcd.print ("Set Mode");
    pushlength = pushlengthset;
    pushlength = getpushlength ();
    if (pushlength != pushlengthset) {
      return TimerMode;
    }

    lcd.setCursor (0,1);
    knob.write(0);
    delay (50);
    knobval=knob.read();
    if (knobval < -1) {
      knobval = -1;
    }
    if (knobval > 1) {
      knobval = 1;
    }
    TimerMode=TimerMode + knobval;
    if (TimerMode < 0) {
      TimerMode = 0;
    }
    if (TimerMode > 2) {
      TimerMode=2;
    }
    if (TimerMode == 0) {
    lcd.print("Off (!)");
    lcd.print("  "); 
    }
    if (TimerMode == 1) {
    lcd.print("On (*)");
    lcd.print("  "); 
    }
    if (TimerMode == 2) {
    lcd.print("Auto");
    lcd.print("  "); 
    }
    setmode ();
}

int CalcSun () { //Calculates the Sunrise and Sunset times
    DateTime now = RTC.now();
    sunTime[3] = now.day(); // Give Timelord the current date
    sunTime[4] = now.month();
    sunTime[5] = now.year();
    myLord.SunRise(sunTime); // Computes Sun Rise.
    Sunrise = sunTime[2] * 60 + sunTime[1]; // Sunrise returned in minutes past midnight
    SunriseHour = sunTime[2];
    SunriseMin = sunTime [1];
    sunTime[3] = now.day(); // Uses the Time library to give Timelord the current date
    sunTime[4] = now.month();
    sunTime[5] = now.year();
    myLord.SunSet(sunTime); // Computes Sun Set.
    Sunset = sunTime[2] * 60 + sunTime[1]; // Sunset returned in minutes past midnight
    SunsetHour = sunTime[2];
    SunsetMin = sunTime [1];
}

void ShortPush () {
  //This displays the calculated sunrise and sunset times when the knob is pushed for a short time.
lcd.clear();
for (long Counter = 0; Counter < 604 ; Counter ++) { //returns to the main loop if it's been run 604 times 
                                                     //(don't ask me why I've set 604,it seemed like a good number)
  lcd.setCursor (0,0);
  lcd.print ("Sunrise ");
  lcd.print (SunriseHour);
  lcd.print (":");
  if (SunriseMin <10) 
     {
     lcd.print("0");
     }
  lcd.print (SunriseMin);
  lcd.setCursor (0,1);
  lcd.print ("Sunset ");
  lcd.print (SunsetHour);
  lcd.print (":"); 
    if (SunsetMin <10) 
     {
     lcd.print("0");
     }
  lcd.print (SunsetMin);        

    
  //If the knob is pushed again, enter the mode set menu
  pushlength = pushlengthset;
  pushlength = getpushlength ();
  if (pushlength != pushlengthset) {
    lcd.clear ();
    TimerMode = setmode ();

  }
  
}
lcd.clear();
}
   Am facut inca 2 filmulete cu noua varianta:
statie meteo cu DHT11 si ceas cu DS1307 reglat cu encoder rotativ si date despre soare
statie meteo cu DHT11 si ceas cu DS1307 reglat cu encoder rotativ si date despre soare (2)