• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Pomiar temperatury dwoma czujnikami MLX90614
#1
Witam, w zasadzie nie znam się na programowaniu, ale za pomocą internetu próbowałem coś posklejać.
Mam dwa czujniki MLX90614 (moduły GY-906), Arduino Mega 2560, wyświetlacz lcd 4x20 HD44780.
Generalnie chodzi o to aby na wyświetlaczu była wyświetlana niezależna temperatura z obu czujników,
Czujnik1:
Tobj1= wskazania prawidłowe
Tsen1= wskazania takie jak Tsen2(identyczny odczyt)

Czujnik2:
Tobj2 = wskazania prawidłowe
Tsen2 = wskazania prawidłowe

Dodaję kod:
Kod:
/**
* Two Infrared Thermometers MLX906114
* by Jaime Patarroyo
* based on 'Is it hot? Arduino + MLX90614 IR Thermometer' by bildr.blog
*
* Returns the temperature in Celcius and Fahrenheit from two MLX90614
* Infrared Thermometers, connected to the TWI/I²C pins (on the Wiring v1
* board 21 (SCL) and 20 (SDA) and on Wiring S board 21 (SCL) and 20 (SDA)).
*/

#include <i2cmaster.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(23, 24, 25, 26, 27, 28);

int adres = 0xb4; // Adres czujnika MLX90614
int erc = 0; // Zmienna przechowująca wartość PEC
int daneH = 0;  // Drugi bajt danych
int daneL = 0;  // Pierwszy bajt danych  
double tempnalsb = 0.02; // Zmienna, przez którą wymnażana będzie wartość cyfrowa
double temperatura = 0;   // Zmienna przechowująca temperaturę

int device1Address = 0x50<<1;   // 0x50 is the assigned address for I²C
                               // communication for sensor 1.
                               // Shift the address 1 bit right, the
                               // I²Cmaster library only needs the 7 most
                               // significant bits for the address.
int device2Address = 0x5A<<1;   // 0x5A is the assigned address for I²C
                               // communication for sensor 2.
                               // Shift the address 1 bit right, the
                               // I²Cmaster library only needs the 7 most
                               // significant bits for the address.
float celcius1 = 0;             // Variable to hold temperature in Celcius
                               // for sensor 1.                                
float celcius2 = 0;             // Variable to hold temperature in Celcius
                               // for sensor 2.


void setup()
{
 
 lcd.begin(20, 4); // Inicjalizacja wyświetlacz
 Serial.begin(115200);           // Start serial communication at 9600bps.
 
 i2c_init();                               // Initialise the i2c bus.
}

void loop()
{
 i2c_start_wait(adres+I2C_WRITE);   // Rozpoczęcie komunikacji I2C w trybie zapisu
 i2c_write(0x07);                    // Zapis wartości 0x07 (wybranie rejestru Tobj1)
 i2c_rep_start(adres+I2C_READ);      // Ponowny start komunikacji I2C pod adresem do odczytu
 daneL = i2c_readAck();               // Odczyt pierwszego bajtu danych
 daneH = i2c_readAck();               // Odczyt drugiego bajtu danych
 erc = i2c_readNak();                // Odczyt trzeciego (nieistotnego) bajtu danych
 i2c_stop();

 temperatura = (double)(((daneH & 0x007F) << 8) + daneL); // Utworzenie 16-sto bitowej zmiennej składającej się z dwóch zmiennych jedno-bajtowych
 temperatura = temperatura*tempnalsb; // Na jeden bit przypada 0.02 K, wynikiem tej operacji jest temperatura w Kelvinach
 temperatura = temperatura - 273.15; // Konwersja na stopnie Celsiusza

 i2c_start_wait(adres+I2C_WRITE);
 i2c_write(0x06);                  // Wybór rejestru temperatury otoczenia
 i2c_rep_start(adres+I2C_READ);
 daneL = i2c_readAck();
 daneH = i2c_readAck();
 erc = i2c_readNak();
 i2c_stop();

 temperatura = (double)(((daneH & 0x007F) << 8) + daneL);
 temperatura = temperatura*tempnalsb;
 temperatura = temperatura - 273.15;

 lcd.setCursor(0,0);        // Wyświetlenie (pierwsza linia LCD)
 lcd.print("Tobj1 = ");
 lcd.print(celcius1);
 lcd.print(" ");
 lcd.write(0xDF);            // Znak stopnia
 lcd.print("C  H");
 
 lcd.setCursor(0,1); // Wyświetlenie (druga linia LCD)
 lcd.print("Tsns1 = ");
 lcd.print(temperatura);
 lcd.print(" ");
 lcd.write(0xDF);
 lcd.print("C  O");  
 delay(200);         // Opóźnienie 200 mS

 lcd.setCursor(0,2);  // Wyświetlenie (trzecia linia LCD)
 lcd.print("Tobj2 = ");
 lcd.print(celcius2);
 lcd.print(" ");
 lcd.write(0xDF);               // Znak stopnia celciusa
 lcd.print("C  M");
 delay(200);          // Opóźnienie 200 mS    
 
 lcd.setCursor(0,3); // Wyświetlenie (czwarta linia LCD)
 lcd.print("Tsns2 = ");
 lcd.print(temperatura);
 lcd.print(" ");
 lcd.write(0xDF);
 lcd.print("C  E");  
 delay(200);         // Opóźnienie 200 mS

 
 
 celcius1 = temperatureCelcius(device1Address);// Read's data from MLX90614
 celcius2 = temperatureCelcius(device2Address);// with the given address,
                                               // transform's it into
                                               // temperature in Celcius and
                                               // store's it in the celcius1
                                               // or celcius2 variables.


 Serial.print("Tobj 1:Temp: ");   // Prints all readings in the Serial
 Serial.print(celcius1);                // port.
 Serial.print(" ");
 Serial.println();
 Serial.print("Tobj 2:Temp: ");
 Serial.print(celcius2);
 Serial.print(" ");
 Serial.println();
 Serial.print("Tsen 3:Temp: ");
 Serial.print(temperatura);
 Serial.print(" ");
 Serial.println();
 Serial.print("Tsen 4:Temp: ");
 Serial.print(temperatura);
 Serial.print(" ");
 Serial.println();
 delay(200);                         // Wait a second before printing again.
}

float temperatureCelcius(int address) {
 int dev = address;
 int data_low = 0;
 int data_high = 0;
 int pec = 0;
 
 // Write
 i2c_start_wait(dev+I2C_WRITE);
 i2c_write(0x07);

 // Read
 i2c_rep_start(dev+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.
 double tempFactor = 0.02;       // 0.02 degrees per LSB (measurement
                                 // resolution of the MLX90614).
 double tempData = 0x0000;       // Zero out the data
 int frac;                       // Data past the decimal point

 // This masks off the error bit of the high byte, then moves it left
 // 8 bits and adds the low byte.
 tempData = (double)(((data_high & 0x007F) << 8) + data_low);
 tempData = (tempData * tempFactor)-0.01;
 float celcius = tempData - 273.15;
 
 // Returns temperature un Celcius.
 return celcius;
}
Adresy czujników są ustawione jak w kodzie.
Proszę o wskazówki jak naprawić ten błąd.
 
Odpowiedź
#2
temperatura czy ta zmienna odpowiada za wyświetlanie temperatury
[Obrazek: banerelektronika.jpg]



Jeśli pomogłem podziękuj punktem reputacji Wink
 
Odpowiedź
#3
(13-06-2016, 21:02)adix napisał(a): temperatura czy ta zmienna odpowiada za wyświetlanie temperatury

Tak, bo po zmianie tego wpisu , nie wyświetla prawidłowej temperatury otoczenia.

Zaznaczam że jestem zielony w temacie.
Było to tak , znalazłem kod do obsługi jednego czujnika( temperatura wyświetlana na LCD), a że mam dwa czujniki to zacząłem kombinować, może się uda,(brak podstaw). W dalszej kolejności znalazłem kod na dwa czujniki, ale dane są wysyłane tylko przez port szeregowy, a że chciałem widzieć to na LCD to kombinacji nie było końca.
Niestety poległem.
 
Odpowiedź
#4
to problem tu leszy masz powielone te same zmiene i wyswietlasz w 2 miescach to samo
Kod:
temperatura = (double)(((daneH & 0x007F) << 8) + daneL);
temperatura = temperatura*tempnalsb;
temperatura = temperatura - 273.15;
i tutaj
Kod:
temperatura = (double)(((daneH & 0x007F) << 8) + daneL); // Utworzenie 16-sto bitowej zmiennej składającej się z dwóch zmiennych jedno-bajtowych
temperatura = temperatura*tempnalsb; // Na jeden bit przypada 0.02 K, wynikiem tej operacji jest temperatura w Kelvinach
temperatura = temperatura - 273.15; // Konwersja na stopnie Celsiusza


musisz zmienic np temperatura2 kturas ze zmienych
Kod:
temperatura2 = (double)(((daneH & 0x007F) << 8) + daneL);
temperatura2 = temperatura2*tempnalsb;
temperatura2 = temperatura2 - 273.15;
[Obrazek: banerelektronika.jpg]



Jeśli pomogłem podziękuj punktem reputacji Wink
 
Odpowiedź
#5
Nie będę udawał że się znam, podam fragment kodu który może wyjaśni o co mi chodzi:
Kod PHP:
void loop()
{
  i2c_start_wait(adres+I2C_WRITE);   // Rozpoczęcie komunikacji I2C w trybie zapisu
  i2c_write(0x07);                    // Zapis wartości 0x07 (wybranie rejestru Tobj1)
  i2c_rep_start(adres+I2C_READ);      // Ponowny start komunikacji I2C pod adresem do odczytu
  daneL i2c_readAck();               // Odczyt pierwszego bajtu danych
  daneH i2c_readAck();               // Odczyt drugiego bajtu danych
  erc i2c_readNak();                // Odczyt trzeciego (nieistotnego) bajtu danych
  i2c_stop(); 

  temperatura 
= (double)(((daneH 0x007F) << 8) + daneL); // Utworzenie 16-sto bitowej zmiennej składającej się z dwóch zmiennych jedno-bajtowych
  temperatura temperatura*tempnalsb// Na jeden bit przypada 0.02 K, wynikiem tej operacji jest temperatura w Kelvinach
  temperatura temperatura 273.15// Konwersja na stopnie Celsiusza

  i2c_start_wait(adres+I2C_WRITE);
  i2c_write(0x06);                  // Wybór rejestru temperatury otoczenia
  i2c_rep_start(adres+I2C_READ);
  daneL i2c_readAck(); 
  daneH 
i2c_readAck(); 
  erc 
i2c_readNak();
  i2c_stop();

  temperatura = (double)(((daneH 0x007F) << 8) + daneL);
  temperatura temperatura*tempnalsb; 
  temperatura 
temperatura 273.15
Czujnik mierzy dwie temperatury, temp. otoczenia "i2c_write(0x06);" i  temp. obiektu "i2c_write(0x07);".

Żeby nie kręcić za bardzo, podam stronę z której kodem się posiłkowałem: http://mikrokontroler.pl/content/termome...-w-arduino


------------------------------------------------------------------------------------------------------------------------------------
Edycja 2016-06-29
Witam, zmieniłem, uprościłem Kod, ale najważniejsze że działa.

Kod:
#include <Wire.h>
#include <Adafruit_MLX90614.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(23, 24, 25, 26, 27, 28);

Adafruit_MLX90614 mlx_1 = Adafruit_MLX90614(); // default address is 0x5A
Adafruit_MLX90614 mlx_2 = Adafruit_MLX90614(0x50);
//Adafruit_MLX90614 mlx_3 = Adafruit_MLX90614(0x5C); 

void setup() {
  lcd.begin(20, 4); // Inicjalizacja wyświetlacz
  Serial.begin(115200);

  Serial.println("Adafruit MLX90614 test");  

  mlx_1.begin();
  mlx_2.begin();  
}

void loop() {
  Serial.print("Ambient1 = "); Serial.print(mlx_1.readAmbientTempC()); 
  Serial.print("*C\tObject1 = "); Serial.print(mlx_1.readObjectTempC()); Serial.println("*C");
  Serial.print("Ambient2 = "); Serial.print(mlx_2.readAmbientTempC()); 
  Serial.print("*C\tObject2 = "); Serial.print(mlx_2.readObjectTempC()); Serial.println("*C");

  Serial.println();
  delay(200);

  lcd.setCursor(0,0);        // Wyświetlenie (pierwsza linia LCD)
  lcd.print("Tobj1 = ");
  lcd.print(mlx_1.readObjectTempC());
  lcd.print(" ");
  lcd.write(0xDF);            // Znak stopnia
  lcd.print("C  H");
 delay(200);
   
   
  lcd.setCursor(0,1); // Wyświetlenie (druga linia LCD)
  lcd.print("Tsns1 = ");
  lcd.print(mlx_1.readAmbientTempC());
  lcd.print(" ");
  lcd.write(0xDF);
  lcd.print("C  O");   
  delay(200);         // Opóźnienie 200 mS

  
  lcd.setCursor(0,2);  // Wyświetlenie (trzecia linia LCD)
  lcd.print("Tobj2 = ");
  lcd.print(mlx_2.readObjectTempC());
  lcd.print(" ");
  lcd.write(0xDF);               // Znak stopnia celciusa
  lcd.print("C  M");
  delay(200);          // Opóźnienie 200 mS     
  

  lcd.setCursor(0,3); // Wyświetlenie (czwarta linia LCD)
  lcd.print("Tsns2 = ");
  lcd.print(mlx_2.readAmbientTempC());
  lcd.print(" ");
  lcd.write(0xDF);
  lcd.print("C  E");   
  delay(200);         // Opóźnienie 200 mS

}
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości