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
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ásSzerző: Tiborx8 » 2016. december 26. hétfő, 20:54

Koszonom a valaszokat.

A forumon rengeteg segitokesz embert talaltam, nekik ezuton is koszonok minden segitseget.

venmedve
Újonc
Újonc
Hozzászólások: 4
Csatlakozott: 2017. február 2. csütörtök, 18:29
Tartózkodási hely: Budapest

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

HozzászólásSzerző: venmedve » 2017. március 1. szerda, 19:51

Eredetileg úgy gondoltam nem foglalkozok még ezzel a házival, de rájöttem a HW nélkül is megoldható.
Előjeles megjelenítés kell? Itt egy lehetséges megoldás.

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

/* I2C thermo EXT1
 LM754/TCN75A sample
 60 nap alatt arduino tanfolyam
 Venmedve megoldása
 
 Akinek van hadrwere kipróbálhatná. :)
*
* A program némi egyszerusitesen esett at
* Ugyanakkor használtam a "C" nyelv altal nyujtott
* lehetosegeket.
*
* Bar az alapelv, a programok hordozhatosaga miatt
* az, hogy a lehetoleg ne hasznaljunk nyelvspecifikus
* megoldasaokat, megis az alabbi programban hasznalt
* megoldasokat megengedhetonek talalom
* Ugyanis a legtobb magas nyelvu program ismeri a
* hasznalt adatipusokat, (C PASCAL C++ Arduino)
* A kis tomoritest meg szukseg eseten ki lehet bontani.
 */

//wire fuggveny kell!
#include "Wire.h"

//2 belso valtozo

// Csak egy valtozo kell !
// t a belovasott homerseklet
// mivel a homero IC kettes komlemensben
// ket byteon tarolja a homersekleti adatokat,
// elegendo az int tipus.
// tudjuk hogy az int tipus 2 byeton tarolt elojeles
// egesz.
// Ez kicsit bonyolitja a tizedes jegyek kiitasat, de megoldhato.

int t;

void setup()
{
  //IIC kommunikacio inicializalas
  Wire.begin();
  //Sorosport megnyitasa
  Serial.begin(9600);
}
void loop()
{ //A 72-es cimrol 2 byte-t kerunk
  Wire.requestFrom(72, 2);
  //ha nincs eszkoz, akkor itt all a program
  while (Wire.available())
  {
    //1. byte megerkezik: egesz fok
    // * ez az eredeti program resze kicsit modositva
    // a beolvasott byte-ot 256-al szorozva az int tipusu
    // t valtozo felso 8 bitjen helyezzuk el
    t = Wire.read() * 256;
    //2. byte megerkezik: tort hofok
    // * Az also 8bitet ami a tizedeseket tartalmazza hozzadjuk a
    // t valtozohoz, igy annak az also nyolc bizjet foglalja el
    // a beolvasott adat a következo keppen nez ki:
    // egeszek  tortek az also negy bit a katalogus szerint 0
    // eeeeeeee tttt0000
    // ha megis ketsegeink lennenek, : t += (Wire.read() & 0xfff0);
    // a tovabbiakban nincs szukseg semmifele muveletre, hiszen a
    // kapott ertek egy elojeles szam ami aranyos a homerseklettel.
    // vagyis az aktualis homerseklet 256 szorosa.
    t += Wire.read();
    Serial.print("Temperature = ");
    // a korrekciot a kiiratasban vegzzuk el.
    // Ezzel lehetove teve a tizedfokok kiirasat
    // a kiiras 4 tizedessel irja ki a homersekletet,
    // ami kicsit nagykepu, mivel a thermometer IC +-2 fok
    // pontasan mer, a gyari adato szerint
    Serial.println(float(t) / 256, 4);
  }
  delay(100);
}

_jani_
DrótVégénSzéndarab
Hozzászólások: 20
Csatlakozott: 2019. február 26. kedd, 16:17

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

HozzászólásSzerző: _jani_ » 2019. május 2. csütörtök, 21:35

A "Bitenkénti operátorok" sem voltak még a leckében.
PL:

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

y = (~x)+1

Vagyis jól gondolom, hogy szó szerint ki kell számolni a kettes komplemens-t a beolvasott értrékből?

_jani_
DrótVégénSzéndarab
Hozzászólások: 20
Csatlakozott: 2019. február 26. kedd, 16:17

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

HozzászólásSzerző: _jani_ » 2019. május 3. péntek, 2:19

venmedve programját átgondolva elkészült a negatív hőfokot is kijelző, számításon alapuló programom:

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

/* (27.01.)
          I2C thermo ext1
         
    LM75/TCN75A sample
       
   60 nap alatt Arduino tanfolyam
   (c) TavIR http://www.tavir.hu
*/
#include <Wire.h>

unsigned int t,t1; // Változó: egész, két bytes,
byte t2; // Változó: egész, egy bytes,

void setup() {
  // IIC kommunikáció inicializálás.
  Wire.begin();
  // Sorosport megnyitása.
  Serial.begin(9600);
}

