I2C komunikace mezi arduiny

KamilV
Příspěvky: 479
Registrován: 03 dub 2018, 15:27
Reputation: 0
Bydliště: Olomouc

Re: I2C komunikace mezi arduiny

Příspěvek od KamilV » 23 lis 2020, 08:23

Ať už zvolí jakýkoliv způsob, já bych ještě přidal ID zařízení. Málokdy totiž "řídící jednotka" řídí jen jedno zařízení. A dřív nebo později se to rozroste a krom teploty a vlhkosti doma bude chtít měřit i skleník, sklep, půdu, zahradní domek... Takže bych si tam přidal ID, abych poznal, odkud naměřená data pocházejí.

zacatecnik1
Příspěvky: 62
Registrován: 05 led 2020, 20:05
Reputation: 0

Re: I2C komunikace mezi arduiny

Příspěvek od zacatecnik1 » 23 lis 2020, 08:43

gilhad píše:
23 lis 2020, 00:21
Pak bych kazdou tu vec posilal (a cetl) zvlast jako balik se dvema polozkama: popis a hodnota.
napriklad jako 4 byty, kde prvni dva jsou ten popis, druhe dva ta hodnota. Prijemce to prijme a podle (napriklad) prvnich dvou bytu se rozhodne jak nalozi s tim zbytkem.

Kód: Vybrat vše

snimaci vysle
TE25
ridici si rekne TE je teplota, takze do teploty si zapisu 25 C
VL50
ridici si rekne VL je vlhkost, takze do vlhkosti si zapisu 50%

Dalsi mozna varianta je, ze pouzijes "adresovani" v ramci komunikace, kde ridici arduino posle pozadavek a snimaci odpovi hodnotou ramci jedne te I2C relace. Takze ridici se pta jen kdyz ma zrovna cas a naladu to zpracovavat a snimane odpovida, co ma za posledni zmerenou hodnotu (a pripadne kdy).

Kód: Vybrat vše

ridici vysle 
TE
a cte do teploty odpoved ve stupnich Celsia
prijimaci posle
25
ridici vysle 
VL
a cte do vlhkosti odpoved v procentech
prijimaci posle
50
A mohl byste mi tady napsat nějaký příklad toho prvního jak by to vypadalo v programu zapsané?
Děkuji

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

Re: I2C komunikace mezi arduiny

Příspěvek od pavel1tu » 23 lis 2020, 19:56

Na serial port odešleš data za sebou (vysílací) - ten určuje četnost měření a odesílání

Kód: Vybrat vše

int teplota;     //T
int tlak;          //P
int vlhkost;     //H
void setup() 
{
    Serial.begin(9600); // Set the baud rate to 9600
     
}

void loop() 
{
// tady vyčteš z čidla a uložíš do proměnných

//odeslání na serialport
Serial.print("T");         //hlavička
Serial.print(teplota);
Serial.print(";");         //oddělovač
Serial.print("P");         //hlavička
Serial.print(tlaka);
Serial.print(";");         //oddělovač
Serial.print("H");         //hlavička
Serial.println(vlhkost);
}
dekodovani je jednoduche - vyzkoušel jsem
pokud se data nepřijímají, může níže probíhat další kod

Kód: Vybrat vše

void setup() 
{
    Serial.begin(9600); // Set the baud rate to 9600
     
}
void loop() 
{
    if (Serial.available()) {
      String s1 = Serial.readStringUntil(';');// s1 is String type variable.
      if(s1[0]== 'T') {
        s1.remove(0, 1);             //odstraní "T"
        int teplota = s1.toInt();
        }
      if(s1[0]== 'P') {
        s1.remove(0, 1);             //odstraní "P"
        int tlak = s1.toInt();
        }
      if(s1[0]== 'H') {
        s1.remove(0, 1);             //odstraní "H"
        int vlhkost = s1.toInt();
        }
    }
 
// dalsi kod na zpracovani prijatych hodnot 
 
}   
 
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

RomanB
Příspěvky: 90
Registrován: 04 zář 2017, 14:28
Reputation: 0
Bydliště: Havířov

