Skip to content

Instantly share code, notes, and snippets.

@giltesa
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save giltesa/c8f6c062c8e9d71fcda5 to your computer and use it in GitHub Desktop.
Save giltesa/c8f6c062c8e9d71fcda5 to your computer and use it in GitHub Desktop.
Arduino - Remote Control of Lighting and Fan
/**
* ARDUINO REMOTE CONTROL OF LIGHTING AND FAN (CRA)
*
* Author: Alberto Gil Tesa
* Website: http://giltesa.com/tag/cra
* License: http://creativecommons.org/licenses/by-nc-sa/3.0
* Version: 2014/08/27 - 2.0
*/
#include "CRA.h"
/**
*
*/
CRA::CRA()
{
fanSpeed = 0;
lightStatus = false;
lightBrightness = 2;
lightIntervals[0] = 5;
lightIntervals[1] = 25;
lightIntervals[2] = 50;
lightIntervals[3] = 100;
lastRemoteValid = 0;
menuModeState = false;
timerFanState = false;
timerFanValue = 0;
}
/**
* Starts and configures all modules.
* Does not consider that a module this bad connected or broken.
*/
void CRA::begin()
{
#ifdef DEBUG
Serial.begin(9600);
while(!Serial);
#endif
pinMode(pBTN , OUTPUT);
pinMode(pRLV1 , OUTPUT);
pinMode(pRLV2 , OUTPUT);
pinMode(pRLV3 , OUTPUT);
pinMode(pRLLED, OUTPUT);
pinMode(pLEDR , OUTPUT);
pinMode(pLEDG , OUTPUT);
pinMode(pBUZ , OUTPUT);
//IrRemote:
irrecv = new IRrecv(pIR);
irrecv->enableIRIn();
#ifdef DEBUG
Serial.println(F("Program started:\r\n"));
#endif
setLedStatus('G');
#ifdef DEBUG
Serial.println();
#endif
}
/**
*
*/
void CRA::workingBackgroundTasks()
{
// Tareas en segundo plano como hacer parpadear el led durante el modo de temporizador...
}
/**
* Change the fan speed according to the value sent:
*/
void CRA::setFanSpeed( byte level )
{
byte tmpSpeed = fanSpeed;
switch( level )
{
case LESS:
fanSpeed = ( fanSpeed > 0 ? fanSpeed-1 : 0 );
break;
case MORE:
fanSpeed = ( fanSpeed < 3 ? fanSpeed+1 : 3 );
break;
case ON:
fanSpeed = 1;
break;
case OFF:
default:
fanSpeed = 0;
break;
}
if( tmpSpeed == fanSpeed )
playSoundAlert(2);
switch( fanSpeed )
{
case 1:
digitalWrite( pRLV1 , HIGH ); delay(20); // White
digitalWrite( pRLV2 , LOW ); delay(20); // Violet
digitalWrite( pRLV3 , HIGH ); delay(20); // Yellow
#ifdef DEBUG
Serial.println(F("Fan speed: SLOW"));
#endif
break;
case 2:
digitalWrite( pRLV1 , HIGH ); delay(20); // White
digitalWrite( pRLV2 , HIGH ); delay(20); // Violet
digitalWrite( pRLV3 , LOW ); delay(20); // Yellow
#ifdef DEBUG
Serial.println(F("Fan speed: MIDDLE"));
#endif
break;
case 3:
digitalWrite( pRLV1 , HIGH ); delay(20); // White
digitalWrite( pRLV2 , HIGH ); delay(20); // Violet
digitalWrite( pRLV3 , HIGH ); delay(20); // Yellow
#ifdef DEBUG
Serial.println(F("Fan speed: FAST"));
#endif
break;
default:
digitalWrite( pRLV1 , LOW ); delay(20); // White
digitalWrite( pRLV2 , LOW ); delay(20); // Violet
digitalWrite( pRLV3 , LOW ); delay(20); // Yellow
#ifdef DEBUG
Serial.println(F("Fan speed: OFF"));
#endif
break;
}
return;
}
/**
*
*/
boolean CRA::getLightState()
{
return lightStatus;
}
/**
* Change the light intensity according to the value sent:
*/
void CRA::setLightBrightness( byte level )
{
byte tmpBrightness = lightBrightness;
switch( level )
{
case LESS:
lightBrightness = ( lightBrightness > 0 ? lightBrightness-1 : 0 );
break;
case MORE:
lightBrightness = ( lightBrightness < size(lightIntervals)-1 ? lightBrightness+1 : size(lightIntervals)-1 );
break;
case ON:
lightStatus = true;
break;
case LVL1:
lightStatus = true;
lightBrightness = 0;
break;
case LVL2:
lightStatus = true;
lightBrightness = 1;
break;
case LVL3:
lightStatus = true;
lightBrightness = 2;
break;
case LVL4:
lightStatus = true;
lightBrightness = 3;
break;
case OFF:
default:
lightStatus = false;
break;
}
if( tmpBrightness == lightBrightness )
playSoundAlert(2);
digitalWrite( pRLLED , lightStatus ); delay(200); // LED RELAY
analogWrite( pTLED , lightStatus ? lightIntervals[lightBrightness] : LOW ); // LED
#ifdef DEBUG
if( lightStatus ){
Serial.print( F("Light: ON (") );
Serial.print( lightIntervals[lightBrightness] );
Serial.println( F("%)") );
}else
Serial.println(F("Light: OFF"));
#endif
setLedStatus( !lightStatus ? 'G' : 'N' );
return;
}
/**
*
*/
void CRA::setInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode)
{
attachInterrupt(interruptNum, userFunc, mode);
}
/**
*
*/
boolean CRA::isButtonPressed()
{
return false;
}
/**
*
*/
boolean CRA::isRemotePressed()
{
if( irrecv->decode(&results) )
{
irrecv->resume();
codeRemote = results.value;
return true;
}
return false;
}
/**
*
*/
boolean CRA::checkRemoteCode( byte numButton )
{
if( millis() - lastRemoteValid > 1000 )
{
for( int i=0 ; i<numRemotes ; i++ )
{
if( remoteCodes[numButton][i] == codeRemote )
{
lastRemoteValid = millis();
return true;
}
}
}
return false;
}
/**
*
*/
void CRA::setMenuMode(boolean value)
{
menuModeState = value;
}
/**
*
*/
boolean CRA::isMenuMode()
{
return menuModeState;
}
/**
*
*/
void CRA::setTimerFanState(boolean value)
{
timerFanState = value;
if( !timerFanState )
timerFanValue = 0;
}
/**
*
*/
boolean CRA::getTimerFanState()
{
return timerFanState;
}
/**
*
*/
void CRA::setTimerFanLevel(byte value)
{
// Aumenta o disminuye el tiempo del temporizador....
// 30 minutos por cada pulsacion -1 o +1
byte tmpTimerFan = timerFanValue;
switch( value )
{
case LESS:
timerFanValue = ( timerFanValue > 30 ? timerFanValue-30 : 0 );
break;
case MORE:
timerFanValue = ( timerFanValue < 120 ? timerFanValue+30 : 120 );
}
if( tmpTimerFan == timerFanValue )
playSoundAlert(2);
}
/**
* Change the color of the status LED:
* Green = Light off
* Red = Programming mode
* Yellow = Timer mode
*/
void CRA::setLedStatus( char color )
{
switch( color )
{
case 'g':
case 'G':
digitalWrite( pLEDR , LOW );
digitalWrite( pLEDG , HIGH );
#ifdef DEBUG
Serial.println(F("LED color: GREEN"));
#endif
break;
case 'r':
case 'R':
digitalWrite( pLEDR , HIGH );
digitalWrite( pLEDG , LOW );
#ifdef DEBUG
Serial.println(F("LED color: RED"));
#endif
break;
case 'y':
case 'Y':
digitalWrite( pLEDR , HIGH );
digitalWrite( pLEDG , HIGH );
#ifdef DEBUG
Serial.println(F("LED color: YELLOW"));
#endif
break;
case 'n':
case 'N':
default:
digitalWrite( pLEDR , LOW );
digitalWrite( pLEDG , LOW );
#ifdef DEBUG
Serial.print(F("LED color: OFF"));
#endif
break;
}
return;
}
/**
* Plays a sound as information or warning:
* 1 = Pressing accepted
* 2 = Pressing the button does not cause any effect.
* 3 = The waiting time is over. The fan will turn off.
* 4 = Critical error due to overheating of the light.
*/
void CRA::playSoundAlert( byte alert )
{
switch( alert )
{
case 1:
#ifdef DEBUG
Serial.println(F("ALERT: Pressing accepted."));
#endif
digitalWrite( pBUZ, HIGH ); delay(10);
digitalWrite( pBUZ, LOW );
break;
case 2:
#ifdef DEBUG
Serial.println(F("ALERT: Pressing the button does not cause any effect."));
#endif
digitalWrite( pBUZ, HIGH ); delay(10);
digitalWrite( pBUZ, LOW ); delay(15);
digitalWrite( pBUZ, HIGH ); delay(10);
digitalWrite( pBUZ, LOW );
break;
case 3:
#ifdef DEBUG
Serial.println(F("ALERT: The waiting time is over. The fan will turn off."));
#endif
digitalWrite( pBUZ, HIGH ); delay(5);
digitalWrite( pBUZ, LOW ); delay(250);
digitalWrite( pBUZ, HIGH ); delay(5);
digitalWrite( pBUZ, LOW );
break;
case 4:
#ifdef DEBUG
Serial.println(F("ALERT: Critical error due to overheating of the light."));
#endif
for( int i=0 ; i<3 ; i++ )
{
digitalWrite( pBUZ, HIGH ); delay(700);
digitalWrite( pBUZ, LOW ); delay(400);
}
break;
default:
#ifdef DEBUG
Serial.println(F("ALERT: Unknown level of alert."));
#endif
break;
}
return;
}
/**
* ARDUINO REMOTE CONTROL OF LIGHTING AND FAN (CRA)
*
* Author: Alberto Gil Tesa
* Website: http://giltesa.com/tag/cra
* License: http://creativecommons.org/licenses/by-nc-sa/3.0
* Version: 2014/08/27 - 2.0
*/
#ifndef CRA_H_
#define CRA_H_
/**
* Libraries
*/
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include "utility/IRremote.h"
/**
* Debug Mode
* Uncomment this line to enable debugging, commenting on again to disable debugging.
*/
#define DEBUG 1
/**
* Constants of the program
*/
#define size(x) sizeof(x)/sizeof(*x)
#define pIR 2 // Infrared receiver
#define pBTN 3 // Wall switch
#define pRLV1 9 // Relay1 - White fan wire
#define pRLV2 8 // Relay2 - Violet fan wire
#define pRLV3 7 // Relay3 - Yellow fan wire
#define pRLLED 4 // Relay4 - Power Light (Led 20W)
#define pTLED 5 // Transistor Light (Led 20W)
#define pLEDR 11 // Red Led
#define pLEDG 12 // Green Led
#define pBUZ 6 // Buzzer
#define pTMP 10 // Temperature sensor
#define LED_ON_OFF_OK 0
#define LED_LESS 1
#define LED_MORE 2
#define FAN_LESS 3
#define FAN_MORE 4
#define MENU 5
#define LESS -2
#define MORE -1
#define OFF 0
#define ON 1
#define LVL1 2
#define LVL2 3
#define LVL3 4
#define LVL4 5
#define numButtons 6
#define numRemotes 2
const unsigned long remoteCodes[numButtons][numRemotes] =
{
//Remote: Apple Remote, Microsoft MCE
{ 2011242676, 2148500571 }, // Led On/Off
{ 2011279540, 2148500572 }, // Led Less
{ 2011287732, 2148500573 }, // Led More
{ 2011238580, 2148500490 }, // Fan Less
{ 2011291828, 2148500491 }, // Fan More
{ 2011250868, 2148500574 } // Menu
};
/**
*
*/
class CRA
{
public:
CRA();
void begin();
void workingBackgroundTasks();
void setFanSpeed( byte level );
boolean getLightState();
void setLightBrightness( byte level );
void setInterrupt(uint8_t, void (*)(void), int mode);
boolean isButtonPressed();
boolean isRemotePressed();
boolean checkRemoteCode(byte button);
void setMenuMode(boolean value);
boolean isMenuMode();
void setTimerFanState(boolean value);
boolean getTimerFanState();
void setTimerFanLevel(byte value);
private:
byte fanSpeed;
boolean lightStatus;
byte lightBrightness;
byte lightIntervals[];
IRrecv *irrecv;
decode_results results;
unsigned long codeRemote;
unsigned long lastRemoteValid;
boolean menuModeState;
boolean timerFanState;
byte timerFanValue;
void setLedStatus(char color);
void playSoundAlert(byte alert);
};
#endif /* CRA_H_ */
/**
* ARDUINO REMOTE CONTROL OF LIGHTING AND FAN (CRA)
*
* Author: Alberto Gil Tesa
* Website: http://giltesa.com/tag/cra
* License: http://creativecommons.org/licenses/by-nc-sa/3.0
* Version: 2014/08/27 - 2.0
*/
/**
* Libraries
*/
#include <CRA.h>
/**
* Variables of the program
*/
CRA cra;
/**
* Functions declaration
*/
void buttonPressed();
void remotePressed();
/**
* Setup function
*/
void setup()
{
Serial.begin(9600);
cra.begin();
// Se puede usar la interrupcion para cancelar el temporizador, aunque tampoc es imprescindible...
//cra.setInterrupt( 0, miFuncion0, CHANGE ); // HIGH > LOW
//cra.setInterrupt( 1, miFuncion1, CHANGE );
}
/**
* Main function
*/
void loop()
{
cra.workingBackgroundTasks();
if( cra.isButtonPressed() )
{
buttonPressed();
}
if( cra.isRemotePressed() )
{
remotePressed();
}
}
/**
* Function for the control of beats from the wall button.
* - Cancels functions launched from the remote control.
* - Turns ON or OFF the light.
*/
void buttonPressed()
{
// Turn off everything:
if( cra.isMenuMode() || cra.getTimerFanState() )
{
cra.setMenuMode(false);
cra.setTimerFanState(false);
//cra.setTimerFanLevel(0);
}
else
{
cra.setLightBrightness( cra.getLightState() ? OFF : LVL3 );
}
}
/**
* Function for the control of beats from infrared remote control.
*/
void remotePressed()
{
if( cra.checkRemoteCode(LED_ON_OFF_OK) && cra.isMenuMode() )
{
cra.setMenuMode(false);
cra.setTimerFanState(true);
}
else if( cra.checkRemoteCode(LED_ON_OFF_OK) )
{
cra.setLightBrightness( cra.getLightState() ? OFF : ON );
}
else if( cra.checkRemoteCode(LED_LESS) && cra.isMenuMode() )
{
cra.setTimerFanLevel(LESS);
}
else if( cra.checkRemoteCode(LED_LESS) )
{
cra.setLightBrightness(LESS);
}
else if( cra.checkRemoteCode(LED_MORE) && cra.isMenuMode() )
{
cra.setTimerFanLevel(MORE);
}
else if( cra.checkRemoteCode(LED_MORE) )
{
cra.setLightBrightness(MORE);
}
else if( cra.checkRemoteCode(FAN_LESS) && !cra.isMenuMode() )
{
cra.setFanSpeed(LESS);
}
else if( cra.checkRemoteCode(FAN_MORE) && !cra.isMenuMode() )
{
cra.setFanSpeed(MORE);
}
else if( cra.checkRemoteCode(MENU) )
{
cra.setMenuMode( !cra.isMenuMode() );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment