//---------------------------------------------------------------------- // Titel : WebWecker-Lösung zum myAVR C++ Tutorial www.avr-cpp.de //---------------------------------------------------------------------- // Funktion : Wecker mit Echtzeituhr, Temperaturanzeige und PC-Frontend // Add-On : myEthernet 128K // 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: I2C_24Cxx myethernet; // I2C-Schittstelle des myEthernet (shared Ram) 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 protected: uint8 stunden; // Stunden für TWI -> myEthernet protected: uint8 minuten; // Minuten für TWI -> myEthernet protected: uint8 sekunden; // Sekunden für TWI -> myEthernet protected: uint8_t wait; // Wartezeit für TWI // 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 myethernet.config(0xB0); // wie in config.cfg festgelegt // 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(); wait= 1; // Wartezeit für TWI } // 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+"|"); stunden = echtzeituhr.hours; // Stunden TWI waitMs(wait); myethernet.writeData(2, stunden); waitMs(wait); minuten = echtzeituhr.minutes; // Minuten TWI waitMs(wait); myethernet.writeData(3, minuten); waitMs(wait); sekunden = echtzeituhr.seconds; // Sekunden TWI waitMs(wait); myethernet.writeData(4, sekunden); waitMs(wait); int16 t = temperatursensor.getValue(); // hole Temperatur t *= 25; // Umrechnung auf Zehntel-Temperatur t += 10; // für Übergabe als 16 Bit Zahl t /= 20; text.formatNum(t, 1, 5, ' '); anzeige.writeLine(2, text); anzeige.write("\xdf" "C"); text += "°C"; konsole.sendString(text + "\n"); myethernet.writeData(0, (uint8_t)t); // Schreibe Byte 1 in SRAM des myEthernets waitMs(wait); myethernet.writeData(1, (uint8_t)(t/256)); // Schreibe Byte 2 in SRAM des myEthernets // 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 //geändert! waitMs(900); } // 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;