Re: I2C komunikace mezi arduiny

Příspěvek od RomanB » 23 lis 2020, 20:42

DTH dává hodnoty ve float, takže by mělo být v kodu s1.toFloat()

Uživatelský avatar
gilhad
Příspěvky: 779
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: I2C komunikace mezi arduiny

Příspěvek od gilhad » 23 lis 2020, 20:48

https://navody.arduino-shop.cz/navody-k ... skami.html

Master cte senzory, slave zpracovava:

Kód: Vybrat vše

/ I2C komunikace mezi Arduiny, master

// připojení potřebné knihovny
#include <Wire.h>

// proměnná pro uložení posílaného čísla
int teplota;
char data [4];
void setup() {
  // zahájení komunikace po I2C, adresa 0x01
  Wire.begin(0x01);
}


int podfuk=0; // takzvane nactena data

void loop() {

  if (podfuk>10) {podfuk =0; } else { podfuk ++; }; // predstiram cteni dat

// zpracovani teploty

teplota=podfuk + 20;
    //ve skutecnosti nejak vycteno ze senzoru a je to v mistnosti, cili vic jak nula a min jak 100
           // cili spis teplota=cti_teplotni_cidlo();

data[0] = 'T';
data[1] = 'E';
data[2] = ( teplota / 10 ) + '0' ; 
data[3] = ( teplota % 10 ) + '0' ; // jednoduchy prevod na znaky 00-99


  // zahájení přenosu dat na I2C adresu "0x02"
  Wire.beginTransmission(0x02);
  // poslání dat
  for (int x=0; x<4; x++) {
      Wire.write(data[x]);
  };
  // ukončení aktuálního přenosu
  Wire.endTransmission();
  
  
  // pauza před novým "ctenim" dat
  delay(1000);
  
// zpracovani vlhkosti

vlhkost= 2*podfuk + 50;
    //ve skutecnosti nejak vycteno ze senzoru 
           // cili spis vlhkost=cti_vlhkostni_cidlo();

data[0] = 'V';
data[1] = 'L';
data[2] = ( vlhkost / 10 ) + '0' ; 
data[3] = ( vlhkost % 10 ) + '0' ; // jednoduchy prevod na znaky 00-99


  // zahájení přenosu dat na I2C adresu "0x02"
  Wire.beginTransmission(0x02);
  // poslání dat
  for (int x=0; x<4; x++) {
      Wire.write(data[x]);
  };
  // ukončení aktuálního přenosu
  Wire.endTransmission();
  
  // obdobne pro jina cidla
  
  // pauza před novým "ctenim" dat
  delay(1000);
}
slave zpracovava data:

Kód: Vybrat vše

// I2C komunikace mezi Arduiny, slave

// připojení potřebné knihovny
#include <Wire.h> 

// proměnná pro uložení přijatého čísla
volatile int teplota,tlak,vlhkost; // volatile - data se muzou zmenit na pozadi, chovej se k nim spravne
volatile bool zmena; // doslo k nejake zmene?
char data[4];

void setup() {
  // zahájení komunikace po sériové lince
  Serial.begin(9600);
  // zahájení komunikace po I2C, adresa 0x02
  Wire.begin(0x02); 
  // nastavení podprogramu, který bude zavolán při přijetí dat po I2C 
  // pricemz se beh hlavniho programu zastavi a deje se to na pozadi
  Wire.onReceive(prichoziDATAI2C);
}

