Wärmebildkamera mit dem MLX90640 und Arduino Due bzw. ESP32

Für Basteleien, Messgeräte und physikalische Experimente.

Moderatoren: MaxZ, ebastler, SeriousD

Benutzeravatar

Thread-Ersteller
stoppi
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

Beitrag von stoppi »

Schönen Tag noch...
Zuletzt geändert von stoppi am Mi 10. Feb 2021, 09:58, insgesamt 2-mal geändert.
Benutzeravatar

Thread-Ersteller
stoppi
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

Beitrag von stoppi »

Schönen Tag noch...
Zuletzt geändert von stoppi am Mi 10. Feb 2021, 09:58, insgesamt 1-mal geändert.
Benutzeravatar

gamerpaddy
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

Beitrag von gamerpaddy »

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

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.
:wurst:
Benutzeravatar

Thread-Ersteller
stoppi
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

Beitrag von stoppi »

Schönen Tag noch...
Zuletzt geändert von stoppi am Mi 10. Feb 2021, 09:58, insgesamt 1-mal geändert.
Benutzeravatar

gamerpaddy
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

Beitrag von gamerpaddy »

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.
:wurst:
Benutzeravatar

Thread-Ersteller
stoppi
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

Beitrag von stoppi »

Schönen Tag noch...
Zuletzt geändert von stoppi am Mi 10. Feb 2021, 09:59, insgesamt 1-mal geändert.
Benutzeravatar

gamerpaddy
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

Beitrag von gamerpaddy »

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

Code: Alles auswählen

Serial.print(Serial1.read(),HEX); 
Serial.print(" ");
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.

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;
  }
 }
}
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.
:wurst:
Benutzeravatar

Thread-Ersteller
stoppi
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

Beitrag von stoppi »

Schönen Tag noch...
Zuletzt geändert von stoppi am Mi 10. Feb 2021, 09:59, insgesamt 2-mal geändert.
Benutzeravatar

Heisath
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

Beitrag von Heisath »

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.

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;
}
Benutzeravatar

Thread-Ersteller
stoppi
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

Beitrag von stoppi »

Schönen Tag noch...
Zuletzt geändert von stoppi am Mi 10. Feb 2021, 09:59, insgesamt 1-mal geändert.
Benutzeravatar

Thread-Ersteller
stoppi
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

Beitrag von stoppi »

Schönen Tag noch...
Zuletzt geändert von stoppi am Mi 10. Feb 2021, 09:59, insgesamt 1-mal geändert.
Benutzeravatar

Heisath
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

Beitrag von Heisath »

Kannst du nochmal den kompletten Code und Schaltung (also vor allem welcher Serielle für was ist) schicken?
Benutzeravatar

VDX
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

Beitrag von VDX »

... manchmal kann es auch sowas banales sein, wie Rx/Tx tauschen ...

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
Benutzeravatar

Thread-Ersteller
stoppi
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

Beitrag von stoppi »

Schönen Tag noch...
Zuletzt geändert von stoppi am Mi 10. Feb 2021, 10:00, insgesamt 1-mal geändert.
Benutzeravatar

Heisath
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

Beitrag von Heisath »

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,
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.
demnach wäre deine Baudrate falsch eingestellt. Evtl damit mal ein wenig experimentieren. Wenn du die falsche Baudrate drin hast,
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;
}
Antworten