void loop() {
  // A 72-es címről 2 byte-t kérünk.
  // ( Az eszköz a 0x48-as címen van... )
  Wire.requestFrom(72, 2);
    // Ha nincs eszköz akkor itt áll a program.
  while(Wire.available()) {
    // 1. byte megérkezik: egész fok.
    t = Wire.read() * 256; // A beolvasott első bytet a t első felére tesszük.
    // 2. byte megérkezik: tört hőfok.
    t += Wire.read(); // A beolvasott első byte-t a t alsó felére tesszük.
    // Bináris megjelenítéssel jól követhető, hogy mi hova kerül. ;)

    // Egész fok kiírása.
    Serial.print("Temperature: ");

    if (t >= 32768) {
      // t1 = (~t)+1; // Bitenkénti NEM (NOT) operátor. (Bitwise NOT operator.)
      // Bitenkénti NOT ( ~ ) operátor nem egyenlő a logikai NOT ( ! ) operátorral!!!
      t1 = ( 65535 - t) + 1; // A bitenkénti NOT kiváltása számítással...
      Serial.print("-");
      Serial.print(t1 / 256); // - Egész fok kiírása.
    } else {
      Serial.print(" ");
      Serial.print(t / 256);  // Egész fok kiírása.
    }

    // A törtfok kiírása.
    t2 = t; // A t alacsonyabb helyértékének elmentése byte-ként t2-be.
   
    if (t2 >= 32 || t2 <= 192) {
   
      t2 = (t2 / 31) * 14;
      // t2 = t2 / 31;  // Eldobjuk a felesleges biteket...
      // t2 = t2 * 14;  // Megközelítőleg decimálisra alakítjuk a kapott eredményt...
     
      Serial.print(".");
      Serial.println(t2);
     
    } else {
      Serial.println(".0");
    }
}
delay(1000);
}


A számítás röviden:
Ha " x >= 32768 " akkor " y = ( 65535 - x) + 1 ".
Vagyis, ha az előjel bit 1-es ( ebben az esetben x nagyobb vagy egyenlő mint 32768 )
akkor az elérhető legnagyobb értékből ( ebben a példában 65535 ) ki kell vonni a mért értéket ( x-et ) és hozzá kell adni egyet,
hogy az eredmény megfeleljen a kettes komplemens-nek.

Tudom, hogy a t és t1 változókat össze lehetne logikailag vonni...
S a tizedes érték képzése is csak közelítő, de ez amúgy is csak egy mintaprogram s nem patikaműszer...

Jó fejben tartani hogy: A Bitenkénti NOT ( ~ ) operátor nem egyenlő a logikai NOT ( ! ) operátorral!!!

venmedve: a programod működik a vasban is...
A programokat csak LM75A-val teszteltem.

_jani_
DrótVégénSzéndarab
Hozzászólások: 20
Csatlakozott: 2019. február 26. kedd, 16:17

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

HozzászólásSzerző: _jani_ » 2019. május 6. hétfő, 21:35

Sziasztok! Időközben próbáltam konfigurálni az LM75A OS kivezetését, hogy ki lehessen használni az IC minden tudását...
Született is egy program ami bár működik, de biztosan megoldható elegánsabban is.
Szeretném ha átnéznétek, hogy mit gondoltam rosszul, vagy hogyan lehetne elegánsabban megírni az inicializáló részt.
A program:

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

/*(27.01.)
        I2C thermo ext1
         
    LM75/TCN75A sample
       
   60 nap alatt Arduino tanfolyam
   (c) TavIR http://www.tavir.hu
*/
#include <Wire.h>

unsigned int t,t1; // Változó: egész, két bites,
byte t2; // Változó: egész, egy bites,

