Saturday, December 31, 2011

Netduino "Robot"

Over the past month or so my son and I built a "Robot" with our Netduino.



Parts:

Physical Assembly:

First, we mounted the 8 pin headers upside down in the motor driver breakout like this:


We did this so that we could easily mount this into the breadboard and see the pin descriptions.  We didn't insert it all of the way into the breadboard - rumor has it that these get hot - although ours does not seem to.

Next, we assembled the robot chassis.  Some of the parts have tight tolerances, but everything fit together fine.

We attached the battery holders to the lower platform and the Netduino and breadboard onto the top platform.  Then we mounted the IR sensor to the "front" (the end with the 2 wheels).

Do NOT mount the IR sensor like it is in the picture above.  Our first day we managed to drive it under a kitchen cabinet and it cracked the circuit board of the IR sensor.  :(  When our replacement arrives, I think we will mount it on the lower deck so it is safer.

Wiring:

We wired it like this:

IR sensor yellow wire to the Netduino AIN0
IR sensor black to ground on Netduino
IR sensor red to Netduino 5V

9 volt power to Netduino
6 volt power black to ground on Netduino (via the RadioShack connector and some hookup wire)
6 volt power red to motor driver VM (same as above)

Netduino to TB6612FNG breakout
DIO0 = Standby (This needs to be high (true))
DIO1 = AIN1
DIO2 = AIN2
DIO5 = PWMA
DIO6 = PWMB
DIO8 = BIN1
DIO9 = BIN2
Ground to ground

TB6612FNG breakout to motors
AO1 = Red motor lead (Right)
AO2 = Black motor lead (Right)
BO2 = Black motor lead (Left)
BO1 = Red motor lead (Left)

Code:

Now it was time to code a little bit.  As usual, the path was paved by the great authors in the communities at Netduino.com (http://forums.netduino.com/index.php?/forum/4-netduino/).

We used the library provided from this post: http://forums.netduino.com/index.php?/topic/493-netduino-tankbot/page__view__findpost__p__3665 from user ajcg1973.


using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
// make sure you include the library - ours was (messily) inline

namespace IRRobot
{
    public class Program
    {
        static AnalogInput analogInput = new AnalogInput(Pins.GPIO_PIN_A0);
        public static void Main()
        {

            OutputPort stby = new OutputPort(Pins.GPIO_PIN_D0, true);
            AjbMotorTB6612FNG motors = new AjbMotorTB6612FNG(Pins.GPIO_PIN_D5, Pins.GPIO_PIN_D1, Pins.GPIO_PIN_D2, Pins.GPIO_PIN_D6, Pins.GPIO_PIN_D8, Pins.GPIO_PIN_D9);
            motors.Motor1Direction = AjbMotorTB6612FNG.MotorDirection.Forward;
            motors.Motor1Speed = 50;  // Set the motor to 50% speed
            motors.Motor2Direction = AjbMotorTB6612FNG.MotorDirection.Forward;
            motors.Motor2Speed = 50;  // Set the motor to 50% speed
            while (true)
            {
                Thread.Sleep(250); // pause to gather analog sample
                int analogValue = 1024 - analogInput.Read();
                Debug.Print(analogValue.ToString());
                if (analogValue < 550)
                {
                    motors.Motor1Direction = AjbMotorTB6612FNG.MotorDirection.Reverse;
                    motors.Motor1Speed = 30;  // Set the motor to 30% speed
                    motors.Motor2Direction = AjbMotorTB6612FNG.MotorDirection.Forward;
                    motors.Motor2Speed = 30;  // Set the motor to 30% speed
                    Thread.Sleep(1000);
                    motors.Motor1Direction = AjbMotorTB6612FNG.MotorDirection.Forward;
                    motors.Motor1Speed = 50;  // Set the motor to 50% speed
                    motors.Motor2Direction = AjbMotorTB6612FNG.MotorDirection.Forward;
                    motors.Motor2Speed = 50;  // Set the motor to 50% speed
                }

            }

        }

    }
}

This still needs some tweaking.  Or a whole re-write.  :)  But it shows how to drive the motors using ajcg1973's library and how to read the IR sensor.  We flipped forward and reverse in the library - this might mean we are driving backwards.  :)

You might want to watch the IR output values for a bit to get a feel for what it can see - ours is a bit far sighted so it runs into things some times. :) 

Conclusion:

This was a fun project.  The kids loved the little robot as it scooted across the floor avoiding obstacles.  We'll probably enhance our software and try some different sensors over the next few weeks.

We hope that you enjoyed this post.

References:

Original library code: http://forums.netduino.com/index.php?/topic/493-netduino-tankbot/page__view__findpost__p__3665
We got wiring help from this thread at the Netduino forum: http://forums.netduino.com/index.php?/topic/2396-control-dc-motor-with-dual-motor-driver/

Wednesday, November 30, 2011

A Netduino Keyboard Simulator

I realized that I haven't posted anything here in awhile...  So, to remedy this, here's my post on a Netduino keyboard simulator.

What this project does is to turn your Netduino into a "Human Interface Device" or HID.  I originally got the idea for this when I needed a fun project for a Halloween blog post at work.  A friend had sent me a link to a similar (but much more focused and useful) project: http://www.irongeek.com/i.php?page=security/programmable-hid-usb-keystroke-dongle

So, in their footsteps, and with some help from a library from the Netduino forums, we built a generic "virtual keyboard."

So, yeah - like hardware based macro keys I guess. :)





Gathering the Parts:


I use SparkFun (and they are great) - but you can probably get all of these parts from a variety of vendors.

Development Environment:

If you don't already have your Netduino dev environment setup, you can go here: http://netduino.com/downloads/ and follow the "getting started" guide to setup your development environment.

Netduino Serial Hardware Setup:

First, connect the ground of the FTDI to the Netduino ground.
Next, hook the FTDI rx pin to the Netduino dio1.
Finally hook the FTDI tx pin to Netduino dio0.

You will also want to hook up an external power source.

Connect a USB to the FTDI.

Connect a USB to the Netduino.

Netduino Serial Setup Software:

(Check your firmware version with MFDeploy - mine didn't need re-flashed.)

Once you get your parts, and your dev environment is all setup - you will need to switch your Netduino to use serial programming (because the debug info is sent over that channel and it will interfere with the USB stuff you are trying to do).

Follow these instructions to do this: http://forums.netduino.com/index.php?showtopic=945

Here's a video from Omar on the Netduino Forum that covers this too:


http://www.youtube.com/user/VCSandARM#p/u/4/-yNC1nU1Nv4

Our Program:

Once you have this setup and tested, you'll want to move on to write your program.  You'll want to download keyboard.cs from this thread (use the last one on the page): http://forums.netduino.com/index.php?/topic/2274-netduino-usb-hid-keyboard-updated-code/

Then create a new "solution" in Visual Studio, target it to your serial interfaced Netduino and add the keyboard.cs to the solution (instructions from Omar in the link above).

Finally, we add our little bit of code for this:
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
using System.IO.Ports;
using Netduino_USB_HID_Library;

namespace Netduino_Touch_Keyboard
{
    public class Program
    {
        public static void Main()
        {

            string setupResult = Keyboard.SetUp();

            Debug.Print(setupResult);

            if (setupResult != "Success")
                return;

            OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);
            led.Write(true);
            Thread.Sleep(1000);
            led.Write(false);
            Thread.Sleep(1000);
            // setup our interrupt port (on-board button)
            // InterruptEdgeLow = Interrupt on button press only (not button up)
            InterruptPort button = new InterruptPort(Pins.ONBOARD_SW1, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeLow);

            // assign our interrupt handler
            button.OnInterrupt += new NativeEventHandler(button_OnInterrupt);

            // go to sleep until the interrupt wakes us (saves power)
            Thread.Sleep(Timeout.Infinite);

        }

        // the interrupt handler
        static void button_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            Keyboard.HoldDown(Keyboard.Modifiers.LeftGUI);
            Keyboard.SendChar('r');
            Keyboard.AllUp();
            Keyboard.SendString("notepad.exe");
            Thread.Sleep(2000);
            Keyboard.SendString("\n");
            Thread.Sleep(2000);
            Keyboard.SendString("Hello World!");
        }
    }
}

Compile and deploy this to the Netduino.

Then unplug (if it was already plugged into the USB) and re-plug the USB to the Netduino. This is needed because the app takes a bit to start the first time and the USB driver will fail if you plug it in too quickly - this isn't a problem in "production" since it will be externally powered and running already.

Now press the on-board button.

It should, open up a copy of notepad.exe then write "Hello World!" into it.

References:
Netduino USB HID Code and Example:
http://forums.netduino.com/index.php?/topic/2274-netduino-usb-hid-keyboard-updated-code/
Official thread on beta HID support:
http://forums.netduino.com/index.php?/topic/1514-driverless-pc-netduino-communication-using-usb/
Keyboard class from here:
http://forums.netduino.com/index.php?/topic/2372-netduino-usb-hid-touch-screen-keyboard/

Tuesday, July 12, 2011

How to annoy your wife with a Netduino...

So, I stopped by a Radio Shack tonight to pick up some parts and decided to buy the Netduino some toys.

Amongst some other pieces, I picked up a 12 VDC Piezoelectric Buzzer (RS# 273-0059).  You can find cheaper ones online - just make sure that the low-end of the voltage range for yours is around 3 volts (http://www.netduino.com/netduino/specs.htm).

You can drive this pretty easily by simply plugging this buzzer in between the ground pin (GND) and one of the digital I/O ports (I used 13 - it's right next to the ground pin).  Somewhat annoyingly, it will immediately begin buzzing when you power-up the Netduino - this does not endear you to your sleeping wife.  :)

The plan was to make the last project into something useful.  As you may know - the FCC requires that amatuer radio operators identify periodically during operation (Sec 97.119 - http://www.w5yi.org/page.php?id=124).  With a couple quick modifications - you can make your Netduino provide your ID whenever you press the button.  This might actually be useful. I don't operate on CW often, but you can ID with CW wherever CW is authorized - So, everywhere but 60 meter right (not an issue for me)?

You can do this with a couple tiny modifications from the previous project:

First, change your OutputPort from:
// setup our output port (on-board LED)
static OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);

to

// setup our output port (piezo buzzer (RS # 273-0059) between D13 and ground)
static OutputPort piezo = new OutputPort(Pins.GPIO_PIN_D13, false);

Then change your write operations from:
led.Write(true|false);

to
piezo.Write(true|false);

Then switch the MESSAGE constant to your call sign.   Hit the "Start debug" button and then press your button and you should get your call sign in CW over the buzzer at about 14 wpm (based on the UNIT constant being left at 100).

(I also ran across this free eBook on the .NET Micro Framework tonight - I haven't read through it yet - but it looks interesting - check it out:  Beginner's Guide to C# and .NET Micro Framework)