ArduShop.ro

ArduShop.ro
cod Z4A413ZN reducere 5%, pentru vizitatorii paginilor mele !

luni, 29 septembrie 2014

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

actualizat poze in 11.08.2015

   In articolul Ceas de timp real (RTC) cu DS1307 si Arduino (partea a 2-a) am folosit modulul RTC (ceas de timp real), ulterior, si senzorul de temperatura si umiditate DHT11, cu un afisaj alfanumeric cu 16 coloane si 2 randuri (LCD1602) conectat la placa Arduino prin intermediul unei  interfete i2c, de data asta am conectat afisajul clasic, dupa cum se vede in schema de mai jos:
   Am avut la indemana 3 afisaje alfanumerice:
 
 
   Sketch-ul folosit este adaptarea celui din articolul mentionat anterior, schimband partea de interfata i2c cu conectarea clasica a afisajului, dar pentru cei incepatori, il postez si pe acesta:
// Date and time functions using a DS1307 RTC 
// original sketck from http://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/
// add part with SQW=1Hz from http://tronixstuff.wordpress.com/ & http://www.bristolwatch.com/arduino/arduino_ds1307.htm

// adapted sketch by niq_ro from http://nicuflorica.blogspot.ro/
// original article from http://nicuflorica.blogspot.ro/2013/06/ceas-de-timp-real-rtc-cu-ds1307-si.html

#include <Wire.h>
#include "RTClib.h"

// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

RTC_DS1307 RTC;

void setup () {
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a logo message to the LCD.
  lcd.print("www.tehnic.go.ro");  
  lcd.setCursor(0, 1);
  lcd.print("creat de niq_ro");
  delay (2500);
  lcd.clear();
    
   // Serial.begin(9600);
    Wire.begin();
  
// 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.endTransmission();
// end part code from http://tronixstuff.wordpress.com/

    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__));
  }
}

void loop () {
   DateTime now = RTC.now();
   lcd.setCursor(4, 0);
   if ( now.hour() < 10)
   {
     lcd.print(" "); 
     lcd.print(now.hour(), DEC);
   }
   else
   {
   lcd.print(now.hour(), DEC);
   }
   lcd.print(":");
   if ( now.minute() < 10)
   {
     lcd.print("0"); 
     lcd.print(now.minute(), DEC);
   }
   else
   {
   lcd.print(now.minute(), DEC);
   }
   lcd.print(":");
   if ( now.second() < 10)
   {
     lcd.print("0"); 
     lcd.print(now.second(), DEC);
   }
   else
   {
   lcd.print(now.second(), DEC);
   }
     lcd.print(" "); 
    
   lcd.setCursor(3, 1);
    if ( now.day() < 10)
   {
     lcd.print("0"); 
     lcd.print(now.day(), DEC);
   }
   else
   {
   lcd.print(now.day(), DEC);
   }
   lcd.print("/");
   if ( now.month() < 10)
   {
     lcd.print("0"); 
     lcd.print(now.month(), DEC);
   }
   else
   {
   lcd.print(now.month(), DEC);
   }
   lcd.print("/");
   lcd.print(now.year(), DEC);
   lcd.print(" "); 
  
   delay(1000);
}
   Dupa asta, am conectat si modulul cu senzorul DHT11, care poate furniza date despre temperatura cu eroare de +20C, iar despre umiditate cu eroare de +5 unitati.
   Schema de conectare devine:
   Sketch-ul adaptat devine:
// Date and time functions using a DS1307 RTC 
// original sketck from http://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/
// add part with SQW=1Hz from http://tronixstuff.wordpress.com & http://www.bristolwatch.com/arduino/arduino_ds1307.htm

// adapted sketch by niq_ro from http://nicuflorica.blogspot.ro/ 
// original article from http://nicuflorica.blogspot.ro/2013/06/ceas-de-timp-real-rtc-cu-ds1307-si.html

#include <Wire.h>
#include "RTClib.h"

// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

