Tuesday, April 17, 2012

Getting Started With a FEZ Hydra Basic Kit


I’m teaching a NETMF Gadgeteer lab for the Nashville .NET User’s Group this week.  Our gracious sponsors have purchased several FEZ Hydra Basic Kits made by GHI Electronics that we’ll be using to introduce everyone to the Gadgeteer world.

The FEZ Hydra Basic Kit consists of:
So, the challenge is what can we build with just these components?



THE PLAN
We’re going to build a simple project that will use the green LEDs on the outer ring of the LED7R module as a gauge to show the light level that is reported by the LightSense module.  In the center of the LED7R module is a bright red LED.  I’m going to use the Joystick module to vary the brightness of this LED.





CREATING THE PROJECT
Before we can start assembling pieces and writing code, there are some prerequisites that we need to ensure you have on your laptop.  Install all of these if you don’t have them already.  Make sure that you are running the latest versions.
  1. Visual Studio 2010 (or later).  Any flavor will do including Express.
  2. Microsoft .NET Micro Framework v4.1 SDK.
  3. GHI NETMF v4.1 and .NET Gadgeteer Package
imageNow that we have all of the bits installed, open Visual Studio and go to File –> New –> Project.  From the “New Project” dialog, we’ll choose the “Gadgeteer” section underneath the “Visual C#” group and we’ll create a new project using the “.NET Gadgeteer Application” template.

After we click “OK”, a new Gadgeteer project will be created and the Gadgeteer GUI designer appears showing an image of the FEZ Hydra mainboard.  If we open the Toolbox we will see a list of modules under the “GHI Electronics” section.  We’ll select the Joystick module and drag & drop it onto the white area somewhere around your mainboard.  Then we’ll do the same for the LED7R module and the LightSense module.

