Hi All,
I had the need for a simple controller that uses a cheap 4 button RF key fob. I needed to control 5 relays and 3 PWMs and thought an Arduino would be perfect for this application.
The usual searches for similar projects yielded very little and none of the projects I could find did much more than pass through the fob's button state. As I needed 8 actions from only 4 buttons this approach would not suffice.
The following sketch is the solution I came up with and I thought it might be useful to others. Utilization of the VT pin found on most of the receivers was the key to expanding the functionality.
NANO V3.0
Arduino IDE 1.0.6
I hope this is helpful.
R.S.
RF_Fob.ino (4.97 KB)
Hi All,
Sorry this is my first time posting and I thought the attachment would show up in the post. Here is sketch.
/*
RF_Fob
Provides simple control functionality from a 4 button RF key fob. (Manufacturer Unknown)
The receiver is based on the Microchip HCS515 chip, it has 5 output pins
labeled D0, D1, D2, D3, and VT. The VT pin goes high when any of the 4 buttons on
the fob are depressed and remains high until the button is released. Each of the D0-D3 pins
goes high when its related button is depressed and remains high for approximately 700ms.
_________________________________________
| |
| |
| RECEIVER |
| |
|___|_|_|_|_|_________________|_|_|_|_|___|
| | | | | | | | | |
| | | | | | | | | |
D3 D2 D1 D0 VT +5V G Antenna
This output protocol was exploited to allow for 5 different available selections from the
4 buttons. This was done by using the attachInterrupt() function based on the falling edge
of the VT pin signal. The interrupt reads which button was just released on the fob
(Resulting in Case 1-4), if any button is held longer than the 700ms then released the
interrupt reads no button (Resulting in Case 0).
Holding a button (Case 0) was used to switch between modes. i.e. Hold any button for longer than
700ms and then released the code switches to the next mode allowing the buttons to be used for 4
new selection. Hold any button again and switch to a new mode or switch back. Theoretically could
have infinite modes each with 4 possible selections if you could keep track.
WARNING: Use at your own risk
created 11 May 2015
by Rod K. Serling
this code is in the public domain
*/
//------ All possible states for three modes
//volatile int State_01 = LOW;
//volatile int State_02 = LOW;
volatile int State_03 = LOW;
volatile int State_04 = LOW;
volatile int State_11 = LOW;
volatile int State_12 = LOW;
//volatile int State_13 = LOW;
volatile int State_14 = LOW;
//volatile int State_21 = LOW;
//volatile int State_22 = LOW;
//volatile int State_23 = LOW;
//volatile int State_24 = LOW;
//------------------------------------------
int CVal = 0;
int scale_0 = 120;
int scale_0MIN = 1;
int scale_0MAX = 255;
int scale_1 = 255;
int scale_1MIN = 127;
int scale_1MAX = 255;
int scale_2 = 1;
int scale_2MIN = 1;
int scale_2MAX = 115;
int SysMode = 0;
volatile int SysMode_0 = LOW;
volatile int SysMode_1 = LOW;
// Inputs Labels from fob
int Fob_D0 = A5;
int Fob_D1 = A4;
int Fob_D2 = A3;
int Fob_D3 = A2;
// Outputs Lables
int Relay_0 = 3;
int Relay_1 = 4;
int Relay_2 = 5;
int Relay_3 = 6;
int Relay_4 = 7;
int PWM_0 = 9;
int PWM_1 = 10;
int PWM_2 = 11;
void setup(void)
{
attachInterrupt(1, fobcall, FALLING); //Fob_VT Uses interup 1 to register fob input
pinMode(Fob_D0, INPUT);
pinMode(Fob_D1, INPUT);
pinMode(Fob_D2, INPUT);
pinMode(Fob_D3, INPUT);
pinMode(Relay_0, OUTPUT);
pinMode(Relay_1, OUTPUT);
pinMode(Relay_2, OUTPUT);
pinMode(Relay_3, OUTPUT);
pinMode(Relay_4, OUTPUT);
pinMode(PWM_0, OUTPUT);
pinMode(PWM_1, OUTPUT);
pinMode(PWM_2, OUTPUT);
}
void loop(void)
{
// Read Fob Pins (order used to match desired function of fob button to action/state)
int D0 = digitalRead(Fob_D0);
int D3 = digitalRead(Fob_D1);
int D2 = digitalRead(Fob_D2);
int D1 = digitalRead(Fob_D3);
// Set outputs
digitalWrite(Relay_0, State_11);
digitalWrite(Relay_1, State_12);
digitalWrite(Relay_0, State_11);
digitalWrite(Relay_1, State_12);
digitalWrite(Relay_0, State_11);
analogWrite(PWM_0, scale_0);
analogWrite(PWM_1, scale_1);
analogWrite(PWM_2, scale_2);
// Determins States and Modes when VT falling edge is detected
CVal = D0+D1*2+D2*3+D3*4+SysMode_0*10+SysMode_1*20;
// Sets the value limits for PWMs
scale_0 = constrain(scale_0, scale_0MIN, scale_0MAX);
scale_1 = constrain(scale_1, scale_1MIN, scale_1MAX);
scale_2 = constrain(scale_2, scale_2MIN, scale_2MAX);
}
// interrupt Call (Keep Commands as simple as possible)
// Use a second switch/case structure in the main loop
// to handle more complex events based on changed states.
void fobcall()
{
switch (CVal) {
//-----SysMode_0--------
case 0:
SysMode_0 = !SysMode_0;
break;
case 1:
++scale_0;
break;
case 2:
--scale_0;
break;
case 3:
State_03 = !State_03;
break;
case 4:
State_04= !State_04;
break;
//-----SysMode_1--------
case 10:
SysMode_0 = !SysMode_0;
SysMode_1 = !SysMode_1;
break;
case 11:
State_11 = !State_11;
break;
case 12:
State_12 = !State_12;
break;
case 13:
SysMode_0 = !SysMode_0; //Used to go directly back to mode one
break;
case 14:
State_14 = !State_14;
break;
//-----SysMode_2--------
case 20:
SysMode_1 = !SysMode_1;
break;
case 21:
++scale_2;
break;
case 22:
--scale_2;
break;
case 23:
--scale_1;
break;
case 24:
++scale_1;
break;
}
}
Sometimes, depending on how the buttons in the key fob are wired, will send multiple button presses( ie multiple buttons pressed at once), even though its not explicitly stated.
If the keyfob is using a SC2262 or equivalent, these chips will send a 4 bit nibble, ie 0 - 15, so you can control
15 devices with them.