Skip to content

Instantly share code, notes, and snippets.

@stas-dovgodko
Last active November 7, 2017 11:12
Show Gist options
  • Select an option

  • Save stas-dovgodko/da7c658837917ea072a35ef19fa8943b to your computer and use it in GitHub Desktop.

Select an option

Save stas-dovgodko/da7c658837917ea072a35ef19fa8943b to your computer and use it in GitHub Desktop.
Arduino 220 detector with debounce + interrupts
#define AC_PIN 3
#define RF_PIN 2
#define LED_PIN 13
volatile int counter = 0;
volatile int ac_status = 0;
volatile unsigned long ac_timer;
int ON[] = {2, 2, 2, 2, 1, 4, 4, 4, 4, 5, 1, 4, 4, 4, 4, 4, 4, 5, 2, 2, 1, 4, 4, 4, 6}; //The RF code that will turn the ON
int OFF[] = {2, 2, 2, 2, 1, 4, 4, 4, 4, 5, 1, 4, 4, 4, 4, 4, 4, 5, 2, 2, 2, 2, 2, 2, 3}; //The RF code that will turn the OFF
void acCheck()
{
ac_timer = millis();
if (ac_status == 0) {
// AC ON state
ac_status = 1;
}
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(AC_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(AC_PIN), acCheck, CHANGE);
pinMode(LED_PIN, OUTPUT);
//set timer1 interrupt at 1Hz
TCCR1A = 0;// set entire TCCR1A register to 0
TCCR1B = 0;// same for TCCR1B
TCNT1 = 0;//initialize counter value to 0
// set compare match register for 1hz increments
OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (must be <65536)
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS12 and CS10 bits for 1024 prescaler
TCCR1B |= (1 << CS12) | (1 << CS10);
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
}
ISR(TIMER1_COMPA_vect) { //timer1 interrupt 1Hz toggles status
unsigned long timer = millis();
if (ac_status > 0) {
if (timer > ac_timer + 500) {
// AC OFF
ac_status = 0;
ac_timer = 0;
acOFF();
} else if (ac_status == 1) {
acON();
ac_status = 2;
} else if (ac_status == 2) {
if (counter++ > 3) {
digitalWrite(LED_PIN, HIGH);
counter = 0;
} else {
digitalWrite(LED_PIN, LOW);
}
}
} else if (++counter > 1) {
digitalWrite(LED_PIN, HIGH);
counter = 0;
} else {
digitalWrite(LED_PIN, LOW);
}
}
void loop() {
}
void acON() {
Serial.println("On");
sendCode(ON);
}
void acOFF() {
Serial.println("Off");
sendCode(OFF);
}
void sendCode(int code[]) {
int timeDelay = 5;
// The LED will be turned on to create a visual signal transmission indicator.
digitalWrite(LED_PIN, HIGH);
//initialise the variables
int highLength = 0;
int lowLength = 0;
//The signal is transmitted 6 times in succession - this may vary with your remote.
for (int j = 0; j < 6; j++) {
for (int i = 0; i < (sizeof(code) / sizeof(int)); i++) {
switch (code[i]) {
case 1: // SH + SL
highLength = 3;
lowLength = 3;
break;
case 2: // SH + LL
highLength = 3;
lowLength = 7;
break;
case 3: // SH + VLL
highLength = 3;
lowLength = 92;
break;
case 4: // LH + SL
highLength = 7;
lowLength = 3;
break;
case 5: // LH + LL
highLength = 7;
lowLength = 7;
break;
case 6: // LH + VLL
highLength = 7;
lowLength = 92;
break;
}
/* Transmit a HIGH signal - the duration of transmission will be determined
by the highLength and timeDelay variables */
digitalWrite(RF_PIN, HIGH);
delayMicroseconds(highLength * timeDelay);
/* Transmit a LOW signal - the duration of transmission will be determined
by the lowLength and timeDelay variables */
digitalWrite(RF_PIN, LOW);
delayMicroseconds(lowLength * timeDelay);
}
}
//Turn the LED off after the code has been transmitted.
digitalWrite(LED_PIN, LOW);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment