ppprzem Napisano Maj 24, 2019 Udostępnij Napisano Maj 24, 2019 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 More sharing options...
marek1707 Maj 24, 2019 Udostępnij Maj 24, 2019 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. 1 Link do komentarza Share on other sites More sharing options...
ppprzem Maj 24, 2019 Autor tematu Udostępnij Maj 24, 2019 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 More sharing options...
ppprzem Maj 24, 2019 Autor tematu Udostępnij Maj 24, 2019 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 1 Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. 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
Treker (Damian Szymański) Maj 25, 2019 Udostępnij Maj 25, 2019 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 More sharing options...
ppprzem Maj 25, 2019 Autor tematu Udostępnij Maj 25, 2019 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 More sharing options...
Treker (Damian Szymański) Maj 26, 2019 Udostępnij Maj 26, 2019 To właściwie nie ma wiele wspólnego z samym Arduino - zerknij na ogólny opis I2C, powinno się coś wyjaśnić: https://pl.wikipedia.org/wiki/I²C Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
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ę »