Wärmebildkamera mit dem MLX90640 und Arduino Due bzw. ESP32
Moderatoren: MaxZ, ebastler, SeriousD
-
- Beiträge: 1475
- Registriert: Mo 29. Mär 2010, 21:39
- Danksagung erhalten: 289 Mal
- Kontaktdaten:
Wärmebildkamera mit dem MLX90640 und Arduino Due bzw. ESP32
Schönen Tag noch...
Zuletzt geändert von stoppi am Mi 10. Feb 2021, 09:58, insgesamt 2-mal geändert.
-
- Beiträge: 1475
- Registriert: Mo 29. Mär 2010, 21:39
- Danksagung erhalten: 289 Mal
- Kontaktdaten:
Re: Wärmebildkamera mit dem MLX90640 und Arduino Due
Schönen Tag noch...
Zuletzt geändert von stoppi am Mi 10. Feb 2021, 09:58, insgesamt 1-mal geändert.
-
- Beiträge: 2743
- Registriert: Mo 13. Aug 2012, 09:03
- Spezialgebiet: Spezialgebiet
- Schule/Uni/Arbeit: Schule/Uni/Arbeit
- Wohnort: Mannheim
- Hat sich bedankt: 38 Mal
- Danksagung erhalten: 329 Mal
- Kontaktdaten:
Re: Wärmebildkamera mit dem MLX90640 und Arduino Due
Der MLX sensor an sich ist nur per i2c ansprechbar, aber auch nur wenn PS auf Masse liegt oder SET zugelötet wird.
Sonst arbeitet der Mikrocontroller der im prinzip die i2c signale in 115200 BAUD Serielle daten umwandelt und raushaut.
Der i2c port ist dabei nicht benutzbar.
Warum bei dir nur Nan ankommt müsste man in der Library nachschauen, ist diese überhaupt mit dem Due kompatibel? Einen Logikanalyzer an den i2c pins während dem Betrieb wäre hilfreich.
Solch billige CY7C68013A basierte LA's mit Saleae Logic Software sind für sowas recht praktisch.
Nachdem was ich gelesen habe (ich habe das modul nicht selbst) gibt der Serielle port 768 werte pro frame aus welche den pixeln entsprechen. ggf. mit temperatur und emissivität-kompensation
Du kannst im Due einen der anderen Hardware-Seriellports einschalten via Serial1.begin(.. Serial2.begin(.. im setup.
Dann verbindest du TX an RX mit Serial1 und dem MLX modul. (TX an RX, und andersherum)
Dann musst du im Arduino noch durchschleifen mittels
Wenn man es nicht mittels Serial port (hauptport zum pc) weiterleiten will, kann man die eingaben auch zwischenspeichern und verarbeiten oder direkt zu einem Display senden.
Der Due hat 96kb RAM, da sollte man die 768 Pixel zwischenspeichern können für evtl. transformationen.
Sonst arbeitet der Mikrocontroller der im prinzip die i2c signale in 115200 BAUD Serielle daten umwandelt und raushaut.
Der i2c port ist dabei nicht benutzbar.
Warum bei dir nur Nan ankommt müsste man in der Library nachschauen, ist diese überhaupt mit dem Due kompatibel? Einen Logikanalyzer an den i2c pins während dem Betrieb wäre hilfreich.
Solch billige CY7C68013A basierte LA's mit Saleae Logic Software sind für sowas recht praktisch.
Nachdem was ich gelesen habe (ich habe das modul nicht selbst) gibt der Serielle port 768 werte pro frame aus welche den pixeln entsprechen. ggf. mit temperatur und emissivität-kompensation
Du kannst im Due einen der anderen Hardware-Seriellports einschalten via Serial1.begin(.. Serial2.begin(.. im setup.
Dann verbindest du TX an RX mit Serial1 und dem MLX modul. (TX an RX, und andersherum)
Dann musst du im Arduino noch durchschleifen mittels
Code: Alles auswählen
const unsigned int BAUD = 115200; // baudrate des MLX moduls.
//man kann zwei verschiedene baudraten nehmen aber wenn einer schneller sendet als der andere weiterleiten kann muss man buffern = blöd
void setup(){
Serial.begin(BAUD)
Serial1.begin(BAUD)
}
void loop(){
if(Serial1.available()){
Serial.write(Serial1.read());
}
if(Serial.available()){
Serial1.wrie(Serial.read());
}
}
Wenn man es nicht mittels Serial port (hauptport zum pc) weiterleiten will, kann man die eingaben auch zwischenspeichern und verarbeiten oder direkt zu einem Display senden.
Der Due hat 96kb RAM, da sollte man die 768 Pixel zwischenspeichern können für evtl. transformationen.
-
- Beiträge: 1475
- Registriert: Mo 29. Mär 2010, 21:39
- Danksagung erhalten: 289 Mal
- Kontaktdaten:
Re: Wärmebildkamera mit dem MLX90640 und Arduino Due
Schönen Tag noch...
Zuletzt geändert von stoppi am Mi 10. Feb 2021, 09:58, insgesamt 1-mal geändert.
-
- Beiträge: 2743
- Registriert: Mo 13. Aug 2012, 09:03
- Spezialgebiet: Spezialgebiet
- Schule/Uni/Arbeit: Schule/Uni/Arbeit
- Wohnort: Mannheim
- Hat sich bedankt: 38 Mal
- Danksagung erhalten: 329 Mal
- Kontaktdaten:
Re: Wärmebildkamera mit dem MLX90640 und Arduino Due
Die daten werden wohl in Hex übertragen, das spart Bandbreite.
Ein byte geht von 0 bis 255, zwei byte zahlen gehen von 0 bis 255^2. Eine typische methode ist es ein Long zu übertragen, sprich 4 bytes (0 bis 255^4, wenn unsigned/ohne minus zeichen).
Wie genau das aufgebaut ist, weiß ich nicht. Versuch mal statt Serial.write, Serial.print(Serial1.read(),HEX) zu machen, dann erkennt man womöglich ein muster.
Nan bedeutet "Not a number", das passiert oft wenn man durch 0 teilt.
Ein byte geht von 0 bis 255, zwei byte zahlen gehen von 0 bis 255^2. Eine typische methode ist es ein Long zu übertragen, sprich 4 bytes (0 bis 255^4, wenn unsigned/ohne minus zeichen).
Wie genau das aufgebaut ist, weiß ich nicht. Versuch mal statt Serial.write, Serial.print(Serial1.read(),HEX) zu machen, dann erkennt man womöglich ein muster.
Nan bedeutet "Not a number", das passiert oft wenn man durch 0 teilt.
-
- Beiträge: 1475
- Registriert: Mo 29. Mär 2010, 21:39
- Danksagung erhalten: 289 Mal
- Kontaktdaten:
Re: Wärmebildkamera mit dem MLX90640 und Arduino Due
Schönen Tag noch...
Zuletzt geändert von stoppi am Mi 10. Feb 2021, 09:59, insgesamt 1-mal geändert.
-
- Beiträge: 2743
- Registriert: Mo 13. Aug 2012, 09:03
- Spezialgebiet: Spezialgebiet
- Schule/Uni/Arbeit: Schule/Uni/Arbeit
- Wohnort: Mannheim
- Hat sich bedankt: 38 Mal
- Danksagung erhalten: 329 Mal
- Kontaktdaten:
Re: Wärmebildkamera mit dem MLX90640 und Arduino Due
sieht mir nach je 2 bytes aus.
0E 20 = 3616 = 36.16°C, 0F 20 = 3872 = 38.72°
am anfang jedes frames oder am anfang jeder zeile müsste eine art bytefolge sein damit das programm weiß wann es synchronisieren soll. in deinem terminal könnte es 5A 5A...... sein
statt screenshots zu machen, poste doch einfach den text aus dem Terminal.
und ändere mal den code in ab, dann erkennt man die hex werte besser.
vielleicht alle 8...16...32..128 bytes ein println(); machen damit nicht alles hintereinander ist.
so zb.
Es kann sein dass das programm dem MCU auf dem MLX modul vorher mitteilt in welcher einheit es die daten senden soll, bevor brauchbare daten kommen
Halte mal ein stück Folie oder etwas das eine gleichbleibende temperatur hat vor den sensor, so das alle pixel den selben wert haben. da kann man die "synchronisierung" bestimmt besser erkennen.
0E 20 = 3616 = 36.16°C, 0F 20 = 3872 = 38.72°
am anfang jedes frames oder am anfang jeder zeile müsste eine art bytefolge sein damit das programm weiß wann es synchronisieren soll. in deinem terminal könnte es 5A 5A...... sein
statt screenshots zu machen, poste doch einfach den text aus dem Terminal.
und ändere mal den code in
Code: Alles auswählen
Serial.print(Serial1.read(),HEX);
Serial.print(" ");
vielleicht alle 8...16...32..128 bytes ein println(); machen damit nicht alles hintereinander ist.
so zb.
Code: Alles auswählen
byte ctr = 0;
void loop(){
if(Serial1.available()){
Serial.print(Serial1.read(),HEX);
Serial.print(" ");
ctr = ctr +1;
if(ctr == 128)
{
Serial.println();
ctr=0;
}
}
}
Halte mal ein stück Folie oder etwas das eine gleichbleibende temperatur hat vor den sensor, so das alle pixel den selben wert haben. da kann man die "synchronisierung" bestimmt besser erkennen.
-
- Beiträge: 1475
- Registriert: Mo 29. Mär 2010, 21:39
- Danksagung erhalten: 289 Mal
- Kontaktdaten:
Re: Wärmebildkamera mit dem MLX90640 und Arduino Due
Schönen Tag noch...
Zuletzt geändert von stoppi am Mi 10. Feb 2021, 09:59, insgesamt 2-mal geändert.
-
- Beiträge: 539
- Registriert: Mi 26. Jun 2013, 15:44
- Hat sich bedankt: 33 Mal
- Danksagung erhalten: 81 Mal
- Kontaktdaten:
Re: Wärmebildkamera mit dem MLX90640 und Arduino Due
Kannst du nicht einfach einen der anderen Serial Ports nehmen?
Die SoftwareSerial ist ja einfach nur dafür da, an beliebigen Pins einen seriellen Port zu benutzten - der Due hat ja aber eh schon 3(?).
Ändere einfach mal das mySerial in einen deiner Hardware Serial Ports (Serial1-3) und versuchs damit.
Dann kann natürlich oben die Deklaration und das Include wegfallen.
Die Hardware Serial Ports sind eh performanter.
lg,
count-doku
EDIT:
Habe nochmal den Code angehangen. Habe im Prinzip nur #define's für die beiden seriellen Ports gemacht - so kannst du schnell einstellen welcher welcher ist.
Die SoftwareSerial ist ja einfach nur dafür da, an beliebigen Pins einen seriellen Port zu benutzten - der Due hat ja aber eh schon 3(?).
Ändere einfach mal das mySerial in einen deiner Hardware Serial Ports (Serial1-3) und versuchs damit.
Dann kann natürlich oben die Deklaration und das Include wegfallen.
Die Hardware Serial Ports sind eh performanter.
lg,
count-doku
EDIT:
Habe nochmal den Code angehangen. Habe im Prinzip nur #define's für die beiden seriellen Ports gemacht - so kannst du schnell einstellen welcher welcher ist.
Code: Alles auswählen
//GY_mlx90640 ARDUINO 测试代码 串口显示
// GY_mlx90640 arduino pro mini
/*
使用步骤:
1.先下载GY_mlx90640_uart程序至arduino
2.再接上GY_mlx90640 VCC GND
3.arduino_TX---GY_mlx90640_RX Rest arduino
4.arduino__RX---GY_mlx90640_TX
5.GYSerial,baud=9600
6.arduino_pin_11---FT232_RX
7.arduino_pin_10---FT232_TX
8.PCSerial ,baud=115200
*/
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Ändere hier, welcher Hardware Serial für was verwendet wird.
#define PCSerial Serial1
#define GYSerial Serial2
uint16_t temp1=0;
int16_t temp2=0;
uint8_t Re_buf[10];
uint16_t re_count=0,rest_count=0;
uint16_t counter=0;
unsigned char sign=0;
int led = 13;
float myMap(float x, float in_min, float in_max, float out_min, float out_max);
float max_temp=0;
float min_temp=500;
//-----------------------------------------------------------
void setup()
{
GYSerial.begin(9600);
PCSerial.begin(115200);
delay(1000);
}
//-------------------------------------------------------------
void loop(){
if (GYSerial.available()>0)
{
Re_buf[counter]=(unsigned char)GYSerial.read();
if(counter==0&&Re_buf[0]!=0x5A) return; // 检查帧头
else if(counter==1&&Re_buf[1]!=0x5A)
{
counter=0;
return;
}; // 检查帧头
if(counter<6)
counter++;
if(counter==4) //接收到数据
{
if(Re_buf[2]==0x02&&Re_buf[3]==0x06)
sign=1;
else
counter=0;
}
if(counter>5)
{
float temp=(float)(Re_buf[4]+Re_buf[5]*256)/100;
if(temp>max_temp)
max_temp=temp;
if(temp<min_temp)
min_temp=temp;
counter=4;
re_count++;
if(rest_count>20)
{
min_temp=500;
max_temp=0;
rest_count=0;
}
//PCSerial.print(temp);
// PCSerial.print(",");
float inv= myMap(temp,min_temp,max_temp,0.5,1);
if(inv>0.75)
PCSerial.print("**");
else
PCSerial.print("--");
if((re_count%32)==0)
PCSerial.println();
if(re_count%768==0)
PCSerial.print("TA:");
if(re_count==769)
{
rest_count++;
counter=0;
PCSerial.print(temp);
PCSerial.println();
re_count=0;
}
}
}
}
//---------------------------------------------------------------
float myMap(float x, float in_min, float in_max, float out_min, float out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
-
- Beiträge: 1475
- Registriert: Mo 29. Mär 2010, 21:39
- Danksagung erhalten: 289 Mal
- Kontaktdaten:
Re: Wärmebildkamera mit dem MLX90640 und Arduino Due
Schönen Tag noch...
Zuletzt geändert von stoppi am Mi 10. Feb 2021, 09:59, insgesamt 1-mal geändert.
-
- Beiträge: 1475
- Registriert: Mo 29. Mär 2010, 21:39
- Danksagung erhalten: 289 Mal
- Kontaktdaten:
Re: Wärmebildkamera mit dem MLX90640 und Arduino Due
Schönen Tag noch...
Zuletzt geändert von stoppi am Mi 10. Feb 2021, 09:59, insgesamt 1-mal geändert.
-
- Beiträge: 539
- Registriert: Mi 26. Jun 2013, 15:44
- Hat sich bedankt: 33 Mal
- Danksagung erhalten: 81 Mal
- Kontaktdaten:
Re: Wärmebildkamera mit dem MLX90640 und Arduino Due
Kannst du nochmal den kompletten Code und Schaltung (also vor allem welcher Serielle für was ist) schicken?
-
- Beiträge: 2166
- Registriert: Fr 13. Jul 2018, 18:23
- Spezialgebiet: Laser und Mikro-/Nanotechnik
- Hat sich bedankt: 14 Mal
- Danksagung erhalten: 237 Mal
Re: Wärmebildkamera mit dem MLX90640 und Arduino Due
... manchmal kann es auch sowas banales sein, wie Rx/Tx tauschen ...
Viktor
Viktor
Aufruf zum Projekt "Müll-freie Meere" - https://reprap.org/forum/list.php?426 -- Facebook-Gruppe - https://www.facebook.com/groups/383822522290730
Call for the project "garbage-free seas" - https://reprap.org/forum/list.php?425
Call for the project "garbage-free seas" - https://reprap.org/forum/list.php?425
-
- Beiträge: 1475
- Registriert: Mo 29. Mär 2010, 21:39
- Danksagung erhalten: 289 Mal
- Kontaktdaten:
Re: Wärmebildkamera mit dem MLX90640 und Arduino Due
Schönen Tag noch...
Zuletzt geändert von stoppi am Mi 10. Feb 2021, 10:00, insgesamt 1-mal geändert.
-
- Beiträge: 539
- Registriert: Mi 26. Jun 2013, 15:44
- Hat sich bedankt: 33 Mal
- Danksagung erhalten: 81 Mal
- Kontaktdaten:
Re: Wärmebildkamera mit dem MLX90640 und Arduino Due
Hmmh ok, die Verkabelung sieht gut aus.
Ich habe im Code nochmal ein wenig aufgeräumt, Einrückung / Klammern. Außerdem dazugeschrieben was ich denke, was wo passiert.
Wenn du mit deinem Print direkt nach dem Lesen schonmal Daten kriegst, könntest du
a) dir jeweils auch den Wert vom counter ausgeben lassen, und schauen ob die Initialisierungssequenz richtig durchkommt
b) mit weiteren Prints schauen, bis in welchen Zustand er noch kommt ( also jeweils in den Zuständen Prints rein)
Du findest im Code jeweils Kommentare mit //! wo ich Befehle ergänzt habe.
Wenn du dann weißt, wo es klemmt, und was da empfangen wird/werden sollte könnte man weiter überlegen.
EDIT:
Sehe gerade weiter oben,
kommen natürlich auch die falschen Werte an.
Ich habe im Code nochmal ein wenig aufgeräumt, Einrückung / Klammern. Außerdem dazugeschrieben was ich denke, was wo passiert.
Wenn du mit deinem Print direkt nach dem Lesen schonmal Daten kriegst, könntest du
a) dir jeweils auch den Wert vom counter ausgeben lassen, und schauen ob die Initialisierungssequenz richtig durchkommt
b) mit weiteren Prints schauen, bis in welchen Zustand er noch kommt ( also jeweils in den Zuständen Prints rein)
Du findest im Code jeweils Kommentare mit //! wo ich Befehle ergänzt habe.
Wenn du dann weißt, wo es klemmt, und was da empfangen wird/werden sollte könnte man weiter überlegen.
EDIT:
Sehe gerade weiter oben,
demnach wäre deine Baudrate falsch eingestellt. Evtl damit mal ein wenig experimentieren. Wenn du die falsche Baudrate drin hast,gamerpaddy hat geschrieben:Der MLX sensor an sich ist nur per i2c ansprechbar, aber auch nur wenn PS auf Masse liegt oder SET zugelötet wird.
Sonst arbeitet der Mikrocontroller der im prinzip die i2c signale in 115200 BAUD Serielle daten umwandelt und raushaut.
Der i2c port ist dabei nicht benutzbar.
kommen natürlich auch die falschen Werte an.
Code: Alles auswählen
//GY_mlx90640 ARDUINO
// GY_mlx90640 arduino pro mini
/*
1.先下载GY_mlx90640_uart程序至arduino
2.再接上GY_mlx90640 VCC GND
3.arduino_TX---GY_mlx90640_RX Rest arduino
4.arduino__RX---GY_mlx90640_TX
5.GYSerial,baud=9600
6.arduino_pin_11---FT232_RX
7.arduino_pin_10---FT232_TX
8.PCSerial ,baud=115200
*/
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Ändere hier, welcher Hardware Serial für was verwendet wird.
#define PCSerial Serial
#define GYSerial Serial1
uint8_t Re_buf[10];
uint16_t re_count = 0, rest_count = 0;
uint16_t counter = 0;
unsigned char sign = 0;
int led = 13;
float myMap(float x, float in_min, float in_max, float out_min, float out_max);
float max_temp = 0;
float min_temp = 500;
//-----------------------------------------------------------
void setup()
{
GYSerial.begin(9600); //! HIER EVENTUELL MAL ANDERE WERTE PROBIEREN
PCSerial.begin(115200);
delay(1000);
}
//-------------------------------------------------------------
void loop() {
if (GYSerial.available() > 0)
{
Re_buf[counter] = (uint8_t)GYSerial.read();
//! Debugging prints hinzugefügt
PCSerial.print(counter);
PCSerial.print(" : ");
PCSerial.println(Re_buf[counter], HEX);
if (counter == 0 && Re_buf[0] != 0x5A) { //! Anfangsmarkierung mit 0x5A an Position 0
return;
}
else if (counter == 1 && Re_buf[1] != 0x5A) //! Markierung des 2. Bytes, ebenfalls 0x5A
{
counter = 0;
return;
}
//! Debugging prints hinzugefügt
PCSerial.println("*** Frame begin marker ok!");
if (counter < 6)
{
counter++;
}
// sind wir beim fünften byte, müssen das 3. und 4. 0x02 und 0x06 sein, ansonsten zurücksetzen
if (counter == 4)
{
if (Re_buf[2] == 0x02 && Re_buf[3] == 0x06)
{
sign = 1;
//! Debugging prints hinzugefügt
PCSerial.println("*** Sign ok!");
}
else
{
counter = 0;
}
}
// wurden die >6 Byte empfangen, sind das 5. und 6. Byte zusammen die Temperatur
if (counter > 5)
{
float temp = (float)(Re_buf[4] + Re_buf[5] * 256) / 100;
if (temp > max_temp)
max_temp = temp;
if (temp < min_temp)
min_temp = temp;
//! Debugging prints hinzugefügt
PCSerial.print("*** Got temperature:");
PCSerial.println(temp);
counter = 4;
re_count++;
if (rest_count > 20)
{
min_temp = 500;
max_temp = 0;
rest_count = 0;
}
PCSerial.print(temp);
PCSerial.print(",");
float inv = myMap(temp, min_temp, max_temp, 0.5, 1);
if (inv > 0.75)
PCSerial.print("**");
else
PCSerial.print("--");
if ((re_count % 32) == 0)
PCSerial.println();
if (re_count % 768 == 0)
PCSerial.print("TA:");
if (re_count == 769)
{
rest_count++;
counter = 0;
PCSerial.print(temp);
PCSerial.println();
re_count = 0;
}
}
}
}
//---------------------------------------------------------------
float myMap(float x, float in_min, float in_max, float out_min, float out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}