In diesem Projekt möchte ich ein Liniendiagramm mit Temperaturwerten auf dem 1,3″ OLED Display zeichnen.

Die Daten für das Diagramm werden von einem analogen Temperatursensor LM35DZ gelesen.
Teileliste
Für dieses Projekt wird benötigt:
- 1x Arduino UNO*,
- 1x 1,3″ OLED Display*,
- 1x analoger Temperatursensor LM35DZ*,
- Breadboardkabel*, männlich – männlich
- Breadboard*, min. 400 Pin
Hinweis von mir: Die mit einem Sternchen (*) markierten Links sind Affiliate-Links. Wenn du über diese Links einkaufst, erhalte ich eine kleine Provision, die dazu beiträgt, diesen Blog zu unterstützen. Der Preis für dich bleibt dabei unverändert. Vielen Dank für deine Unterstützung!
Aufbau & Schaltung
Zunächst wollen wir die Schaltung aufbauen. Durch die überschaubare Teileliste ist dieser schnell erledigt.
Bauelement / Pin | Arduino UNO |
---|---|
1,3″ OLED Display | |
SDA | SDA bzw. analoger Pin A4 |
SCL | SCL bzw. analoger Pin A5 |
VCC | 3,3 V |
GND | GND |
LM35D | |
GND | GND |
Vout | analoger Pin A0 |
+Vs | 5V |
Aufbau des Temperatursensors LM35DZ
Der analoge Temperatursensor LM35DZ verfügt über 3 Pins. Um die korrekte Einbauweise zu ermitteln, gibt es zwei Indikatoren. Das Bauelement ist abgeflacht und hat eine runde Auswölbung und auf der abgeflachten Seite steht die Bezeichnung des Sensors.
Schritt 1 – Grundgerüst des Sketches erstellen
Im ersten Schritt wollen wir das Grundgerüst erstellen. D.h. wir zeichnen das Liniendiagramm und erstellen die Texte für den aktuellen, maximalen sowie minimalen Wert.
#include "U8glib.h" //Bibliothek für das Display #define tempsensor A0 //Temperatursensor LM35DZ am analogen Pin A0 int tempValue = 0; //default Wert für die aktuelle Temperatur int maxValue = 0; //default Wert für die maximale Temperatur int minValue = 160; //default Wert für die minimale Temperatur //Da der LM35DZ eine maximale Temperatur von 150°C messen kann //wird der minimale Wert immer überschrieben. U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE); //erzeugen des Display Objektes void draw(void) { //Setzen der Schriftart & Schriftgröße u8g.setFont(u8g_font_04b_24r); //Position des Cursors zum schreiben setzen u8g.setPrintPos(80, 10); //Schreiben des aktuellen Temperaturwertes u8g.print("current: " + String(tempValue)+"C"); u8g.setPrintPos(80, 20); u8g.print("max: " + String(maxValue)+"C"); u8g.setPrintPos(80, 30); u8g.print("min: " + String(minValue)+"C"); //zeichnen der Linien für das Diagramm u8g.drawLine(5, 5, 5, 60); u8g.drawLine(5, 60, 80, 60); } void setup(void) { //bleibt leer } void loop(void) { //zeichnet die erste Seite u8g.firstPage(); //solange eine neue Seite existiert mache.... do { //Funktion zum zeichnen des Layouts //sowie schreiben der aktuellen Werte //aufrufen. draw(); } while( u8g.nextPage() ); delay(250); //kleine Pause von 250ms. }
Schritt 2 – aufzeichnen der Temperaturwerte
Um die Temperaturwerte auszulesen, müssen wir den Temperatursensor am analogen Pin A0 mit der Funktion analogRead(A0) auslesen.
int value = analogRead(A0);
Der Temperatursensor LM35DZ liefert einen Wert von 0 bis 1,5V am analogen Pin dieses interpretiert der Arduino als Wert von 0 bis 307 (5V == 1023, somit sind 1,5 == 307). Diesen Wert mappen wir nun mit der Funktion map auf die möglichen Temperaturwerte von 0 bis 150 °C.
tempValue = map(tempValue, 0, 307, 0, 150);
Die Funktion map hat 5 Parameter:
map(ausgangsWert, minWert1, maxWert1, minWert2, maxWert2)
- ausgangswert ist der Wert welcher gemappt werden soll,
- minWert1, untere Grenze des Ausgangswertes,
- maxWert1, obere Grenze des Ausgangswertes,
- minWert2, untere Grenze des Zielwertes,
- maxWert2, obere Grenze des Zielwertes
Somit erhalten wir jetzt einen ziemlich genauen Temperaturwert in Grad Celsius. Diese Werte speichern wir uns in ein Array mit maximal 17 Stellen.
//Startwert für die Anzahl der gelesenen Temperaturwerte int valueCounter = -1; //Maximale Werte in dem Array const int MAX_VALUES = 14; //Array zum speichern der Temperaturwerte int values[MAX_VALUES]; //Lesen des Temperaturwertes am analogen Pin A0 tempValue = analogRead(tempsensor); //Mappen des gelesenen Wertes tempValue = map(tempValue, 0, 307, 0, 150); //ermitteln der minimalen Temperatur minValue = min(tempValue, minValue); //ermitteln der maximalen Temperatur maxValue = max(tempValue, maxValue); if(valueCounter > MAX_VALUES){ valueCounter = 0; } valueCounter = valueCounter+1; values[valueCounter] = tempValue;
Schritt 3 – Zeichen der Temperaturwerte
Im vorherigen Schritt haben wir die Temperaturwerte in einem Array gespeichert, nun wollen wir diese auf dem Display zeichnen. Es wird jetzt für jeden Wert aus dem Array ein Kreis (gefüllt) auf dem Display gezeichnet.
Der Wert 0,0 in dem Diagramm liegt an der Position x = 5 y = 60. Wobei der Wert 60 unsere untere Grenze ist. Der Vorteil des Temperatursensor ist das dieser nur positive Temperaturwerte messen kann somit können wir einfach von dem maximalen Wert den Temperaturwert abziehen und haben somit eine X,Y Koordinate.
Zusätzlich zeichnen wir eine Linie zwischen die Verbindungspunkte. Dazu müssen wir uns die alte Koordinate zwischenspeichern.
int x = 5; //Ausgangswert der X Achse int y = 60; //Ausgangswert der Y Achse int yOld = 0; //alter Wert //Für jeden Wert in dem Array mache... for(int i=0;i<=valueCounter;i++){ //lesen des Temperaturwertes im Array, an Position i int value = values[i]; //"berechnen" der Y Koordinate y = START-value; //Zeichnen eines Kreises an der Position, x & y mit dem Durchmesser von 1 //Es wird ein "+" auf dem Display gezeichnet. //Erst ab einem Durchmesser von 2 wird ein Kreis dargestellt. u8g.drawDisc(x, y,1); //Zeichnen einer Linie //Wenn der x Wert größer als 5 ist dann soll von diesem 5 abgezogen //werden ansonsten wird x verwendet. Dieses wird benötigt da im ersten Durchlauf keine alten Werte //existieren. u8g.drawLine(x, y, x>5?x-5:x, yOld); //den Wert X um 5 erhöhen x = x+5; //speichern der alten Y Koordinate für den nächsten Durchlauf. yOld = y; }
Quellcode
Hier nun der gesamte Quellcode (ohne Kommentare).
#include "U8glib.h" #define tempsensor A0 int tempValue = 0; int maxValue = 0; int minValue = 100; U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE); //erzeugen des Display Objektes int x = 5; int y = 60; const int START = 60; int valueCounter = -1; const int MAX_VALUES = 14; int values[MAX_VALUES]; void draw(void) { u8g.setFont(u8g_font_04b_24r); u8g.setPrintPos(80, 10); u8g.print("current: " + String(tempValue)+"°C"); u8g.setPrintPos(80, 20); u8g.print("max: " + String(maxValue)+"°C"); u8g.setPrintPos(80, 30); u8g.print("min: " + String(minValue)+"°C"); u8g.drawLine(5, 5, 5, 60); u8g.drawLine(5, 60, 80, 60); int x = 5; int y = 60; int yOld = 0; for(int i=0;i<=valueCounter;i++){ int value = values[i]; y = START-value; u8g.drawDisc(x, y,1); u8g.drawLine(x, y, x>5?x-5:x, yOld); x = x+5; yOld = y; } } void setup(void) { Serial.begin(9600); for(int i=0;i<MAX_VALUES;i++){ values[valueCounter] = 1337; } } void loop(void) { tempValue = analogRead(tempsensor); tempValue = map(tempValue, 0, 307, 0, 150); minValue = min(tempValue, minValue); maxValue = max(tempValue, maxValue); if(valueCounter > MAX_VALUES){ valueCounter = 0; } valueCounter = valueCounter+1; values[valueCounter] = tempValue; u8g.firstPage(); do { draw(); } while( u8g.nextPage() ); delay(250); }