/*
The code is to interface a DSC PC1500RK alarm keypad.
It has 15 keys, 11 LEDs, and a Beeper that can be controlled.
This code cycles through all the LEDs in a top-down fashion.
The beeper is used to acknowledge that a key has been pressed.
If the key was pressed successfully, its character is output on the serial line, at 9600 bps.
I was originally communicating at 115200, but due to the read speed, and also the tendency to
quickly overfill the read buffer if lots of commands are sent at once, I slowed it down to 9600.
It is still possible to overfill the buffer, but that is mainly if you sends tons of flag
altering commands, or if you send a bunch of beep/delay commands all at once.
The general thing, is Hurry up and wait. :).
(In other words, maintain a slower pace whenever possible.)
The fastest that this keypad can be read out, is ~30 times a second. I tried doing 500
microsecond delays between clock cycles, and things started becoming unresponsive.
Wiring is simple. Red is Vcc, hooked to 5V
Black is Gnd.
Yellow is the Clock line. In this configuration, it is on Digital Pin 3.
Green is Data, and is on Digital Pin 2.
Beeper 0x0001
unknown 0x0002
unknown 0x0004
Trouble LED 0x0008
By-Pass LED 0x0010
Memory LED 0x0020
Armed LED 0x0040
Ready LED 0x0080
unknown 0x0100
unknown 0x0200
Zone 6 LED 0x0400
Zone 5 LED 0x0800
Zone 4 LED 0x1000
Zone 3 LED 0x2000
Zone 2 LED 0x4000
Zone 1 LED 0x8000
Matrix output is in the format of RCCCRRRR.
Matrix Output Key Output ^ 0xFF
11111111 -Nothing 0x00
10111110 1 0x41
11011110 2 0x21
11101110 3 0x11
10111101 4 0x42
11011101 5 0x22
11101101 6 0x12
10111011 7 0x44
11011011 8 0x24
11101011 9 0x14
10110111 * 0x48
11010111 0 0x28
11100111 # 0x18
00111111 F 0xC0
01011111 E 0xA0
01101111 P 0x90
*/
#define CLOCKPIN 3
#define DATAPIN 2
#define NO_FLAGS 0x0000
#define BUZZER 0x0001
#define TROUBLE 0x0008
#define BYPASS 0x0010
#define MEMORY 0x0020
#define ARMED 0x0040
#define READY 0x0080
#define ZONE_1 0x8000
#define ZONE_2 0x4000
#define ZONE_3 0x2000
#define ZONE_4 0x1000
#define ZONE_5 0x0800
#define ZONE_6 0x0400
#define NO_KEY_PRESSED 0
void setup() {
//Pin 2 is Data, and is bidirectional.
//Pin 3 is Clock, and is an output.
pinMode(DATAPIN, OUTPUT);
pinMode(CLOCKPIN, OUTPUT);
Serial.begin(9600); //Any faster, and we run the risk of doing hurry up and wait.
}
int readdata(int control)
{
int i,j=0,k=control;
int bitcount=0;
for(i=0;i<8;i++)
{
j<<=1;
digitalWrite(DATAPIN,HIGH);
digitalWrite(CLOCKPIN,LOW);
delayMicroseconds(625);
//delay(1);
if(digitalRead(DATAPIN)==LOW)
j|=1;
digitalWrite(CLOCKPIN,HIGH);
delayMicroseconds(625);
//delay(1);
}
for(i=0;i<16;i++)
{
if(k&0x8000)
digitalWrite(DATAPIN,HIGH);
else
digitalWrite(DATAPIN,LOW);
digitalWrite(CLOCKPIN,LOW);
delayMicroseconds(625);
//delay(1);
digitalWrite(CLOCKPIN,HIGH);
delayMicroseconds(625);
//delay(1);
k<<=1;
}
if(j==0x41) return '1';
if(j==0x42) return '4';
if(j==0x44) return '7';
if(j==0x48) return '*';
if(j==0x21) return '2';
if(j==0x22) return '5';
if(j==0x24) return '8';
if(j==0x28) return '0';
if(j==0x11) return '3';
if(j==0x12) return '6';
if(j==0x14) return '9';
if(j==0x18) return '#';
if(j==0x90) return 'P';
if(j==0xA0) return 'E';
if(j==0xC0) return 'F';
return 0;
}
void loop() {
int i;
static int last_key_pressed=0,key_just_pressed;
static unsigned int flags=0x80;
static unsigned int buzzer_counter=0;
int breakloop=0;
while(Serial.available() && (breakloop==0))
{
i=Serial.read();
if((i>='1')&&(i<='6'))
flags ^= (ZONE_1 >> (i-'1'));
if((i=='r')||(i=='R'))
flags ^= READY;
if((i=='a')||(i=='A'))
flags ^= ARMED;
if((i=='m')||(i=='M'))
flags ^= MEMORY;
if((i=='b')||(i=='B'))
flags ^= BYPASS;
if((i=='t')||(i=='T'))
flags ^= TROUBLE;
if(i=='S')
{
flags |= BUZZER;
buzzer_counter+=16;
break;
}
if(i=='s')
{
flags |= BUZZER;
buzzer_counter++;
break;
}
if(i==' ')
break;
}
if(buzzer_counter)
buzzer_counter--;
else
flags &= ~BUZZER;
i=readdata(flags ^ key_just_pressed);
if(last_key_pressed==NO_KEY_PRESSED)
{
if(i != NO_KEY_PRESSED)
Serial.print((char)(i));
}
if((last_key_pressed!=i)&&(last_key_pressed==NO_KEY_PRESSED))
key_just_pressed=BUZZER;
else
key_just_pressed=NO_FLAGS;
last_key_pressed=i;
delayMicroseconds(3333);
}