void prichoziDATAI2C(int pocet) {
  // načtení přijatych dat do proměnné
  if (pocet !=4 ) {   // asi je to blbe zahodim data a vratim se
   while (Wire.available()) { Wire.read(); }; // prectu dostupna data a ignoruju je
   return;
  };
  // prisly 4 byty, nactu je
  for (int x=0; x<4; x++) { 
     data[x] = Wire.read();
  };
  
  // poresim prirazeni:
  if ( data[0] =='T' && data[1] == 'E' ) { // jde o teplotu
     teplota = 10*(data[2] - '0') + (data[3] -'0' ) ;
   } else if ( data[0] =='V' && data[1] == 'L' ) { // jde o vlhkost
     vlhkost = 10*(data[2] - '0') + (data[3] -'0' ) ;
   } else if ( data[0] =='T' && data[1] == 'L' ) { // jde o tlak
        tlak = 10*(data[2] - '0') + (data[3] -'0' ) ;
   } else { 
       return;
       // je to neco neznameho, bud to osetrim, nebo nedelam nic
   }
   zmena=True; // signalizuju, ze se data "nejak" zmenila
}
void loop() {
 if (zmena) {
  zmena=False; // beru na vedomi zmenu
  Serial.print ("Teplota = ");
  Serial.print (teplota);
  Serial.println (" C");
  Serial.print ("Vlhkost = ");
  Serial.print (vlhkost);
  Serial.println (" %");
  Serial.print ("Tlak = ");
  Serial.println (tlak);
  Serial.println ("=========");
  }
}

Je to strasne odflaknute, ale snad to ukaze tu myslenku.

Master si data proste vymysli, mel by je merit. Samozrejme nemusi merit vsechna data naraz.

Spravne by slave mel ta data cist do bufferu, zpracovat odpovidajici cast bufferu kdyz je naplnena, nejak se starat o preteceni/podteceni dat, lip si resit "zamykani" pri zmene, ....

Prenasim to jako text, ale klidne by slo ta data prenaset jako byty a jenom navesti jako text (nebo treba byty, ktere neco oznacuji 1 tlak, 2 vlhkost ...)

Cele je to velice jednoduse naprasene, takze to neni ani efektivni, ani zcela spolehlive, ale zato je to celkem primocare

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

Re: I2C komunikace mezi arduiny

Příspěvek od pavel1tu » 23 lis 2020, 21:21

RomanB píše:
23 lis 2020, 20:42
DTH dává hodnoty ve float, takže by mělo být v kodu s1.toFloat()
Asi takhle, je to něco co funguje a klidně se může posílat i float - cokoliv,
já float posílám jako int, jen ho vynásobím 1000, převedu na celé číslo, pak pošlu jako int, přijmu jako string, převedu na int, vydělím 1000 a mám zpět float - protože konverze ze string na float je zbytečně složitá.
Tohle je funkční - na 232 i 485 mi to funguje a dekoduje co přijde a roztřídí podle hlavičky na teplotu, tlak i vlhkost.
Já to mám napsané univerzálně na posílání int, float, string jako funkci (včetně adresace a kontrolního součtu), ale to by asi nepobral.

Zatím jsem tu za tu dobu konverzace od tazatele neviděl ani čárku kodu, tak netuším co zatím má a nemá.
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

zacatecnik1
Příspěvky: 62
Registrován: 05 led 2020, 20:05
Reputation: 0

Re: I2C komunikace mezi arduiny

Příspěvek od zacatecnik1 » 23 lis 2020, 21:35

Děkuji za rady.
Bohužel nemohu poslat kód protože jsem zapoměl heslo a mám hi uložené jen na telefonu.
Já jsem dneska zkoušel nabastlit nějak ten program podle internetu ale ukazovalo to jen 1 a 0, takže to zkusím zítra co jste mi poslali a napíšu jak to fungovalo.

zacatecnik1
Příspěvky: 62
Registrován: 05 led 2020, 20:05
Reputation: 0

Re: I2C komunikace mezi arduiny

Příspěvek od zacatecnik1 » 24 lis 2020, 09:14

Takže tam program na komunikaci po RX a TX mi funguje ale to I2C furt ne, ale to nevadí, děkuji za rady a tipy.
A chtěl bych se jen okrajově zeptat když u toho arduina uno(myslím že je to klon) zmáčknu resetovací tlačítko tak se mi začne strašně zahřívá ten integrák na fotce (můžu poslat i označení pokud bude třeba) nevíte čím to může být?
Přílohy
3984AA85-A063-444C-AFD3-5ECF08D58682.jpeg

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 11 hostů