'jleblanc 3.21.06
'NEW VERSION WITH crappy CALL AND RESPONSE ESQ SYSTEM
'this code writes a keyboard input out to the LCD
'Hiting enter will send the message to Processing and display it
'the LCD will clear so you can start again!
'uses code from Daryl Owen 7/11/00 (see my website for link)
'for my connector:
'red to ground
'white to power
'black to C4
'yellow to C5
'See just below for LCD setup
DEFINE OSC 20
'SETUP COMMUNICATION WITH XPORT
' We communicate with the XPort using 9600 8N1 serial
true9600 CON 84
timeOut CON 50 ' the serial incoming timeout in milliseconds
'NOTE: this code is not currently using the timeOut constant
' Our serial communication pins
tx VAR PORTC.6
rx VAR PORTC.7
' Used to read data from the XPort
inByteX VAR BYTE 'gets mouseposition X
inByteX=1
inByteY VAR BYTE 'gets mouseposition Y
inByteY=1
' Used to send a byte from the XPort
outByte VAR BYTE
' Track whether or not we are connected to the remote server
connected VAR BIT
connected = 0
'SETUP LCD
'This setup will tell PBP a 2-line LCD is connected in 4-bit
'mode with the data bus on the top 4 bits of PORTB, Register
'Select on PORTB.1, and Enable on PORTB.0.
'Data Bits go like: 3>B.7, 2>B.6, 1>B.5, 0>B.4
DEFINE LCD_DREG PORTB
' Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_DBIT 4
' Set LCD Register Select port
DEFINE LCD_RSREG PORTB
' Set LCD Register Select bit
DEFINE LCD_RSBIT 1
' Set LCD Enable port
DEFINE LCD_EREG PORTB
' Set LCD Enable bit
DEFINE LCD_EBIT 0
' Set LCD bus size (4 or 8 bits)
DEFINE LCD_BITS 4
' Set number of lines on LCD
DEFINE LCD_LINES 2
' Set command delay time in us
DEFINE LCD_COMMANDUS 2000
' Set data delay time in us
DEFINE LCD_DATAUS 50
'Variables used to interface with keyboard
Keypress VAR BYTE'Keyboard value read from keyboard
AscKey VAR BYTE'This is used to send key scan data and subroutine controls to other subroutines
TempReg VAR BYTE'Misc temp register
Temp2Reg VAR BYTE'Misc temp register
ShiftReg VAR BIT'Stores the shift key status. 1=shift 0=no shift
DumpReg VAR BIT'Temp reg for dumping keypress values after a releasecommand
'Message array
i VAR BYTE
pos VAR BYTE
Msg VAR BYTE[24]
control VAR BYTE
'initialize
pos=0
FOR i=0 TO 23
Msg[i]=" "
NEXT i
LCDOUT $fe, 1 ' Clear screen
LCDOUT "Starting Up" ' Send Hello Message
PAUSE 5000
LCDOUT $fe, 1 ' Clear screen
Main:
GOSUB ScanKeyboard'Gets key pressed keycode
GOSUB BackSpace 'Handles backspacing
GOSUB ChrtoASCII'Changes keycode into ascii
GOSUB UpdateMSG 'Updates Msg array
GOSUB RenderScreen 'Updates LCD
GOTO Main
WAITmsg:
'After the command A is sent
'control will get number of pieces
'We KNOW that processing will send 24 pieces
SERIN2 rx,true9600,[wait ("A"),control]
FOR i=0 TO control-1 'Control will always be 24
SERIN2 rx, true9600, [Msg[i]]
NEXT
GOSUB RenderScreen
'THEN wait for return to exit and return
GOSUB ScanforReturn
RETURN
ScanKeyboard:
DumpReg = 0
DumpKeys:'NOTE
AscKey = 0
Keypress = 0
TrisC.5 = 1 : PortC.5 = 1 'Release Clock Line for Com from Keyboard to PIC
GOSUB ClockCycle'Dumps start bit
FOR TempReg = 0 TO 7
GOSUB ClockCycle
IF PortC.4 = 1 THEN 'Calculates bit value
LOOKUP TempReg,[1,2,4,8,16,32,64,128],Temp2Reg
Keypress = Keypress + Temp2Reg'Adds the bit values together
ENDIF
NEXT TempReg
GOSUB ClockCycle'Dumps parity bit
GOSUB ClockCycle'Dumps stop bit
TrisC.5 = 0 : PortC.5 = 0 'Set Clock Line Low and hold Com from Keyboard to PIC
IF Keypress = $F0 THEN'If key release command then go again
DumpReg = 1'Set so that next key will also get dumped
GOTO DumpKeys'Rerun loop
ENDIF
IF Keypress=$58 || Keypress=$12 || Keypress=$59 && DumpReg = 1 THEN'Turn off ShiftReg
ShiftReg = 0'Sets the Shift Reg for Shift
AscKey = 255'Will not print anything on LCD
ENDIF
IF DumpReg = 1 THEN'If this loop was to dump chr then send a 255 to next
DumpReg = 0 '???????
Keypress = 255
ENDIF
IF Keypress=$58 || Keypress=$12 || Keypress=$59 THEN'Turn on ShiftReg
ShiftReg = 1'Sets the Shift Reg for Shift
AscKey = 255'Will not print anything on LCD
ENDIF
'IF hit return then send message
IF Keypress=$5A THEN'Turn on ShiftReg
HIGH PortA.0
GOSUB SENDmsg
'We want now to reset everything
FOR i=0 TO 23
Msg[i]=" "
NEXT
pos=0
'GO TO SOMETHING LIKE A WAIT ROUTINE
GOSUB WAITmsg
AscKey = 255'Will not print anything on LCD
ENDIF
RETURN
ScanforReturn:
DumpReg = 0
DumpKeysAA:'NOTE
AscKey = 255'NOTE WAS 0 !!!!!!
Keypress = 0
TrisC.5 = 1 : PortC.5 = 1 'Release Clock Line for Com from Keyboard to PIC
GOSUB ClockCycle'Dumps start bit
FOR TempReg = 0 TO 7
GOSUB ClockCycle
IF PortC.4 = 1 THEN 'Calculates bit value
LOOKUP TempReg,[1,2,4,8,16,32,64,128],Temp2Reg
Keypress = Keypress + Temp2Reg'Adds the bit values together
ENDIF
NEXT TempReg
GOSUB ClockCycle'Dumps parity bit
GOSUB ClockCycle'Dumps stop bit
TrisC.5 = 0 : PortC.5 = 0 'Set Clock Line Low and hold Com from Keyboard to PIC
IF Keypress = $F0 THEN'If key release command then go again
DumpReg = 1'Set so that next key will also get dumped
GOTO DumpKeysAA'Rerun loop
ENDIF
IF DumpReg = 1 THEN'If this loop was to dump chr then send a 255 to next
DumpReg = 0 '???????
Keypress = 255
ENDIF
'IF hit return then exit and ready to write again
'ELSE rerun the loop
IF Keypress=$5A THEN
'We want now to reset everything
FOR i=0 TO 23
Msg[i]=" "
NEXT
pos=0
AscKey = 255'Will not print anything on LCD
ELSE
GOTO DumpKeysAA'Rerun loop
ENDIF
RETURN
SENDmsg:
FOR i=0 TO 23
SEROUT2 tx, true9600, [Msg[i]]
NEXT
RETURN
UpdateMSG:'This will convert the key scan codes to ASCCII
IF AscKey <> 255 THEN
Msg[pos]=Keypress
pos=pos+1
IF pos > 23 THEN pos=23
ENDIF
RETURN
RenderScreen:
'Clear Screen
LCDOUT $fe, 1
'Render first line
FOR i=0 TO 11
LCDOUT Msg[i]
NEXT
'Move to second line
LCDOUT $fe, $C0
'Render second line
FOR i=12 TO 23
LCDOUT Msg[i]
NEXT
RETURN
ClockCycle:'Waits for the clock to cycle from keyboard
HoldClockLow:
IF PortC.5 = 0 THEN HoldClockLow
HoldClockHi:
IF PortC.5 = 1 THEN HoldClockHi
RETURN
ChrtoASCII:'Converts keycode into ASCII
IF AscKey <> 255 THEN
AscKey = 255
LOOKDOWN Keypress,[69,22,30,38,37,46,54,61,62,70,28,50,33,35,36,43,52,51,67,59,66,75,58,49,68,77,21,45,27,44,60,42,29,34,53,26,41,78,85,93,84,91,76,82,65,73,74],AscKey
IF ShiftReg = 0 THEN
LOOKUP AscKey,["0123456789abcdefghijklmnopqrstuvwxyz -=|{};',./"],Keypress
ELSE
LOOKUP AscKey,[")!@#$%^&*(ABCDEFGHIJKLMNOPQRSTUVWXYZ _+|{}:'<>?"],Keypress
ENDIF
ENDIF
RETURN
BackSpace:
IF Keypress = $66 THEN'Backspace key pressed
IF pos=23 THEN
IF Msg[pos]=" " THEN
pos=pos-1: Msg[pos]=" "
ELSE
Msg[pos]=" "
ENDIF
ELSE
IF pos > 0 THEN
pos=pos-1
Msg[pos]=" "
ENDIF
ENDIF
AscKey = 255 'Don't enable further writing
ENDIF
RETURN
'//jleblanc 3.20.06
'//This is not very clean but it recieves bytes (24)
'//from the PIC and displays it in the window
'//IMPORT JAVA .awt FOR GUI//
'import java.awt.*;
'import java.io.*; // this is the input/output library needed for data streams
'import java.net.*; // this is the network library needed for sockets
'public class Messenger extends PApplet implements ActionListener
'{
' //NETWORK STUFF
' String host;
' int port;
' Socket mySocket; // declare Socket
' DataInputStream myInputStream; // declare data input stream. This will run within a socket, bringing data into Java
' DataOutputStream myOutputStream; // declare data output stream. This will run within a socket, sending data out from Java
' byte myDataIn, myDataOut; // declare some variables to store the data we're sending and receiving
' //NOTE that in processing a byte is from 127 to -128 where:
' //for a byte from 0-255 0->0, 127->127, 128->-128, 255->-1
' int DATA=0;
' //String message;
' int holdsize;
' byte[] hold = new byte[30];
' //STRING STUFF
' String message;
' TextField input = new TextField("msg", 25);
' Button send = new Button();
' PFont font;
' //VARIABLES NEEDED//////////////////////////
' //String[] stringhold = new String[1];
' String displayString;
' byte[] bytehold = new byte[24];
' int i;
' int signal;
' int flip;
'////////////////////////////////////////////
' void setup()
' {
' size(500,250);
' background(0);
' //SET NETWORK STUFF
' host = "128.122.151.199"; // define a host to communicate with. This can be a name or IP address
' port = 10001; // define a port to contact on that host. Must be a number, typically 10001 for an XPort
' //SET INTERFACE STUFF
' font = loadFont("ArialMT-24.vlw");
' //Storage Variables
' message = "test";
' displayString="initial";
' flip=0;
' }//END setup
' void draw ()
' {
' background(50); smooth (); fill(255);
' textFont(font); textSize(24);
' //CHECK NETWORK
' checkConnection(host, port); // subroutine to create a connection, via a socket, to the XPort
' //Get the incoming Message
' GatherMsg();
' //After that send a message back
' Acknowledge();
' println("FLIP "+flip);
' }//END draw
' void Acknowledge()
' {
' int ddd;
' String a=str(millis()%1000);
' if(flip==1)
' {
' //NOTE this should be given a max size
' myDataOut = 65;
' sendSomeData(myDataOut);
' holdsize=message.length();
' myDataOut = (byte) 24;//holdsize;
' sendSomeData(myDataOut);
' for(int i=0; i<hold.length; i++)
' {
' hold[i]=(byte)' ';
' }
' for(int i=0; i<a.length(); i++)
' {
' hold[i]=(byte) a.charAt(i);
' }
' //SECOND we send the message
' //The question is should we send a signal character ahead of time?
' for(int i=0; i<holdsize;i++)
' {
' myDataOut = hold[i];//redundant in some ways
' sendSomeData(myDataOut);
' //should we pause in these gaps?
' }
' //flip=0;
' delay(10); //WE WAIT SO DON'T OVERLOAD PIC??????
' }
' }//END Acknowledge
' void GatherMsg()
' {
' String[] stringhold = new String[1];
' signal=0;
' i=0;
' //while (dataIsWaiting()==false)
' //{}
' while (dataIsWaiting() == true)
' {
' myDataIn = getSomeData();
' bytehold[i]=(byte)(myDataIn);
' i++;
' signal=1;
' flip=1;
' }
' if(signal==1)
' {
' //initialize msg
' stringhold[0]="";
' //Load the string
' for(int x=0; x<i; x++)
' { stringhold=append(stringhold,str((char)bytehold[x])); println(x);}
' //Create single string
' displayString=join(stringhold,"");
' }
' text(displayString, 20,20);
' }
'//INTERFACE FUNCTIONS
' void actionPerformed(ActionEvent e)
' {
' String command = e.getActionCommand();
' if (command == "SEND")
' {
' message = getText(input);//message gets whatever is in the text box
' //NOW WE MUST SEND IT!!!!!
' //So this is the test send a message section
' //We want to take a string and break it up into an array of bytes and then send them
' //FIRST we load the hold array with the message
' //NOTE this should be given a max size
' myDataOut = 65;
' sendSomeData(myDataOut);
' holdsize=message.length();
' myDataOut = (byte) holdsize;
' sendSomeData(myDataOut);
' for(int i=0; i<message.length(); i++)
' {
' hold[i]=(byte) message.charAt(i);
' }
' //SECOND we send the message
' //The question is should we send a signal character ahead of time?
' for(int i=0; i<holdsize;i++)
' {
' myDataOut = hold[i];//redundant in some ways
' sendSomeData(myDataOut);
' //should we pause in these gaps?
' }
' }//END of if for send
' }//END actionPerformed
' String getText(TextField input)
' {
' return input.getText();
' }
'//NETWORK FUNCTIONS
' ////////CHECK CONNECTION\\\\\\\\
'void checkConnection(String host, int port)
'{
' if(mySocket == null || mySocket.isConnected() == false)
' {
' println("trying to connect to: " + host + " at port: " + port);
' try // make an attempt to run the following code
' {
' mySocket = new Socket(host,port); // initialize socket, connecting it to a host computer's port
' println("connected!");
' }
' catch(Exception e) // if the "try" attempt gave an error, run the following code
' {
' e.printStackTrace(); // print the error to the log
' println("unable to connect to: " + host + " at port: " + port);
' }
' }
'}
'////////CHECK TO SEE IF DATA IS WAITING TO COME IN\\\\\\\\\\\
'boolean dataIsWaiting()
'{
' boolean bytesAvailable = false;
' if ( myInputStream == null) // if there's no active input stream
' {
' try // create an new input stream from a particular socket
' {
' myInputStream = new DataInputStream(mySocket.getInputStream());
' println("opening input stream");
' }
' catch (Exception e)
' {
' e.printStackTrace();
' println("error while opening input stream");
' }
' }
' try
' {
' if (myInputStream.available()>0) // check to see if any bytes are available
' {
' bytesAvailable = true; // ...and if they are set the variable to true
' println(myInputStream.available() + " bytes available...");
' }
' }
' catch(Exception e)
' {
' e.printStackTrace();
' println("error while checking for bytes available");
' }
' return bytesAvailable;
'}
'////////GET SOME DATA \\\\\\\\\\
'byte getSomeData()
'{
' byte inData = 0; // declare and initialize the data variable
' try
' {
' if (myInputStream.available()>0) // only read the byte if there's a byte to read [this is a redundant check]
' {
' inData = myInputStream.readByte(); // read a byte from the input stream
' println("data received: " + inData);
' }
' }
' catch(Exception e)
' {
' e.printStackTrace();
' println("no data");
' }
' return inData;
'}
'////////SEND SOME DATA\\\\\\\\\\
'void sendSomeData(byte outData)
'{
' if (myOutputStream == null) // if there's no active output stream
' {
' try
' {
' myOutputStream = new DataOutputStream(mySocket.getOutputStream()); // create an new output stream from a particular socket
' }
' catch (Exception e)
' {
' e.printStackTrace();
' // println("no output stream");
' }
' }
' try
' {
' myOutputStream.writeByte(outData); // write a byte to the output stream
' //println("data sent: " + outData);
' }
' catch(Exception e)
' {
' e.printStackTrace();
' //println("event send failed");
' }
'}
'public void stop() // when the program quits
'{
' try
' {
' myInputStream.close(); // close the input stream
' myOutputStream.close(); // close the output stream
' mySocket.close(); // close the socket
' }
' catch (Exception e)
' {
' e.printStackTrace();
' println("couldn't close connection");
' }
'}
'}//END Messenger