imageIf we left-click on the socket (the orange box) on our module then compatible sockets on our mainboard will be highlighted in green.  We can then drag the connector to the compatible socket that we want to plug the module into and click.  The sockets will then turn blue and a blue wire will be drawn between them.  Repeat for the other modules.
image
Now we’ll connect our physical components & cables up to match the connection decisions we made in the GUI designer.  Also, we’ll plug our SP power module (the red one) into the D socket (#2) and connect the USB cable to it and to our computer.

image
TIP: The name below each module in the GUI is the variable name that you’ll use in code to reference the module. If you want to change it, you can do so by click the name in the GUI a couple times to get into edit mode. If you change it after code has been written then your code will automatically update.


Let’s write some code!!!


HELLO WORLD!
Now that everything is connected and powered up, we should see a red LED on our power module, on our mainboard, and on our LED7R module.

imageNext, let’s make sure that our project is configured to run on our Hydra and not the emulator.  In the Solution Explorer, we’ll right-click on our project and go to Properties.  In the Properties page, choose the “.NET Micro Framework” tab on the left.  We’ll choose the “USB” Transport option.  When we do this, the “Device” should automatically populate with “FEZ Hydra_Gadgeteer” (assuming we only have one mainboard connected to our PC).  Save your options and close the page.

Hit F5!  If everything is connected correctly, the default program should compile and deploy to the Hydra and in our Debug Window we should see a lot of memory information flash by and then finally you should see…
image

If you don’t then it’s time to call for help


imageLED7R MODULE
We’ll start by writing a quick test of our LED7R module.  Note that I have renamed my module from it’s default name to “led” in the code below. 

The LED7R module has the following methods available to it:image
Animate() Cycles through all the LEDs on the module in a circular pattern. There are parameters to determine speed, direction, whether the lights are to be turned on or off, and an option to leave the lights on or to turn them off before moving to the next one.
TurnLightOn() Turns an LED on. It has one parameter – the number of the LED to turn on. Note the “D” numbers printed next to the LEDs on the module. They are the index numbers.
TurnLightOff() Turns an LED off. Same parameter as TurnLightOn().

Let’s add some code to test out our LEDs.  In the Program.cs file in ProgramStarted() let’s add the following code below the Debug.Print line that was added automatically.
   1:  // Cycle through the lights to show we're alive.
   2:  led.Animate(100, true, true, false);
   3:  led.TurnLightOff(6);  // a bug causes the last light to stay on...

Hit F5 to compile, deploy, & run the code and you should see the LEDs on the module light up in a clockwise direction.


imageLIGHTSENSE MODULE
Now that we know our LED7R module is working fine, let’s do something with our LightSense module.  The LightSense module has two methods.  Both are used for polling the sensor to capture it’s settings.

ReadLightSensorPercentage()Returns the light level as a percentage value from 0.0 (dim) to 1.0 (bright).
ReadLightSensorVoltage()Returns the light level as a measure of voltage from the sensor (0V-3.3V).

As you can tell from the methods, to do anything with the meter we are going to have to poll it on a regular basis.  For this we’ll need a timer.  At the bottom ProgramStarted() let’s add the following:

   1:  // Light meter 
   2:  var timer1 = new GT.Timer(100);
   3:  timer1.Tick += OnLightMeterTick;
   4:  timer1.Start();

And let’s add a new function to our Program class…

   1:  private void OnLightMeterTick(Timer timer)
   2:  {
   3:      var lightLevel = (int) lightSensor.ReadLightSensorPercentage();
   4:   
   5:      for (var ndx = 1; ndx < 7; ndx++)
   6:      {
   7:          if (ndx <= lightLevel/100.0*7)
   8:          {
   9:              led.TurnLightOn(ndx);
  10:          }
  11:          else
  12:          {
  13:              led.TurnLightOff(ndx);   
  14:          }                
  15:      }
  16:  }

Run the code again and you should now see the LED7R do it’s initialization loop and then the number of LEDs lit should vary depending on the brightness that the LightSense is reading.  Try moving your hand over the LightSense module.  The number of LEDs lit should decrease.

Having fun yet?


JOYSTICK MODULE
It’s time to put our hands on this thing!  I bet you never thought you’d be able to actually touch a C# project :D 

The Joystick module moves in X & Y directions and has a button we can use when the stick is pushed downward.  We’re going to use the Y (up & down) direction of the Joystick to dim the red LED in the middle of our LED7R module.  Fully explaining the Joystick module is beyond the scope of this post.  I’ll do that in the near future.

But wait!  If we take another look at the LED7R module we’ll notice that there isn’t a method we can use to dim LEDs.  What to do?  We’ll use an optical trick called persistence of vision (POV) to make the LED appear dim by using a timer to pulse the light on & off many times per second and vary the length of time that it is on between pulses.

Add the following to ProgramStarted():

   1:  // Monitor joystick to update red LED brightness.
   2:  var timer2 = new GT.Timer(10);
   3:  timer2.Tick += OnRedBrightnessTick;
   4:  timer2.Start();

And let’s add this new function to our Program class…

   1:  void OnRedBrightnessTick(Timer timer)
   2:  {
   3:      led.TurnLightOn(7);
   4:      Thread.Sleep((int)(joystick.GetJoystickPostion().Y*100)/20);
   5:      led.TurnLightOff(7);
   6:  }

Run the program and now when you move the Joystick up & down you should see a slight variation in the brightness of the red LED in the middle of the LED7R module. 

Surely, you’re having fun now???

You may be asking yourself why we used Timers instead of just putting a loop in our ProgramStarted() event.  This is one area where Gadgeteer is very different than traditional NETMF projects.  Read this blog post for an excellent explanation and you’ll save yourself some frustration down the line.


WHAT NEXT?
Well, that’s up to you!  I’ve given you a simple example of a couple things you can do with the FEZ Hydra Basic Kit.  Now, take this example and improve it or come up with something better (a game maybe?).  Be sure to leave a comment on this post and tell me what you did or even better post a link to a video.

Have fun!

Download the complete project source here.

5 comments:

Jason A Myers said...

Just a word of note while attempting to do part 2 of the code to use the light sense module, I got a complaint about the OnLightMeterTick routine. First we did not call it with a timer so it complains about not having a proper overload.

Jason A Myers said...

For me my code had to look like:
public partial class Program
{
// This method is run when the mainboard is powered up or reset.
void ProgramStarted()
{
/*******************************************************************************************
Modules added in the Program.gadgeteer designer view are used by typing
their name followed by a period, e.g. button. or camera.

Many modules generate useful events. Type += to add a handler to an event, e.g.:
button.ButtonPressed +=

If you want to do something periodically, use a GT.Timer and handle its Tick event, e.g.:
GT.Timer timer = new GT.Timer(1000); // every second (1000ms)
timer.Tick +=
timer.Start();
*******************************************************************************************/


// Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
Debug.Print("Program Started");

lED7R.Animate(100, true, true, false);
lED7R.TurnLightOff(6);

var timer1 = new GT.Timer(100);
timer1.Tick += new GT.Timer.TickEventHandler(OnLightMeterTick);
timer1.Start();

var timer2 = new GT.Timer(10);
timer2.Tick += new GT.Timer.TickEventHandler(OnRedBrightnessTick);
timer2.Start();


}
void OnLightMeterTick(GT.Timer timer)
{
var lightLevel = (int)lightSensor.ReadLightSensorPercentage();

for (var ndx = 1; ndx < 7; ndx++)
{
if (ndx <= lightLevel / 100.0 * 7)
{
lED7R.TurnLightOn(ndx);
}
else
{
lED7R.TurnLightOff(ndx);
}
}
}

void OnRedBrightnessTick(GT.Timer timer)
{
lED7R.TurnLightOn(7);
Thread.Sleep((int)(joystick.GetJoystickPostion().Y * 100) / 20);
lED7R.TurnLightOff(7);
}
}

Chelsea said...

I honestly like the fresh perpective you did relating to the issue.

Luke said...

Have you tried using the Hydra with the ENC28 Ethernet module (apparently the Spider one doesn't work with the Hydra, which is kind of strange seeing as the modules are supposed to be interchangeable)? I've set everything up and can't get DHCP to work, outgoing connections time out, and although I am able to get to the WebServer welcome page to show in my browser I am unable to intercept WebEvents, the event is never fired and the page never loads. There was a thread on the TinyCLR forums from a user who was having similar problems, and the GHI response was basically that they didn't have time to properly test the module before its release (http://www.tinyclr.com/forum/topic?id=7060). I'm thinking about chucking my Hydra out the window and buying a Spider.

ianlee74 said...

Luke, I have the ENC28 but I haven't really spent any time with it yet. I certainly wouldn't chuck the Hydra. It's a great board. But, it is a fairly young board and is OSHW so it doesn't get first priority support. That being said, GHI does a great job supporting all their boards whether they be OSHW or proprietary. Getting NETMF 4.2 out has been their priority the past month or two and that is coming to a close. I suspect that in the next few weeks a driver will come out to help you out. That being said, you should always report all problems to the tinyclr.com forums to be sure they know you're having the problem. If the thread you found describes your problem exactly, then you should mention that you're also having the problem so they know to elevate the priority of the fix. Also, given that it is an open source board with open source drivers. If you have the means, you can always attempt to fix it yourself.

Concerning the lack of compatibility of the Spider ethernet module... The Spider mainboard is based on the GHI EMX module which has some built-in networking support that the ethernet module for Spider is taking advantage. The Hydra does not have this additional hardware on the mainboard which is why that module will not work with it. The EMX module has been around for a few years and it is tried and true and includes the premium libraries from GHI. The Spider is certainly the most stable of all Gadgeteer mainboards anywhere. If you want to get a second mainboard then this is certainly the one to get. The Hydra is quickly reaching that level of stability but like I said, it is a fairly new board.

Good luck and keep making Gadgets!

Post a Comment