RTC_DS1307 RTC;

#include <DHT.h>
#define DHTPIN A2     // what pin we're connected DHT11
#define DHTTYPE DHT11   // DHT 11 
DHT dht(DHTPIN, DHTTYPE);

void setup () {
  // DHT init
  dht.begin();
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a logo message to the LCD.
  lcd.print("www.tehnic.go.ro");  
  lcd.setCursor(0, 1);
  lcd.print("creat de niq_ro");
  delay (2500);
  lcd.clear();
    
   // Serial.begin(9600);
    Wire.begin();
  
// 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.endTransmission();
// end part code from http://tronixstuff.wordpress.com/

    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__));
  }
}

void loop () {
   DateTime now = RTC.now();
  int h = dht.readHumidity();
  int t = dht.readTemperature();

   lcd.setCursor(1, 0);
   if ( now.hour() < 10)
   {
     lcd.print(" "); 
     lcd.print(now.hour(), DEC);
   }
   else
   {
   lcd.print(now.hour(), DEC);
   }
   lcd.print(":");
   if ( now.minute() < 10)
   {
     lcd.print("0"); 
     lcd.print(now.minute(), DEC);
   }
   else
   {
   lcd.print(now.minute(), DEC);
   }
   lcd.print(":");
   if ( now.second() < 10)
   {
     lcd.print("0"); 
     lcd.print(now.second(), DEC);
   }
   else
   {
   lcd.print(now.second(), DEC);
   }
     lcd.print(" "); 
 
  lcd.setCursor(11, 0);
  // lcd.print("t=");
    if ( t < 10)
   {
     lcd.print(" "); 
     lcd.print(t);
   }
   else
   {
   lcd.print(t);
   }
   lcd.write(0b11011111);
   lcd.print("C");
    
   lcd.setCursor(0, 1);
    if ( now.day() < 10)
   {
     lcd.print("0"); 
     lcd.print(now.day(), DEC);
   }
   else
   {
   lcd.print(now.day(), DEC);
   }
   lcd.print("/");
   if ( now.month() < 10)
   {
     lcd.print("0"); 
     lcd.print(now.month(), DEC);
   }
   else
   {
   lcd.print(now.month(), DEC);
   }
   lcd.print("/");
   lcd.print(now.year(), DEC);
   lcd.print(" "); 
  
   lcd.setCursor(11, 1);
  // lcd.print("H=");
   lcd.print(h);
   lcd.print("%RH");
   
   delay(1000);
}
   Pe ecran informatia este afisata astfel:
   Am facut 2 filmulete de prezentare a montajului:
ceas RTC cu date meteo oferite de DHT11 pe afisaj LCD1602 folosind Arduino
date and hour with RTC DS1307, temperature and humidity with DHT11 on LCD1602 with Arduino
   La sugestia lui Janios, un cititor al blogului, am eliminat partea de data, pastrand doar ora si temperatura si umiditatea oferite de senzorul DHT11.
   M-am gandit ca acum pot pune partea de reglaj al orei din butoane, cum am facut si la ceasul cu afisaje LCD cu 7 sesegmente multiplexate, care l-am prezentat in articolul Afisaje LED cu 7 segmente si.. Arduino (IV), asa ca schema devine:
   Dupa cum se observa, am mutat senzorul DHT11 pe pinul D8, iar tastele pentru intrarea in modul de reglaj, de schimare ore si munute sunt pe partea de senzori analogici, pe post de intrari digitale.
 
   Modul de conectare poate fi diferit de al meu, dar trebuie definite in sketch:
// Date and time functions using a DS1307 RTC 
// original sketck from http://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/
// add part with SQW=1Hz from http://tronixstuff.wordpress.com/ & http://www.bristolwatch.com/arduino/arduino_ds1307.htm

// adapted sketch by niq_ro from http://nicuflorica.blogspot.ro/
// original article from http://nicuflorica.blogspot.ro/2013/06/ceas-de-timp-real-rtc-cu-ds1307-si.html

