///////////////////////////////////////////////////////////////////////// //// Sony.C //// //// Program to read Sony remote control and convert to ASCII //// //// This program uses the RTCC (timer0) to time a single pulse //// //// input to the PIC. It reads the Sony IR from pin 4 (port pin 3) //// //// It outputs the ASCII serial on pin 7 (port pin 0). //// //// It was improved over previous version by limiting length of ///// //// allowed start pulse and checking for valid values. ////// ///////////////////////////////////////////////////////////////////////// #include <12C509.H> #list #fuses PAR,NOPROTECT,NOWDT,INTRC,MCLR /*for internal clock */ //#fuses PAR,NOPROTECT,NOWDT,XT,MCLR /* for external crystal/resonat*/ #use delay(clock=4000000) #use rs232(baud=2400, xmit=PIN_B0) //#rom 0x03ff={0x0c40} /*w factor for EPROM devices*/ #define START_MIN 100 /* 16us X 120 = 2.0ms min start bit */ #define START_MAX 260 /* 16us X 260 = 4.2ms max start bit */ #define BITTIME 60 /* 16us X 63 = 1ms 700us = 0 1200us = 1 */ byte const valid_code[22] = {128,129,130,131,132,133,134,135,136,137, 146,147,144,145,88,89,92,91,90,106,148,187}; byte time, n; byte prev_value, value; byte check_for_valid( byte code){ for(n=0;n<=21;n++){ if(code==valid_code[n]) return(1); } return(0); } void wait_for_high_to_low() { while(!input(PIN_B3)) ; /* if it's high, wait for a low */ delay_us(3); /* account for fall time */ while(input(PIN_B3)); /* wait for signal to go high */ } void wait_for_high() { delay_us(3); /* account for rise time */ while(!input(PIN_B3)); /* wait for signal to go high */ } main() { setup_counters( RTCC_INTERNAL, RTCC_DIV_16); do { value = 0; do { /* start bit */ wait_for_high_to_low(); /* must be between 2-3ms */ set_rtcc(0); wait_for_high(); time = get_rtcc(); } while ((time < START_MIN) || (time > START_MAX)); for (n = 0 ; n <= 7 ; n++){ /*get data bits */ wait_for_high_to_low(); set_rtcc(0); wait_for_high(); time = get_rtcc(); if (time > BITTIME) bit_set(value,n); } /*Get data bit 8 */ bit_clear(value,6); /* This code removes the value for bit 6*/ wait_for_high_to_low(); /* and uses the value of bit 8 instead */ set_rtcc(0); /* bits 6,9,10, and 11 are ignored */ wait_for_high(); time = get_rtcc(); if (time > BITTIME) bit_set(value,6); if(prev_value == value){ /* must be same twice in a row */ if(check_for_valid(value)) /* must be one of valid codes */ printf("%c", value); /* output value to serial port in ASCII */ } prev_value = value; } while (TRUE); }