vineri, 17 octombrie 2014

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

   In septembrie, am postat articolul Ceas RTC cu DS1307 si date mediu cu DHT11 pe afisaj alfanumeric LCD1602 folosind Arduino si 
dupa cum spune si titlul, am inlocuit senzorul DHT11 cu DHT22 (AM2302), care este mult mai performant si are domeniul de masura mai larg (precizie +0,50C si +2 unitati umiditate, domeniul de masura este de -40..+800C si 0..100% umiditate).
   Ca si in cazul senzorului DHT11, mai raspandit (fiind mai ieftin), senzorul DHT22 (sau AM2302) se vinde ca modul cu 3 pini, sau ca piesa cu 4 pini, evident ca varianta ca poiesa e mai ieftina, necesitand o rezistenta de 4k7 conectata intre iesire (OUT/DATA) si (VDD/5V).
   Pentru informatii suplimentare recomand articolul DHTxx Sensors postat pe site-ul Adafruit.
DHT11 / DHT22
   Deoarece ministatia meteo cu ceas, varianta propusa de Janos, mi s-a parut ok, am refacut schema partial (practic nu am mai pus cele trei butoane fara retinere pentru reglare ore si minute).
   Daca aveti modulul cu 3 pini, schema de conectare este identica:
iar daca este doar senzorul (inscriptionat AM2302) schema devine:
   Practic, montajul arata asa, iar pe ecran informatiile sunt prezentate astfel (am schimbat 3 afisaje, care cu fundal rosu, albastru si galben):
   Sketch-ul adaptat, pentru a indica si temperaturi negative, este:
// 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
// DHT library from https://github.com/adafruit/DHT-sensor-library
// 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
// adapted sketch drom http://nicuflorica.blogspot.ro/2014/09/ceas-rtc-cu-ds1307-si-date-mediu-cu.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   |
                                      -------------------
*/
// http://arduino.cc/en/Reference/LiquidCrystalCreateChar
byte grad[8] = {
  B01100,
  B10010,
  B10010,
  B01100,
  B00000,
  B00000,
  B00000,
};

RTC_DS1307 RTC;

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

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;

// 
float t1;

void setup () {
  // DHT init
  dht.begin();
  // create custom symbol
  lcd.createChar(0, grad);
  // 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();
    
  // Print a logo message to the LCD.
  lcd.print("ministatie meteo");  
  lcd.setCursor(0, 1);
  lcd.print("cu DHT22 ver.1.0");
  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();

  float t = dht.readTemperature();
// float t = 23.56;
//float t = 7.32;
//float t = 0.01;
//float t = 0;
//float t = -0.02;
//float t = -6.45;
//float t=-13.25;


   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(0, 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,1);
   //lcd.print(",0");
//   lcd.write(0b11011111);
   lcd.write(byte(0));
   lcd.print("C  ");
    

   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");
}
}
   In filmuletul numit ministatie meteo cu DHT22 si ceas cu DS1307 am prezentat aceasta ministatie meteo c senzorul DHT22, partea de ceas este fara butoanele de reglaj:

miercuri, 15 octombrie 2014

Senzorul de presiune BMP180

English version: BMP180 sensor and Arduino

   Cu ceva timp in urma, am cumparat de pe ebay un modul GY-68 cu senzor de presiunea BMP180, despre care trebuie sa stim, in primul rand ca tensiunea de alimentare maxima este de 3,6V, deci putem sa-l alimentam de la placa Arduino din pinul notat 3.3V sau 3V (depinde de producatorul placii); mai trebuie sa stim ca modulul se conecteaza prin 2 fire (comunicare i2c).
   Pe langa informatii despre presiune, senzorul masoara si temperatura cu o precizie de +10C.
   Schema de conectare este simpla, cum este prezentat in articolul BMP180 Barometric Pressure Sensor Hookup:
   Schema de conexiuni realizata de mine este:
   Pentru a-l putea folosi, am folosit libraria Adafruit-BMP085, obtinand pe ecranul de monitorizare seriala:
   Am modificat sketch-ul pentru informatii in romana si a-mi da si alte date:
   Sketch-ul modificat este:
// http://nicuflorica.blogspot.ro & http://arduinotehniq.blogspot.com 
// https://github.com/adafruit/Adafruit-BMP085-Library
#include <Wire.h>
#include <Adafruit_BMP085.h>