#include <Wire.h>
#include "RTClib.h"

// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

/*                                    -------------------
                                      |  LCD  | Arduino |
                                      -------------------
 LCD RS pin to digital pin 7          |  RS   |   D7    |
 LCD Enable pin to digital pin 6      |  E    |   D6    |
 LCD D4 pin to digital pin 5          |  D4   |   D6    |
 LCD D5 pin to digital pin 4          |  D5   |   D4    |
 LCD D6 pin to digital pin 3          |  D6   |   D3    |
 LCD D7 pin to digital pin 2          |  D7   |   D2    |
 LCD R/W pin to ground                |  R/W  |   GND   |
                                      -------------------
*/

RTC_DS1307 RTC;

#include <DHT.h>
#define DHTPIN 8     // what pin we're connected DHT11
#define DHTTYPE DHT11   // DHT 11 
DHT dht(DHTPIN, DHTTYPE);

byte SW0 = A0;
byte SW1 = A1;
byte SW2 = A2;

// use for hexa in zecimal conversion
int zh, uh, ore;
int zm, um, miniti;


void setup () {
  // DHT init
  dht.begin();
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a logo message to the LCD.
  lcd.print("www.tehnic.go.ro");  
  lcd.setCursor(0, 1);
  lcd.print("creat de niq_ro");
  delay (2500);
  lcd.clear();
    
   // Serial.begin(9600);
    Wire.begin();
  
// 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.endTransmission();
// end part code from http://tronixstuff.wordpress.com/

    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__));
  }

 pinMode(SW0, INPUT);  // for this use a slide switch
  pinMode(SW1, INPUT);  // N.O. push button switch
  pinMode(SW2, INPUT);  // N.O. push button switch

  digitalWrite(SW0, HIGH); // pull-ups on
  digitalWrite(SW1, HIGH);
  digitalWrite(SW2, HIGH);

}

void loop () {
   DateTime now = RTC.now();
  int h = dht.readHumidity();
  int t = dht.readTemperature();

   lcd.setCursor(4, 0);
   if ( now.hour() < 10)
   {
     lcd.print(" "); 
     lcd.print(now.hour(), DEC);
   }
   else
   {
   lcd.print(now.hour(), DEC);
   }
   lcd.print(":");
   if ( now.minute() < 10)
   {
     lcd.print("0"); 
     lcd.print(now.minute(), DEC);
   }
   else
   {
   lcd.print(now.minute(), DEC);
   }
   lcd.print(":");
   if ( now.second() < 10)
   {
     lcd.print("0"); 
     lcd.print(now.second(), DEC);
   }
   else
   {
   lcd.print(now.second(), DEC);
   }
     lcd.print(" "); 
 
  lcd.setCursor(1, 1);
  // lcd.print("t=");
    if ( t < 10)
   {
     lcd.print(" "); 
     lcd.print(t);
   }
   else
   {
   lcd.print(t);
   }
   //lcd.print(",0");
   lcd.write(0b11011111);
   lcd.print("C");
    
/*   lcd.setCursor(0, 1);
    if ( now.day() < 10)
   {
     lcd.print("0"); 
     lcd.print(now.day(), DEC);
   }
   else
   {
   lcd.print(now.day(), DEC);
   }
   lcd.print("/");
   if ( now.month() < 10)
   {
     lcd.print("0"); 
     lcd.print(now.month(), DEC);
   }
   else
   {
   lcd.print(now.month(), DEC);
   }
   lcd.print("/");
   lcd.print(now.year(), DEC);
   lcd.print(" "); 
*/  
   lcd.setCursor(10, 1);
  // lcd.print("H=");
   lcd.print(h);
   lcd.print("%RH");
 
   if (!(digitalRead(SW0))) set_time(); // hold the switch to set time

 
   delay(500);
}

