//----------------------------------------------------------------------
// 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;
zurück