/*************************************************** 
  This is an example for the BMP085 Barometric Pressure & Temp Sensor

  Designed specifically to work with the Adafruit BMP085 Breakout 
  ----> https://www.adafruit.com/products/391

  These displays use I2C to communicate, 2 pins are required to  
  interface
  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ****************************************************/

// Connect VCC of the BMP085 sensor to 3.3V (NOT 5.0V!)
// Connect GND to Ground
// Connect SCL to i2c clock - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 5
// Connect SDA to i2c data - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 4
// EOC is not used, it signifies an end of conversion
// XCLR is a reset pin, also not used here

Adafruit_BMP085 bmp;
  
void setup() {
  Serial.begin(9600);
  if (!bmp.begin()) {
 Serial.println("nu exita senzor compatibil BMP085 sau BMP180");
 while (1) {}
  }
}
  
void loop() {
    Serial.print("Temperatura = ");
    Serial.print(bmp.readTemperature());
    Serial.println(" *C");
    
    Serial.print("Presiune = ");
    Serial.print(bmp.readPressure());
    Serial.print(" Pa / ");
    
 //   Serial.print("Presiune = ");
    float presiune1 = bmp.readPressure()/101.325;
    presiune1 = presiune1 * 0.760;
    Serial.print(presiune1);
    Serial.println(" mmHg");
    
    
    // Calculate altitude assuming 'standard' barometric
    // pressure of 1013.25 millibar = 101325 Pascal
    Serial.print("Altitudine = ");
    Serial.print(bmp.readAltitude());
    Serial.println(" m");

    Serial.print("Presiune la nivelul marii (calculata) = ");
    Serial.print(bmp.readSealevelPressure());
    Serial.print(" Pa / ");
    
    // http://en.wikipedia.org/wiki/Atmospheric_pressure#Mean_sea_level_pressure
  //  Serial.print("Presiure la nivelul marii (calculata) = ");
    float presiune = bmp.readSealevelPressure()/101.325;
    presiune = presiune * 0.760;
    Serial.print(presiune);
    Serial.println(" mmHg");
    

  // you can get a more precise measurement of altitude
  // if you know the current sea level pressure which will
  // vary with weather and such. If it is 1015 millibars
  // that is equal to 101500 Pascals.
    Serial.print("Altitudine reala = ");
    Serial.print(bmp.readAltitude(101500));
    Serial.println(" m");
    
    Serial.println();
    delay(2500);
}
   Am realizat un mic filmulet numit senzorul BMP180 si Arduino:
   Am folosit acest senzor intr-un proiect mai amplu, o ministatie meteo cu Arduino Due si un afisaj grafic color de 2,2" cu driver ILI9341. Acest proiect a fost prezentat detaliat in articolul Arduino Due si afisajul QVGA de 2,2" (5,6cm) comandat de ILI9341.
   Revenind la senzor si placa Arduino Uno, am zis ca e mai util sa afisez informatiile pe un ecran alfanumeric 1602, de genul:
asa ca am facut un filmulet numit senzorul BMP180 si Arduino (2)
   Sketch-ul scris de mine, arata asa:
// adapted sketch by niq_ro from http://nicuflorica.blogspot.ro/ & http://arduinotehniq.blogspot.com/
// https://github.com/adafruit/Adafruit-BMP085-Library
#include <Wire.h>
#include <Adafruit_BMP085.h>

/*************************************************** 
  This is an example for the BMP085 Barometric Pressure & Temp Sensor

  Designed specifically to work with the Adafruit BMP085 Breakout 
  ----> https://www.adafruit.com/products/391

  These displays use I2C to communicate, 2 pins are required to  
  interface
  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ****************************************************/

// Connect VCC of the BMP085 sensor to 3.3V (NOT 5.0V!)
// Connect GND to Ground
// Connect SCL to i2c clock - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 5
// Connect SDA to i2c data - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 4
// EOC is not used, it signifies an end of conversion
// XCLR is a reset pin, also not used here

// 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   |
                                      -------------------
*/



Adafruit_BMP085 bmp;
  
void setup() {
  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();

  // Print another message to the LCD.
  lcd.setCursor(2, 0);
  lcd.print("termometru -");  
  lcd.setCursor(0, 1);
  lcd.print("barometru ver1.0");
  delay (2500);
  lcd.clear();

  Serial.begin(9600);
  if (!bmp.begin()) {
 Serial.println("nu exita senzor compatibil BMP085 sau BMP180");
 while (1) {}
  }
}
  