void set_time()   {
  byte minutes1 = 0;
  byte hours1 = 0;
  byte minutes = 0;
  byte hours = 0;

  while (!digitalRead(SW0))  // set time switch must be released to exit
  {
    minutes1=minutes;
    hours1=hours;
    
     
    while (!digitalRead(SW1)) // set minutes
    { 
     minutes++;  
   // converting hexa in zecimal:
    zh = hours / 16;
    uh = hours - 16 * zh ;
    ore = 10 * zh + uh; 
    zm = minutes / 16;
    um = minutes - 16 * zm ;
    miniti = 10 * zm + um; 
  
  /*  
     for(int i = 20 ; i >0  ; i--) {
     displayNumber01(ore*100+miniti); 
     }
   */
   lcd.setCursor(4, 0);
   if ( ore < 10)
   {
     lcd.print(" "); 
     lcd.print(ore);
   }
   else
   {
   lcd.print(ore);
   }
   lcd.print(":");
   if ( miniti < 10)
   {
     lcd.print("0"); 
     lcd.print(miniti);
   }
   else
   {
   lcd.print(miniti);
   }
   lcd.print(":");
   lcd.print("00"); 
      
      if ((minutes & 0x0f) > 9) minutes = minutes + 6;
      if (minutes > 0x59) minutes = 0;
      Serial.print("Minutes = ");
      if (minutes >= 9) Serial.print("0");
      Serial.println(minutes, HEX);
    delay(150);    
    }

    while (!digitalRead(SW2)) // set hours
    { 
     hours++;          
     
   // converting hexa in zecimal:
    zh = hours / 16;
    uh = hours - 16 * zh ;
    ore = 10 * zh + uh; 
    zm = minutes / 16;
    um = minutes - 16 * zm ;
    miniti = 10 * zm + um; 
    
   /*
     for(int i = 20 ; i >0  ; i--) {
     displayNumber01(ore*100+miniti); 
     }
   */
   lcd.setCursor(4, 0);
   if ( ore < 10)
   {
     lcd.print(" "); 
     lcd.print(ore);
   }
   else
   {
   lcd.print(ore);
   }
   lcd.print(":");
   if ( miniti < 10)
   {
     lcd.print("0"); 
     lcd.print(miniti);
   }
   else
   {
   lcd.print(miniti);
   }
   lcd.print(":");
   lcd.print("00");
      
      if ((hours & 0x0f) > 9) hours =  hours + 6;
      if (hours > 0x23) hours = 0;
      Serial.print("Hours = ");
      if (hours <= 9) Serial.print("0");
      Serial.println(hours, HEX);
    delay(150);
    }

    Wire.beginTransmission(0x68); // activate DS1307
    Wire.write(0); // where to begin
    Wire.write(0x00);          //seconds
    Wire.write(minutes);          //minutes
    Wire.write(0x80 | hours);    //hours (24hr time)
    Wire.write(0x06);  // Day 01-07
    Wire.write(0x01);  // Date 0-31
    Wire.write(0x05);  // month 0-12
    Wire.write(0x09);  // Year 00-99
    Wire.write(0x10); // Control 0x10 produces a 1 HZ square wave on pin 7. 
    Wire.endTransmission();
  
    // converting hexa in zecimal:
    zh = hours / 16;
    uh = hours - 16 * zh ;
    ore = 10 * zh + uh; 
    zm = minutes / 16;
    um = minutes - 16 * zm ;
    miniti = 10 * zm + um; 
    
   /*  for(int i = 20 ; i >0  ; i--) {
     displayNumber01(ore*100+miniti); 
     }
 //  delay(150);
    */

   lcd.setCursor(4, 0);
   if ( ore < 10)
   {
     lcd.print(" "); 
     lcd.print(ore);
   }
   else
   {
   lcd.print(ore);
   }
   lcd.print(":");
   if ( miniti < 10)
   {
     lcd.print("0"); 
     lcd.print(miniti);
   }
   else
   {
   lcd.print(miniti);
   }
   lcd.print(":");
   lcd.print("00");
}
}
   Am facut 2 filmulete, care prezinta modul de functionare si reglaj: ceas RTC si date meteo cu Arduino pe afisaj LCD1602, reglaj manual al orei si minutelor
