60 nap alatt Arduino #29 - I2C busz és a TC75/LM75

A "60 nap alatt Arduino" tanfolyam házi feladatai és közvetlen témái
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

60 nap alatt Arduino #29 - I2C busz és a TC75/LM75

Hozzászólás Szerző: Robert »

Az I2C hőmérő és a házi feladatok.
A hőmérő a mért eredményét írja ki az LCD-re, és Min/Max hőmérőként is működjön.
Avatar
szegoj
SzínkódFestő
Hozzászólások: 92
Csatlakozott: 2010. február 4. csütörtök, 7:00

Hozzászólás Szerző: szegoj »

A program kezdeti verziója még nem vizsgálja a negatív hőmérsékletet.
Másodpercenként méri és kijelzi a mért értéket (fok Celziusszal kiegészítve), ezenkívűl kiírja a min illetve max értékeket is / jellel elválasztva.

A min illeve max értékeket a hasonló nevű függvények határozzák meg. A két változó kezdeti értékét az első méréskor kapja meg.

Kód: Egész kijelölése

/*----------------------------------------------------------------  
 Projekt:       AVR-DUINO/Shieldboard Ext1
 Fájlnév:       TC75.PDE
 Verziószám:    V1.1
 ------------------------------------------------------------------
 
 Feladat
 -------
 A TC75 hőmérő által mért eredményt írja ki az LCD-re, és Min/Max  
 hőmérőként is működjön.    
 
 A kijelző bekötése
 ------------------
 DB4..DB7 -> Digital pins 6..9 (PD6,7 és PB0,1), külön portokon !!!
 RS       -> Digital pin 4 (PD4)
 E        -> Digital pin 5 (PD5)
 ------------------------------------------------------------------
*/

#include <LiquidCrystal.h>
#include <Wire.h>

// LCD konfiguráló parancs LiquidCrystal(rs, enable, d4, d5, d6, d7)
LiquidCrystal lcd(4, 5, 6, 7, 8, 9);       

byte circle[8] = {
  B00110,
  B01001,
  B01001,
  B00110,
  B00000,
  B00000,
  B00000,
};

int ledPin = 13; 

int tc75_addr = 0x48;
int temperature, temp_min, temp_max;

void setup() {
  Serial.begin(9600);
  Wire.begin();                     
  // a ledpin kivezetést kimenetként konfigurálja
  pinMode(ledPin, OUTPUT);
  // ledpin kivezetés magasba állítása (háttérvilágítás bekapcsolása)
  digitalWrite(ledPin, HIGH);
  // LCD kijelző oszlop, sor megadása
  lcd.begin(16, 2);
  // kijelző törlés
  lcd.createChar(0, circle);
  lcd.clear();
  // kurzor alappozícióba kerül: sor=0, oszlop=0)
  lcd.home();
  // LCD üzenet kiiratása
  lcd.print("TC75 Thermometer");
}

void tc75_read() {
  byte data;
  Wire.beginTransmission(tc75_addr);
  Wire.send(0);
  Wire.endTransmission();
  Wire.requestFrom(tc75_addr, 2);
  if (Wire.available()) { 
    data = Wire.receive();
    // negatív eredmény még nincs figyelembe véve
    temperature = data * 10;
    data = Wire.receive();
    // tizedesjegy kompenzálás
    if (data>>7) temperature += 5;
  }
  else {
  }
}

void loop() {
  delay(1000);
  tc75_read();
  temp_min = temperature;
  temp_max = temperature;
  while(1) {
    delay(1000);
    // új kurzor pozíció: második sor, első karakter
    lcd.setCursor(0, 1);             
    // LCD üzenet kiiratása
    tc75_read();
    temp_min = min(temperature, temp_min);
    temp_max = max(temperature, temp_max);
    lcd.print(temperature/10);
    lcd.print(',');
    lcd.print(temperature%10);
    lcd.write(0);
    lcd.print('C');
    lcd.print(' ');
    lcd.print(temp_min/10);
    lcd.print(',');
    lcd.print(temp_min%10);
    lcd.print('/');
    lcd.print(temp_max/10);
    lcd.print(',');
    lcd.print(temp_max%10);
  }
}

Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

Kis kiegészítés (nem volt még a leckékben):

Kód: Egész kijelölése

data>>7
Ez az ún shift művelet. A data változó típusa: integer.
A >> jel a változó bináris értékét tolja el a paramétereként megadott alkalommal. Azaz:

Kód: Egész kijelölése

0000.1010.1010.1010  >> 7 =
0000.0000.0001.0101
A kieső egyesek és nullák eltűnnek, míg a magas helyiértékre 0-k kerülnek be.
Gyakorlatilag osztásnak felel meg:
>>1 : /2 (azaz:2^1)
>>2 : /4 (azaz:2^2)
>>3 : /8 (azaz:2^3)


A programban még 1 trükk van:
- nem float (lebegőpontos törtszám) a hőfoktárolás, hanem a hőfok 10x-ese. A kiíráskor a _személőben_ alakul csak ki a tizedesfokok élménye, valójában a teljes kiírásaz az egészrész megjeleítése, majd pont, majd a maradékos osztás eredménye.
Ez jótékonyan hat a kódméretre.
Avatar
szegoj
SzínkódFestő
Hozzászólások: 92
Csatlakozott: 2010. február 4. csütörtök, 7:00

Hozzászólás Szerző: szegoj »

:oops:
Kicsit szégyellem magam:
A 10-el történő szorzás nem az én ötletem volt, innen vettem kölcsön:
http://blog.astech.hu/2011/03/lm75-os-i ... rduinoval/
Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00

Hozzászólás Szerző: macsek »

szegoj írta::oops:
Kicsit szégyellem magam:
A 10-el történő szorzás nem az én ötletem volt, innen vettem kölcsön:
http://blog.astech.hu/2011/03/lm75-os-i ... rduinoval/
Akkor ezért volt ismerős a dolog :-) Én is a napokban néztem.
Egyébként tetszetős program, grat. A fok jel definiálása külön tetszik.

Amit én másképp csináltam volna (de a tied is jó!):

Kód: Egész kijelölése

int temperature, temp_min=32000, temp_max=-32000; // ennél tuti lesz kisebb/ nagyobb értékünk 
...
void loop() { 
  delay(1000); 
  tc75_read(); 

  // új kurzor pozíció: második sor, első karakter 
  lcd.setCursor(0, 1);             
  // LCD üzenet kiiratása 
  tc75_read(); 
  temp_min = min(temperature, temp_min); 
  temp_max = max(temperature, temp_max); 
  lcd.print(temperature/10);
  ...
Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00

Hozzászólás Szerző: macsek »

Na én is összeszedtem magam, itt a programom:

#include "Wire.h" //I2C, azaz TWI miatt kell

#define HOMERO_CIME 0x48 


void setup(void)
{
  int led=13;
  pinMode(led, OUTPUT);
  for(byte c=1; c<=10; c++) // varakozunk, h legyen ido soros monitort inditani
  {
    digitalWrite(led, c%2);
    delay(500);
  }
  Serial.begin(9600);
  // azert kezdunk uj sorral, h ha reset-et nyomunk akkor szebben nezzen ki :-)
  Serial.println("\nHomersekletmero, Macsek");
  Serial.println("v1.0 2012.09.07");

  Wire.begin();
}


void loop(void)
{
  int t0=-31000, t1;
  int tmin=30000, tmax=-32500;
  byte c=0;

  while(true)
  {
    t1=homerseklet();
    if(t0 != t1)
    {
      t0=t1;
      if(t1<tmin)
        tmin=t1;
      if(t1>tmax)
        tmax=t1;

      Serial.println();
      hofok_kiiras(t1, false);
      Serial.print(" min:");
      hofok_kiiras(tmin, false);
      Serial.print(" / max:");
      hofok_kiiras(tmax, true);

      c=1;
      Serial.print('.'); // elso potty
    }
    else
    {
      if(++c > 10) // tizenkent uj sor, h jol lathato legyen
      {
        c=1;
        Serial.println();
      }
      Serial.print('.');
      if(c==5)
        Serial.print(' '); // 5-onkent szokoz, h konnyebb legyen szamolni
    }

    delay(1000);
  } 
}

////////////////////////////
// hofok kiiras
// be: 10* homerseklet,
//       fel fok felbontassal
//     utana kuldjunk-e ki CR-t (true) 
void hofok_kiiras(int t, byte soremeles_kell)
{
  Serial.print(t/10);
  Serial.print('.');
  Serial.print(t & 5);
  Serial.print(" C");
  if(soremeles_kell)
    Serial.println();
}

////////////////////////////
// 10*hofok C -ot ad vissza
int homerseklet(void)
{
  char t1,t2; // mert ez elojeles, 8 bites
  int t; // ez pedig 16 bites es elojeles

  Wire.requestFrom(HOMERO_CIME, 2); //A 72-es cimrol 2 byte-t kerunk
  //ha nincs eszkoz, akkor itt all a program
  if(Wire.available())
  {
    //1. byte megerkezik: egesz fok
    t1 = Wire.read(); // elojeles
    //2. byte megerkezik: tort hofok
    t2 = Wire.read(); // bit7: fel fok

    t=10*(int)t1 + (t2&0x80 ? 5 : 0);
  }
  else
    t = -32000;  // ez viszonylag hideg

  return t;


Kód: Egész kijelölése

Homersekletmero, Macsek
v1.0 2012.09.07

24.5 C      min:24.5 C / max:24.5 C
..
24.0 C      min:24.0 C / max:24.5 C
.
24.5 C      min:24.0 C / max:24.5 C
.
24.0 C      min:24.0 C / max:24.5 C
.
24.5 C      min:24.0 C / max:24.5 C
.
24.0 C      min:24.0 C / max:24.5 C
.
24.5 C      min:24.0 C / max:24.5 C
..
24.0 C      min:24.0 C / max:24.5 C
.
24.5 C      min:24.0 C / max:24.5 C
.
24.0 C      min:24.0 C / max:24.5 C
....
24.5 C      min:24.0 C / max:24.5 C
.
24.0 C      min:24.0 C / max:24.5 C
..
Avatar
glezmen
Bitmanipulátor
Hozzászólások: 139
Csatlakozott: 2012. augusztus 9. csütörtök, 6:00

Hozzászólás Szerző: glezmen »

par kerdesem lenne a leckevel kapcsolatban :)

az I2C bevezetoben az szerepelt hogy "visszamenőleges kompatibilitást megtartva, kibővítette a protokollt. Így született meg az Atmel részéről a Two-Wire-Interface (TWI)" -> tehat az Arduinoban meglevo Wire lib az 100%-osan hasznalhato barmilyen I2C eszkozhoz?

illetve: jol latom hogy I2C-t azt csak az analog in 4/5 labakon keresztul lehet hasznalni?

bonuszkerdes: az x75 chipben beallitott pontossag resetig/aramtalanitasig marad meg?
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

Igen. A TWI 1:1 csereszabatos a I2C-vel. Bármilyen I2C chip használható.

A TWI belső hardware összetevő, így a kivezetés kötött. ha meglesed az adatlapot, látszik, hogy az ATMega x8 család esetén az A4/A5 lábak funkciói:
- I/O láb lehet,
- Analog bemenet,
- TWI busz kivezetés.
Egyidőben csak az egyik! Arduio alatt nincs összevissza kapcsolgatás :).


Az x75 chpek jellemzően 0,5 fok felbontásúak. A TC75A chip esetén van mód ezt átállítani 0,5/0,25/0,125/0,0625 fokos pontosságra. DE:
- kikapcsoláskor a defaultba visszaáll (0,5)
- az adatlapot lesd meg: 0,0625 fok a parasztvakítás. Abszolut, Relativ es reprodukciós pontosságot nézd meg. ha 0,5 fok már örülhetsz, mert egy jó chipet fogtál ki :P

Szóval a családi béke miatt termosztátot ne csinálj belőle, mert a +/-1 fokot igen morcosan veszik....
Avatar
glezmen
Bitmanipulátor
Hozzászólások: 139
Csatlakozott: 2012. augusztus 9. csütörtök, 6:00

Hozzászólás Szerző: glezmen »

koszonom! :)
KissGe
Újonc
Újonc
Hozzászólások: 6
Csatlakozott: 2016. január 3. vasárnap, 20:06

Re: 60 nap alatt Arduino #29 - I2C busz és a TC75/LM75

Hozzászólás Szerző: KissGe »

Sziasztok!

A segítségeteket szeretném kérni (itt is), mert egyszerűen képtelen vagyok rájönni, hogy miért így számolt Robi a minta példájában, amikor 0.0625 -ös felbontást választott.

Kód: Egész kijelölése

  t = Wire.read();
  l = Wire.read();
    l=l /16;
    fok=t;
    fok=fok + l*0.125;
A magas érték természetesen OK, az az egész, az alacsony, tört rész viszont homályos...

Az adatlap alapján az alacsony helyiértékek 2^-1 , 2ˇ-2, 2ˇ-3, 2ˇ-4 értéket vesznek fel, tehát decimálisan 0,5, 0,25, 0,125, 0,0625 .
A változónk nem float, tehát csak egész értékeket vehet fel, továbbá az adatlap szerint nem világos az sem teljesen, hogy 0,5 - 0,25 - 0,125 választás esetén miért marad "0" mindig a 6,7,8 -as bitek helyén.

Előre is nagyon köszönöm!
Tiborx8
DrótVégénSzéndarab
Hozzászólások: 35
Csatlakozott: 2016. november 28. hétfő, 19:40

Re: 60 nap alatt Arduino #29 - I2C busz és a TC75/LM75

Hozzászólás Szerző: Tiborx8 »

Sziasztok,

Tudja valaki hogy miert kell busz-os homerot hasznalnunk? Nem lenne egyszerubb busz nelkuli homerovel inditani a kezdo tanfolyamon?

Udv.
Avatar
SanyiSay
Elektronbűvölő
Hozzászólások: 1031
Csatlakozott: 2009. február 28. szombat, 7:00

Re: 60 nap alatt Arduino #29 - I2C busz és a TC75/LM75

Hozzászólás Szerző: SanyiSay »

Ezt a kérdést már olvastuk. Teljesen felesleges mindenhova beírni.
Amúgy pedig a "buszos szenzoroknak" az az előnye hogy már kész adatot kapsz nem kell bajlódni a kapott számértékek értelmezésével, zavarok kiszűrésével, meg kalibrálással, és effélék, de ki is próbálhatod. ADC bemenetre köss egy hőmérő elemet, fillérekért lehet kapni sokfélét. Adatlapját nézd meg milyen hőfokra milyen értéket kapsz milyen hibákkal, tudj meg mindent az ADC lehetőségeiről és ezekből írd meg hozzá a kódot ami hőfokká alakítja azt. Nem egy kezdő szint, de megoldható.
Avatar
SanyiSay
Elektronbűvölő
Hozzászólások: 1031
Csatlakozott: 2009. február 28. szombat, 7:00

Re: 60 nap alatt Arduino #29 - I2C busz és a TC75/LM75

Hozzászólás Szerző: SanyiSay »

Amúgy ezen az oldalon
http://www.tavir.hu/
a TAVIR-AVR FÓRUM résznél látod az utolsó 10 hozzászólást.
Ha nem kapsz választ az nem azért van mert nem látja senki, csak nem mindenre érkezik válasz egyből.

Amikor pedig efféle megnyilvánulások vannak.
Eleg vicces -lenne ha komedianak fognam fel a tanfolyamot
Akkor pedig jobb ha az ember elszámol a válasz előtt 10-ig és utána válaszol, vagy egyáltalán nem válaszol.
Szerintem. :wink:
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Re: 60 nap alatt Arduino #29 - I2C busz és a TC75/LM75

Hozzászólás Szerző: Robert »

Hőmérőből az I2C LM75 azért került a terítékre:
- ezen át az I2C busz működése magyarázható,
- precíz hőmérő, és egyből _digitális_ adatként van meg az eredmény,
- I2C elve követhető, írás, olvasás módon,
- többet felfűzhetsz lábpazarlás nélkül,
- nem zavar/zajérzékeny mérésre.
- a Float / egész szám méretkorlátok bemutathatóak


Busz nélküli:
Melyik?
- NTC/PTC amit kalibrálni kell?
- Valamelyik LM35 vagy hasonló, ahol a precíziós ellenállás kell?
- az egy szem szabad AD lábat is ellőni erre?
- Ott a chip belsejében levő - ha analóg kell :)

Analóg jelekre meg a potmétert meglestük a tanfolyamon, ill a külső fénymérőt...
http://www.tavir.hu - a gazda :)
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: 60 nap alatt Arduino #29 - I2C busz és a TC75/LM75

Hozzászólás Szerző: kapu48 »

Válasz Tiborx8-nak!
Először ez ingyenes tanfolyam, magán kezdeményezésből.
Másodszor már létezik ennek a bővített folytatása a Tavir Webshop oldalon megrendelhető!
Harmadszor nagy vicc, de sehol máshól az országban nem találsz még 1 ilyen lelkes segítőkész emberkét ingyen! Mint akit most gorombán lekezeltél!

Szerintem inkább tanulással töltenéd az idődet!
Válasz küldése