/* 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); }