soll der Pixelmatsch schon das Wärmebild sein? Da scheint eher etwas mit
dem einlesen nicht zu klappen als mit der Farbpalette.
Für einen Omron Sensor habe ich mir eine C++ Klasse für eine Farbpalette
gebaut. Es können Farben als Stützpunkte eingefügt werden und dazwischen
wird interpoliert, so können verschiedene Farbverläufe realisiert
werden. Der RGB565 Werte wird berechnet, als Optimierung könnte man noch
eine Tabelle vorberechnen lassen. Ich habe das auf einem STM32F407
laufen, der ist so schnell das eine Tabelle nicht nötig war. Das TFT für
Board ist allerdings nicht besonders gut, die Farben sind extrem
blickwinkelabhängig.
Im Anhang ist meine C++ Klasse und wird so benutzt:
1
// create palette
2
ColorPalette cpRainbow;
3
cpRainbow.addItem( 0.0f, 0, 0, 255); // 0 % blue
4
cpRainbow.addItem( 33.0f, 0, 255, 0); // 33 % green
Christoph E. schrieb:> Das Wärmebild besteht noch aus reinen Zufallstemperaturen [random(180)],> da ich ja den Sensor noch nicht habe.
ok, das war durch 'Farben werden aber durch die Kamera nach wie vor
nicht 1:1 wiedergegeben...' etwas missverständlich.
Im Anhang ein Bild wie das auf minem Display aussieht. Der Balken gibt
den Farbverlauf von 0..max wieder.
So, der Sensor ist gestern angekommen. Leider bringe ich ihn am Arduino
Due nicht zum Laufen. Ich erhalte anstelle der Temperaturen nur den
"Wert" nan
Habe mich im Internet nach einer Lösung umgesehen, aber mit einem Due
hat scheinbar noch keiner den MLX90640 erfolgreich betrieben...
Habe schon so einiges versucht. Den PS-pin an/nicht an GND usw.
Betreiben tue ich das Board an 5V, da es einen 3.3V-Spannungswandler
integriert hat. Die SDA/SCL-Leitungen verfügen über je einen 2.2kOhm
pull-up Widerstand.
Eine Frage an die Spezialisten: Mein Board verfügt neben der SDA/SCL
Schnittstelle auch noch über RX/TX-pins. Das Board verfügt bereits über
einen eigenen microcontroller, der dann die 768 Temperaturen ausgibt. Im
Netz findet man ein Programm, welches die Daten dann gleich graphisch
ausgibt. Hat jemand vielleicht eine Idee, wie ich diese Daten mit dem
Arduino Due an den RX/TX pins abgreifen und auslesen kann?
Wenn das alles nicht weiterführt, werde ich mir wohl einen empfohlenen
Teensy besorgen müssen. Nur kann ich mit einem Teensy auch so einfach
wie mit dem Arduino Due ein 320x480 display anschließen?
Link zum Sensor:
https://www.aliexpress.com/snapshot/0.html?spm=a2g0s.9042647.6.2.77b74c4dxkdXfJ&orderId=97282295260631&productId=32958277975
sparkfun-Seite mit einem anderen board nur mit SDA/SCL:
https://learn.sparkfun.com/tutorials/qwiic-ir-array-mlx90640-hookup-guide/all
Verwendete Software:
https://github.com/sparkfun/SparkFun_MLX90640_Arduino_Example/tree/master/Firmware/Example1_BasicReadings
Danke im voraus für eure Hilfe...
So, ich habe inzwischen aus China Software für PC und Arduino erhalten
(siehe code). Verwende wie gesagt einen Arduino Due. RX/TX vom Sensor
habe ich mit TX1/RX1 vom Due verbunden. Problem ist, es tut sich im
seriellen Monitor überhaupt nichts. TX vom MLX90640 sendet aber Signale
(siehe Abbildung).
Da ich mit Kommunikationscode alles andere als fit bin, vielleicht hätte
einer von den Profis für mich einen Tipp was ich noch versuchen könnte.
Danke im voraus...
P.S.: Die Zeilen mit Serial1 und Serial2 sind nicht original aus China,
da hat sich der Compiler aber immer aufgeregt...
P.P.S: Bei GYSerial.available()> 0 kommt scheinbar gar nichts an...
1
//GY_mlx90640 ARDUINO
2
3
// GY_mlx90640 arduino pro mini
4
/*
5
1.GY_mlx90640_uart arduino
6
2.GY_mlx90640 VCC GND
7
3.arduino_TX---GY_mlx90640_RX Rest arduino
8
4.arduino__RX---GY_mlx90640_TX
9
5.GYSerial,baud=9600
10
6.arduino_pin_11---FT232_RX
11
7.arduino_pin_10---FT232_TX
12
8.PCSerial ,baud=115200
13
*/
14
15
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
16
// Ändere hier, welcher Hardware Serial für was verwendet wird.
Hallo Christoph,
vor einiger Zeit habe ich auch mit dem Sensor und einem ESP32 herum
probiert.
Es ging ewig lange nichts und ich habe schon geglaubt, es liegt am
Sensor.
Dann habe ich einen zweiten bekommen, da ging auch nichts.
Irgendwann hatte ich aber ein Lösung gefunden: Der Sensor hat ein EEPROM
eingebaut und es ist vermutlich so, dass die meiste Open-Source-Software
nur mit den vor eingestellten Werten funktioniert ( ich weiß nicht mehr,
ob es Adafruit war, die den Sensor mit vor eingestellten Werten
ausliefern ). Die anderen gehen dann nicht mit der Software.
Ich habe die dann rein geschrieben, und siehe da, beide Sensoren gingen.
Leider weiß ich schon nicht mehr, welche es waren.
Hallo Cornelius!
Vielen Dank für deinen interessanten Hinweis. Ich habe meinen Sensor
über aliexpress gekauft und er hat bereits einen microcontroller an
Bord, der per serieller Schnittstelle (Tx/Rx) eben die 768 Temperaturen
ausgibt. Die reinen Sensoren von Sparkfun etc. haben den nicht und daher
kommunizieren diese direkt mit dem Sensor über den I2C-Bus (SCL,SDA)...
Oben im Programm habe ich nun PCSerial mit Serial definiert. So kann ich
zumindest das array Re_buf[Counter] auslesen. Die Werte sind aber auch
nicht nachvollziehbar...
Das hier sind die Werte ab Adresse 0x8000, mit dem der Sensor geht.
Vielleicht hilft Dir das weiter:
// Sparkfun sensor
Device found @ 0x33
0: 9
1: AB
2: 499B
3: 0
4: 2061
5: 5
6: 320
7: 3E0
8: 1A26
9: A228
10: 185
11: 499
12: 0
13: 1901
14: 0
15: 0
Vielen Dank Cornelius für deine Hilfe!
Habe nun das Programm so weit wie möglich entschlackt. Ich erhalte jetzt
mit Baud = 115200 im 32x24-Raster auch zum Teil recht plausible Werte
(Zimmertemperaturen um die 21°C bzw. Handtemperatur um die 35°C), aber
auch etliche nicht nachvollziehbare Temperaturen über 100-400°C.
Vielleicht hat ja jemand von euch noch einen Tipp für mich...
Auf dem Oszibild oben sehe ich eine UART-Datenstrom mit 115.200 kBaud,
8N1. Ich tippe auf ein Problem mit dem Stoppbit. Da es nur eines ist,
könnte das Probleme mit der Synchronisation über einen so langen
Datenstrom geben.
Schau dir mal den Wikieintrag zu Baudratenquarz an.
Danke Elias für deinen Hinweis. Das klingt dann aber nach unlösbaren
Problem oder? Denn die Länge bzw. Aufteilung des Datenstroms kann ich ja
so nicht beeinflussen.
Deine Vermutung mit timing-Problemen würde sich mit der Beobachtung
decken, dass zumindest zu Beginn der Übertragung die Temperaturen
stimmen und erst nach einer Zeit durch einen Zeitdrift falsche Werte
eingelesen werden...
Christoph E. schrieb:> Würde es ggf. Sinn machen die baudrate z.B. auf 9600 zu senken um mehr> Genauigkeit beim Einlesen der Temperaturen zu bekommen?
Probieren geht über studieren. Könnte klappen Die Übertragung eines
Frames dauert dann aber schon ganz schön lang.
Eine schöne Möglichkeit wäre, wenn du den Controller bei der Camera auf
8N2 (2 Stoppbits) setzen könntest, und den Arduino auf 8N1 Empfang. Das
gibt eine kleine Lücke zur Re-Synchronisation.
Auch gut wäre, wenn beide Seiten passende Quarze haben. Der Controller
an der Kamera nutzt aber wahrscheinlich den internen Taktgenerator, der
idR alles andere als genaue Takte generiert. Also eher nicht
praktikabel...
Lesestoff:
https://www.allaboutcircuits.com/technical-articles/the-uart-baud-rate-clock-how-accurate-does-it-need-to-be/
Evtl. lohnt es auch, den UART auf dem Arduino per Hand zu tunen. Also
die Register im Atmega selbst zu setzen. Dazu findet sich im Atmega
Datenblatt unter Kapitel USART jede Menge Lesestoff.
Vielleicht reicht es auch, wenn du den Takt auf dem Arduino etwas
schneller/langsamer machst. Das könnte durch einen Austausch der
Kondensatoren am Quarz klappen.
Lesestoff:
https://www.all-electronics.de/wp-content/uploads/migrated/article-pdf/113375/174ag0206.pdf
Vielen Dank Elias für die Tipps...
Es geht voran. Habe nun mittels TTL-USB-Adapter die China-PC-Software
ausprobiert und siehe da, ich erhalte ein Bild.
Problem ist nur, dass ich im Programm trotz vorhandener Buttons
scheinbar die baud-rate nicht ändern kann. Deshalb schnell in teraterm
die baud-rate von 115200 auf 9600 gesenkt. Und siehe da, ich habe nun
mit dem Arduino-Programm keine falschen Temperaturen mehr.
Schönheitsfehler: Ich erhalte so nur etwa 1 Bild pro Sekunde...
Das eigenartige ist aber nun, dass ich mit teraterm (siehe Abbildung)
die baud-rate nicht mehr z.B. auf 115200 zurücksetzen kann. Mache ich da
irgendetwas falsch?
Gebe die Kommandos laut Abbildung (danke count-doku für den link) ein.
Wie gesagt, bei der ersten Umstellung von 115200 auf 9600 hat es so
geklappt, nur jetzt nicht mehr...
Als nächstes werde ich die 768 Temperaturen in einem array abspeichern
und dann mit dem bereits geschriebenen Programm graphisch ausgeben.
Hallo Christoph,
ein interessantes Thema. Danke dass du uns teilnehmen lässt.
Frage
Es gibt von den MLX90640 zwei Typen, mit BAA und BAB am Ende.
Welchen hast du im Einsatz?
Habe den MLX90640BAB mit 55°x35° Gesichtsfeld...
Schlechte Nachrichten: Der Sensor scheint tot zu sein. Es kommen über TX
keine Signale mehr. Warum dies so ist, weiß ich leider nicht. Sprich ein
Fehler (Überspannung o.ä.) ist mir nicht bewusst.
Werde jetzt versuchen, einen zweiten günstig zu bekommen. Anbei noch das
letzte Bild von mir und Halogenlampe an der Wohnungsdecke...
>Schlechte Nachrichten: Der Sensor scheint tot zu sein. Es kommen über TX>keine Signale mehr.
Gib nicht so schnell auf. Mit dem Arduino-Due kannst Du einen
I2C-Scanner programmieren und dann mal sehen, ob der Sensor noch auf die
Adresse antwortet.
https://playground.arduino.cc/Main/I2cScanner
Vielleicht ist ja nur die Konfiguration des Sensors zerschossen.
Zu früh möchte ich die Flinte eh nicht ins Korn werfen...
Habe mir die Signale nochmals angesehen. Also wie gesagt TX ist tot.
Über I2C kommen aber noch Signale und der I2C-Scanner erkennt den Sensor
an 0x33, was ja auch passen würde.
Das Sparkfun-Programm für den MLX90640, welches auf den I2C zurückgreift
funktioniert zwar nicht, liefert aber diesselben Ergebnisse wie noch vor
wenigen Tagen (siehe Abbildung MLX90640_Arduino_44)
Ich tippe daher auf einen defekten Microcontroller (STM32F103). Was sagt
ihr?
Christoph E. schrieb:> Ich tippe daher auf einen defekten Microcontroller (STM32F103). Was sagt> ihr?
Na also, halb so wild. Ein Microcontroller Ersatz lässt sich doch
schnell und billig beschaffen. Sollte man m.E. sowieso immer i.d.
Schublade liegen haben.
Allerdings sollte auch ein mutmaßlicher Grund da sein, WARUM etwas
kaputt gegangen sein könnte. Von selbst gehen ICs i.d.R. nicht kaput.
Bleib dran. Ich beobachte, es interessiert mich.
und viel Erfolg :-)
>Ich tippe daher auf einen defekten Microcontroller (STM32F103). Was sagt>ihr?
Schwierig zu sagen. Ich könnte mir vorstellen, dass Du die EEPROM
Konfiguration im MLX zerschossen hast und das Sparkfun Programm nur mit
voreingestellten Werten funktioniert.
Was dann hilft: Werte einfach neu rein schreiben. Zur Not kann man sie
auch einfach jedesmal beim Start ins RAM schreiben. So kannst Du
übrigens auch Deinen MC testen: Einfach Werte ins RAM schreiben und
zurück lesen.
So, habe mich nun auf die Suche gemacht, wie ich das EEPROM des Sensors
auslesen und verändern kann.
Bin hier bei einem Programm für den Arduino fündig geworden:
http://forum.arduino.cc/index.php?topic=351494.msg3004267#msg3004267
Ich muss ja laut Cornelius (siehe Beitrag weiter oben) folgende Werte
ins EEPROM ab Adresse 0x8000 schreiben:
// Sparkfun sensor
Device found @ 0x33
0: 9
1: AB
2: 499B
3: 0
4: 2061
5: 5
6: 320
7: 3E0
8: 1A26
9: A228
10: 185
11: 499
12: 0
13: 1901
14: 0
15: 0
Ausgelesen habe ich bei meinem MLX90640 Sensor einmal folgende Werte
(siehe auch Abbildung):
9 172 27039 0 8289 5 800 992 2571 24488 390 1177 0 6657 0
0
Jetzt regt sich das Programm aber beim "Wert" AB usw. auf. Muss ich nun
AB etwa vom hexadezimalen ins dezimale Zahlensystem umwandeln und statt
AB = 10 * 16 + 11 * 1 = 171 ins EEPROM schreiben?
So, habe nun die HEX-Werte in DEZ-Werte umgewandelt und versucht, den
EEPROM-Speicher abzuändern. Er behält aber scheinbar nicht die
geänderten Werte, da noch die alten Werte gelesen werden....
Kann mir da jemand vielleicht helfen? Danke im voraus...
Christoph E. schrieb:> Ich tippe daher auf einen defekten Microcontroller (STM32F103). Was sagt> ihr?
Der STM32 ist der zusätzliche Controller auf der Kameraplatine? Gut
möglich, dass der die Hufe gehoben hat. Vielleicht auch nur irgendein
Problem in der Ansteuerung. Alles in allem aber eine Blackbox, wo man
nicht weiß, was Sache ist. (Oder hast du das Programm, was da drauf
ist?) Deswegen würde ich mich (wie du ja bereits machst) auf I2C
konzentrieren.
Wieso die neuen Werte im Speicher nicht ankommen, kann ich aus dem Code
nicht erkennen. Hast du die Möglichkeit, mit dem Oszi die Übertragung
aufzunehmen? Wenn ja, dann schau dir die Telegramme doch mal an, ob die
passen. Z.B. den ersten Schreibbefehl und das erste gelesene Telegramm.
Hast du im Datenblatt auf Seite 13 gesehen, dass du eine ca. 4s Pause
nach Power On Reset einhalten solltest?
Hast du probiert, die vom I2C zurückgelesenen Werte direkt nach "data =
Wire.read()" auszugeben, um Fehler im Programm auszuschließen?
Was soll die folgende Zeile erreichen? "if ((ptr[j] >> 8) != (buf[j] >>
8))" Wieso schreibst du nicht pauschal alle Werte?
Hast du im Datenblatt gesehen, dass das LSB der Deviceadresse angibt, ob
die folgenden Daten geschrieben oder gelesen werden? (Siehe Bild) Ich
kann in dem Programm nicht erkennen, dass du die Deviceadresse
entsprechend ändern würdest.
>So, habe nun die HEX-Werte in DEZ-Werte umgewandelt und versucht, den>EEPROM-Speicher abzuändern.
Versuche erst mal, nur die Ram-Registerwerte direkt am Anfang des
Programms zu schreiben und zu lesen. Mehr brauchst Du nicht.
Hallo!
Vielen Dank für die Rückmeldung.
@Elias: Programm des MC habe ich leider nicht...
Ist das Ansprechen/Abändern von Speicherzuständen über I²C nicht
softwareseitig standardisiert? Falls nein, und dieser MLX90640-sensor
z.B. ein spezielles/das oben angehängte Ansprechen verlangt, wie müsste
ich dann die Programmzeilen abändern?
@Christoph: RAM ist ja wieder ein ganz eigener Speicherbereich (0x0400
bis 0x07FF). Was fange ich dann mit den Speicherwerten von Cornelius an?
Bin wie gesagt alles andere als der Fachmann auf diesen Gebiet...
Christoph E. schrieb:> Ist das Ansprechen/Abändern von Speicherzuständen über I²C nicht> softwareseitig standardisiert?
Habe nochmal kurz recherchiert. Wahrscheinlich kümmern sich die beiden
Funktionen Wire.beginTransmission() und Wire.requestFrom() um das
besagte Lesen-/Schreiben-Bit. Trotzdem schadet es sicher nicht, sich am
Oszi anzuschauen, ob exakt die Daten übermittelt werden, die du
erwartest.
RAM/ROM: Ich kann nicht ohne weiteres im Datenblatt finden, welche
Speicherbereiche du überhaupt ändern kannst. Also nimm etwas, was du
sicher ändern darfst. Zum Beispiel das Datenwort bei Adresse 0x800D, Bit
7, 8 und 9. Am Anfang reicht es auch, wenn du nur ein Bit ändern kannst.
Das eliminiert viele versteckte Fehlerquellen in Schleifen, Pointern,
... Wenn dir das gelingt, dann kannst du weiterschauen.
>@Christoph: RAM ist ja wieder ein ganz eigener Speicherbereich (0x0400>bis 0x07FF). Was fange ich dann mit den Speicherwerten von Cornelius an?
Die Konfigurationsregister liegen ab 0x8000.
Schau Dir im Datenblatt deren Bedeutung an, und versuche sie zu
verstehen.
Hier wollte ich ursprünglich posten:
Hier gibt es auch ein Problem mit dem Auslesen:
Beitrag "Wer nutzt das Nucleo-64 und kann mir"
Allerding liegt das wohl an einer I2C-Lib. Der wo helfen könnte, wollte
anscheinend nicht...
Damit kann ich z.B. den Speicherwert 1A01 (HEX) an der Stelle 0x800D in
1901 (HEX) umwandeln und wieder retour.
Mit anderen Stellen, z.B. 0x8000, funktioniert das nicht. Die sind ja
auch scheinbar für Melexis reserviert...
Warum muss/kann ich aber die Stelle 0x800D direkt mittels
MLX90640_I2CWrite(0x33, 0x800D, 6401); ansprechen und verändern? Die
Speicheradresse 0x800D ist ja mit 0x240C verknüpft und nur diese lässt
sich doch verändern und dann auf 0x800D übertragen?
Was ist mit den anderen Speicherwerten von Cornelius ab 0x8000? Die kann
ich wohl nicht ändern oder?
Die Veränderung in 1901 der Stelle 0x800D hat übrigens leider keine
Auswirkungen auf das Auslesen der Temperaturen. Erhalte nach wie vor
"nan"
Danke im voraus für eure Hilfe...
Es gibt Neuigkeiten: Heute ist ein ESP32 angekommen und ich habe
natürlich sofort den Arduino-Code ausprobiert und....
... heureka, der Sensor lebt noch und übermittelt passende Temperaturen.
Damit dies so ist, muss jedoch in der Datei MLX90640_I2C_Driver.cpp zu
Beginn die Zeile #include <Arduino.h> hinzugefügt werden.
Von den 768 Pixel scheint nur ein einziges defekt zu sein, da es die
Temperatur "nan" liefert. Da übernehme ich nach Abfrage aber den
Temperaturwert des Nachbarn.
Jetzt warte ich noch auf das ILI9341 320x240 display, dann biegt dieses
Projekt in die Zielgerade ein.
>Es gibt Neuigkeiten: Heute ist ein ESP32 angekommen und ich habe>natürlich sofort den Arduino-Code ausprobiert und....
Welchen? Den gleichen wie auf dem Due?
Falls nicht, musst Du einfach nur die Stelle im Code finden, in der das
Register richtig beschrieben wird und in den Due-Code kopieren ....
>Nein, ist derselbe Code wie jener, der eben mit dem Arduino Due nicht>funktioniert hat...
Erstaunlich ... an was könnte es liegen: timing, I2C Widerstände?
Heute ist das ILI9341 display angekommen und ich habe die
Wärmebildkamera fertig stellen können. Anbei noch die Verkabelung, die
display-pins, einige Testbilder, der code und das youtube-video:
https://www.youtube.com/watch?v=k6qim96wB4k
const byte MLX90640_address = 0x33; //Default 7-bit unshifted address of the MLX90640
20
21
#define TA_SHIFT 8 //Default shift for MLX90640 in open air
22
23
static float mlx90640To[768];
24
paramsMLX90640 mlx90640;
25
26
int xPos, yPos; // Abtastposition
27
int R_colour, G_colour, B_colour; // RGB-Farbwert
28
int i, j; // Zählvariable
29
float T_max, T_min; // maximale bzw. minimale gemessene Temperatur
30
float T_center; // Temperatur in der Bildschirmmitte
31
32
33
34
35
// ***************************************
36
// **************** SETUP ****************
37
// ***************************************
38
39
void setup()
40
{
41
Serial.begin(115200);
42
43
Wire.begin();
44
Wire.setClock(400000); //Increase I2C clock speed to 400kHz
45
46
while (!Serial); //Wait for user to open terminal
47
48
Serial.println("MLX90640 IR Array Example");
49
50
if (isConnected() == false)
51
{
52
Serial.println("MLX90640 not detected at default I2C address. Please check wiring. Freezing.");
53
while (1);
54
}
55
56
Serial.println("MLX90640 online!");
57
58
//Get device parameters - We only have to do this once
59
int status;
60
uint16_t eeMLX90640[832];
61
62
status = MLX90640_DumpEE(MLX90640_address, eeMLX90640);
63
64
if (status != 0)
65
Serial.println("Failed to load system parameters");
66
67
status = MLX90640_ExtractParameters(eeMLX90640, &mlx90640);
68
69
if (status != 0)
70
{
71
Serial.println("Parameter extraction failed");
72
Serial.print(" status = ");
73
Serial.println(status);
74
}
75
76
//Once params are extracted, we can release eeMLX90640 array
77
78
MLX90640_I2CWrite(0x33, 0x800D, 6401); // Schreibt den Wert 1901 (HEX) = 6401 (DEC) ins Register an die Stelle 0x800D, damit der Sensor ausgelesen werden kann!!!
Ich weiß der Thread ist älter, habe jedoch eine kurze Frage zu den MLX
Sensoren.
Muss man Pullup Widerstände auf die SDA- und SCL-Leitungen hinzufügen
wenn man den Sensor ohne fertiges Breakout-Board kauft? Sprich, den
Sensor wie im letzten Kauflink von as-electronic. Du hast ja von
Aliexpress das blaue Breakout-Board benutzt (ich vermute, dass da
nämlich Pullups drauf sind).
LG