void loop() {
    Serial.print("Temperatura = ");
    Serial.print(bmp.readTemperature());
    Serial.println(" *C");
    
    Serial.print("Presiune = ");
    Serial.print(bmp.readPressure());
    Serial.print(" Pa / ");
    
 //   Serial.print("Presiune = ");
    float presiune1 = bmp.readPressure()/101.325;
    presiune1 = presiune1 * 0.760;
    Serial.print(presiune1);
    Serial.println(" mmHg");
    
    
    // Calculate altitude assuming 'standard' barometric
    // pressure of 1013.25 millibar = 101325 Pascal
    Serial.print("Altitudine = ");
    Serial.print(bmp.readAltitude());
    Serial.println(" m");

    Serial.print("Presiune la nivelul marii (calculata) = ");
    Serial.print(bmp.readSealevelPressure());
    Serial.print(" Pa / ");
    
    // http://en.wikipedia.org/wiki/Atmospheric_pressure#Mean_sea_level_pressure
  //  Serial.print("Presiure la nivelul marii (calculata) = ");
    float presiune = bmp.readSealevelPressure()/101.325;
    presiune = presiune * 0.760;
    Serial.print(presiune);
    Serial.println(" mmHg");
    

  // you can get a more precise measurement of altitude
  // if you know the current sea level pressure which will
  // vary with weather and such. If it is 1015 millibars
  // that is equal to 101500 Pascals.
    Serial.print("Altitudine reala = ");
    Serial.print(bmp.readAltitude(101500));
    Serial.println(" m");
    
    Serial.println();
    
    
   lcd.setCursor(1, 0);
   lcd.print("temp.=  ");
    if ( bmp.readTemperature() < 10)
   {
     lcd.print(" "); 
     lcd.print(bmp.readTemperature());
   }
   else
   {
   lcd.print(bmp.readTemperature(),1);
   }
   lcd.write(0b11011111);
   lcd.print("C   ");
   
   lcd.setCursor(1, 1);
   lcd.print("pres.= p");
   lcd.print(presiune,0);
   lcd.print("mmHg  ");
    
   delay(2500);
}
iar schema este:
24.11.2014
   In weak-end am primit 3 poze de la Dave, un radioamator foarte cunoscut din West Cumbria, care are blog-ul http://g4rvh.wordpress.com/.
   Dave si-a facut un shield facut la CNC prin frezare, dupa schema de mai sus.
   Sketch-ul l-am modificat sa-i prezinte temperatura in grade Fahrenheit in loc de Celsius, dupa informatiile din articolul Conversion of Temperature:

marți, 14 octombrie 2014

Comunicatii intre placi Arduino prin 2 fire (protocol i2c)

   Avand la dispozitie 2 placi de dezvoltare Arduino, am considerat ca e timpul sa testez si modul de comunicare i2c, despre care puteti gasi informatii pe net.
   Pe scurt comunicarea se face pe 2 "fire": SDA (A4 la Arduino Uno)  si SCL (A5 la Arduino Uno), necesitand si firul de masa (GND).
   In mod normal, cele 2 "fire" se conecteaza la plus (5V) prin rezistente de 1..10kohmi, dar pentru o placa Master (stapan) si una Slave (sclav), pot lipsi, cum am facut eu in montajul de test.
   Sursa de inspiratie a fost articolul Comunicarea i2c de pe site-ul roroid, care are schema de conexiuni pentru teste:
   Eu voi folosi placuta (brick, shield/semishield) cu un LED multicolor si 3 rezistente, cu conector pentru zona digitala D8...D13 si GND
   Schema mea de testare are doar 4 fire, plus 5V, masa (GND), SDA(A4) si SCL(A5); ea permite alimentarea din cablul USB folosit la una din placi:
   Practic, montajul arata asa:
   Pentru inceput, am adaptat sketch-urile din articolul mentionat mai sus, schimband doar partea de conectare a led-ului de la pinul D8 la D8 cum are placuta mea.
   Ulterior, am modificat sketch-urile pentru a comanda cele 3 led-uri componente ale led-ului multicolor, obtinand:
   Sketch-urile pentru comanda celor 3 led-uri sunt:
