iPhone controlled RGB LED via Arduino and DMX

26th August 2009

Yes, the title of this post might sound a bit weird but this is actually what I was working on the last days.

I actually planned to dive into this physical computing thing. I guess I told some people about it. Because when I turned 30 there were two unexpected but great gifts. A microcontrolled robot which I soldered in one weekend with more than 150(!) solderings. And a new Arduino board! Thanks to the guys from BigSource for the board! ;)

I wanted to create something that is useful. There are thousands of physical computing examples that do nothing more than switching an LED on or off. I guess there is so much potential in the whole subject. And I’m sure that we will see more and more computer controlled physical objects that are connected to the internet in our every day life.

The cool thing about it is that you break the common workflow of having Keyboard or Mouse inputs and outputs on the screen. Now you can have inputs from thousand of sensors! I bought a motion sensor which detects a finger flip in 10 meter distance. I’m not sure what to do with it yet, but this is so cool! The output can be as different as well. You can control servos or lights or switch your outlets, whatever you want. Plus you can connect the whole thing to the internet. You can imagine how many possibilities you have if you know a bit about programming.

My goal was to create something for the everyday life. Something that is useful for me.
Actually I needed some decoration for my naked white walls in my living room. I was looking for pictures and art over five years and nothing could compete with my beautiful white walls. Now I can keep them white but very colorful. I created an iPhone controlled RGB LED light. This nothing new I guess, but it’s perfect for my living room.

I got the Arduino Board and began programming, soldered a DMX Shield (thanks to Raphael Perret for the etched board), bought a WiFi-Shield and a DMX controller, a RGB LED light and some cables.

Programming in Processing and Objective-C can be very exhausting. There are so many datatypes I never heard of. Something like uint8_t for example which is just a byte. The problem is more about knowing them and knowing when to use which one. Plus the whole pointer stuff really made me want to go back to the warm ActionScript 3 nest where everything made sense and seemed so easy.

Finally it worked. I managed to connect my iPhone with a socket connection via WiFi to my Arduino board. The Arduino board receives the bytes I sent from the iPhone app, converts them, adds some springing for smoother color changes and puts them in a DMX conform protocol. These data are sent to the DMX controller which controlled the lights. Sounds easy, right? It was not. But it was worth the effort! ;)

Ok, have a look for yourself!

This is a video where you can see the parts I have used and how they are assembled.


Get Adobe Flash player

This is the light in action! ;)


Get Adobe Flash player

Creating Custom 3D DisplayObjects in Papervision – Part 3

27th May 2009

Ok, now it’s getting really interesting! In the last posts you learned how to set up your own custom Papervision object and how to display textures on it.

Now we are going to animate our object. The idea behind is pretty simple. You add an Event.ENTER_FRAME handler to your object and in every frame you add new vertices to your object, draw new triangles and if there are already enough triangles you remove the one you don’t need anymore.

In detail it will work like this: In every frame we create 2 new vertices and draw 2 new triangles with it. But to draw 2 triangels we need a minimum of 4 vertices. So we take the the last ones we added the frame before.
In every frame we take slightly different coordinates so that or vertices are moving.
Theres only one situation that is special. It is when we start our Event.ENTER_FRAME handler we don’t have 4 vertices. So we just add 2 vertices and wait for the next frame. And this is the code:

public function AnimatedMesh (meshMaterial : MaterialObject3D, stage : Stage)
{
    super( meshMaterial, new Array( ), new Array( ) );
    _stage = stage;
           
    _count = 0;
    _width = 50;

    _stage.addEventListener( Event.ENTER_FRAME, onEnterFrame );
}

private function onEnterFrame (event : Event) : void
{
    var vertices : Array = geometry.vertices;
    var faces : Array = geometry.faces;
           
    var v1 : Vertex3D, v2 : Vertex3D, v3 : Vertex3D, v4 : Vertex3D;
    var z:Number = _count * _width;

    if(vertices.length == 0)
    {
        v1 = new Vertex3D( 0, 0, z );
        v2 = new Vertex3D( _width, 0, z );
        vertices.push( v1, v2 );
    }
    else
    {
        v1 = vertices[vertices.length - 2];
        v2 = vertices[vertices.length - 1];
        v3 = new Vertex3D( 0, 0, z );
        v4 = new Vertex3D( _width, 0, z );
        vertices.push( v3, v4 );
               
        var triangle1Vertices : Array = [ v1, v2, v3 ];
        var triangle1Face : Triangle3D = new Triangle3D( this, triangle1Vertices, material, null );
        faces.push( triangle1Face );
               
        var triangle2Vertices : Array = [ v2, v3, v4 ];
        var triangle2Face : Triangle3D = new Triangle3D( this, triangle2Vertices, material, null );
        faces.push( triangle2Face );
    }

    geometry.ready = true;

    _count++;
}

And the compiled SWF looks like this. If you try it for yourself and you just see a growing line, move your camera up.


Get Adobe Flash player

Simply adding the same value to one axis is pretty boring. If you draw a circle with Sinus and Cosinus its getting better. I also deleted some vertices and faces if we have enough from them:

public function AnimatedMesh (meshMaterial : MaterialObject3D, stage : Stage)
{
    super( meshMaterial, new Array( ), new Array( ) );
    _stage = stage;
       
    _count = 0;
    _segments = 40;
    _width = 50;
    _radius = 300;
   
    _stage.addEventListener( Event.ENTER_FRAME, onEnterFrame );
}      
       
private function onEnterFrame (event : Event) : void
{
    var vertices : Array = geometry.vertices;
    var faces : Array = geometry.faces;
   
    var v1 : Vertex3D, v2 : Vertex3D, v3 : Vertex3D, v4 : Vertex3D;
    var x : Number = 0;
    var y : Number = Math.cos( _count / 8 ) * _radius;
    var z : Number = Math.sin( _count / 8 ) * _radius;
           
    if(vertices.length == 0)
    {
        v1 = new Vertex3D( x, y, z );
        v2 = new Vertex3D( x + _width, y, z );
        vertices.push( v1, v2 );
    }
    else
    {
        v1 = vertices[vertices.length - 2];
        v2 = vertices[vertices.length - 1];
        v3 = new Vertex3D( x, y, z );
        v4 = new Vertex3D( x + _width, y, z );
        vertices.push( v3, v4 );
           
        var triangle1Vertices : Array = [ v1, v2, v3 ];
        var triangle1Face : Triangle3D = new Triangle3D( this, triangle1Vertices, material, null );
        faces.push( triangle1Face );
               
        var triangle2Vertices : Array = [ v2, v3, v4 ];
        var triangle2Face : Triangle3D = new Triangle3D( this, triangle2Vertices, material, null );
        faces.push( triangle2Face );
    }

    geometry.ready = true;

    _count++;
           
    if(_count > _segments)
    {
        vertices.splice( 0, 2 );
        faces.splice( 0, 2 );
    }
}

And the compiled SWF:


Get Adobe Flash player

That’s a nice circle.
If you change this line

var x : Number = 0;

to this line

var x : Number = Math.sin( _count / 5 ) * _radius;

The result is this:


Get Adobe Flash player

Now I just changed the material from WireFrameMaterial to ColorMaterial and I drew the whole scene to a BitmapData added a BlurFilter and a ColorTransform.
Then you finally get this ;)

Get Adobe Flash player

I hope that helped you to understand the basic principle of animating objects in Papervision. If you got it you can do so many cool things with it. Imaging that you could code for examle a flying paper in the wind or a moving sea! Or you could transform spheres to planes or whatever you want.

I think it is great, I’m just waiting for my next project where I can make use of that! ;)

Creating Custom 3D DisplayObjects in Papervision – Part 2

3rd May 2009

Ok, now that you know how to set up your own custom object in Papervision I’m going to show you how texture maps work.

In the preceding Post we omitted the texture map in our face. So if you want to apply a BitmapMaterial to your object you won’t see the texture. So we need a texture map.

The first thing we are going to do is adding another triangle and making our object a rectangle. Something like the Plane primitive. A rectangle consists of a minimum of 2 triangles. So if we want to draw another triangle we need one more vertex.

