Skocz do zawartości

DFRobot MLX90164 dwa czujniki


ppprzem

Pomocna odpowiedź

Witam,

czy jest możliwość obsługi dwóch takich czujników DFRobot Gravity -MLX90614 na Arduino? Oba komunikują się poprzez I2C. Na szybko gdzieś przeczytałem, że chcąc korzystać z dwóch urządzeń podłączonych do tej magistrali, to urządzenia muszą posiadać różne adresy. Proszę o podpowiedź czy jest w ogóle możliwe ustalenie takich adresów? Jesli tak, to jak się do nich odnosić? Znalazłem kawałek kodu który sprawdza adresy podlaczonych do I2C urządzen i mam na kazdym z nich ten sam adres. Probowalem uzywać kodu (wydawac by sie moglo) do zmiany adresów, ale niestety też bezskutecznie. proszę o poradę

Przy obsłudze jednego takiego czujnika korzystam z wiedzy udostepnionej na dfrobot:

IR_Thermometer_Sensor_MLX90614 MLX90614 = IR_Thermometer_Sensor_MLX90614(); 

MLX90614.begin();

MLX90614.GetObjectTemp_Celsius();

Jak to będzie przy dwóch czujnikach?

Link do komentarza
Share on other sites

Dobrze przeczytałeś: urządzenia wiszące w jednej szynie I2C muszą mieć różne adresy. W przypadku tych czujników musisz użyć programu do zmiany adresu w jednym z czujników. Nie wiemy jakiego programu dokładnie użyłeś i w jaki sposób, ale dopóki tego nie załatwisz, nie zadziała więcej jak jeden czujnik. Może pokaż jakiś link albo wrzuć kod tego co miało zmienić adres czujnika i opisz krok po kroku co robiłeś. Adres czujnika przechowywany jest w jego wewnętrznej pamięci EEPROM i jest jak najbardziej możliwa jego zmiana.

  • Lubię! 1
Link do komentarza
Share on other sites

tak więc uzyłem czegoś takiego:

#include <i2cmaster.h>
// Pins: Standard: SDA:A4  SCL:A5
//       Mega:     SDA:D20 SCL:D21

byte MLXAddr = 0x11<<1;           // Default address
//byte MLXAddr = 0;               // Universal address

void setup(){
 Serial.begin(9600);
 Serial.println("Setup...");
 
 i2c_init();                              //Initialise the i2c bus
 PORTC = (1 << PORTC4) | (1 << PORTC5);   //enable pullups
 
 delay(5000);                    // Wait to allow serial connection
 ReadAddr(0);                    // Read current address bytes
 ChangeAddr(0x11, 0xBE);         // Change address to new value
 //ChangeAddr(0x5A, 0xBE);       // Change address to default value
 ReadAddr(0);                    // Read address bytes
 delay(5000);                    // Cycle power to MLX during this pause
 ReadTemp(0);                    // Read temperature using default address
 ReadTemp(MLXAddr);              // Read temperature using new address
}

void loop(){
   delay(1000); // wait a second
}

word ChangeAddr(byte NewAddr1, byte NewAddr2) {

 Serial.println("> Change address");

 i2c_start_wait(0 + I2C_WRITE);    //send start condition and write bit
 i2c_write(0x2E);                  //send command for device to return address
 i2c_write(0x00);                  // send low byte zero to erase
 i2c_write(0x00);                  //send high byte zero to erase
 if (i2c_write(0x6F) == 0) {
   i2c_stop();                     //Release bus, end transaction
   Serial.println("  Data erased.");
 }
 else {
   i2c_stop();                     //Release bus, end transaction
   Serial.println("  Failed to erase data");
   return -1;
 }

 Serial.print("  Writing data: ");
 Serial.print(NewAddr1, HEX);
 Serial.print(", ");
 Serial.println(NewAddr2, HEX);

 for (int a = 0; a != 256; a++) {
   i2c_start_wait(0 + I2C_WRITE);  //send start condition and write bit
   i2c_write(0x2E);                //send command for device to return address
   i2c_write(NewAddr1);            // send low byte zero to erase
   i2c_write(NewAddr2);            //send high byte zero to erase
   if (i2c_write(a) == 0) {
     i2c_stop();                   //Release bus, end transaction
     delay(100);                   // then wait 10ms
     Serial.print("Found correct CRC: 0x");
     Serial.println(a, HEX);
     return a;
   }
 }
 i2c_stop();                       //Release bus, end transaction
 Serial.println("Correct CRC not found");
 return -1;
}

