Add

Making Things + AS3 – Part 4 Serial LCD


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:

Make Controller Serial LCD Diagram Flash AS3

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.

package com.hydrotik.make {
 
	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 = 0x00FF66;
			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:

package org.fwiidom.osc { 
	/**
	 * @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;
		}
 
	}
}

Making Things Serial LCD Source

The Discussion

see what everyone is saying

  • Nacho September 6th, 2007 at 5:36 am #1

    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 :) )

  • John Barton September 12th, 2007 at 3:36 pm #2

    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.

  • [...] Connecting AS3 and Flex with the real world. Link [...]

Respond

get in on the action.

* Required

bottega veneta deep coffee pocket bag deep weight loss pills bingo and game casino gambling online virtual how to win at slots versace deep coffee venus bag women does viagra work online bingo uk discount drugstore where to get viagra or cialis diazepam cheap without rx bingo and slots does cialis really work bingo gaming chanel yellow shoulder bag bingo for cash slot machine buy meds online without presciption lancel pearl premier flirt prada white shoulder bag prescriptions pain killers without a prescription viagra product information cialis generic levitra viagra cialis male enhancement online gambling offers manolo blahnik beige hangisi valium indications anya hindmarch beige hobo how does diazepam work who has the cheapest cialis price for tramadol levitra website price for generic viagra top anti depressants pharmacy zolpidem marc jacobs antique gold keylock messenger bag pill for acne casino gambling buy carisoprodol cheap create poker website zyban tablet jimmy choo purple wells shoes valtrex medication counseling for erectile dysfunction hey bingo louis vuitton patent beige sandals louis vuitton monogram idylle pink tote power bingo slot games gucci black evening bag xanax fedex oral jelly viagra new casino slots discount erectile dysfunction medication christian louboutin white ambrosina pumps poker machine games buy no phentermine prescription high stakes poker buy tory burch golden reva ballerina flats casino locations roulette casinos play online casinos bingo and slots viagra effect on women louis vuitton damier graphite keepall bandouliere marc jacobs royal blue keylock shoulder bag play roulette online casino mania online buy compazine buy gucci black trainers online casinos en internet how to win slots christian louboutin blush barcelona sandals prescription diet drugs us only mobile casino games natural clomid buy overseas viagra online casino canada online xanax fedex norvasc generic erectile dysfunction products zoloft canada uk viagra supplier casino bonus tory burch deep blue tory logo rain boots poker for money prescription drugs online adipex no prescription needed pharmacies geniune cialis no prescription ambien dosing how do muscle relaxants work valentino beige snakeskin clutch what is tadalafil ativan dosages sales viagra ysl white muse bag cialis to buy online gambling strategy cheapest phentermine pills christian dior biege medium saddle handbag alprazolam brand cheap viagra new zealand low cost adipex bally patent patent red jana tote ambien pharmacy manolo blahnik bow booties what is viagra used for dosage viagra new diet pill fda approved play slots online now cialis best price las vegas bingo cialis generic tabs versace purple venita bow satchel chloe patent purple cyndi tote fendi apricot snake peekaboo handbag discount lipitor prescription ambien ambien 10mg poker us levitra free samples do meridia phentermine work the same order celine black shoulder bag louis vuitton patent black sandals over the counter medication cheap 37 5 phentermine safe effective diet pills loewe white handbag dolce gabbana black trainers buying phentermine alprazolam generic for xanax ativan 2mg prada beige fairy l bag generic cialis canadian diet phentermine viagra online cheap europe cialis platinum play bingo levitra info prescription drugs migraines levitra alternative phentermine ingredient how does cialis work louis vuitton damier azure canvas galliera gm order amoxicillin new arthritis and psoriasis drug lipitor online pharmacy professional blackjack how does cialis ultram ingredients