/**************************************************************************** seatalk_wireless_remote_tx_1.c This program is a remote control transmitter that sends a RxCx number in an eight-byte message sentence with checksum. Message protocol to the wireless receiver * Each 9600 baud message contains a command and checksum: 0xff // wake up the transmitter and receiver 0xff // wake up the transmitter and receiver 0xff // wake up the transmitter and receiver 'J' // character 'S' // character 'F' // character cMsgCode // which key was pressed 'J' + 'S' + 'F' + cMsgCode // equals checksum +5 | 14 ---------- R4 ----6-| B0 A0 |-17-- out to Parallax 433MHz transmitter R3 ----7-| B1 A1 |-18-- out to LED R2 ----8-| B2 | R1 ----9-| B3 | C3 ---13-| B7 | C2 ---12-| B6 | C1 ---11-| B5 | | | 10MHz XTAL-15-| 16F628 | XTAL-16-| | ---------- 5 | Gnd KEYBOARD ASSIGNMENTS C1 C2 C3 +------------------------+ R1 | (cable here) | | | R2 | | | | R3 | | | | R4 | | +------------------------+ ***************************************************************************/ #include <16F628.h> #include#fuses HS, NOPROTECT, PUT, BROWNOUT, NOMCLR, NOLVP, WDT, NOCPD #use fast_io ( A ) #use fast_io ( B ) #use delay ( clock = 10MHZ, restart_wdt ) #use rs232 ( baud = 9600, xmit = PIN_A0 ) #byte PORT_A = 5 #byte PORT_B = 6 #bit LED = PORT_A.1 #bit TX_PWR = PORT_A.2 #define KEY_NONE 0 #define KEY_C1_R1 1 #define KEY_C1_R2 2 #define KEY_C1_R3 3 #define KEY_C1_R4 4 #define KEY_C2_R1 5 #define KEY_C2_R2 6 #define KEY_C2_R3 7 #define KEY_C2_R4 8 #define KEY_C3_R1 9 #define KEY_C3_R2 10 #define KEY_C3_R3 11 #define KEY_C3_R4 12 void SendMsg ( char cMsgCode ); char GetKey ( void ); void DelayMs ( int cCount ); void main ( void ) { char cKey, cCnt, cX; set_tris_a ( 0b11111000 ); // A0, A1, A2 are outputs set_tris_b ( 0b00011111 ); // Columns are outputs, rows are inputs, RB4 is input (LVP) TX_PWR = OFF; setup_counters ( RTCC_INTERNAL, WDT_36MS ); // 256 * 4uS = 1.024mS timer wrap port_b_pullups ( TRUE ); disable_interrupts ( GLOBAL ); cCnt = 0; // preset LED flash for ( cX = 0; cX < 20; cX++ ) // 2 second power up flash { LED = HIGH; DelayMs ( 50 ); LED=LOW; DelayMs ( 50 ); } while ( TRUE ) // do forever { sleep(); // stop here, wait for WDT every 36mS if ( cCnt++ >= 138 ) // flash LED once every 5 seconds @ 36mS WDT { LED = HIGH; DelayMs ( 10 ); LED = LOW; cCnt = 0; } cKey = GetKey(); if ( cKey != KEY_NONE ) { switch ( cKey ) { case KEY_C1_R1: { SendMsg ( KEY_C1_R1 ); break; } case KEY_C1_R2: { SendMsg ( KEY_C1_R2 ); break; } case KEY_C1_R3: { SendMsg ( KEY_C1_R3 ); break; } case KEY_C1_R4: { SendMsg ( KEY_C1_R4 ); break; } case KEY_C2_R1: { SendMsg ( KEY_C2_R1 ); break; } case KEY_C2_R2: { SendMsg ( KEY_C2_R2 ); break; } case KEY_C2_R3: { SendMsg ( KEY_C2_R3 ); break; } case KEY_C2_R4: { SendMsg ( KEY_C2_R4 ); break; } case KEY_C3_R1: { SendMsg ( KEY_C3_R1 ); break; } case KEY_C3_R2: { SendMsg ( KEY_C3_R2 ); break; } case KEY_C3_R3: { SendMsg ( KEY_C3_R3 ); break; } case KEY_C3_R4: { SendMsg ( KEY_C3_R4 ); break; } } } } } GetKey ( void ) { char cKey, cPortBIn; restart_wdt(); cKey = KEY_NONE; // default is invalidated key PORT_B = 0b00011111; // make all three columns low delay_us ( 500 ); // wait for row lines to settle (was 5mS, lowered to consume less avg pwr) if ( ( PORT_B & 0x0F ) != 0x0F ) // if any row line is low { DelayMs ( 5 ); // debounce PORT_B = 0b01111111; // make C3 low delay_us ( 10 ); // wait 10uS to settle cPortBIn = PORT_B; // get port B contents if ( ( cPortBIn & 0x0F ) == 0b00001110 ) // check rows { cKey = KEY_C3_R4; } if ( ( cPortBIn & 0x0F ) == 0b00001101 ) { cKey = KEY_C3_R3; } if ( ( cPortBIn & 0x0F ) == 0b00001011 ) { cKey = KEY_C3_R2; } if ( ( cPortBIn & 0x0F ) == 0b00000111 ) { cKey = KEY_C3_R1; } PORT_B = 0b10111111; // make C2 low delay_us ( 10 ); // wait 10uS to settle cPortBIn = PORT_B; // get port B contents if ( ( cPortBIn & 0x0F ) == 0b00001110 ) // check rows { cKey = KEY_C2_R4; } if ( ( cPortBIn & 0x0F ) == 0b00001101 ) { cKey = KEY_C2_R3; } if ( ( cPortBIn & 0x0F ) == 0b00001011 ) { cKey = KEY_C2_R2; } if ( ( cPortBIn & 0x0F ) == 0b00000111 ) { cKey = KEY_C2_R1; } PORT_B = 0b11011111; // make C1 low delay_us ( 10 ); // wait 10uS to settle cPortBIn = PORT_B; // get port B contents if ( ( cPortBIn & 0x0F ) == 0b00001110 ) // check rows { cKey = KEY_C1_R4; } if ( ( cPortBIn & 0x0F ) == 0b00001101 ) { cKey = KEY_C1_R3; } if ( ( cPortBIn & 0x0F ) == 0b00001011 ) { cKey = KEY_C1_R2; } if ( ( cPortBIn & 0x0F ) == 0b00000111 ) { cKey = KEY_C1_R1; } DelayMs ( 5 ); PORT_B = 0b00011111; // make all three columns low delay_us ( 10 ); // wait 10uS to settle while ( ( PORT_B & 0x0F ) != 0x0F ) // wait until all rows are high (no keys pressed ) { DelayMs ( 5 ); } } PORT_B = 0b11111111; // make all three columns high return ( cKey ); } void SendMsg ( char cMsgCode ) { TX_PWR = ON; LED = HIGH; DelayMs ( 10 ); // power on time for transmitter (at least 4mS) putc ( 0x00 ); // wake up the receiver putc ( 0x00 ); // wake up the receiver putc ( 0x00 ); // wake up the receiver putc ( 'J' ); putc ( 'S' ); putc ( 'F' ); putc ( cMsgCode ); putc ( 'J' + 'S' + 'F' + cMsgCode ); // checksum restart_wdt(); LED = LOW; TX_PWR = OFF; } void DelayMs ( int cCount ) { int cX; for ( cX = 0; cX < cCount; cX++ ) { delay_ms ( 1 ); restart_wdt(); } }