//----------------------------------------------------------------------
// 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