Neues Temperaturmessgerät oder Spaß mit Datentypen

Thermo/Hygrometer

Nokia5110 Display am Arduino

Nachdem eines meiner ersten kleinen Projekte mit dem Arduino ja ein Thermometer war und ich damit nicht wirklich zufrieden war, habe ich mir mal Gedanken gemacht, was denn da noch gehen könnte ohne gleich viel zu viel Zeit und Geld zu investieren.

Ich ging also erst einmal einkaufen:

Des Sensor gab es, weil er deutlich genauer ist, als den, den ich bis jetzt verwendete und weil er die Luftfeuchtigkeit gleich mit misst. Das Display, weil ich mir eh mal anschauen wollte, wie man so ein LCD ansteuert und weil ich eine Textausgabe haben wollte. Für den Sensor gibt es netterweise schon fertig Bibliotheken von adafruit. Und für das Display gibt es ein hevorragendes Tutorial inklusive Code-Schnippseln von Julian Ilett. Die beiden Teile getrennt zu testen ging dann auch sehr schnell, die Programmierung war dann auch nicht komplex. Dummerweise setzte ich mir in den Kopf den Code für das Display in eine kleine Bibliothek zu packen. Da ich nun zum ersten mal seit Jahren programmiere, dauerte das ne ganze Weile – am Ende scheiterte es fast an einem Tippfehler in einer Funktion. Am Ende sah das Programm dafür sehr aufgeräumt und übersichtlich aus.

//include needed libs

#include //code from https://www.youtube.com/watch?v=E6PUa4n2DnA
#include //code from http://learn.adafruit.com/dht/downloads

// define pins
#define RST 12
#define CE 11
#define DC 10
#define DIN 9
#define CLK 8

#define DHTPIN 2
#define DHTTYPE DHT22

//construct sensor and LCD object
DHT sensor(DHTPIN, DHTTYPE);
nokia5110 LCD(RST, CE, DC, DIN, CLK);

void setup() {
LCD.SetXY(1,0);
LCD.WriteString("TEMPERATURE");
LCD.SetXY(20,1);
unsigned char extended[] = "°C"; //° hat einen Wert von 0xB0 und ist damit im negativen Bereich eines signed chars
LCD.WriteExtendedASCII(extended);
LCD.SetXY(1,3);
LCD.WriteString("HUMIDITY");
LCD.SetXY(25,4);
LCD.WriteString("% rel.");
sensor.begin();
}

void loop() {
double h = sensor.readHumidity();
double t = sensor.readTemperature();
char hygro[5];
ftoa(hygro, h, 1);
char temp[5];
ftoa(temp, t, 1);
LCD.SetXY(1,1);
LCD.Clear(24); // clear part of LCD
LCD.SetXY(1,1);
LCD.WriteString(temp);
LCD.SetXY(1,4);
LCD.Clear(24); // clear part of LCD
LCD.SetXY(1,4);
LCD.WriteString(hygro);
delay(1000);
}

//credits to skumlerud for the ftoa function http://forum.arduino.cc/index.php/topic,44262.0.html
char *ftoa(char *a, double f, int precision)
{
long p[] = {0,10,100,1000,10000,100000,1000000,10000000,100000000};

char *ret = a;
long heiltal = (long)f;
itoa(heiltal, a, 10);
while (*a != '\0') a++;
*a++ = '.';
long desimal = abs((long)((f - heiltal) * p[precision]));
itoa(desimal, a, 10);
return ret;
}

Soweit so gut. Für die LCD-Bibliothek, zeige ich euch nur mal den Header.

/* code from Julian Ilett https://www.youtube.com/watch?v=E6PUa4n2DnA
modified and put in library by Martin Schmidt */

#ifndef nokia5110_H
#define nokia5110_H
#if ARDUINO >= 100
 #include "Arduino.h"
#else
 #include "WProgram.h"
#endif

class nokia5110 {
	private:
		uint8_t _RST;
		uint8_t _CE;
		uint8_t _DC;
		uint8_t _DIN;
		uint8_t _CLK;
		static const unsigned char ASCII[][5];
		void WriteExtendedCharacter(unsigned char character);
		void WriteCmd(unsigned char cmd);
		void WriteCharacter(char character);
		void WriteData(unsigned char dat);
		void Setup();

	public:
		nokia5110(uint8_t reset, uint8_t enable,uint8_t datacom, uint8_t datain,uint8_t clock);
		void WriteString(char *characters);
		void SetXY(uint8_t x, uint8_t y);
		void Clear(int size = 504);
		void WriteExtendedASCII(unsigned char *characters);
};

#endif

Vielleich fallen euch die Funktionen WriteExtendedASCII und WriteExtendedCharacter auf. Während eigentlich alles andere in dem Video von Julian verständlich wird und auch klar ist, wie die Font definiert ist (5×6 pixel, jeden Reihe ansprechen und entsprechend zeichnen, das ist in dem ASCII-Array hinterlegt), hatte ich ne lustige Zeit herauszufinden, warum das ° Zeichen nicht bzw. nur Schrott ausgegeben wurde. Des Rätsels Lösung ist, dass Strings als char-Arrays definiert sind. Jetzt deckt ein char den Bereich von -128 bis +127 ab. Dummerweise hat das ° Zeichen aber ein ASCII Wert von 176. Sprich, das wird als negative Zahl gespeichert. Und das die Font einfach ein zweidimensionales Array ist, dass stur die ASCII-Werte hochzählt um das entsprechende Zeichen zu finden, rannte das fröhlich in die Wüste. Ich habe mich dann dafür entschieden die beiden oben genannten Funktionen zu schreiben und den String für „°C“ als unsigned char-Array zu definieren. Das wäre sicher auch anders gegangen, oder aber in fertigen Bibliotheken schon richtig durchgeführt werden. Aber ich wollte ja auch noch was lernen.

Prototyp

Prototyp: Arduinio, DHT22, nokia5110 LCD

Nächste Woche gibt es dann wahrscheinlich die Schaltpläne. Wie immer freue ich mich na klar über Kritik und Tipps. Und auch über Tipps wie ich den Prototypen auf eine Platine überführt bekomme, würde ich mich freuen.

Dieser Beitrag wurde unter Arduino veröffentlicht. Setze ein Lesezeichen auf den Permalink.

Eine Antwort auf Neues Temperaturmessgerät oder Spaß mit Datentypen

  1. Alex sagt:

    Da bekomme ich ja auch richtig Lust mal wieder meinen Arduino auszupacken =)
    Ich hatte ja vor ein paar Jahren mal einen LED-Cube damit gebastelt.

Schreibe einen Kommentar

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