Ok, so the code will look like this:

public function CustomTriangle (triangleMaterial : MaterialObject3D)
{
    super( triangleMaterial, new Array( ), new Array( ) );

    var v1 : Vertex3D = new Vertex3D( -200, -200, 0 );
    var v2 : Vertex3D = new Vertex3D( 200, -200, 0 );
    var v3 : Vertex3D = new Vertex3D( 200, 200, 0 );
    var v4 : Vertex3D = new Vertex3D( -200, 200, 0 );
    geometry.vertices.push( v1, v2, v3, v4 );

    var triangleVertices1 : Array = [ v1, v2, v3 ];
    var triangleFace1 : Triangle3D = new Triangle3D( this, triangleVertices1, material );
    geometry.faces.push( triangleFace1 );

    var triangleVertices2 : Array = [ v1, v3, v4 ];
    var triangleFace2 : Triangle3D = new Triangle3D( this, triangleVertices2, material );
    geometry.faces.push( triangleFace2 );

    geometry.ready = true;
}

We added another vertex and built another face. As you see we used the same vertices we used with our first face. That is pretty important to understand. The vertices are not bound to the triangles. We can use them with different triangles. They are just coordinates in our 3D space.

Ok, our new rectangle will look like this now. I applied a WireFrameMaterial to it because it is better to see the triangles we made:


Get Adobe Flash player

Ok, now it is getting interesting. We have our object and we want to apply a BitmapMaterial to it. If you already tried that you would have realized that your object did not show the texture. That is because the texture maps were missing in our faces.

A texture map is basically the information about where to display which part of the texture in every face or triangle. So every triangle gets its own texture map. And because every triangle consists of 3 vertices our texture map will need 3 information about the position of the texture. The information is an instance of the NumberUV class which holds two properties. The u and the v. Which represent the horizontal and vertical axes of our texture. Think of them as x- and y-axes. Textures are always 2D so we don’t have a z-axis here.
The u and v are numbers which go from 0 to 1. u=0 means the most left pixel of our texture and u=1 is the most right pixel in our texture.

Ok, so we take our first triangle which consists of these three vertices:

var triangleVertices1 : Array = [ v1, v2, v3 ];

v1 is the vertex in the lower left corner. That means it should display the lower left corner of our texture. That represents u=0 and v=0. You might have noticed that the y-axis is flipped in Papervision.
v2 is in the lower right corner which represents u=1 and v=0. v3 is on the upper right corner and so it gets u=1 and v=1.

In code this will look like this:

var triangleTextureMap1 : Array = [ new NumberUV( 0, 0 ), new NumberUV( 1, 0 ), new NumberUV( 1, 1 ) ];

Ok, now we need to pass our triangle the texturemap.
Before:

var triangleFace1 : Triangle3D = new Triangle3D( this, triangleVertices1, material );

After:

var triangleFace1 : Triangle3D = new Triangle3D( this, triangleVertices1, material, triangleTextureMap1 );

Ok, so we have to do the same for our second triangle. I hope it is clear now how to handle the second texturemap. Our class will look like this now:

public function CustomTriangle (triangleMaterial : MaterialObject3D)
{
    super( triangleMaterial, new Array( ), new Array( ) );

    var v1 : Vertex3D = new Vertex3D( -200, -200, 0 );
    var v2 : Vertex3D = new Vertex3D( 200, -200, 0 );
    var v3 : Vertex3D = new Vertex3D( 200, 200, 0 );
    var v4 : Vertex3D = new Vertex3D( -200, 200, 0 );
    geometry.vertices.push( v1, v2, v3, v4 );

    var triangleVertices1 : Array = [ v1, v2, v3 ];
    var triangleTextureMap1 : Array = [ new NumberUV( 0, 0 ), new NumberUV( 1, 0 ), new NumberUV( 1, 1 ) ];
    var triangleFace1 : Triangle3D = new Triangle3D( this, triangleVertices1, material, triangleTextureMap1 );
    geometry.faces.push( triangleFace1 );

    var triangleVertices2 : Array = [ v1, v3, v4 ];
    var triangleTextureMap2 : Array = [ new NumberUV( 0, 0 ), new NumberUV( 1, 1 ), new NumberUV( 0, 1 ) ];
    var triangleFace2 : Triangle3D = new Triangle3D( this, triangleVertices2, material, triangleTextureMap2 );
    geometry.faces.push( triangleFace2 );

    geometry.ready = true;
}

