//---------------------------------------------------------------------- // Titel : Beispiellösung zum myAVR C++ Tutorial www.avr-cpp.de //---------------------------------------------------------------------- // Funktion : Wecker mit Echtzeituhr, Temperaturanzeige und PC-Frontend // Schaltung : PortD = LCD, PortB.0 = Taste, PortB.1 = LCD-Backlight // PortB.2 = Speaker, PortC.0 = Lichtsensor // PortC.4 und PortC.5 = I2C (TWI/SCL/SDA) //---------------------------------------------------------------------- // Prozessor : ATmega8 // Takt : 3,6864 MHz // Sprache : myAVR C++ // Version : 1.01 // Datum : 21.06.2012 // Autor : Alexander Huwaldt //---------------------------------------------------------------------- class Application : public Controller { protected: Button taste; // Klicken = Schlummerfunktion, Halten = Alarm aus protected: AnalogDevice lichtsensor; // Dunkel -> LCD Beleuchtung an protected: LcdMK2 anzeige; // Anzeige Uhrzeit, Temperatur und Alarm protected: SoundChanelB lautsprecher; // Wecksignal/-melodie ausgeben protected: I2C_LM75 temperatursensor; // Raumtemperatur ermitteln protected: I2C_DS1307 echtzeituhr; // Batteriegestützte Echtzeituhr protected: Uart konsole; // Verbindung zum PC-Programm protected: String buffer; // Zwischenspeicher für Kommandos vom PC-Programm protected: bool neuerAlarm; // true wenn neue Weckzeit empfangen wurde protected: bool neueZeit; // true wenn neue Uhrzeit empfangen wurde protected: String text; // Zwischenspeicher für Texteausgaben protected: Eeprom eeprom; // Initialisiert EEPROM-Zugriff protected: Eeprom_uint8 weckStunde; // SRAM gepufferte EEPROM Variable protected: Eeprom_uint8 weckMinute; // SRAM gepufferte EEPROM Variable protected: Eeprom_uint8 weckSekunde; // SRAM gepufferte EEPROM Variable protected: uint8 alarmDauer; // Dauer des Weckalarms in Serunden // wird einmalig bein Einschalten des Systems ausgeführt public: void onStart() { // Initialisierungssequenz // weckStunde=weckMinute=weckSekunde=0xFF nach Brennen alarmDauer = 0; // Alarm aus neueZeit = false; // noch keine neue Uhrzeit vom PC empfangen neuerAlarm = false; // noch keine neue Weckzeit vom PC empfangen taste.config(portB,bit0); // Taste initialisieren lichtsensor.config(0); // Lichstsensor initialisieren temperatursensor.config(0x90); // Temperatursensor initialisieren echtzeituhr.config(0xD0); // Echtzeituhr initialisieren konsole.config(9600); // UART initialisieren // Begrüßungssequenz nach Programmieren, Reset oder Power ON anzeige.backLightOn(); anzeige.writeLine(1,"Willkommen beim"); anzeige.writeLine(2,"kleinen Projekt"); // Begrüßungstonfolge lautsprecher.play(FLASHSTR("a.a.a.ddd.ccc")); // einen Moment fürs Auge stehen lassen waitMs(3000); anzeige.clear(); anzeige.backLightOff(); } // wird wiedeholend aus der "MainLoop" des AppKernel aufgerufen // hier alles was Zeit hat verarbeiten public: void onWork() { // Anzeigezyklus echtzeituhr.formatTimeToString(text,"%h:%m:%s Uhr"); anzeige.writeLine(1,text); konsole.sendString(text+"|"); temperatursensor.formatGradToString(text,1); anzeige.writeLine(2, text); anzeige.write("\xdf" "C"); konsole.sendString(text + "°C\n"); // Beleuchtungslogik if (lichtsensor.getValue8()>150) anzeige.backLightOff(); else anzeige.backLightOn(); // Wecklogik if (weckSekunde<60) { // Weckzyklus starten? if ( alarmDauer == 0 && weckStunde == echtzeituhr.hours && weckMinute == echtzeituhr.minutes && weckSekunde == echtzeituhr.seconds ) { // Weckzeit 120s alarmDauer = 120; } anzeige.setPos(2,10); if (alarmDauer>120) anzeige.write("SNOOZE "); if (alarmDauer>0) anzeige.write("ALARM "); else anzeige.write("* "); } else anzeige.write(" "); // wenn vom PC neue Uhrzeit empfangen -> Echtzeituhr stellen if ( neueZeit ) { // Format: 13:44:00T neueZeit = false; echtzeituhr.setTime(buffer); buffer = ""; } // wenn vom PC neue Weckzeit empfangen -> Wecker stellen if ( neuerAlarm ) { // Format: 06:30:00A neuerAlarm = false; echtzeituhr.convertTime(buffer); weckStunde = echtzeituhr.hours; weckMinute = echtzeituhr.minutes; weckSekunde= echtzeituhr.seconds; buffer = ""; } // Pause, Zeit fürs Auge waitMs(1000); } // einmal pro Sekunde nachschauen ob Weckmelodie neu gestartet werden muss public: void onTimer1s() { if (alarmDauer>0) { alarmDauer--; if (alarmDauer<=120 && !lautsprecher.isPlaying()) lautsprecher.play( FLASHSTR("vfff,,fff,,fff,,dd,a,ff.dd,a,ffff.." "CCC,,CCC,,CCC,,DD,C,ff.dd,a,ffff...") ); } } // Ereignisbehandlung für Daten vom PC oder Tastenaktivität public: void onEvent(const Object& sender, uint8 data) { if (sender == konsole) { buffer+=(char)data; if (data=='T') neueZeit=true; else if (data=='A') neuerAlarm=true; } else if (sender == taste) { lautsprecher.stop(); if (data == Button::Click) alarmDauer = 120 + 60; // 120s Alarmzeit + 60s Snooze else if (data==Button::HoldStart) alarmDauer = 0; // Alarm aus } } } app;