'jleblanc 3.7.06
'rough message sender
'processing code at bottom

'*******************************************************************
'SETUP 
'*******************************************************************
DEFINE OSC 20

'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

'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 ADC REGISTERS
    'Setup ADC pins
        DEFINE ADC_BITS 10
        DEFINE ADC_CLOCK 3
        DEFINE ADC_SAMPLEUS 5
        TRISA = %11111111  'set all "A" ports to inputs
        adcon1 = %10000010 'right justify results(?)
    'declare variables
        adcVar VAR WORD 'store adc input value

'SETUP STATUS LED
    statusPin VAR PORTC.4
    OUTPUT statusPin
    'LED var byte

'SETUP COUNTER VARIABLE (used in blinkLED subroutine)
    counter VAR BYTE
    
'SETUP PAUSE CONSTANT
    'This pause is used in main
     waitp CON 1  

'SETUP Message system
    i VAR BYTE
    Message VAR BYTE[10]
    control VAR BYTE
    control=0


'*******************************************************************
'RUN
'*******************************************************************

'LET XPORT BOOT UP
    ' Turn on our LED so we know that the startup sequence is going
        HIGH statusPin
    ' Wait for the XPort to boot up
        PAUSE 5000
    ' Turn off the status LED while operating
        LOW statusPin

    MAIN:
        'Get and send bytes
        GOSUB READABYTE
        GOSUB CHECKINPUT
        GOSUB SENDANALOGVALUES
        
        'Display
        LCDOUT $fe, 1, "msg:"
        FOR i=0 TO control-1
            LCDOUT  Message[i]   ' Send X value
    '        Lcdout $fe, 1, "X=", inbyteX   ' Send X value
    '        Lcdout $fe, $c0, "Y=", inbyteY ' Send Y value
        NEXT
        PAUSE waitp
    GOTO MAIN
    
    CHECKINPUT:                     
        IF inByteX > 100 THEN
            'gosub BLINKLED 'NOTE we don't use this as it interrupts data system
            HIGH statusPin
        ELSE
            LOW statusPin
        ENDIF
    RETURN
    
    
    READABYTE:
             'After the command A is sent
             'control will get number of pieces
             SERIN2 rx,true9600,[wait ("A"),control]
             FOR i=0 TO control-1
                  SERIN2 rx, true9600, [Message[i]]
             NEXT
            
            'SERIN2 rx, true9600, [Message[0]]
            
            
'            'Wait until the character “A” is received serially on 
'            'Pin1 and put next character into inByteX
'        	    SERIN2 rx,true9600,[wait ("A"),inByteX]
'        	    SERIN2 rx,true9600,[wait ("B"),inByteY]
'       	    'NOTE this is old system:
'    	    'serin2 rx, true9600, timeOut, noData, [inByte]
    RETURN
    
    NODATA:
        'NOT currently being used
        'inByte = 0
    RETURN
    
    SENDANALOGVALUES:
         ADCIN 0, adcVar  '0-1024
         outByte = adcVar/4'convert to byte
         SEROUT2 tx, true9600, [outByte]
    RETURN
    
    BLINKLED:
        counter = 0
        WHILE counter < 3
            HIGH portc.4
            PAUSE 100
            LOW portc.4
            PAUSE 100
            counter = counter + 1
        WEND
    RETURN



' //jleblanc 3.6.06
'//Works with the Xport and PIC

'// rob@faludi.com
'// A full example for using Sockets in Processing to communicate with a Lantronix XPort.
'// This program could also be used to communicate primitive variables (bytes) with any other TCP/IP enabled device.
'//
'// We open a Socket, check to see if data is available, get a byte of data
'// from the remote device, and then send a byte of data to the remote device.
'// At the end of the program, we close the streams of data and close the Socket.
'// (Once you are done debugging your code, you should remove all the println statements for better speed.)


'import java.io.*;  // this is the input/output library needed for data streams
'import java.net.*; // this is the network library needed for sockets

'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[30];
'  byte[] hold = new byte[30];

'void setup()
'{
'  size(255,255);
'  background(0);
'  framerate(30);
'  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

'  message="howA";
  

'}


'void draw()
'{
'  checkConnection(host, port);        // subroutine to create a connection, via a socket, to the XPort
'  if (dataIsWaiting() == true)        //  check to see if there's new data waiting to come in
'  {     
'    myDataIn = getSomeData();         //  ... and if there's new data, get it
'  }
  
'  //Every 2 milliseconds we send the data. We do every 2 seconds
'  //Because the PIC looks for data every 2 milliseconds so this gives the PIC time
'  if(millis()%2==0)
'  {
'    //Note that this sequence (X then Y) is what the PIC expects
'    /*
'    //the X position is procedded by 'A'
'      myDataOut = 65; 
'      sendSomeData(myDataOut);
'      myDataOut = (byte) mouseX;
'      sendSomeData(myDataOut);
    
'    //the Y position is procedded by 'B'
'      myDataOut = 66; 
'      sendSomeData(myDataOut);
'      myDataOut = (byte) mouseY;
'      sendSomeData(myDataOut);
'     */ 
'    //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?
'      }
'  }
  
'  //WITH Data taken in we set the color of the background
'  //This data is provided by the POT on the PIC
'    //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
'    DATA=(int)myDataIn;
'    if(DATA<0)
'      { DATA=DATA+256;}
'    background(DATA);
    
'}//END draw


'////////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");
'  }
'}