duminică, 9 iunie 2013

Ceas de timp real (RTC) cu DS1307 si Arduino (partea a 2-a)

   Am realizat modulul de timp real, o parte cu piese, o parte cu piese recuperate, conform schemei din articolul Ceas de timp real (RTC) cu DS1307 si Arduino conform penultimei scheme.
 
   Am alimentat si conectat modulul RTC la placuta Arduino, constatand ca LED-ul conectat la iesirea SQW se aprinde, chiar daca timpul nu este setat.
 

   Am folosit libraria de la https://codeload.github.com/adafruit/RTClib/zip/master pentru prime teste.
   Codul folosit este cel din exemplul insotitor, deoarece preia data din RTC-ul calculatorului la momentul compilarii sketch-ului si o transfera apoi RTC-ului meu:

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib

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

RTC_DS1307 RTC;

void setup () {
    Serial.begin(57600);
    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__));
  }
}

void loop () {
    DateTime now = RTC.now();
    
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    
    Serial.print(" since midnight 1/1/1970 = ");
    Serial.print(now.unixtime());
    Serial.print("s = ");
    Serial.print(now.unixtime() / 86400L);
    Serial.println("d");
    
    // calculate a date which is 7 days and 30 seconds into the future
    DateTime future (now.unixtime() + 7 * 86400L + 30);
    
    Serial.print(" now + 7d + 30s: ");
    Serial.print(future.year(), DEC);
    Serial.print('/');
    Serial.print(future.month(), DEC);
    Serial.print('/');
    Serial.print(future.day(), DEC);
    Serial.print(' ');
    Serial.print(future.hour(), DEC);
    Serial.print(':');
    Serial.print(future.minute(), DEC);
    Serial.print(':');
    Serial.print(future.second(), DEC);
    Serial.println();
    
    Serial.println();
    delay(3000);

}


  La acest sketch nu este activata iesirea SQW sa "clipoceasca" cu frecventa de 1Hz,asa ca am inceput sa mai caut,asa ca am dat de urmatoarele articole:
- Real Time Clock Module (DS1307) (SKU:DFR0151)
- RTC1307 - Real Time Clock
   Am gasit la http://forum.arduino.cc/index.php?topic=3171.5;wap2 o parte de cod:

Serial.begin(9600);
  // code courtesy of Mr. BroHogan (a.k.a. "Life Clock");
  Wire.beginTransmission(0x68);
  Wire.send(0x07);
  Wire.send(0x90);                       // 0x90=1Hz, 0x91=4kHz, 0x92=8kHz, 0x93=32kHz
  Wire.endTransmission();

   Am ajuns la http://forum.arduino.cc/index.php?topic=137067.0, care duce la https://github.com/davidhbrown/RealTimeClockDS1307, rezultatul din exemplul de acolo este:


   Dupa mai multe cautari pe net, am gasit articolul Tutorial: Arduino and the I2C bus – Part One in care se regaseste un sketch, care prezinta modul de comanda al iesirii SQW (pinul 7):


/*
DS1307 Square-wave machine
 Used to demonstrate the four different square-wave outputs from Maxim DS1307
 See page nine of data sheet for more information
 John Boxall - tronixstuff.wordpress.com
 */
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68 // each I2C object has a unique bus address, the DS1307 is 0x68
void setup()
{
 Wire.begin();
}
void sqw1() // set to 1Hz
{
 Wire.beginTransmission(DS1307_I2C_ADDRESS);
 Wire.write(0x07); // move pointer to SQW address
 Wire.write(0x10); // sends 0x10 (hex) 00010000 (binary)
 Wire.endTransmission();
}
void sqw2() // set to 4.096 kHz
{
 Wire.beginTransmission(DS1307_I2C_ADDRESS);
 Wire.write(0x07); // move pointer to SQW address 
 Wire.write(0x11); // sends 0x11 (hex) 00010001 (binary)
 Wire.endTransmission();
}
void sqw3() // set to 8.192 kHz
{
 Wire.beginTransmission(DS1307_I2C_ADDRESS);
 Wire.write(0x07); // move pointer to SQW address 
 Wire.write(0x12); // sends 0x12 (hex) 00010010 (binary)
 Wire.endTransmission();
}
void sqw4() // set to 32.768 kHz (the crystal frequency)
{
 Wire.beginTransmission(DS1307_I2C_ADDRESS);
 Wire.write(0x07); // move pointer to SQW address 
 Wire.write(0x13); // sends 0x13 (hex) 00010011 (binary)
 Wire.endTransmission();
}
void sqwOff()
// turns the SQW off
{
 Wire.beginTransmission(DS1307_I2C_ADDRESS);
 Wire.write(0x07); // move pointer to SQW address
 Wire.write(0x00); // turns the SQW pin off
 Wire.endTransmission();
}
void loop()
{
 sqw1();
 delay(5000);
 sqw2();
 delay(5000);
 sqw3();
 delay(5000);
 sqw4();
 delay(5000);
 sqwOff();
 delay(5000);
}

   Un exemplu al modificarii celor 5 variante de frecvente pe pinul SQW(zero, 1Hz, 4096Hz, 8192Hz, respectiv 32768Hz) se regaseste in filmuletul numit DS1307 square-wave demonstration:
   Tot acolo se face o trimitere la alt articol numit Blinky the one-eyed clock unde gasim tot ce ne trebuie, asa ca am reusit si eu sa faca LED-ul sa "clipoceaca" si sa citesc pe monitorul serial data si ora:


