Möhren frieren nicht

So als hauptberuflicher Elektronenschubser kommen einem beim Reiten ja die merkwürdigsten Ideen. Letzten Dezember zum Beispiel fand ich es sehr unschön, dass der Sonnenschein die Möhren erstmal warmlutschen musste bevor sie genossen werden konnten. Da ich daheim zwei formschicke Laminatoren rumstehen hatte, von denen ich nur einen brauchte hab ich kurzerhand einen Blick in die heimische Bastelkiste geworfen und eine Spind-Möhren-Heizung zusammengelötet.

AVR-BeschaltungEinige Atmegas 88PA altern hier in der Kiste vor sich her und ich dachte zumindest einer könnte mal was tun für seine Daseinsberechtigung. Also hab ich mal ein Standardlayout auf meinem Rechner rausgesucht und ging ein wenig ans Platinen ätzen. Ein LM50 zum Temperaturmessen war leider grade nicht verfügbar aber ein LM335z samt 2k2 Vorwiderstand an PC2 ist auch ganz hervorragend. Ein Crydom HD48125 (an PC1 angeschlossen, SSR - Solid-State-Relay) schaltet den Laminator entsprechend ein und aus.

Der Programmcode ist sehr einfach gehalten. Das komplizierteste ist die Konfiguration des Analog-Digital-Convertes (ADC). Alle 20 Minuten misst der Atmega gleich vier mal hintereinander die Temperatur und bildet den Mittelwert aus den vier Messungen. Wird 2 °C oder weniger gemessen wird für 10 Minuten der Laminator eingeschaltet. Der komplette Code fordert nicht mal 1% der Kapazität des Atmegas. Übrigens: RS232 ist mehr schein denn sein: Ich war nur zu faul zum Löschen aus dem Plan.

#ifndef F_CPU

#define F_CPU 8000000

#endif

#include <avr/io.h>

#include <util/delay.h>

#define Solltemp 563 //entspricht ca. +2°C

/* ADC initialisieren */

void ADC_Init(void) {

uint16_t result;

ADMUX = (0<<REFS1) | (1<<REFS0);      // AVcc als Referenz benutzen

//  ADMUX = (1<<REFS1) | (1<<REFS0);      // interne Referenzspannung nutzen

ADCSRA = (1<<ADPS1) | (1<<ADPS0);     // Frequenzvorteiler

ADCSRA |= (1<<ADEN);                  // ADC aktivieren

/* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest

also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */

ADCSRA |= (1<<ADSC);                  // eine ADC-Wandlung

while (ADCSRA & (1<<ADSC) ) {}        // auf Abschluss der Konvertierung warten

/* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten

Wandlung nicht übernommen. */

result = ADCW;

}

/* ADC Einzelmessung */

uint16_t ADC_Read( uint8_t channel )

{

// Kanal waehlen, ohne andere Bits zu beeinfluflen

ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);

ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"

while (ADCSRA & (1<<ADSC) ) {}  // auf Abschluss der Konvertierung warten

return ADCW;                    // ADC auslesen und zurückgeben

}

/* ADC Mehrfachmessung mit Mittelwertbbildung */

uint16_t ADC_Read_Avg( uint8_t channel, uint8_t average )

{

uint32_t result = 0;

for (uint8_t i = 0; i < average; ++i )

result += ADC_Read( channel );

return (uint16_t)( result / average );

}

int main(void) {

uint16_t i = 0;

DDRB = 0;

PORTB = 0;

DDRC = (1 << PC3); //PC3 als Eingang eingestellt

PORTC = 0;

DDRD = 0;

PORTD = 0;

uint16_t adcval = 0;

ADC_Init();

while(1) {

adcval = ADC_Read_Avg(2, 4); //4 Messungen auf Kanal 2

if (adcval <= Solltemp){

PORTC |= (1 << PC3);

for (i = 0; i < 600; i++){

_delay_ms(1000);

}

PORTC &= ~(1 << PC3);

for (i = 0; i < 600; i++){

_delay_ms(1000);

}

}

else {

for (i=0; i < 1200; i++){

_delay_ms(1000);

}

}

}

return 0;

}

Ich weiß, ich weiß. Der Kundige AVR-Programmierer wird nun sagen:

"WAS?!? Der nimmt _delay_ms() und ne for-Schleife für 10 Minuten warten? Sowas macht man doch mit Timern!"

Dazu kann ich nur folgendes sagen:

  1. Für meine Anwendung ist es völlig wurscht ob es nun 10 Minuten sind oder 10 Minuten und 3 Sekunden
  2. Eine eigene Timerfunktion für 10 Minuten zu schreiben hätte mich sicher mehr Zeit gekostet als das ganze Projekt (2.5h wobei 2h für die Platine samt Lötstopplaminat draufgegangen sind)
  3. delay.h war grad verfügbar

Den Code für den ADC hab ich übrigens auch aus dem Internet gefischt, ich glaub aus dem AVR-GCC-Tutorial von http://www.mikrocontroller.net.

Die meiste Zeit hat eigentlich die Suche nach einem passenden Behältnis für die Heizung in anspruch genommen. Glücklicher Weise gab es Sperrmuss und jemand hat eine Küche entsorgt deren Hängeschränke genau auf meine Anforderungen passte. So steht nun in meinem Spind ein Hängeschrank aus Kiefernholz (massiv!) in dem die Möhren lagern. Auf einen Einlegeboden wurde das Innenleben des Laminators wie die Steuerungseinheit samt Atmega geschraubt. In den letzten Tagen war es schon recht kühl und die Heizung war schon in betrieb. Weder sind bisher die Möhren eingefroren noch ist der Stall abgebrannt. Es scheint zu funktionieren, was ich mir hier überlegt haben.

Dieser Beitrag wurde unter Programmierung, Reiten veröffentlicht. Setze ein Lesezeichen auf den Permalink.

Schreibe einen Kommentar

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

Time limit is exhausted. Please reload the CAPTCHA.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.