Skip to content
Newer
Older
100644 298 lines (275 sloc) 10.6 KB
4375d6e @str4w committing arduino code
authored
1 // X10 communication system
2 // codes can be typed on the serial line
3 // and will be sent
4 // codes received will be printed back
5 //
6 // X10 recieve code from an example by Brohogan
7 //
8 // (c) 2012 strawdog3@gmail.com
9 //
10 // License: An ye harm none, do as ye will
11 //
12 // Defines and constants for PSC05 receiving
13
14 #define OFFSET_DELAY 500 // uS from zero cross to center of bit (sugg 500-700 us)
15 #define HALF_CYCLE_DELAY 8334 // Calculated 8334 uS between bit repeats in a half-cycle
16
17 #ifndef ON // use same defines from x10constants.h for rcvd cmnds
18 #define ON B00101 // these are examples
19 #endif
20 #ifndef OFF
21 #define OFF B00111
22 #endif
23
24 byte House[16] = { // Lookup table for House Code
25 B0110, // A
26 B1110, // B
27 B0010, // C
28 B1010, // D
29 B0001, // E
30 B1001, // F
31 B0101, // G
32 B1101, // H
33 B0111, // I
34 B1111, // J
35 B0011, // K
36 B1011, // L
37 B0000, // M
38 B1000, // N
39 B0100, // O
40 B1100, // P
41 };
42
43 byte Unit[16] = { // Lookup table for Unit Code
44 B01100, // 1
45 B11100, // 2
46 B00100, // 3
47 B10100, // 4
48 B00010, // 5
49 B10010, // 6
50 B01010, // 7
51 B11010, // 8
52 B01110, // 9
53 B11110, // 10
54 B00110, // 11
55 B10110, // 12
56 B00000, // 13
57 B10000, // 14
58 B01000, // 15
59 B11000, // 16
60 };
61
62 #include "WProgram.h" // this is needed to compile with Rel. 0013
63 #include <x10.h> // X10 lib is used for transmitting X10
64 #include <x10constants.h> // X10 Lib constants
65 #define RPT_SEND 2 // how many times transmit repeats if noisy set higher
66
67 //#include "PSC05.h" // constants for PSC05 X10 Receiver
68 #define OUT0 8 // YEL pin 4 of PSC05
69 #define OUT1 9 // YEL pin 4 of PSC05
70 #define TRANS_PIN 5 // YEL pin 4 of PSC05
71 #define RCVE_PIN 4 // GRN pin 3 of PSC05
72 #define ZCROSS_PIN 2 // BLK pin 1 of PSC05
73 #define LED_PIN 13 // for testing
74
75 volatile unsigned long mask; // MSB first - bit 12 - bit 0
76 volatile unsigned int X10BitCnt = 0; // counts bit sequence in frame
77 volatile unsigned int ZCrossCnt = 0; // counts Z crossings in frame
78 volatile unsigned long rcveBuff; // holds the 13 bits received in a frame
79 volatile boolean X10rcvd = false; // true if a new frame has been received
80 boolean newX10 = false; // both the unit frame and the command frame received
81 byte houseCode, unitCode, cmndCode; // current house, unit, and command code
82 byte startCode; // only needed for testing - sb B1110 (14)
83
84 x10 SendX10= x10(ZCROSS_PIN,TRANS_PIN);// set up a x10 library instance:
85 int countZC=0;
86 void Check_Rcvr(){ // ISR - called when zero crossing (on CHANGE)
87 if (X10BitCnt == 0) { // looking for new frame
88 delayMicroseconds(OFFSET_DELAY); // wait for bit
89 if(digitalRead(RCVE_PIN)) return; // still high - no start bit - get out
90 digitalWrite(LED_PIN, HIGH); // indicate you got something
91 rcveBuff = 0;
92 mask = 0x1000; // bitmask with bit 12 set
93 rcveBuff = rcveBuff | mask; // sets bit 12 (highest)
94 mask = mask >> 1; // move bit down in bit mask
95 X10BitCnt = 1; // inc the bit count
96 ZCrossCnt = 1; // need to count zero crossings too
97 return;
98 }
99 // Begins here if NOT the first bit . . .
100 ZCrossCnt++; // inc the zero crossing count
101 // after SC (first 4 bits) ignore the pariety bits - so only read odd crossings
102 if (X10BitCnt < 5 || (ZCrossCnt & 0x01)){ // if it's an odd # zero crossing
103 delayMicroseconds(OFFSET_DELAY); // wait for bit
104 if(!digitalRead(RCVE_PIN)) rcveBuff = rcveBuff | mask; // got a 1 set the bit, else skip and leave it 0
105 mask = mask >> 1; // move bit down in bit mask
106 X10BitCnt++;
107
108 if(X10BitCnt == 13){ // done with frame after 13 bits
109 for (byte i=0;i<5;i++)delayMicroseconds(HALF_CYCLE_DELAY); // need this
110 X10rcvd = true; // a new frame has been received
111 digitalWrite(LED_PIN, LOW);
112 X10BitCnt = 0;
113 Parse_Frame(); // parse out the house & unit code and command
114 }
115 }
116 // if(countZC%120==0)
117 // {
118 // Serial.println("checking "+countZC);
119 // }
120 countZC++;
121 }
122
123 void Parse_Frame() { // parses the receive buffer to get House, Unit, and Cmnd
124 if(rcveBuff & 0x1){ // last bit set so it's a command
125 cmndCode = rcveBuff & 0x1F; // mask 5 bits 0 - 4 to get the command
126 newX10 = true; // now have complete pair of frames
127 }
128 else { // last bit not set so it's a unit
129 unitCode = rcveBuff & 0x1F; // mask 5 bits 0 - 4 to get the unit
130 newX10 = false; // now wait for the command
131 for (byte i=0; i<16; i++){ // use lookup table to get the actual unit #
132 if (Unit[i] == unitCode){
133 unitCode = i+1; // this gives Unit 1-16
134 break; // stop search when found!
135 }
136 }
137 }
138 rcveBuff = rcveBuff >> 5; // shift the house code down to LSB
139 houseCode = rcveBuff & 0x0F; // mask the last 4 bits to get the house code
140 for (byte i=0; i<16; i++){ // use lookup table to get the actual command #
141 if (House[i] == houseCode){
142 houseCode = i+65; // this gives House 'A' - 'P'
143 break; // stop search when found!
144 }
145 }
146 rcveBuff = rcveBuff >> 4; // shift the start code down to LSB
147 startCode = rcveBuff & 0x0F; // mask the last 4 bits to get the start code
148 X10rcvd = false; // reset status
149 }
150
151 void X10_Debug(){
152 Serial.print("SC-");
153 Serial.print(startCode,BIN);
154 Serial.print(" HOUSE-");
155 Serial.print(houseCode);
156 Serial.print(" UNIT-");
157 Serial.print(unitCode,DEC);
158 Serial.print(" CMND");
159 Serial.print(cmndCode,DEC);
160 if(cmndCode == ALL_UNITS_OFF) Serial.print(" (ALL_UNITS_OFF)");
161 if(cmndCode == ALL_LIGHTS_ON) Serial.print(" (ALL_LIGHTS_ON)");
162 if(cmndCode == ON) Serial.print(" (ON)");
163 if(cmndCode == OFF) Serial.print(" (OFF)");
164 if(cmndCode == DIM) Serial.print(" (DIM)");
165 if(cmndCode == BRIGHT) Serial.print(" (BRIGHT)");
166 if(cmndCode == ALL_LIGHTS_OFF) Serial.print(" (ALL_LIGHTS_OFF)");
167 if(cmndCode == EXTENDED_CODE) Serial.print(" (EXTENDED_CODE)");
168 if(cmndCode == HAIL_REQUEST) Serial.print(" (HAIL_REQUEST)");
169 if(cmndCode == HAIL_ACKNOWLEDGE) Serial.print(" (HAIL_ACKNOWLEDGE)");
170 if(cmndCode == PRE_SET_DIM) Serial.print(" (PRE_SET_DIM)");
171 if(cmndCode == EXTENDED_DATA) Serial.print(" (EXTENDED_DATA)");
172 if(cmndCode == STATUS_ON) Serial.print(" (STATUS_ON)");
173 if(cmndCode == STATUS_OFF) Serial.print(" (STATUS_OFF)");
174 if(cmndCode == STATUS_REQUEST) Serial.print(" (STATUS_REQUEST)");
175 Serial.println("");
176 }
177 long now,now2;
178 byte state=0,state2=0;
179 void setup() {
180 Serial.begin(9600);
181 pinMode(OUT0,OUTPUT); // onboard LED
182 pinMode(OUT1,OUTPUT); // onboard LED
183 pinMode(LED_PIN,OUTPUT); // onboard LED
184 pinMode(RCVE_PIN,INPUT); // receive X10 commands - low = 1
185 pinMode(ZCROSS_PIN,INPUT); // zero crossing - 60 Hz square wave
186 digitalWrite(RCVE_PIN, HIGH); // set 20K pullup (low active signal)
187 digitalWrite(ZCROSS_PIN, HIGH); // set 20K pullup (low active signal)
188 now = millis();
189 now2 = millis();
190 Serial.println ("All your base are belong to us");
191 attachInterrupt(0,Check_Rcvr,CHANGE);// (pin 2) trigger zero cross
192 }
193
194 char inputWord[2];
195 int parsestate=0;
196 byte hcSend;
197 byte ucSend;
198 byte opCode;
199 int ctr=0;
200
201
202 void loop(){
203
204 if (newX10){ // received a new command
205 X10_Debug(); // print out the received command
206 newX10 = false;
207 }
208 Serial.println("Listening...");
209 // read a string
210 char inData[80];
211 int index=0;
212 inData[index]=0;
213 boolean eol=false;
214 while(!eol)
215 {
216 while(Serial.available()>0) {
217 char aChar = Serial.read();
218 if(aChar == '\n' || aChar == '\r')
219 {
220 // End of record detected. Time to parse
221 eol=true;
222 break;
223 }
224 else
225 {
226 inData[index] = aChar;
227 index++;
228 inData[index] = '\0'; // Keep the string NULL terminated
229 if(index==79) {eol=true; break;}
230 }
231 }
232 }
233
234 //parse
235 switch(inData[0]) {
236 case 'A': hcSend=A; Serial.println("parsed A"); break;
237 case 'B': hcSend=B; Serial.println("parsed B"); break;
238 case 'C': hcSend=C; Serial.println("parsed C"); break;
239 case 'D': hcSend=D; Serial.println("parsed D"); break;
240 case 'E': hcSend=E; Serial.println("parsed E"); break;
241 case 'F': hcSend=F; Serial.println("parsed F"); break;
242 case 'G': hcSend=G; Serial.println("parsed G"); break;
243 case 'H': hcSend=H; Serial.println("parsed H"); break;
244 case 'I': hcSend=I; Serial.println("parsed I"); break;
245 case 'J': hcSend=J; Serial.println("parsed J"); break;
246 case 'K': hcSend=K; Serial.println("parsed K"); break;
247 case 'L': hcSend=L; Serial.println("parsed L"); break;
248 case 'M': hcSend=M; Serial.println("parsed M"); break;
249 case 'N': hcSend=N; Serial.println("parsed N"); break;
250 case 'O': hcSend=O; Serial.println("parsed O"); break;
251 case 'P': hcSend=P; Serial.println("parsed P"); break;
252 default:
253 Serial.print("Unknown house code: ");
254 Serial.println(inData);
255 return;
256 }
257 char codeString[3];
258 codeString[0]=inData[1];
259 codeString[1]=inData[2];
260 codeString[2]=0;
261 int unitCode=atoi(codeString);
262 codeString[0]=inData[3];
263 codeString[1]=inData[4];
264 codeString[2]=0;
265 if(unitCode<1 || unitCode>16) {
266 Serial.print("Illegal unit code: ");
267 Serial.println(unitCode);
268 Serial.println(inData);
269 return;
270 }
271 byte unSend=Unit[unitCode-1];
272 int cmdCode=atoi(codeString);
273 if(cmdCode<0 || cmdCode>31) {
274 Serial.print("Illegal unit code: ");
275 Serial.println(unitCode);
276 Serial.println(inData);
277 return;
278 }
279 Serial.print("Parsed unit: ");
280 Serial.print(unitCode);
281 Serial.print(" ");
282 Serial.print(unSend,BIN);
283 Serial.print(" command: ");
284 Serial.print(cmdCode);
285 Serial.print(" ");
286 Serial.println(cmdCode,BIN);
287
288 detachInterrupt(0); // must detach interrupt before sending
289 SendX10.write(hcSend,unSend,RPT_SEND);
290 SendX10.write(hcSend,cmdCode,RPT_SEND);
291 attachInterrupt(0,Check_Rcvr,CHANGE);// re-attach interrupt
292
293
294
295 }
296
297
Something went wrong with that request. Please try again.