And if you apply a BitmapMaterial from the outside to your object it will look like that:


Get Adobe Flash player

It looks a bit distorted. This is because we should actually build up a rectangle with more than 2 triangles. The more you use the better the texture is rendered and the more your CPU needs to work.

We could also tell our texture map that we don’t want to display the whole texture. With your set of NumberUV instances you can practically tell every triangle to display a different part of your texture. Just use .5 instead of 1 to display only the lower left part of the texure for example. Let’s play around with the values and you will see what I mean.

Im changing the values of our first texture map like this:

var triangleTextureMap1 : Array = [ new NumberUV( 1, 1 ), new NumberUV( 1, 0 ), new NumberUV( 0, 0 ) ];

I replaced the first with the last coordinate and the texture from our first triangle is rotated now:


Get Adobe Flash player

It is just important for you to understand, that you can tell every triangle which part of the texture it should display.

Ok, thats it for now. In the next part we are going to animate our object.

Creating Custom 3D DisplayObjects in Papervision – Part 1

8th April 2009

Have you ever thought of how to do these moving and transforming objects in Papervision? Click “Start” to see what I mean.


Get Adobe Flash player

I did. My world was limited to the Papervision primitives and collada objects. Then I needed a growing and transforming object for my current project. So I asked my friend Lars who already did things like that (he also created his own 3D framework by the way). He said that it is not that simple. I didn’t understand everything he was saying but had a rough idea in mind.

I found some information in the internet and set up my own custom object. Actually it is pretty much like drawing lines in ActionScript. You know this stuff:

shape.graphics.beginFill( 0xFF );
shape.graphics.lineTo( 100, 0 );
shape.graphics.lineTo( 100, 100 );
shape.graphics.lineTo( 0, 0 );

This will give you a blue triangle. That is easy.

Creating custom objects in a 3D world is pretty much the same.
3D objects in Papervision are basically defined through vertices and faces. Vertices are something like Points in 3D Space. They are stored in an array called vertices and are instances of the Vertex3D class.

The faces are the triangles (polygons) you draw with your vertices. Easily spoken you take 3 vertices and build a triangle with them. You should know that every 3D Object is made out of triangles.
And you also need tell your face how it should display a texture. If you just have a WireFrameMaterial or a ColorMaterial applied to your object you don’t need that necessarily. But you never know what kind of material people will use with your Object, so it is better to define it.

Let’s try that with a really simple custom 3D object. A triangle.
I assume that you have basic Papervision knowledge and that you use Papervision 2.0 Great White.

Ok, this will look like this:

package
{
    import org.papervision3d.core.geom.TriangleMesh3D;
    import org.papervision3d.core.geom.renderables.Triangle3D;
    import org.papervision3d.core.geom.renderables.Vertex3D;
    import org.papervision3d.core.math.NumberUV;
    import org.papervision3d.core.proto.MaterialObject3D;  
   
    public class CustomTriangle extends TriangleMesh3D
    {

        public function CustomTriangle (triangleMaterial : MaterialObject3D)
        {
            super( triangleMaterial, new Array( ), new Array( ) );

            var v1 : Vertex3D = new Vertex3D( -100, -100, 0 );
            var v2 : Vertex3D = new Vertex3D( 100, -100, 0 );
            var v3 : Vertex3D = new Vertex3D( 100, 100, 0 );
            geometry.vertices.push( v1, v2, v3 );
               
            var triangleVertices : Array = [ v1, v2, v3 ];
            var triangleFace : Triangle3D = new Triangle3D( this, triangleVertices, material, null );
            geometry.faces.push( triangleFace );

            geometry.ready = true;
        }
    }
}

Our custom object is extending the TriangleMesh3D class. If you take a look in the Papervision primitives classes you will see that they all extend this class.

Ok, so the constructor of the TriangleMesh3D needs 3 parameters. A material, a vertices array and a faces array. Our custom triangle requires a material as well so we push it to the super constructor. Then we give our super class 2 empty arrays which means something like: We don’t have any vertices and faces for you yet but you will get them very soon.

Let’s build the triangle. A triangle consits of 3 points and 1 shape. Here we will call it 3 vertices and 1 face. We create 3 instances of the Vertex3D class, give them the coordinates in 3D Space and push them in the vertices array which is a property of the geometry instance. The coordinates are pretty much the same as in our lineTo example earlier.

Now that we have 3 vertices we can make a face. In our lineTo example flash automatically connected the 3 points and draw a shape. Here we have to say with which vertices we want to create a face with. So basically we just choose 3 vertices push them in an array and pass them to our new instance of the Triangle3D class which represents the face. The Triangle3D class also needs a material. We just take the one of our displayobject. And it wants a texture map. I will explain that later for keeping things simple at this point it is null for now. As long as you don’t apply a texture material on the object you won’t need it.

So, here we go. Our first custom 3D Object:


Get Adobe Flash player

Here is the code which does the Papervision setup:

private function init3D () : void
{
    _basicView = new BasicView( 455, 256, false, false, CameraType.FREE );
    addChild( _basicView );
    addEventListener( Event.ENTER_FRAME, onRender );
           
    var material : ColorMaterial = new ColorMaterial( 0xFF );
    material.doubleSided = true;
    _arrow = new CustomTriangle( material );
    _basicView.scene.addChild( _arrow );
}

private function onRender (event : Event) : void
{          
    _arrow.yaw( 2 );
    _basicView.singleRender( );
}

Ok, cool. So now you know how to set up your own custom Papervision DisplayObject. In the next part I’m going to show you how texturemaps work.

Beginning iPhone Development

5th March 2009

The title says what I am doing and it’s also the title of my current favourite book.

I bought two books. One is for diving into Objective-C and the other one is about the iPhone SDK. It worked out to be a good idea having two books. One for Objective-C basics and the other one more iPhone specific. Although the iPhone book is my favourite book, you need to have basic knowledge about Objective-C to understand what they are doing there.

This book: Beginning iPhone Development is really good. Every chapter contains a Step by Step tutorial on a specific theme. It’s really fun reading and everything is really easy explained.

The second book called Programming in Objective-C is ok but it’s nothing special. It’s not bad though. It’s just a usual book about a programming language. If you consider buying this book better buy this one: “Programming in Objective-C 2.0″. Or a completely different one.

So I started reading the Objective-C book. If you are familiar with ActionScript everything seems different to you. How you declare variables, call functions, handle events and a lot more. Tracing! So simple in ActionScript. And a good example for a comparison:

trace("myNumber: " + myNumber);
NSLog([[NSString alloc]
    initWithFormat:@"myNumber: %f", myNumber]);

What is that?! Some things are really strange. And I’m not into it that much that I could say: “Ok, it is a little bit odd but actually it is better because … “. So I just accepted it ;)

Even if it is a little bit painful for me leaving the comfortable ActionScript enviroment it is a lot fun starting with iPhone programming. You simply have access to data you normally don’t have in ActionScript. Think of things like multitouch, accelerometer, GPS location, access to the adressbook of the user and a lot more.

So I started developing a really simple game. I think it is always good if you set yourself a goal to achieve. My goal is to develop a simple football game. The concept is pretty easy. You kick a ball and have to keep in the air. The longer you keep the ball in the air the higher the score. The score is to be saved in a database later.

I read the iPhone book and Keith Peters tutorial about gravity on the iPhone. And i watched some videos on this site: www.iphonedevcentral.org.

This is the current state. Unfortunately it doesn’t run that smooth on the iPhone. The difference between the X-Code-Simulator and the runtime on the iPhone is pretty big. I guess I should do the movement with openGL. Another language I don’t know. But the book is already ordered ;) Have a look for yourself:


Get Adobe Flash player

Custom Events in Objective-C

2nd March 2009