// 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 from http://tronixstuff.wordpress.com/2010/10/20/tutorial-arduino-and-the-i2c-bus/
// adapted sketch by niq_ro from http://nicuflorica.blogspot.ro/

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

RTC_DS1307 RTC;

void setup () {
    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();
    
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print("       ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
  
    Serial.println();
    delay(3000);
}


   Avand in vedere ca am achitionat o placuta breadboard SYB-120 si niste fire cu conectori tata-tata si tata-mama, am facut repede legaturile pentru RTC si LCD folosind protocolul de comunicare i2c:
   Am combinat sketch-ul din articolul Interfata i2c la LCD pentru Arduino cu cel anterior, obtinand:


// 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/
// add part with LCD from http://blog.gotencool.com/2012/03/arduino-lcd-via-i2c.html
// adapted sketch by niq_ro from http://nicuflorica.blogspot.ro/

#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x20,16,2); // 0x20 is adresss for LCC 16x2
RTC_DS1307 RTC;

void setup () {
   lcd.init(); 
  lcd.backlight(); //backlight is now ON
  // 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(6, 0);
   lcd.print(now.hour(), DEC);
   lcd.print(":");
   lcd.print(now.minute(), DEC);
   lcd.print(":");
   lcd.print(now.second(), DEC);
   lcd.print(" "); 
    
   lcd.setCursor(5, 1);
   lcd.print(now.day(), DEC);
   lcd.print("/");
   lcd.print(now.month(), DEC);
   lcd.print("/");
   lcd.print(now.year(), DEC);
   lcd.print(""); 
  
   delay(1000);
}
   Am facut 2 filmulete cu ce am realizat:
- RTC DS1307 LCD1602A using i2c with Arduino (I)
- RTC DS1307 LCD1602A using i2c with Arduino (II)

   Am conectat si senzorul de temperatura si umiditate DHT11, combinand cu ultimul sketch din articolul Ministatie meteo cu senzorul DHT11 si.. Arduino, obtinand:


// 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/
// add part with LCD from http://blog.gotencool.com/2012/03/arduino-lcd-via-i2c.html
// adapted sketch by niq_ro from http://nicuflorica.blogspot.ro/

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



#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x20,16,2); // 0x20 is adresss for LCC 16x2
RTC_DS1307 RTC;

void setup () {
  dht.begin();
  lcd.init(); 
  lcd.backlight(); //backlight is now ON
  // 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(0, 0);
   lcd.print(now.hour(), DEC);
   lcd.print(":");
   lcd.print(now.minute(), DEC);
   lcd.print(":");
   lcd.print(now.second(), DEC);
   lcd.print(" "); 
   
   lcd.setCursor(10, 0);
   lcd.print("t=");
   lcd.print(t);
   lcd.write(0b11011111);
   lcd.print("C");
    
   lcd.setCursor(0, 1);
   lcd.print(now.day(), DEC);
   lcd.print("/");
   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("%");
  
   delay(1000);
}

apoi inca unu', care se numeste date and hour, temperature and humidity with RTC DS1307 DHT11 LCD on i2c with Arduino (II)
   Deoarece valorile afisate ale secundelor, minutelor, orelor, zilelor si lunilor dintr-o cifra se afisau doar asa, dintr-o cifra, am pus sa apara un zero in fata, iar la ore un spatiu...
   Sketch-ul a devenit:
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
// adapted sketch for DHT11 by by niq_ro from http://nicuflorica.blogspot.ro
// version 4.0

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


#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x20,16,2); // 0x20 is adresss for LCC 16x2
RTC_DS1307 RTC;

void setup () {
  dht.begin();
  lcd.init(); 
  lcd.backlight(); //backlight is now ON
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a logo message to the LCD.
  lcd.setCursor(0, 0);
  lcd.print("www.tehnic.go.ro");  
  lcd.setCursor(0, 1);
  lcd.print("creat de niq_ro");
  delay (2500);
  lcd.clear();
  
  lcd.setCursor(0, 0);
  lcd.print("ceas cu calendar");  
  lcd.setCursor(0, 1);
  lcd.print("temp. si umidit.");
  delay (2500);
  lcd.clear();  
  lcd.setCursor(0, 0);
  lcd.print("ceas cu calendar"); 
  lcd.setCursor(2, 1);
  lcd.print("versiunea 4.0");
  delay (2500);
  lcd.clear();  
  
  Wire.begin();
  
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();
// RTC.adjust(DateTime(__DATE__, __TIME__));
// if you need set clock... just remove // from line above this
  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(12, 0);
   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(12, 1);
   lcd.print(h);
   lcd.print("%u");
  
   delay(500);
}
   Am creat un simbol pentru umiditate (un pahar umplut pe jumatate) folosindu-ma de informatiile de la ROROID:



vineri, 7 iunie 2013

Afisajul folosit la telefoanele Nokia 5110/3310 si Arduino

   Fata de afisajul cu cristale lichide pe 2 randuri si 16 coloane, pe care l-am tot prezentat, acum e randul afisajului folosit la telefoanele Nokia 5110/3310, care foloseste controlerul PCD8544, afisarea facandu-se la o rezolutie de 48x84 puncte (pixeli).
   Un articol cu prezentare sugestiva este Nokia LCD 3310 + Arduino:
  Dupa cum se constata de aici si din datasheet, tensiunile recomandate de alimentare si comanda sunt intre 2,7 si 3,3V... mai mici decat cea de 5V a lui Arduino, asa ca eu as lucra pe "adaptoate de nivel logic", realizate din divizoare rezistive, cum e prezentat la Nokia 3310 display and Arduino connections:
 .. pe scurt tensiunea de 5V de alimentare este "scazuta" cu cca. 2V (3 x0,65.0,7V), iar tensiunile de control, sunte reduse cu divizor rezistiv.
     Schema de la Electrónica de Invierno devine:
   Un articol care trateaza acest mod de conectare se numeste How to use the Nokia 5110 LCD Module at Arduino, folosind o limitare de curent prin inserierea unor rezistente de 10k pe liniile de comanda:
11.6.2013
   Din aceste informatii, m-am gandit la o varianta, care combina, aceste 2 variante:
   Partea de adaptor, completata cu posibilitatea aprinderii permanente a LED-ului de fundal sau in functie de tensiunea de pe un anumit pin sau chiar stins permanent, are schema urmatoare:

   Cablajul, respectiv montajul desenat cu ajutorul programului Eagle PCB Editor pot fi realizate astfel:

   Cand va compar cablajul realizat cu dimensiunile placutei afisajului, am constatat ca pinii sunt inscriptionati altfel fata de ce am gasit pe net...


   Am verificat si la furnizor si... surpriza, inscriptionarea corespunde documentatiei lui:
1.RST----------- reset.
2.CE------------ chip selection.
3.DC------------ data/commands choice.
4.DIN----------- serial data line.
5.CLK----------- serial Clock Speed.
6.3.3V---------- VCC.
7.LIGHT--------- backlight control terminal.
8.GND----------- power negative.
si se mentioneaza ca "tensiune de alimentare: 2.7V-3.3V, chiar si  5V este OK, dar o parte a ecranului a devenit negru când a fost testat"..."nivelele logice: 2.7-5V".

   Voi reface cablajul pentru noua configuratie, pastrand schema, cu reducerea tensiunii cu 3 diode si limitarea curentului pe terminalele de comanda...   



16.iun.2013
   Am facut un mic montaj pe un cablaj de test, folosind conectori mama si tata. plus jamper pentru selectia iluminarii fundalului (permenent sau functie de comanda unui pin):
 
am conectat montajul la Arduino 
si am constatat ca nici macar LED-urile de fundal nu se aprind...
dupa masuratori si folosind lupa am descoperi ca cele 4 rezistente de 18 ohmi din schema sunt de 270 ohmi, iar LED-urile sunt montate invers... 
PS: afisajul se aprinde daca se conecteaza pinul la masa...
 
... momentan atat... :(  totusi, cred ca o sa recuperez un afisaj dintr-un telefon vechi deoarece am gasit un mic tutorial la http://serdisplib.sourceforge.net/ser/pcd8544.html

PS: Dupa ce am mai studiat documentatia despre afisaj, gasita la techref.massmind.org,am ajuns la concluzia ca ecranul nu era presat bine in carcasa si...
apoi: