/****************************************************************************
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();
}
}