The art of Windows Phone

Menu

More Netduino + WP8 + Bluetooth fun- 3D reconstruction

The goal for this project is the following: Have a Netduino sending it’s orientation data (XYZ) over Bluetooth to WP8 which displays a 3D representation of it (at the right angle of course), and for bonus points attach a potentiometer to control the zoom.

In the video above, as with the last one, the Netduino is only plugged in because I don’t have a 9v battery lying around. And you might notice a few MS of lag – that’s due to the smoothing filters. It’s possible to get the movement to just about real-time (Bluetooth is impressively fast) but then you also get all the fluctuations of the accelerometer.

I found a 6DOF chip from an old project (a gyro and accelerometer on one chip – although I’m only using the accelerometer here) so stuck it into the breadboard and wired it up. The specific one I’m using is: https://www.sparkfun.com/products/10121 (which is really cool, but overpriced in my opinion)

From there it’s not too complicated to start getting values. LoveElectronics.co.uk has a good guide, or you can download the solution I have below which simplifies the matter. I’ve just got a few little helpers that initialize the accelerometer, and then return XYZ after converting each to a value between –90 and 90. One thing to note is that in my code I have a bunch of stuff referencing the gyro. Although it get’s values back from the gyro, I haven’t really figured out how to convert them into something useful – but will do that when I get more time.

Reading the values from it basically comes down to this:

C#

1

2

3

4

byte[]res=I2CHelper.Read(0x32,Device.ADXL345,6);

_xAcc=(((int)res[1]&lt;&lt;8)|(int)res[0]).CheckAccVal();

_yAcc=(((int)res[3]&lt;&lt;8)|(int)res[2]).CheckAccVal();

_zAcc=(((int)res[5]&lt;&lt;8)|(int)res[4]).CheckAccVal();

Next up is the potentiometer. This is basically a turning knob that you can use to get a range of values from. I’m using this one from Sparkfun, but they are all pretty much the same: https://www.sparkfun.com/products/9806

It has 3 pins. The first goes to GND, the last goes to 3.3V, and the middle one goes to Analog 1 (in this case). Don’t worry about mixing up GND and 3.3V – it just inverts the knob.

To get the value from the potentiometer you first need to initialize the port:

C#

1

AnalogInput pot=newAnalogInput(Cpu.AnalogChannel.ANALOG_1);

Then, inside the loop, it’s very easy to read from it:

C#

1

pot.Read()

So, with those values in hand we just need to continually send them over BT to the phone. I covered BT in detail in the post mentioned earlier so I won’t go into it here. But this is what the while loop looks like:

That will send the orientation values and potentiometer value over to the phone.

For the phone app I’ve copied pretty much the entire code from the last post. Some is commented out because it referenced UI stuff that isn’t in this project. Because the previous post covered all this, I’m not going to go into any of that code.

So how do we show a 3D model? Well, in my opinion the easiest way is XNA. However, Microsoft killed XNA on WP8 (and W8) leaving native code as the only way. Enter: MonoGame. MonoGame is a framework that enables XNA developers to write one code base and have it run on many different platforms. So even though XNA isn’t officially supported on WP8, we can still use MonoGame – which is pretty much identical (at least for anything we’re going to be doing). Here is their explanation of it:

MonoGame is an Open Source implementation of the Microsoft XNA 4 Framework. Our goal is to allow XNA developers on Xbox 360, Windows & Windows Phone to port their games to the iOS, Android, Mac OS X, Linux and Windows 8 Metro. Windows Phone 8, OUYA and PlayStation Mobile development is currently in progress.

Download the installer for VS, and create a new “MonoGame Windows Phone 8 project”. If you’ve used XNA before then the default Game.cs will be exactly as you expect.

We need a few class variables:

C#

1

2

3

4

5

6

Model _demoModel;

Matrix _projection;

Vector3 _rotation;

Filter _xFilter=newFilter(0.25);

Filter _yFilter=newFilter(0.25);

Filter _zoomFilter=newFilter(0.15);

These are just to hold info about the model and then filters to smooth out the values we receive from the Netduino. The value given to each filter is to determine how much smoothing it does. A lower value will be more reactive, but not as smooth. As mentioned, I’m not going to go into the BT stuff here so to see how those filters actually get their values checkout the source.

Before loading up the model, you need to create a folder called “Content” in the root of the project. Add your model and it’s related files into there and set their Build Action to Content, and Copy to Copy if newer. Remember that in XNA you don’t use models straight from Maya or Max, you first compile them into XNA’s native format. In another post my designer will detail how the Netduino model was made and how to get it to the right format.

OK, to load up the model, add the following to the LoadContent method:

C#

1

_demoModel=Content.Load&lt;Model&gt;("Netduino");

That will load the model called “Netduino” through the Content Pipeline. And because XNA is awesome, to draw the model, all we need is the following code in the Draw method:

C#

1

2

3

4

5

6

7

8

9

GraphicsDevice.Clear(Color.CornflowerBlue);

_demoModel.Draw(

Matrix.CreateRotationX(MathHelper.ToRadians(_rotation.X+90))*

Matrix.CreateRotationY(MathHelper.ToRadians(_rotation.Y))*

Matrix.CreateRotationZ(MathHelper.ToRadians(_rotation.Z+90)),

Matrix.CreateLookAt(newVector3(0,0,(float)(14*_zoomFilter.Value)+2),

Vector3.Zero,

Vector3.Up),

_projection);

First we clear the screen, then draw the model. Keep in mind that this is a very simplistic approach to drawing a model – and there are better ways. To draw the model we provide it with it’s world matrix. We create that matrix from the rotation of each axis. Notice that on the X and Z I’ve added 90 degrees – that’s just to rotate the model to the right orientation. Next the view matrix is calculated from the zoom (remember that potentiometer?).

And that’s pretty much all there is to it.

If you’ve got question you can ask me here or on the Twitter machine: @roguecode

Below are the solutions for both the Netduino and WP8 app. Please note, that neither are very clean, and I’ve used both to just hack around with some ideas.

Post navigation

Excellent article. Can you describe how the 3d model was created and exported to a format that Monogames can understand? Quote: “In another post my designer will detail how the Netduino model was made and how to get it to the right format.”

Thank you

About

I am Matt from RogueCode, and I blog here.
Yip! I'm a Windows Phone developer!