weather & manual adjust for RTC clock with Arduino and LCD1602 display
   Tot la sugestia lui Janos, voi schimba senzorul DHT11 cu unul DHT22, datorita preciziei mai mari (+0,50C si +2 unitati umiditate), dar trebuie sa imi soseasca de peste mari si tari, si abia atunci, o sa fac si modificarea asta.

miercuri, 24 septembrie 2014

Combinare module DRL (Day Time Light) si CHLH (coming home/leaving home) folosind Arduino

   Deoarece am tot fost intrebat de detaliile de executie a unor module pentru masina m-am gandit sa combin 2 dintre ele folosindu-ma de o placa Arduino (ulterior transferat proiectul pe un cablaj).
   Separat le-am tratat, in articolele modul "Daytime Running Light" - (DRL) si Modul "coming home / leaving home" ("follow me home") si in mare, DRL-ul are functia de a aprinde automat, cu intensitare redusa, pe timp de zi, a luminilor autovehiculului, dupa ce tensiunea pe acumulator este mai mare de o anumita valoare, iar CHLH (numit la unele masini si "confort") functioneaza doar noaptea, dupa ce se incuie masina (inchidere centralizata, alarma, etc) si aprinde, pentru cateva zeci de secunde, becurile de pozitie (sau faza scurta) pentru ca soferul si insotitorii "sa vada drumul spre casa"; similar, se intampla la descuierea masinii. 
   DRL-ul cu componente obisnuite are o schema de genul:
iar CHLH-ul:
   Avand in vedere ca ambele depind de intensitatea luminoasa a mediului exterior, voi folosi doar o fotorezistenta, cum am prezentat in articolul O fotorezistenta si Arduino, iar schema de test este foarte simpla (doar partea stanga):
   Pentru DRL, trebuie sa masor tensiunea pe acumulator si daca creste peste 13,8V sa aprinda cu intensitate redusa "faza scurta", folosindu-ma de o iesire PWM a lui Arduino.
   Masurarea tensiunii acumulatorului o s-o fac, clasic, cu un divizor rezistiv de tensiune, cum se prezinta in articlul Measuring DC Voltage using Arduino:
   Modul de reglaj a intensitatii luminoase sau a turatiei unui motor de curent continuu l-am tratat in articolul Control turatie motor (prin varierea factorului de umplere - PWM).
   Modul de reglaj al intensitatii luminoase cu Arduino si un tranzistor MOS-FET este foarte simplu, cum este prezentat in articolul High-Power Control: Arduino + N-Channel MOSFET:
   Momentan, este doar o idee de proiect, trebuie sa imi fac "calculele" si sa ma apuc de munca :)))) astept pareri si idei, variante, etc...

   Pentru inceput, am ales divizorul de tensiune, compus din 2 rezistente:
   Deoarece la intrarile analogice (dar si al cele digitale) nu trebuie sa depasim tensiunea de alimentare a placii de dezvoltare Arduino, adica 5V, aceasta fiind atinsa doar cand tensiunea pe acumulator ar fi (teoretic) de 16V, ceea ce nu este posbil, in mod normal:
  Daca vrem sa fim prevazatori si modificam divizorul astfel:
   Pentru pragul de 13,8V vom avea la intrarea analogica a placii Arduino o tensiune de 2,42V:
 
   Pentru a controla intensitatea luminoasa, cred ca o sa aleg varianta propusa la Help using MOSFET to switch on/off IC
care-i identica cu cea din articolul Microcontroller Interfacing (unde se gasesc si alte "chestii" utile):
   Schema de testare, va fi asta sau foarte asemanatoare cu asta:

Senzor de masurare tensiune si curent INA219

   Am achizitionat de curand, de la colaboratorii mei de la  ArduShop.ro , un modul cu senzor INA219, care poate masura tensiuni pana la 26V...