- sketch-ul pentru "master" (stapan):
// MASTER ver1
// sketch de inspiratie de la http://www.roroid.ro/comunicarea-i2c/
// sketch adaptat pentru led multicolor de niq_ro de la http://nicuflorica.blogspot.ro/
// si http://arduinotehniq.blogspot.com/
//se incarca biblioteca pentru comunicarea pe I2C
#include <Wire.h>
void setup()
{
// initializeaza bus pentru i2c
Wire.begin();
Serial.begin(9600);
}

void loop()
{

Serial.println("MASTER:Toate LED-urile stinse");
Wire.beginTransmission(4); // transmit dispozitivului de la adresa #4
//in functie de cate dispozitive aveti legate pe I2C acest numar variaza

//comenzile de mai jos comanda ledurile de pe pinii 9, 10 si 11
//comenzile sunt de formatul LPPS; unde L- inseamna LED;PP-reprezinta numarul pinului;S-inseamna starea pinului
//Ex. L100;-va stinge ledul de pe pinul 10;L081 va aprinde ledul de pe pinul8
//L100;L081;-va stinge ledul de pe pinul 10 si aprinde ledul de pe pinul 8 concomitent.
Wire.write("L09"); // trimite numarul ledului care sa fie aprins/stins
Wire.write("0"); // trimite starea acestuia
Wire.write(";"); // trimite separator
Wire.write("L10"); // trimite numarul ledului care sa fie aprins/stins
Wire.write("0"); // trimite starea acestuia
Wire.write(";"); // trimite separator
Wire.write("L11"); // trimite numarul ledului care sa fie aprins/stins
Wire.write("0"); // trimite starea acestuia
Wire.write(";"); // trimite separator
Wire.requestFrom(4, 15); // se citesc 15 biti de raspuns de la dispozitivul
//de pe adresa 4

while(Wire.available()) //atata timp cat se primeste ceva
{
char c = Wire.read();
Serial.print(c); // tipareste caracterele primite
}
Serial.println("");
Wire.endTransmission(); // intrerupe transmisia

delay(2000); //asteptam un pic dupa care reluam cu 0

Serial.println("MASTER:Aprind LED-ul 1");
Wire.beginTransmission(4); // transmit dispozitivului de la adresa #4
//in functie de cate dispozitive aveti legate pe I2C acest numar variaza

//comenzile de mai jos comanda ledurile de pe pinii 9, 10 si 11
//comenzile sunt de formatul LPPS; unde L- inseamna LED;PP-reprezinta numarul pinului;S-inseamna starea pinului
//Ex. L100;-va stinge ledul de pe pinul 10;L081 va aprinde ledul de pe pinul8
//L100;L081;-va stinge ledul de pe pinul 10 si aprinde ledul de pe pinul 8 concomitent.
Wire.write("L09"); // trimite numarul ledului care sa fie aprins/stins
Wire.write("1"); // trimite starea acestuia
Wire.write(";"); // trimite separator
Wire.write("L10"); // trimite numarul ledului care sa fie aprins/stins
Wire.write("0"); // trimite starea acestuia
Wire.write(";"); // trimite separator
Wire.write("L11"); // trimite numarul ledului care sa fie aprins/stins
Wire.write("0"); // trimite starea acestuia
Wire.write(";"); // trimite separator
Wire.requestFrom(4, 15); // se citesc 15 biti de raspuns de la dispozitivul
//de pe adresa 4

while(Wire.available()) //atata timp cat se primeste ceva
{
char c = Wire.read();
Serial.print(c); // tipareste caracterele primite
}
Serial.println("");
Wire.endTransmission(); // intrerupe transmisia

delay(2000); //asteptam un pic dupa care reluam cu 0


Serial.println("MASTER:Aprind LED-ul 2");
Wire.beginTransmission(4); // transmit dispozitivului de la adresa #4
//in functie de cate dispozitive aveti legate pe I2C acest numar variaza

//comenzile de mai jos comanda ledurile de pe pinii 9, 10 si 11
//comenzile sunt de formatul LPPS; unde L- inseamna LED;PP-reprezinta numarul pinului;S-inseamna starea pinului
//Ex. L100;-va stinge ledul de pe pinul 10;L081 va aprinde ledul de pe pinul8
//L100;L081;-va stinge ledul de pe pinul 10 si aprinde ledul de pe pinul 8 concomitent.
Wire.write("L09"); // trimite numarul ledului care sa fie aprins/stins
Wire.write("0"); // trimite starea acestuia
Wire.write(";"); // trimite separator
Wire.write("L10"); // trimite numarul ledului care sa fie aprins/stins
Wire.write("1"); // trimite starea acestuia
Wire.write(";"); // trimite separator
Wire.write("L11"); // trimite numarul ledului care sa fie aprins/stins
Wire.write("0"); // trimite starea acestuia
Wire.write(";"); // trimite separator
Wire.requestFrom(4, 15); // se citesc 15 biti de raspuns de la dispozitivul
//de pe adresa 4

while(Wire.available()) //atata timp cat se primeste ceva
{
char c = Wire.read();
Serial.print(c); // tipareste caracterele primite
}
Serial.println("");
Wire.endTransmission(); // intrerupe transmisia

delay(2000); //asteptam un pic dupa care reluam cu 0

Serial.println("MASTER:Aprind LED-ul 3");
Wire.beginTransmission(4); // transmit dispozitivului de la adresa #4
//in functie de cate dispozitive aveti legate pe I2C acest numar variaza

//comenzile de mai jos comanda ledurile de pe pinii 9, 10 si 11
//comenzile sunt de formatul LPPS; unde L- inseamna LED;PP-reprezinta numarul pinului;S-inseamna starea pinului
//Ex. L100;-va stinge ledul de pe pinul 10;L081 va aprinde ledul de pe pinul8
//L100;L081;-va stinge ledul de pe pinul 10 si aprinde ledul de pe pinul 8 concomitent.
Wire.write("L09"); // trimite numarul ledului care sa fie aprins/stins
Wire.write("0"); // trimite starea acestuia
Wire.write(";"); // trimite separator
Wire.write("L10"); // trimite numarul ledului care sa fie aprins/stins
Wire.write("0"); // trimite starea acestuia
Wire.write(";"); // trimite separator
Wire.write("L11"); // trimite numarul ledului care sa fie aprins/stins
Wire.write("1"); // trimite starea acestuia
Wire.write(";"); // trimite separator
Wire.requestFrom(4, 15); // se citesc 15 biti de raspuns de la dispozitivul
//de pe adresa 4

while(Wire.available()) //atata timp cat se primeste ceva
{
char c = Wire.read();
Serial.print(c); // tipareste caracterele primite
}
Serial.println("");
Wire.endTransmission(); // intrerupe transmisia

delay(2000); //asteptam un pic dupa care reluam cu 0

}

