Arduino Projekt: Liniendiagramm mit Temperaturwerten

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

Arduino Projekt - Liniendiagramm mit Temperaturwerten
Arduino Projekt – Liniendiagramm mit Temperaturwerten

Die Daten für das Diagramm werden von einem analogen Temperatursensor LM35DZ gelesen.

Temperatursensor LM35DZ
Temperatursensor LM35DZ

Teileliste

Für dieses Projekt wird benötigt:

Aufbau & Schaltung

Zunächst wollen wir die Schaltung aufbauen. Durch die überschaubare Teileliste ist dieser schnell erledigt.

Schaltung - LM35DZ & 1,3" OLED Display am Arduino UNO
Schaltung – LM35DZ & 1,3″ OLED Display am Arduino UNO

 

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). Dieses 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 nun 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 nun 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);
}

Video

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.