Hardware
Die Hardware ist recht unspektakulär:
Im Prinzip besteht die Fernbedinung nur aus einem Attiny44A, einem Pullup-Widerstand für den Reset-Eingang, drei Knöpfen (hoch, runter, stopp), einem Halter für eine CR3032-Knopfzelle und natürlich dem 433MHz-Sender. Die drei Knöpfe sind jeweils mit einem Eingang des Attiny verbunden und ziehen den Eingang bei Betätigung auf Ground
Software
Die einzelnen Funktionen der Software wurden bereits in den vorhergehenden Posts zum Thema erläutert. Außerdem ist der Code (für meine Verhältnisse) gut kommentiert. Ich werde daher nicht auf den kompletten Code eingehen.
#include <RCSwitch.h> #include <avr/sleep.h> #include <avr/wdt.h> RCSwitch mySwitch = RCSwitch(); unsigned char buttonDown = 10; unsigned char buttonStopp = 9; unsigned char buttonUp = 7; unsigned char buttonPressed = 0; char stopRequest = 0; void setup() { //Interrupts global deaktivieren cli(); //Pins initialisieren pinMode(buttonDown, INPUT_PULLUP); pinMode(buttonStopp, INPUT_PULLUP); pinMode(buttonUp, INPUT_PULLUP); //Funkmodul intialisieren und Steckdose ausschalten mySwitch.enableTransmit(0); //Sender hängt an Pin 0 mySwitch.setProtocol(1); mySwitch.switchOff("11011", "10000"); //Energie sparen ADCSRA &= ~(1<<ADEN); //Deaktiviere ADC ACSR = (1<<ACD); //Deaktiviere Analog Comparator //Pin-Change-Interrupt intialisieren PCMSK1 |= (1<<PCINT8); //Pin-Change-Interrupt an Pin 2 (Arduino Pin 10) PCMSK1 |= (1<<PCINT9); //Pin-Change-Interrupt an Pin 3 (Arduino Pin 9) PCMSK0 |= (1<<PCINT7); //Pin-Change-Interrupt an Pin 6 (Arduino Pin 7) //Power-Down-Modus vorbereiten set_sleep_mode(SLEEP_MODE_PWR_DOWN); //Interrupts global aktivieren sei(); } void loop() { sendCommand(); powerDown(); } void sendCommand() { if (buttonPressed == buttonDown) { mySwitch.switchOn("11011", "10000"); delay(750); sendCommandDown(); powerDown(25); mySwitch.switchOff("11011", "10000"); buttonPressed = 0; } else if (buttonPressed == buttonUp) { mySwitch.switchOn("11011", "10000"); delay(750); sendCommandUp(); powerDown(25); mySwitch.switchOff("11011", "10000"); buttonPressed = 0; } } //Befehl Rolladen rauf void sendCommandUp() { mySwitch.setProtocol(4); mySwitch.sendQuadState("0F0F0100QQ0F100F0F0F"); mySwitch.sendQuadState("0F0F0100QQ0F100F0F1Q"); mySwitch.setProtocol(1); } //Befehl Rolladen stopp void sendCommandStopp() { mySwitch.setProtocol(4); mySwitch.sendQuadState("0F0F0100QQ0F100FFFFF"); mySwitch.setProtocol(1); } //Befehl Rolladen runter void sendCommandDown() { mySwitch.setProtocol(4); mySwitch.sendQuadState("0F0F0100QQ0F100F0101"); mySwitch.sendQuadState("0F0F0100QQ0F100F0110"); mySwitch.setProtocol(1); } //lässt Attiny für time Sekunden warten void powerDown(char time) { GIMSK |= (1<<PCIE1); //Pin-Change-Interrupt aktivieren GIMSK |= (1<<PCIE0); stopRequest = 0; for (char i = 1; i<= time*1000; i++) { if (stopRequest == 0) { delay(1); } } GIMSK &= ~(1<<PCIE1); //Pin-Change-Interrupt deaktivieren GIMSK &= ~(1<<PCIE0); } //setzt Attiny solange in Powerdown-Modus, bis Pin-Change-Interrupt ausgelöst wurde void powerDown() { GIMSK |= (1<<PCIE1); //Pin-Change-Interrupt aktivieren GIMSK |= (1<<PCIE0); sleep_mode(); //Schlafen gehen //hier gehts weiter nach aufwachen GIMSK &= ~(1<<PCIE1); //Pin-Change-Interrupt deaktivieren GIMSK &= ~(1<<PCIE0); } void checkButton() { if (digitalRead(buttonDown) == LOW) { buttonPressed = buttonDown; } else if (digitalRead(buttonStopp) == LOW) { stopRequest = 1; mySwitch.switchOff("11011", "10000"); } else if (digitalRead(buttonUp) == LOW) { buttonPressed = buttonUp; } } //ISR für PCINT1 und PCINT0 (Pin-Change-Interrupts) ISR(PCINT1_vect) { checkButton(); } ISR(PCINT0_vect) { checkButton(); }Einige Details der Software möchte ich dennoch erläutern. Die Spannungsversorgung der Fernbedienung erfolgt über eine CR2032-Knopfzelle. Da diese so lange wie möglich halten soll und die Fernbedienung 99,999% der Zeit sowieso nur rum liegt und nichts tut, geht der Attiny bei Inaktivität mit der Funktion powerdown() in den Schlaf-Modus. Er schläft so lange, bis er durch einen Tastendruck (Pin Change Interrupt) wieder geweckt wird. Um im Schlaf-Modus so wenig Energie wie möglich zu verbrauchen, wird zu Beginn zusätzlich der AD-Wandler sowie der Analog Comparator abgeschaltet. Dadurch sinkt der Ruhestrom auf wenige µA.
Habe was sehr ähnliches gemacht. Vorschlag: füge ein relay hinzu der auf button click den stromkreis aktiv hält und den stromkreis dann unterbricht wenn die signale gesendet hatt.
AntwortenLöschen