- sketch-ul pentru "slave" (sclav):

// SLAVE ver.1
// sketch de inspiratie de la http://www.roroid.ro/comunicarea-i2c/
// sketch adaptat pentru led multicolor de niq_ro de la http://nicuflorica.blogspot.ro/
// si http://arduinotehniq.blogspot.com/
//se incarca biblioteca pentru comunicarea pe I2C
#include <Wire.h>

int LED[] = {99,4,5,6,7,8,9,10,11,12,13};//se definesc pinii pe care sunt conectate LED-urile
char comanda[15]; //vectorul in care va fi receptionata comanda pe I2c
char *i;
String p="";
void setup()
{
Serial.begin(9600);
for(int i = 0; i <= 10; i++){
pinMode(LED[i],OUTPUT);//initializeaza toti pini pe care sunt legate leduri ca output
}

Wire.begin(4);//suntem dispozitivul de la adresa #4
Wire.onReceive(receptie);//datele primite pe i2c le interpretam in functia receptie
Wire.onRequest(da_sefu); // activam functia da_Sefu
}

void loop()
{
delay(100);
}

// aici interpretam datele
void receptie(int howMany)
{
byte index = 0;
//se salveaza comanda primita pe I2C intr-un string
while(Wire.available())
{
comanda[index++] = Wire.read();
}
//se interpreteaza comanda
p=strtok_r(comanda,";",&i);
while(p!="")
{
if (p.startsWith("L")) //se verifica daca trebuie sa aprindem un led
{//daca este led stim ca urmatoarele 2 caractere reprezinta pinul iar urmatorul caracter starea
String pin=p.substring(1,3);//cauta valoarea pin in comanda
String stare=p.substring(3,4);//cauta valoarea stare in comanda

digitalWrite(pin.toInt(),stare.toInt());//trimite valorile pinului respectiv
}
p=strtok_r(NULL,";",&i);//verific daca mai am ceva de executat
}

}