void ReadAddr(byte Address) {

 Serial.println("> Read address");

 Serial.print("  MLX address: ");
 Serial.print(Address, HEX);
 Serial.print(", Data: ");

 i2c_start_wait(Address + I2C_WRITE);  //send start condition and write bit
 i2c_write(0x2E);                  //send command for device to return address
 i2c_rep_start(Address + I2C_READ);
 
 Serial.print(i2c_readAck(), HEX); //Read 1 byte and then send ack
 Serial.print(", ");
 Serial.print(i2c_readAck(), HEX); //Read 1 byte and then send ack
 Serial.print(", ");
 Serial.println(i2c_readNak(), HEX);
 i2c_stop();
}

float ReadTemp(byte Address) {
 int data_low = 0;
 int data_high = 0;
 int pec = 0;

 Serial.println("> Read temperature");

 Serial.print("  MLX address: ");
 Serial.print(Address, HEX);
 Serial.print(", ");

 i2c_start_wait(Address + I2C_WRITE);
 i2c_write(0x07);                  // Address of temp bytes
 
 // read
 i2c_rep_start(Address + I2C_READ);
 data_low = i2c_readAck();         //Read 1 byte and then send ack
 data_high = i2c_readAck();        //Read 1 byte and then send ack
 pec = i2c_readNak();
 i2c_stop();
 
 //This converts high and low bytes together and processes temperature, MSB is a error bit and is ignored for temps
 float Temperature = 0x0000;       // zero out the data
 
 // This masks off the error bit of the high byte, then moves it left 8 bits and adds the low byte.
 Temperature = (float)(((data_high & 0x007F) << 8) + data_low);
 Temperature = (Temperature * 0.02) - 273.16;
 
 Serial.print(Temperature);
 Serial.println(" C");
 return Temperature;
}

majstrowałem tych dwóch w liniach:


byte MLXAddr = 0x11<<1;           // Default address


ChangeAddr(0x11, 0xBE);         // Change address to new value

nastepnie przy użyciu "skanera" wyszło mi że mam podłączone urządzenia o adresach 0x5A i 0x11

skaner:

#include <Wire.h>
 
 
void setup()
{
  Wire.begin();
 
  Serial.begin(9600);
  while (!Serial);             // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
}
 
 
void loop()
{
  byte error, address;
  int nDevices;
 
  Serial.println("Scanning...");
 
  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
 
    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
 
      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknown error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
 
  delay(5000);           // wait 5 seconds for next scan
}

i teraz czujnik o adresie 0x11 stale pokazuje jedną wartość 1037.55

namieszałem....

Link do komentarza
Share on other sites

jestem za cienki w te klocki, ale podmieniłem w bibliotece domyślny adres na obecnie wskazywany 0x11 i z powrotem czujnik pokazuje normalna i prawidlową temperaturę. Do czujnika, który ma stary (już nie domyślny adres 0x5A) odwołuję się w kodzie w ten sposób:

IR_Thermometer_Sensor_MLX90614 czujnik_nr_2 = IR_Thermometer_Sensor_MLX90614(0x5A);

szkoda, że nie wiem jak to działa z tymi adresami, ale osiągnąłem swój cel pomiaru z dwóch czujników na jednej magistrali I2C

  • Lubię! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

9 godzin temu, ppprzem napisał:

szkoda, że nie wiem jak to działa z tymi adresami

Czego dokładnie nie rozumiesz? Nie wiesz skąd się "fizycznie" biorą te różne adresy czy jak są używane w programie?

Link do komentarza
Share on other sites

Probowalem przeanalizowac kod programu, aby poznac co dokładnie krok po kroku dzieje sie z adresami. Tak ze nie wiem jak te adresy są używane. W tym kodzie znajduje sie kilka instrukcji ktorych dzialanie jest dla mnie nieznane. Z powodu pewnie nieznajomosci tematu. Interesuje mnie w kazdym razie algorytm zmlamiany adresu i w jaki sposob jest to realizowane

 

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.