Hallo Arduino Welt!

Das Thermometer im Betrieb, betrieben von einem Akkupack für Mobilgeräte mit USB Anschluss. Angezeigt werden 16.5°C.

Das Thermometer im Betrieb, betrieben von einem Akkupack für Mobilgeräte mit USB Anschluss. Angezeigt werden 16.5°C.

Geplant war für diese Woche eigentlich mal wieder ein Foto zu veröffentlichen. Dummerweise für euch, kam aber letzte Woche ein Päckchen bei mir an, dass einen Arduino UNO und diverse elektronische Bauteile enthielt. Daher gibt es heute einen „Hallo Arduino Welt!“ Post. Da müsst ihr jetzt durch.

Nachdem ich mich mit dem Breadboard, dem Ansprechen einiger Bauteile und auch der Funktion einiger Bauteile mal wieder vertraut gemacht hatte, fragte ich mich, was ich denn nun anstellen könnte. Da mein Körper und das Thermometer, welches die Heizung steuert, immer unterschiedlicher Meinung sind war mir relativ schnell klar, dass ich ein Thermometer basteln will. Aber wie will ich die Temperatur ausgeben? Seriell per USB? Zu einfach und zu umständlich weil immer ein PC oder Tablett benötigt wird. Display kaufen? Dauert zu lange und zu langweilig. Also das ganze per LEDs im binären Format. 8 LEDs sollten reichen, 1 bit für Vorzeichen, 1 bit für unter x.5 bzw. über x.5 °C, 6 bit für die Temperatur – reicht für 64°C, also den normalen Hausgebrauch. Jetzt hat der Arduino zwar genügen I/O Pins um die 8 LEDs direkt anzusprechen, das war mir aber auch irgendwie zu langweilig. Da lag doch noch ein 8-Bit Shift Register rum? Ich wollte mich damit eh mal etwas genauer auseinandersetzen und damit war klar was ich bauen würde: Einen Temperatursensor der über ein 8-Bit Shift Register die Temperatur binär mit Indikation für 0.5°C Schritte und Vorzeichen ausgibt.
Nach ein wenig Verwirrung in welcher Reihenfolge die Bits ins Register müssen und dem Aha-Moment als mir klar wurde, dass ein logisches UND ein XOR sein muss funktionierte das Gerät dann auch. Da der Sensor aber etwas Träge und ungenau ist +/-2°C habe ich jetzt drei „Geräte“ die sich uneins sind: Der Thermostat, mein Körper und der Arduino.

Soviel zur Geschichte, jetzt noch kurz zum Technischen. Code zu veröffentlichen ist ja einfach, das ist nur copy&paste. Schaltpläne zu malen ist von Hand auch einfach, am PC war das neu für mich. Verwendet habe ich dann das Programm von Fritzing. Da Breadboard-Layouts aber auch etwas langweilig und schnell unübersichtlich sind, habe ich den Schaltplan gleich noch mit erstellt und dabei gelernt, dass das auto-routing der Verbindungen nicht ganz so gut klappt bzw. erst dann besser klappt, wenn man die Bauteile von Hand anordnet.

Breadboard Layout des binären Thermometers, erstellt mit Fritzing.

Breadboard Layout des binären Thermometers, erstellt mit Fritzing.

Schaltplan des binären Themometers, erstellt mit Fritzing.

Schaltplan des binären Themometers, erstellt mit Fritzing.

Und weil sowas ohne Code nicht komplett wäre, kommt hier noch der Code.

/* Digital Temp with TMP36 and binary output via MM74HC595
MSB = pos or neg
LSB = 0.5 or full centigrade*/

// define pins
const byte clock = 10;
const byte latch = 11;
const byte data = 12;
const byte tempIn = 5;

//define bitmasks
const byte cold_half = B10000001;
const byte cold_full = B10000000;
const byte warm_half = B00000001;
const byte warm_full = B00000000;

//declare functions
void setup();
void loop();
byte calcData(float&); //use references to save memory, faster?
void getTempAverage(float&); //use references to save memory, no return value neede as we use reference, faster?

//setup pins
void setup() {
pinMode(clock, OUTPUT);
pinMode(latch, OUTPUT);
pinMode(data, OUTPUT);
//Serial.begin(9600); //initialize serial communication
}

//run over and over again
void loop() {
float temperature = 0;
getTempAverage(temperature);
Serial.println(temperature);
byte temp = calcData(temperature);
// Serial.println(temp);
digitalWrite(latch, LOW); //write into inut registers
shiftOut(data, clock, LSBFIRST, temp); //LSB will bis at Qh, MSB at Qa
digitalWrite(latch, HIGH); //transfer to output registers
}

void getTempAverage(float& act_tmp) {
float sum_temp = 0;
for(int i = 0; i < 20; i++) { //make 20 measurements every 3 secs, store them
act_tmp = analogRead(tempIn) * 0.0048828125; //5 volts in 1024 steps
act_tmp = (act_tmp - 0.5) * 100; //500 mV offset, 10 mV per centigrade
sum_temp += act_tmp;
delay(3000);
}
act_tmp = sum_temp/20; //mean of 20 measurments in 60 seconds
}

byte calcData(float& temperature) {
boolean half = false;
boolean negative = false;
if (temperature < 0) {negative = true;} //if below 0 centigrade set negative true
byte print_temp = byte(temperature); //convert float to integer for display
// Serial.print("conversion ");
// Serial.println(print_temp);
// Serial.println(print_temp, BIN);
if (print_temp < byte(temperature+0.5)) {half = true;} //check if temperaute is over .5 or below .5
print_temp = print_temp << 1; //shift one bit to left so we can applay bitmasks
//Serial.println(print_temp, BIN); //print temperature to serial out
if(!negative && half) {return(print_temp ^ warm_half);}
else if (!negative && !half) {return(print_temp = print_temp ^ warm_full);}
else if (negative && half) {return(print_temp ^ cold_half);}
else if (negative && !half) {return(print_temp ^ cold_full);}
else {return(B11111111);}
}

Über (konstruktive) Kritik bin ich sehr dankbar. Es ist echt schon ne ganze Weile her, dass ich mich mit Elektronik und C beschäftigt habe.

Dieser Beitrag wurde unter Arduino abgelegt und mit , , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

Schreibe einen Kommentar

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