void da_sefu()
{
Wire.write("ARDUINO:Da sefu"); // raspunde cu un mesaj de 15 bytes
}

   Am facut un filmulet numit i2c: un Arduino comanda, celalalt executa si raporteaza in care se vede mai bine ce am descris eu mai sus:
   Dupa ce am vazut cum "lucreaza", atat "stapanul", cat si "sclavul", am rescris cele 2 sketck-uri pentru a aprinde led-urile cu intensitate regabila (cu factor de umplere variabil - PWM), dupa cum se vede in filmuletul i2c: un Arduino comanda, celalalt executa si raporteaza (2)
   Sketch-ul pentru "stapan" este:
// MASTER ver2
// sketch de inspiratie de la http://www.roroid.ro/comunicarea-i2c/
// sketch adaptat pentru led multicolor de niq_ro de la http://nicuflorica.blogspot.ro/
// si http://arduinotehniq.blogspot.com/
//se incarca biblioteca pentru comunicarea pe I2C
#include <Wire.h>

int r, g, b; // variabile pentru intensitate culori
int r1, g1, b1; // alte variabile
int intarziere = 1000; // intarziere intre comenzile mari, in ms
int fadespeed = 100; // intarziere intre trepte de intensitate, in ms
String ghe1;

void setup()
{
// initializeaza bus pentru i2c
Wire.begin();
Serial.begin(9600);
}

void loop()
{
// trecere de la stins la alb
  for (r = 0; r < 25; r++) { 
    Serial.println(r);
  r1 = r *10;
  ordin (r1, r1, r1);
  delay(fadespeed); 
  }
  delay(intarziere);

// trecere de la alb la stins
  for (r = 25; r > 0; r--) {
    Serial.println(r); 
  r1 = r *10; 
  ordin (r1, r1, r1);
  delay(fadespeed); 
  }
  delay(intarziere);


// trecere de la stins la rosu
  for (r = 0; r < 25; r++) { 
    Serial.println(r);
  r1 = r *10;
  ordin (0, 0, r1);
  delay(fadespeed); 
  }
  delay(intarziere);

// trecere de la rosu la stins
  for (r = 25; r > 0; r--) {
    Serial.println(r); 
  r1 = r *10; 
  ordin (0, 0, r1);
  delay(fadespeed); 
  }
  delay(intarziere);


// trecere de la stins la verde
  for (r = 0; r < 25; r++) { 
    Serial.println(r);
  r1 = r *10;
  ordin (r1, 0, 0);
  delay(fadespeed); 
  }
  delay(intarziere);

// trecere de la verde la stins
  for (r = 25; r > 0; r--) {
    Serial.println(r); 
  r1 = r *10; 
  ordin (r1, 0, 0);
  delay(fadespeed); 
  }
  delay(intarziere);


// trecere de la stins la albastru
  for (r = 0; r < 25; r++) { 
    Serial.println(r);
  r1 = r *10;
  ordin (0, r1, 0);
  delay(fadespeed); 
  }
  delay(intarziere);

// trecere de la albastru la stins
  for (r = 25; r > 0; r--) {
    Serial.println(r); 
  r1 = r *10; 
  ordin (0, r1, 0);
  delay(fadespeed); 
  }
  delay(intarziere);


}




