/* This program for an IRX 2.0 board with PIC16C84 uses the IR * reciever to detect the emmisions of various IR beacons placed throughout * the lab. It sends the results of this detection to the RS232 serial port. * Additionally, upon signal from the RS232, it transfers a single byte * message from the RS232 port up to the beacon via the IR LED. * * Writen by Dana Kirsch for April 2nd. * Modified and implemented by Solomon Assefa * */ #include /* Use the PIC16C84 chip */ #include /* Device has a 4Mhz clock [used by DELAY_MS() and DELAY_US()] */ #use DELAY(CLOCK=4000000) #use FAST_IO(B) /* Fast I/O switching of ports */ #use RS232(BAUD=2400,XMIT=PIN_7,RCV=PIN_11) /* Possibly to use the putchar */ #define RED_LED PIN_8 /* Port B pin definitions */ #define IR_RCV PIN_10 #define IR_XMT PIN_9 #define SR_RCV PIN_11 #define SR_XMT PIN_7 #define offIR OUTPUT_HIGH(IR_XMT) /* High turns IR_LED off */ #define onIR OUTPUT_LOW(IR_XMT) #define offRED OUTPUT_HIGH(RED_LED) /* High turns off RED_LED */ #define onRED OUTPUT_LOW(RED_LED) #define offSR OUTPUT_LOW(SR_XMT) /* Low outputs a zero to SRport */ #define onSR OUTPUT_HIGH(SR_XMT) #define RTCC_PERIOD 160 /* Each period is 104us */ /* =========================== MORSE CODE ========================== */ void flash_dit() { onRED; DELAY_MS(100); offRED; DELAY_MS(100); } void flash_dah() { onRED; DELAY_MS(300); offRED; DELAY_MS(100); } void flash_space() { DELAY_MS(200); } /* ========================= IR OUT ========================= */ IRburst(int D) { /* Send one IR bit */ int c; /* Flash 5 times at 38KHz */ for (c=0; c<10; c++) { onIR; DELAY_US(6); offIR; DELAY_US(11); } /* Bit is pause between flashes */ /* This conserves power */ if (D == 0) { /* IRstartbit = 1650 us */ DELAY_MS(1); DELAY_US(250); DELAY_US(250); DELAY_US(150); } else if (D==1) { /* IRonebit = 1100us */ DELAY_MS(1); DELAY_US(100); } else if (D==2) { /* IRzerobit = 550us */ DELAY_US(250); /* PCM problem with # > 255 */ DELAY_US(250); DELAY_US(50); } else if (D==3) { DELAY_US(100); /* IRstopbit = 2000us */ } } #define IRstartbit IRburst(0) #define IRonebit IRburst(1) #define IRzerobit IRburst(2) #define IRstopbit IRburst(3) IRsendbyte(int Z) /* Construct and send one IRbyte */ { DISABLE_INTERRUPTS(GLOBAL); IRstartbit; if (((Z&0x01) )==1) IRonebit; else IRzerobit; if (((Z&0x02) >> 1)==1) IRonebit; else IRzerobit; if (((Z&0x04) >> 2)==1) IRonebit; else IRzerobit; if (((Z&0x08) >> 3)==1) IRonebit; else IRzerobit; if (((Z&0x10) >> 4)==1) IRonebit; else IRzerobit; if (((Z&0x20) >> 5)==1) IRonebit; else IRzerobit; if (((Z&0x40) >> 6)==1) IRonebit; else IRzerobit; if (((Z&0x80) >> 7)==1) IRonebit; else IRzerobit; IRstopbit; ENABLE_INTERRUPTS(GLOBAL); } int ircheck; /* Error checking variable */ int irXmtData[1]; /* IR output buffer of 1 byte */ send_ir_packet() /* Send the IR information packet */ { int x; ircheck = 1; IRsendbyte(1); /* First send a one */ IRsendbyte(irXmtData[0]); /* Send the byte of IR info */ ircheck = ircheck^irXmtData[0]; if (ircheck == 1) ircheck = 2; IRsendbyte(ircheck); /* Finally send the error checking byte */ } /* ========================= SERIAL OUT ========================= */ Sburst(int z) /* Output one serial bit */ { if (z == 0) offSR; else if (z == 1) onSR; DELAY_US(400); /* RS232 protocol delay */ } #define Sstartbit Sburst(0) /* Standard RS232 protocol */ #define Sonebit Sburst(1) #define Szerobit Sburst(0) #define Sstopbit Sburst(1) Ssendbyte(int Z) /* Output one serial byte */ { /* RED_LED flashes during SR_out */ DISABLE_INTERRUPTS(GLOBAL); Sstartbit; if (((Z&0x01) )==1) Sonebit; else Szerobit; if (((Z&0x02) >> 1)==1) Sonebit; else Szerobit; if (((Z&0x04) >> 2)==1) Sonebit; else Szerobit; if (((Z&0x08) >> 3)==1) Sonebit; else Szerobit; if (((Z&0x10) >> 4)==1) Sonebit; else Szerobit; if (((Z&0x20) >> 5)==1) Sonebit; else Szerobit; if (((Z&0x40) >> 6)==1) Sonebit; else Szerobit; if (((Z&0x80) >> 7)==1) Sonebit; else Szerobit; Sstopbit; ENABLE_INTERRUPTS(GLOBAL); } /* ========================= IR IN ========================= */ int srXmtData[4]; /* Buffer for 4 bytes to send */ int irBit; int irBits=0; int irClk=0; int irRcv[1]; /* Buffer for message received */ int irLast=1; int srOut; #inline ir() { /* IR script */ irBit = INPUT(IR_RCV); irClk++; if (irBit == 0 && irLast == 1) { /* Leading edge of 38KHz pulse*/ if (irClk > 13 || irClk < 4) { /* If the timing is off reset */ irClk = 0; irBits = 0; } else if (irClk > 9 && irBits < 8) { irBits++; SHIFT_RIGHT(irRcv, 1, 1); /* Add a one if delay long */ irClk = 0; } else if (irBits < 8) { irBits++; SHIFT_RIGHT(irRcv, 1, 0); /* Add a zero if delay short */ irClk = 0; } } if (irBits == 8) { irBits = 9; srOut = irRcv[0]; } irLast = irBit; } /* ========================= SERIAL IN ========================= */ int srBit; int srBits=0; int srRcv[1]; /* Buffer for Serial data received */ int srLast=1; int irOut; int sendRcvState=0; /* Transmit SR until recieved */ int w; #inline sr() { /* Serial script */ srBit = INPUT(SR_RCV); if (srBit == 0 && srLast == 1) { /* Find the Startbit */ DISABLE_INTERRUPTS(GLOBAL); DELAY_US(385); for(w=1; w<9; w++){ /* Catch the byte -- was 10 */ srBit = INPUT(SR_RCV); SHIFT_RIGHT(srRcv, 1, srBit); srBits++; DELAY_US(385); } srBit = INPUT(SR_RCV); if (srBits == 8) { /* Confirm the Stopbit */ srBits = 15; /* Set the flag */ irOut = srRcv[0]; flash_dit(); } ENABLE_INTERRUPTS(GLOBAL); sendRcvState=1; } else { sendRcvState=0; } srLast = srBit; } /* ========================= MAIN =========================== */ #INT_RTCC interrupt_script() { /* Run every time RTCC reaches zero */ SET_RTCC(RTCC_PERIOD); /* Reset countdown */ ir(); sr(); } int s, m; int c = 0; int ercheck; /* IR error check byte */ main() { DISABLE_INTERRUPTS(GLOBAL); /* Don't interrupt */ SET_TRIS_B(0x30); /* Set B out xpt (IR_RCV,SR_RCV) */ SETUP_COUNTERS(RTCC_INTERNAL, WDT_18MS); ENABLE_INTERRUPTS(RTCC_ZERO); /* Interrupt when RTCC = 0 */ flash_dit(); flash_dit(); flash_space(); flash_dah(); flash_dit(); ENABLE_INTERRUPTS(GLOBAL); /* Activates enabled interrupt */ while (1) { /* Main loop */ if (sendRcvState == 1) { /* Prepare to send IR */ if (srBits == 15) { for(m=0;m<5;m++) /* was 10 */ { srBits = 0; irXmtData[0] = irOut; /* Buffer the byte of data */ send_ir_packet(); /* Upload the message */ } } } if (sendRcvState == 0) { /* No SR signal, Rcv IR */ if (irBits == 9) { irBits = 0; if (s == 0 && srOut == 1) { /* First recieve an IR one */ ercheck = srOut; s = 1; } else if (s >= 1 && s <= 4) { srXmtData[s-1] = srOut; ercheck = ercheck ^ srOut; s++; } else if (s == 5) { if (ercheck == 1) ercheck = 2; if (srOut == ercheck) { /* Match the IR check byte */ Ssendbyte(srXmtData[0]); Ssendbyte(srXmtData[1]); Ssendbyte(srXmtData[2]); Ssendbyte(srXmtData[3]); } s = 0; } else s = 0; } } } }