/* XBee terminal language: processing This program is a basic serial terminal program. It replaces newline characters from the keyboard with return characters. It's designed for use with Linux, Unix, and OS X and XBee radios, because the XBees don't send newline characters back. created and modified by Tom Igoe 2007 Comprehensive improvements by Max Whitney 2/28/2009 Serial port switching by Rob Faludi 3/2009 */ String VERSION = "1.06"; import processing.serial.*; import controlP5.*; Serial myPort; // the serial port you're using String portnum; // name of the serial port int portID = 0; // number of the current serial port String outString = ""; // the string being sent out the serial port String inString = ""; // the string coming in from the serial port int receivedLines = 0; // how many lines have been received int bufferedLines = 10; // number of incoming lines to keep ControlP5 controlP5; // GUI control library Textarea SentTextArea; // Text area for stuff you are sending to Xbee Textarea RecdTextArea; // Text area for what you are getting back Textarea SerialPortTextArea; // static space for displaying which serial port is hooked up Textarea VersionArea; // show the version number String textSent = ""; // Buffer of text already sent. String textRecd = ""; // Buffer of text we have received. char nextChar; // Someplace for the byte consumed to live int fillColor = (255); int height = 480; int width = 640; int margin = 25; // make sure you leave enough margin to display the serial port hookup. Not less than 10 void setup() { size(width, height); // window size controlP5 = new ControlP5(this); SerialPortTextArea = controlP5.addTextarea("serial_port_in_use", "", width/3,5,width/3*2,margin-5 ); RecdTextArea = controlP5.addTextarea( "recd_messages", "", margin,margin,width-(2*margin),(height/2)-(margin*2)); textRecd = "INCOMING MESSAGES:\n---------------------\n"; SentTextArea = controlP5.addTextarea( "sent_messages", "", margin,(height+margin)/2,width-(2*margin),(height/2)-(margin*2)); textSent = "OUTGOING TEXT:\n----------------\n"; VersionArea = controlP5.addTextarea("version_number", "", 4,height-14,30,8 ); controlP5.addButton("change",12,width/3 - 45,3,38,14).setId(1); RecdTextArea.setText(textRecd); RecdTextArea.setColor(0); RecdTextArea.scroll(1); SentTextArea.setText(textSent); SentTextArea.setColor(0); SentTextArea.scroll(1); VersionArea.setColor(0); VersionArea.setText("v" + VERSION); // controlP5 comes with its own font choices // create a font with the second font available to the system: // PFont myFont = createFont(PFont.list()[2], 14); // textFont(myFont); // list all the serial ports: // println(Serial.list()); // based on the list of serial ports printed from the //previous command setPort(portID); // set the initial serial port println("XBee Terminal Max v" + VERSION); } void draw() { // clear the screen: background(200); // print the name of the serial port: // text("Serial port: " + portnum, 10, 20); // Print out what you get: // text("typed: " + outString, 10, 40); // text("received:\n" + inString, 10, 80); fill(fillColor); stroke(200); rect(margin,margin,width-(2*margin),(height/2)-(margin*2)); rect(margin,(height+margin)/2,width-(2*margin),(height/2)-(margin*2)); SentTextArea.setText(textSent); RecdTextArea.setText(textRecd); } // This method responds to key presses when the // program window is active: void keyPressed() { switch (key) { // in OSX, if the user types return, // a linefeed is returned. But to // communicate with the XBee, you want a carriage return: case '\n': if ( outString.length()>2 && outString.substring(outString.length() -3, outString.length()).equals("+++") ) { textSent += "\nDon't press return after +++ !"; } myPort.write(outString + "\r"); outString = ""; textSent += '\n'; break; case 8: // backspace // delete the last character in the string: if (outString.length() > 0){ outString = outString.substring(0, outString.length() -1); textSent = textSent.substring(0, textSent.length() -1); } break; case '+': // we have to send the + signs even without a return: myPort.write(key); // add the key to the end of the string: outString += key; textSent += key; break; case 65535: // If the user types the shift key, don't type anything: break; // any other key typed, add it to outString: default: // add the key to the end of the string: outString += key; textSent += key; break; } } // this method runs when bytes show up in the serial port: void serialEvent(Serial myPort) { // read the next byte from the serial port: int inByte = myPort.read(); // add it to inString: inString += char(inByte); textRecd += char(inByte); if (inByte == '\r') { // if the byte is a carriage return, print // a newline and carriage return: inString += '\n'; // there is one character of garbage right before the '\r' // std out takes it like a champ, but the ControlP5 thingarie does not textRecd = textRecd.substring(0, textRecd.length() -1) + '\n'; } } void controlEvent(ControlEvent theEvent) { // println(theEvent.controller().id()); } void change(float theValue) { portID++; portID = portID % Serial.list().length; println("setting port to: "+portID); setPort(portID); } void setPort(int thePort) { portnum = Serial.list()[thePort]; // initialize the serial port: try { myPort = new Serial(this, portnum, 9600); fillColor = (255); SerialPortTextArea.setColor(0); SerialPortTextArea.setText("serial port " +portID+ ": " + portnum); } catch (Exception e) { fillColor = color(200); SerialPortTextArea.setColor(0xff0000); SerialPortTextArea.setText("** ERROR ** serial port " +portID+ ": " + portnum); } }