void ordin (int er, int ghe, int be)
{
Serial.println("MASTER:ordon sa executi comanda - ");
Wire.beginTransmission(4); // transmit dispozitivului de la adresa #4
//in functie de cate dispozitive aveti legate pe I2C acest numar variaza

//comenzile de mai jos comanda ledurile de pe pinii 9, 10 si 11
//comenzile sunt de formatul LPPSSS; unde L-inseamna LED;PP-reprezinta numarul pinului;SSS-inseamna numarul PWM pentru aprindere reglabila
//Ex. L10000;-va stinge ledul de pe pinul 10;L09255 va aprinde ledul de pe pinul9 la maxim, iar L11123 va aprinde ledul de la pinul 11 la jumatate

Wire.write("L11"); // trimite numarul ledului care sa fie aprins/stins (aici e rosu, la pinul 11)
Serial.print("L11");
Serial.println(er);
// starea trebuie sa fie din 3 cifre, dar trebuie sa le transmit drept caractere
Serial.print("=");
int er1 = er/100;
Wire.write(er1+48); // trimit cifra sutelor
Serial.print(er1);
er = er-100*er1;
er1 = er/10;
Wire.write(er1+48); // trimit cifra zecilor
Serial.print(er1);
er = er-er1*10;
Serial.println(er);
Wire.write(er+48); // trimit cifra unitatilor
Wire.write(";"); // trimite separator

Wire.write("L09"); // trimite numarul ledului care sa fie aprins/stins (aici e verde, la pinul 9)
// starea trebuie sa fie din 3 cifre, dar trebuie sa le transmit drept caractere
Serial.print("L09");
Serial.println(ghe);
// starea trebuie sa fie din 3 cifre, dar trebuie sa le transmit drept caractere
Serial.print("=");
int ghe1 = ghe/100;
Wire.write(ghe1+48); // trimit cifra sutelor
Serial.print(ghe1);
ghe = ghe-100*ghe1;
ghe1 = ghe/10;
Wire.write(ghe1+48); // trimit cifra zecilor
Serial.print(ghe1);
ghe = ghe-ghe1*10;
Serial.println(ghe);
Wire.write(ghe+48); // trimit cifra unitatilor
Wire.write(";"); // trimite separator

Wire.write("L10"); // trimite numarul ledului care sa fie aprins/stins (aici e albastru, la pinul 10)
// starea trebuie sa fie din 3 cifre, dar trebuie sa le transmit drept caractere
Serial.print("L10");
Serial.println(be);
// starea trebuie sa fie din 3 cifre, dar trebuie sa le transmit drept caractere
Serial.print("=");
int be1 = be/100;
Wire.write(be1+48); // trimit cifra sutelor
Serial.print(be1);
be = be-100*be1;
be1 = be/10;
Wire.write(be1+48); // trimit cifra zecilor
Serial.print(er1);
be = be-be1*10;
Serial.println(be);
Wire.write(be+48); // trimit cifra unitatilor
Wire.write(";"); // trimite separator

Wire.requestFrom(4, 15); // se citesc 15 biti de raspuns de la dispozitivul
//de pe adresa 4

while(Wire.available()) //atata timp cat se primeste ceva
{
char c = Wire.read();
Serial.print(c); // tipareste caracterele primite
}
Serial.println("");
Wire.endTransmission(); // intrerupe transmisia
}
   Sketch-ul pentru "sclav" este:
// SLAVE ver.2
// sketch de inspiratie de la http://www.roroid.ro/comunicarea-i2c/
// sketch adaptat pentru led multicolor de niq_ro de la http://nicuflorica.blogspot.ro/
// si http://arduinotehniq.blogspot.com/
//se incarca biblioteca pentru comunicarea pe I2C
#include <Wire.h>

int LED[] = {99,4,5,6,7,8,9,10,11,12,13};//se definesc pinii pe care sunt conectate LED-urile
char comanda[21]; //vectorul in care va fi receptionata comanda pe I2c
char *i;
String p="";
void setup()
{
Serial.begin(9600);
for(int i = 0; i <= 10; i++){
pinMode(LED[i],OUTPUT);//initializeaza toti pini pe care sunt legate leduri ca output
}

}
void loop()
{
Wire.begin(4);//suntem dispozitivul de la adresa #4
Wire.onReceive(receptie);//datele primite pe i2c le interpretam in functia receptie
Wire.onRequest(da_sefu); // activam functia da_Sefu

 delay(5);
}

// aici interpretam datele
void receptie(int howMany)
{
byte index = 0;
//se salveaza comanda primita pe I2C intr-un string
while(Wire.available())
{
comanda[index++] = Wire.read();
}
//se interpreteaza comanda
p=strtok_r(comanda,";",&i);
while(p!="")
{
//  Serial.print(p);
if (p.startsWith("L")) //se verifica daca trebuie sa aprindem un led
{//daca este led stim ca urmatoarele 2 caractere reprezinta pinul iar urmatorul caracter starea
//Serial.println("---------------------------");
String pin=p.substring(1,3);//cauta valoarea pin in comanda
//Serial.print(pin);
String stare=p.substring(3,6);//cauta valoarea stare in comanda
//Serial.print(stare);
//digitalWrite(pin.toInt(),stare.toInt());//trimite valorile pinului respectiv
analogWrite(pin.toInt(),stare.toInt());//trimite valorile pinului respectiv
//digitalWrite(pin.toInt(),);//trimite valorile pinului respectiv
}
p=strtok_r(NULL,";",&i);//verific daca mai am ceva de executat
}
}

void da_sefu()
{
Wire.write("ARDUINO:Da sefu"); // raspunde cu un mesaj de 15 bytes
}
   Pentru moment, cred ca e suficient ce am invatat despre acest mod de comunicare...