void setup() {
  // IIC kommunikáció inicializálás.
  Wire.begin();
 
/* Hőfokbeállítás... Egy próba.
 * 
 * Wire.beginTransmission(lm75a_sensor ADDRESS)-címen;
 * POINTER BYTE kiküldése; B00000010 = THYST ( alsó kapcsolási pont )
 * MSB hőfok-byte kiküldése; (8-bit)
 * LSB byte (bitek) kiküldése; (max 3-bit: B...xxxxx (adatlap szerint: B.xxxxxxx))
 * STOP paranccsal a port felszabadítása;   
 *
 * Wire.beginTransmission(lm75a_sensor ADDRESS)-címen;
 * POINTER BYTE kiküldése; B00000011 = TOS ( felső kapcsolási pont )
 * MSB hőfok-byte kiküldése; (8-bit)   
 * LSB byte (bitek) kiküldése; (max 3-bit:B...xxxxx (adatlap szerint: B.xxxxxxx))
 * STOP paranccsal a port felszabadítása;   
 *
 * Wire.beginTransmission(lm75a_sensor ADDRESS)-címen;
 * POINTER BYTE kiküldése; B00000000 = Config - hőfokolvasás.
 * STOP paranccsal a port felszabadítása;
 *
 * (talán valahogy így nézne ki a program)
 *
*/
 
 Wire.beginTransmission(0x48);
  Wire.write(B00000010); // THYST ( alsó ˇ kapcsolási pont )
  Wire.write(B00011100); // (28C = B00011100)
  // Wire.write(B000xxxxx); // (Tört C = B...xxxxx)
  if (Wire.endTransmission());
 
 Wire.beginTransmission(0x48);
  Wire.write(B00000011); // TOS ( felső ^ kapcsolási pont )
  Wire.write(B00011101); // (29C = B00011101)
  //  Wire.write(B000xxxxx); // (Tört C = B...xxxxx)
  if (Wire.endTransmission());

// Configurációs regiszter beállítása.
 Wire.beginTransmission(0x48);
  Wire.write(B0000001); // Config - Regiszter
  Wire.write(B0001000); // Config adat ( Lásd adatlapban... )
  // B.......0 = Normál üzem.                B.......1 = Alacsony teljesítményű üzemmód.
  // B......0. = Comparátor üzemmód (OS kimenet).    B......1. = INTERRUPT (INT.) üzemmód.
  // B.....0.. = OS kimenet : Aktív LOW.             B.....1.. = OS kimenet : Aktív HIGH üzemmód.
  // B...XX...  Hibakezelés XX-bit : B00 =_1_Default. B01 = 2. B10 = 4. B11 = 6.
  if (Wire.endTransmission());

// Vissza kell állítani az érzékelőt hőmérsékletmérésre (CONFIG: B00000000)
 Wire.beginTransmission(0x48);
  Wire.write(B0000000); // Config - hőfokolvasás.
  if (Wire.endTransmission());
 
  // Sorosport megnyitása.
  Serial.begin(9600);
}

void loop() {
  // A 72-es címről 2 byte-t kérünk.
  // ( Az eszköz a 0x48-as címen van... )
  Wire.requestFrom(72, 2);
  // Wire.requestFrom(72, 2, stop);
  // Ha nincs eszköz akkor itt áll a program.
  while(Wire.available()) {
    // 1. byte megérkezik: egész fok.
    t = Wire.read() * 256; // A beolvasott első byte-t a t első felére tesszük.
    // 2. byte megérkezik: tört hőfok.
    t += Wire.read(); // A beolvasott első byte-t a t alsó felére tesszük.
    // Bináris megjelenítéssel jól követhető, hogy mi hova kerül. ;)

    // Egész fok kiírása.
    Serial.print("Temperature: ");

    if (t >= 32768) {
      // t1 = (~t)+1; // Bitenkénti NEM (NOT) operátor. (Bitwise NOT operator.)
      // Bitenkénti NOT ( ~ ) operátor nem egyenlő a logikai NOT ( ! ) operátorral!!!
      t1 = ( 65535 - t) + 1; // A bitenkénti NOT kiváltása számítással...
      Serial.print("-");
      Serial.print(t1 / 256); // - Egész fok kiírása.
    } else {
      Serial.print(" ");
      Serial.print(t / 256);  // Egész fok kiírása.
    }

    // A törtfok kiírása.
    t2 = t; // A t alacsonyabb helyértékének elmentése byte-ként t2-be.
   
    if (t2 >= 32 || t2 <= 192) {
   
      t2 = (t2 / 31) * 14;
      // t2 = t2 / 31;  // Eldobjuk a felesleges biteket...
      // t2 = t2 * 14;  // Nagyjából decimálisra alakítjuk a kapott eredményt.
     
      Serial.print(".");
      Serial.println(t2);
     
    } else {
      Serial.println(".0");
    }
}
delay(1000);
}

Előre Köszönöm a választ!

Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3292
Csatlakozott: 2008. augusztus 29. péntek, 6:00
Tartózkodási hely: Újkígyós

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

HozzászólásSzerző: kapu48 » 2019. május 7. kedd, 12:51

A ;-vel lezárt iff-ek mire szolgálnak? ( if (Wire.endTransmission()); ?)

Szerintem értelmetlen lekérdezni az adott függvény visszatérési értékét, ha utána nem dolgozzuk fel azt!
Ha nem érdekel, hogy sikeresen le tudta zárni a Wire.endTransmission()?
Akkor elég simán if nélkül a Wire.endTransmission();

Vagy ha már vizsgálod?
// Sorosport megnyitása.
Serial.begin(9600);

Akkor írasdki, ha hibás: if (!Wire.endTransmission()) Serial.print("Transmission Error! ");

Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3292
Csatlakozott: 2008. augusztus 29. péntek, 6:00
Tartózkodási hely: Újkígyós

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

HozzászólásSzerző: kapu48 » 2019. május 7. kedd, 13:02

Egy jobb IDE az ilyen if(?);-eket ki optimizálja, de szerintem az arduino IDE nem a jobbak közé tartozik!


Vissza: “60 nap alatt Arduino - Házi feladatok”

Ki van itt

Jelenlévő fórumozók: nincs regisztrált felhasználó valamint 0 vendég