Making Things + AS3 - Part 4 Serial LCD
UPDATE - it seems that the classes I have been using are out of date!
Making things has released a library that works with the mchelper application which I actually haven’t been able to get working with this example. Also Adam Robertson has developed a library that works with flex. I tried porting this library to this example but had no luck. And finally, Ignacio/Nacho, from John Barton’s earlier posts has developed a library as well as updates to the Flosc application which I am in the process of testing.
While I haven’t gotten any of the examples working with the LCD, each of them is excellent in its approach and I’m trying to round up John, Liam, Adam, Ignacio, and myself and see if we can make this a collaborative effort. Things have slowed down a bit with work and the Flash Forward convention, but stay tuned for more updates. In the meantime, the included code I have does work if you want to tinker and get a feel for what’s going on with the controller.
Anyone else who is interested, give me a shout!
Be sure to read parts 1-3. Still haven’t tackled the getting data from the board issue yet. I wound up having a lot of fun getting this experiment working and got sidetracked. So this is an example and how-to on getting the making things controller to send serial data to an LCD screen. There’s a weather RSS example out there that doesn’t use flash. This is a scaled down version of that as I haven’t had a chance to get the board working via an internet connection. So what we have here is a simple text input swf that will send the text to the LCD. So let’s get this thing hooked up first. Obviously you will need an LCD screen with serial capability. I purchased mine from SparkFun here. Try not to let the GPS modules distract you
Here’s a diagram of the connections for the controller:

You might be wondering where that green wire is going. Well if you look really close, you’ll see a set of punched out solder points. This is the serial/RS232 interface connection area. There are points for 3.3v, TX, RX, and some others as well. The TX is the one we need for transmitting the serial data. Grnd to Grnd, 5V to VO, and TX on the board to RX on the LCD. Make sure the power jumper for the digital bank is set to 5V (It’s not in the diagram). Go here for more on that. There is a sub-mini pot on the back of the LCD for adjusting contrast.
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.utils.Timer;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.net.URLRequest;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.text.*;
import org.fwiidom.osc.*;
public class MakeSerialLCD extends Sprite {
private static const STR_LOCAL_IP:String = “169.254.73.165″;
private static const STR_REMOTE_IP:String = “192.168.0.200″;
private static const NUM_PORT:Number = 10000;
private var oscConn:OSCConnection;
private var tf:TextField;
public function MakeSerialLCD() {
//Initialize connection to the FLOSC server
oscConn = new OSCConnection(STR_LOCAL_IP, NUM_PORT);
oscConn.addEventListener(OSCConnectionEvent.ON_CONNECT, onConnect);
oscConn.addEventListener(OSCConnectionEvent.ON_CONNECT_ERROR, onConnectError);
oscConn.addEventListener(OSCConnectionEvent.ON_PACKET_IN, onPacketIn);
oscConn.addEventListener(OSCConnectionEvent.ON_PACKET_OUT, onPacketOut);
oscConn.addEventListener(OSCConnectionEvent.ON_CLOSE, onClose);
oscConn.connect();
}
private function onConnect(evtEvent:OSCConnectionEvent):void {
trace(“FLOSC Connection established”);
oscConn.sendOSCPacket(new OSCPacket(“/serial/baud”, [9600], STR_REMOTE_IP, NUM_PORT));
var button1:Sprite = new Sprite();
button1.graphics.beginFill(0xCC6666);
button1.graphics.drawRect(20, 10, 40, 20);
button1.buttonMode = true;
button1.addEventListener(MouseEvent.CLICK, onClick1Handler);
addChild(button1);
tf = new TextField();
tf.background = true;
tf.border = true;
tf.backgroundColor = 0×00FF66;
tf.maxChars = 32;
tf.multiline = true;
tf.width = 120;
tf.height = 32;
tf.wordWrap = true;
tf.x = 80;
tf.y = 10;
tf.type = TextFieldType.INPUT;
tf.restrict = “A-Z 0-9!.\”\’?”;
tf.tabEnabled = true;
tf.tabIndex = 0;
addChild(tf);
}
private function onConnectError(evtEvent:OSCConnectionEvent):void {
trace(“FLOSC Connection error”);
}
private function onClose(evtEvent:OSCConnectionEvent):void {
trace(“FLOSC Connection closed”);
}
private function onPacketIn(evtOSC:OSCConnectionEvent):void {
trace(“\t>> data received: “ + evtOSC.data.name + ” “ + evtOSC.data.data);
}
private function onPacketOut(evtOSC:OSCConnectionEvent):void {
trace(“\t>> data sent: “ + evtOSC.data.name + ” “ + evtOSC.data.data);
}
private function onClick1Handler(event:MouseEvent):void {
parseString(tf.text);
tf.text = “”;
}
private function parseString(str:String):void {
//Initialize LCD
oscConn.sendOSCPacket(
new OSCPacket(“/serial/char”, [254], STR_REMOTE_IP, NUM_PORT)
);
//Clears LCD
oscConn.sendOSCPacket(
new OSCPacket(“/serial/char”, [1], STR_REMOTE_IP, NUM_PORT)
);
//Loop and send ascii dec
for(var i:int = 0; i<str.length ; i++){
oscConn.sendOSCPacket(
new OSCPacket(“/serial/char”, [str.charCodeAt(i)], STR_REMOTE_IP, NUM_PORT)
);
}
}
}
}
The code is pretty straight forward. It’s not doing anything too exciting other then sending the data. I have one OSC command sending a baud rates and a couple other OSC commands that clear the existing text on the screen and prepare it for a fresh batch of characters. Other things you’ll notice is that I have a restriction of chars attached to the input field. You can play with this and add lowercase if you like.
Below I’ve included the changes I made to the OSC class:
/**
* @author adam
*(based originally on demo code included with Flosc)
*
* (c) 2007 Fwiidom.org
*/
import flash.events.DataEvent;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.net.XMLSocket;
import flash.xml.XMLDocument;
import flash.xml.XMLNode;
public class OSCConnection extends EventDispatcher {
protected var mSocket:XMLSocket;
protected var mPort:Number;
protected var mIp:String;
protected var mDefaultSendPort:Number = 10000;
protected var mDefaultSendIp:String = “192.168.5.210″;
protected var mConnected:Boolean;
public function OSCConnection(inIp:String, inPort:Number) {
super();
mIp = inIp;
mPort = inPort;
}
public function connect () : void {
trace(“OSCConnection.connect()”);
mSocket = new XMLSocket();
mSocket.addEventListener(Event.CONNECT,onConnect);
mSocket.addEventListener(Event.CLOSE,onClose);
mSocket.addEventListener(DataEvent.DATA,onXml);
mSocket.connect(mIp,mPort);
//if (!mSocket.connect(mIp,mPort)) onConnectError();
}
public function disconnect () : void {
mSocket.close();
mConnected = false;
}
// *** event handler for incoming XMLDocument-encoded OSC packets
protected function onXml (e:DataEvent) : void {
var inXml:XMLDocument = new XMLDocument(e.data);
trace(“OSCConnection.onXml—”+inXml);
// parse out the packet information
var n:XMLNode = inXml.firstChild;
if (n != null && n.nodeName == “OSCPACKET”) {
parseXml(n);
}
}
// *** event handler to respond to successful connection attempt
protected function onConnect (succeeded:Boolean) : void {
trace(“OSCConnection.onConnect(succeeded)”);
if(succeeded) {
trace (“success”);
mConnected = true;
dispatchEvent(new OSCConnectionEvent(OSCConnectionEvent.ON_CONNECT,null));
} else {
trace (“fail”);
onConnectError();
}
}
// *** event handler called when server kills the connection
protected function onClose (e:Event) : void {
trace(“OSCConnection.onClose()”);
mConnected = false;
dispatchEvent(new OSCConnectionEvent(OSCConnectionEvent.ON_CLOSE));
}
protected function onConnectError() : void {
trace(“OSCConnection.onConnectError()”);
mConnected = false;
dispatchEvent(new OSCConnectionEvent(OSCConnectionEvent.ON_CONNECT_ERROR));
}
// *** parse the messages from some XMLDocument-encoded OSC packet
protected function parseXml(node:XMLNode) : void {
trace(“/——————- OSCConnection.parseXml(node) “);
trace (node);
trace(“——————- /”);
if (node.firstChild.nodeName == “MESSAGE”) {
var message:XMLNode = node.firstChild;
var name:String = message.attributes.NAME;
var data:Array = [];
for (var child:XMLNode = message.firstChild; child != null; child=child.nextSibling) {
if (child.nodeName == “ARGUMENT”) {
var type:String = child.attributes.TYPE;
//boolean
if (type==“T” || type==“F”) {
data.push((type==“T”)?true:false);
} else if (type==“f”) {
//float
data.push(parseFloat(child.attributes.VALUE));
//////————————————————————————///////////////////////////////////////////////////
////// Added new type "i", as "f" is not a type in the Make Controller
//////————————————————————————///////////////////////////////////////////////////
} else if (type==“i” || type==“I”) {
//float
data.push(parseInt(child.attributes.VALUE));
} else
//string
if (type==“s”) {
data.push(child.attributes.VALUE);
}
}
}
var packet:OSCPacket = new OSCPacket(name, data, node.attributes.address, node.attributes.port);
packet.time = node.attributes.time;
dispatchEvent(new OSCConnectionEvent(OSCConnectionEvent.ON_PACKET_IN,packet));
}
else {
// look recursively for a message node
for (var subchild:XMLNode = node.firstChild; subchild != null; subchild=subchild.nextSibling) {
parseXml(subchild);
}
}
}
// *** build and send XMLDocument-encoded OSC
public function sendOSCPacket(outPacket:OSCPacket) : void {
var xmlOut:XMLDocument = new XMLDocument();
var osc:XMLNode = xmlOut.createElement(“OSCPACKET”);
osc.attributes.TIME = 0;
osc.attributes.PORT = outPacket.port;
osc.attributes.ADDRESS = outPacket.address;
var message:XMLNode = xmlOut.createElement(“MESSAGE”);
message.attributes.NAME = outPacket.name;
for (var i:Number=0;i<outPacket.data.length; i++) {
// send everything as a string
// NOTE : the server expects all strings to be encoded
// with the escape function.
var argument:XMLNode = xmlOut.createElement(“ARGUMENT”);
setType(argument, “i”); //argument.attributes.TYPE = "s";
setValue(argument, escape(outPacket.data[i])); //argument.attributes.VALUE = escape(outPacket.data[i]);
message.appendChild(argument);
}
osc.appendChild(message);
xmlOut.appendChild(osc);
if (mSocket && mConnected) {
//trace ("XMLDocument SEND - ");
trace (xmlOut);
mSocket.send(xmlOut);
dispatchEvent(new OSCConnectionEvent(OSCConnectionEvent.ON_PACKET_OUT,outPacket));
}
}
private function setType(arg:XMLNode, str:String):void{
arg.attributes.TYPE = str;
}
private function setValue(arg:XMLNode, str:String):void{
arg.attributes.VALUE = str;
}
}
}

September 6th, 2007 at 5:36 am
Hi Donovan!
Try to check the updated AS3 classes I made to have an OSC connection from a Flosc server. Maybe you have some great ideas to improve them. You can find the sources at http://code.google.com/p/flosc/ (I’ve created a new project to update and continue Ben Chun’s work
)
September 12th, 2007 at 3:36 pm
Nice work. I’m glad that my updated AS3 classes and articles were able to get you started. Although at this point, since the new release of the MakingThings classes and the updated mchelper, I’m still evaluating if I’m going to continue with working on flosc and my updated Fwiidom classes or start over and begin hacking on the MakingThings classes.
February 16th, 2008 at 3:04 pm
[...] Connecting AS3 and Flex with the real world. Link [...]