If you are living in the ActionScript world and you are looking for something like an event handling system, you might won’t find any. I googled events and custom events, callbacks and finally figured out that they call it “Notifications”.

Events or in this case Notifications are used for having loosely coupled relationships between instances in your application. So it is possible to let other instances listen to specific events without knowing each other.

If you want to listen to a custom event in ActionScript it would look something like this:

instance.addEventListener("eventType", eventHandler);

function eventHandler(e:Event)
{
    trace("event triggered");
}

In your instance you would trigger the event like this:

dispatchEvent( new Event("eventType") );

The Objective-C approach to listen to a Notification looks like this:

[[NSNotificationCenter defaultCenter]
    addObserver:self
    selector:@selector(eventHandler:)
    name:@"eventType"
    object:nil ];

-(void)eventHandler: (NSNotification *) notification
{
    NSLog(@"event triggered");
}

The funny thing is that you don’t need to put this Event Listener on an instance. It just listens to the eventtype and as far as I understood you can trigger this event wherever you want. This makes it even more loosely coupled than the instance.addEventListener(); approach.

The “NSNotificationCenter” is something like a Singleton which is one unique Class that manages your events in your application.

And this is how you dispatch or trigger the event:

[[NSNotificationCenter defaultCenter]
    postNotificationName:@"eventType"
    object:nil ];

That’s it. Actually I like the approach in Objective-C even if it is more to write it is pretty easy to read.

Objective-C, first steps

8th February 2009

Actually I’m wondering how many people start coding Objective-C these days. Especially Flash coders. It must be the App-Store that comes with the iPhone making it really easy to publish your applications to millions of people with a minimum of effort.

Plus Flash 10 doesn’t really come with that much new stuff that you don’t need to study every day to keep track with the development. Compared to the times when AS2 was released for example. It’s not that there is nothing new to learn for me. Especially in the area of Application Frameworks.. I’m still stuck with Cairngorm which does a good job for me though.

I’m just interested in some new things. And Objective-C is something pretty new for me. Its a C-Language and the syntax is fairly different from what you know from ActionScript.

The good thing I realized is: If you understood the core concepts of object oriented programming, you can easily learn Objective-C. It’s more like a different dialect from the same logical language.

Today I wrote my first application. It’s a really simple calculator but it gives you an impression on how the Objective-C syntax looks like.

//
//  main.m
//  Calculator
//
//  Created by Raphael Wichmann on 05.02.09.
//  Copyright Raphael Wichmann 2009. All rights reserved.
//

#import <stdio.h>
#import <objc/Object.h>


@interface Calculator: Object
{
    int _numbera;
    int _numberb;
}

-(void) print;
-(void) setNumberA: (int) a;
-(void) setNumberB: (int) b;

@end


@implementation Calculator

-(void) print
{
    int result = _numbera + _numberb;
    printf("Result: %i + %i = %i", _numbera, _numberb, result);
}

-(void) setNumberA: (int) a
{
    _numbera = a;
}

-(void) setNumberB: (int) b
{
    _numberb = b;
}

@end




int main(int argc, char *argv[])
{
    Calculator *_calculator = [Calculator new];
    [_calculator setNumberA:15];
    [_calculator setNumberB:7];
    [_calculator print];
   
    return 0;
}

With the magic of Objective-C this complex application is capable of adding 15 to 7 which makes 22. Whew ;)

Just another Flash-Blog

6th February 2009

Yes, it’s true. This is just another Flash-Blog. One of thousand others..
And actually I don’t think that this one is going to be better than other blogs or that it’s a cool idea of having a blog.

So what’s my motivation for it?
I think it’s just fair sharing some information about things I figured out about ActionScript or others things people may want to know. If I think about how many information I’m pulling out of the Internet every day.. So what is my contribution? Maybe this blog is a good starting point.

Why English?
I am German and my mother tongue is German. My clients are German and the most people I know in this business are German. But in a globalized world it’s just better to speak English. I don’t restrict the information to german people only and the programming languages are English too. Last but not least I like this language and I’m getting some more practice with it. I’m sorry if some sentences sound weird.. ;)

Ok, so welcome to my new Blog! I hope you’ll enjoy it.
Raphael ;)