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

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • 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.