/* This program xmtbyte for the IRX 2.0 board with PIC16C84 uses the IR * transmitter to repeatedly send out a 3 byte address which * corresponds to a Media Lab room number. Additionally this program, * listens for the IR receiver and will upload one byte of information * appending this to the transmitted signal. The beacon will continue * to emit this new signal until it recieves verification of the message, * in the form of the same byte again. * * Writen by Dana Kirsch * 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 for port B */ #use RS232(BAUD=2400,XMIT=PIN_7,RCV=PIN_11) /* Possibly for putchar */ #define RED_LED PIN_8 /* Port definitions */ #define IR_XMT PIN_9 #define IR_RCV PIN_10 #define RTCC_PERIOD 160 /* Timing; want 104 uSec 'tics.' */ #define offIR OUTPUT_HIGH(IR_XMT) /* High turns IR_LED off */ #define onIR OUTPUT_LOW(IR_XMT) #define onRED OUTPUT_LOW(RED_LED) #define offRED OUTPUT_HIGH(RED_LED) #define FLOOR 0x00 #define ROOM 0x5F #define LETTER 0x55 /* =========================== 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 = 1650us */ 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) { /* IRstopbit = 100us */ DELAY_US(100); } } #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[4]; /* IR output buffer of 4 bytes */ send_packet() /* Send the IR information packet */ { int x; ircheck = 1; IRsendbyte(1); /* First send a one */ for(x=0; x<4; x++){ /* Send the four bytes of info */ IRsendbyte(irXmtData[x]); ircheck = ircheck^irXmtData[x]; } if (ircheck == 1) ircheck = 2; IRsendbyte(ircheck); /* Last, the error checking byte */ } /* ============================= IR IN ============================= */ int irBit; int irBits=0; int irClk=0; int irRcv[1]; /* Buffer for message received */ int irLast=1; int irOut; int sendRcvState=0; /* Var for I/O state */ int dataInMemory=0; /* State of post-it data */ #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; sendRcvState = 1; } } if (irClk > 250) { sendRcvState = 0; if (dataInMemory == 1) { dataInMemory = 2; } else if (dataInMemory == 3) { dataInMemory = 0; } } if (irBits == 8) { irBits = 9; irOut = irRcv[0]; } irLast = irBit; } #INT_RTCC interrupt_script() { /* Run every time RTCC reaches zero */ SET_RTCC(RTCC_PERIOD); /* Reset countdown */ ir(); } int s, m; int ercheck; int irRcvData; int tmpMemory=9; 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 is zero */ irXmtData[0] = FLOOR; /* Read data in eeprom to array */ irXmtData[1] = ROOM; irXmtData[2] = LETTER; irXmtData[3] = 0x00; ENABLE_INTERRUPTS(GLOBAL); /* Activates interrupt */ while (1) { /* Main loop */ if (sendRcvState == 0) { send_packet(); } for(m=1; m <7 ; m++) { if (irBits == 9) { irBits = 0; if (s == 0 && irOut == 1) { ercheck = irOut; /* First recieve a one */ s = 1; } else if (s == 1) { irRcvData = irOut; /* Then the byte of data */ ercheck = ercheck ^ irOut; s = 2; } else if (s == 2) { if (ercheck == 1) ercheck = 2; if (irOut == ercheck) { /* Match the check byte */ if (tmpMemory == irRcvData) { if (dataInMemory == 0) { irXmtData[3] = irRcvData; /* Upload data */ sendRcvState = 0; dataInMemory = 1; } else if (dataInMemory == 1) { /* Do nothing */ sendRcvState = 0; } else if (dataInMemory == 2) { /* Reset */ irXmtData[3] = 0x00; sendRcvState = 0; dataInMemory = 3; } else sendRcvState = 0; /* Do nothing */ } else tmpMemory = irRcvData; /* Write info to memory */ } s = 0; } else s = 0; } } } }