Search This Blog

Sunday, April 22, 2012

NetDuino Plus–steerable webcam

Did some practice with the Netduino Plus this weekend, trying to see how hard it would be to make a remotely-steerable webcam.  Answer:  not very hard at all.  Right now I just have it hooked up to a potentiometer on the left.  (The other one was for the other servo, but it turned out I only had a continuous rotation one in the box, so I just have the yaw axis working despite having a a pitch-axis pot on the board.)

The code's pretty simple, too.  See below.  Now I just integrate this as a thread/subroutine with the tiny-webserver code from last week and fabricate a mount for the webcam.  I've found some interesting libraries/modules for the .NET Micro Framework at CodePlex.  Check out:  http://neonmikawebserver.codeplex.com/

The webcam itself is a Linksys WVC54GCA, which is a standalone unit with a built-in webserver, so I'll probably wrap a simple steering UI around the URLs available on the camera.

NetduinoPlusServoControl

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;
namespace BlinkLED {
    public class Program {
        static OutputPort led = new OutputPort(Pins.GPIO_PIN_D13, false);
        static AnalogInput pot = new AnalogInput(Pins.GPIO_PIN_A0);
        static int SensorValue = 0;
        static int LastSensorValue = SensorValue;
        const int ErrorBand = 50;
        const int PotRange = 1023 - 0;
        //  Parallax Standard Servo range seems to be roughly 2300-400
        const int ServoFullLeft = 2300;
        const int ServoFullRight = 400;
        const int Middle = (ServoFullLeft + ServoFullRight) / 2;
        const int ServoPulseDuration = 20000;
        const int ServoRange = ServoFullLeft - ServoFullRight;
        public static void Main() {
            PWM Servo = new PWM(Pins.GPIO_PIN_D10);
            //            int Position = Middle;
            while (true) {
                //  0 (fastest/full right) - 1024 (slowest/full left)
                SensorValue = pot.Read();
                if (SensorValue > LastSensorValue + ErrorBand || SensorValue < LastSensorValue - ErrorBand) {
                    Debug.Print("Potentiometer-> Last value: " + LastSensorValue.ToString() + "  Current value: " + SensorValue.ToString());
                    float NormalizedValue = ((float) SensorValue / ((float) PotRange / (float) ServoRange)) + ServoFullRight;
                    Debug.Print("Set servo to " + ((int) NormalizedValue).ToString());
                    //                Servo.SetDutyCycle(0);
                    Servo.SetPulse(ServoPulseDuration, (uint) NormalizedValue);
                }
                //  Enable for flashy LED
                //led.Write(true);
                //Thread.Sleep(SensorValue);
                //led.Write(false);
                //  Don't adjust more than 4x/second
                Thread.Sleep(250);
                LastSensorValue = SensorValue;
            }
        }
    }
}

No comments: