microframework.dk

.NET softwired

Controlling Servo Motors with .NET MicroFramework

This post illustrates how you can control Servo Motors from .NET MicroFramework using only simple output pins and C# code.

I have this idea of making a walking robot, so in order to test the basic servo control from .NET MicroFramework, I have used 2 servo motors and built a leg. Each Servo motor controls a joint in a leg.


You can start out with a look at the short video on YouTube that I made to show the leg moving.


In my first test I have used the GHI USBizi development board, but no special hardware has been used, only simple GPIO pins. I wanted to use the built-in PWM feature of the GHI board, but the program locked up when I initialized the PWM feature! I don't know if this is an error in the GHI firmware or what, but instead of investigating this further I made my own Servo control class in C#, which implements the PWM control.


Update 2015.

The code running in the video, is as follows:

using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using System.Threading;

namespace PFJ.NETMF.Hardware.Motor
{
    public class Servo
    {
        OutputPort servoPort;
        int pulseWidth;

        int max;
        int min;
        int mid;

        object lockitem;

        public Servo(Cpu.Pin Pin)
        {
            servoPort = new OutputPort(Pin, false);

            max = 1450;
            min = 300;
            mid = 575; // (max - min) / 2;
            pulseWidth = mid;

            lockitem = new object();

            Thread ServoThread = new Thread(ServoProcessor);
            ServoThread.Start();
        }

        public void Left()
        {
            lock (lockitem)
            {
                pulseWidth = min;
            }
        }

        public void Middle()
        {
            lock (lockitem)
            {
                pulseWidth = mid;
            }
        }

        public void Right()
        {
            lock (lockitem)
            {
                pulseWidth = max;
            }
        }

        public void Position(double Percent)
        {
            double d = System.Math.Round((Percent / 100D) * (max - min) + min);
            lock (lockitem)
            {
                pulseWidth = Convert.ToInt32(d.ToString());
            }
        }

        public void Wait(int Delay)
        {
            Thread.Sleep(Delay);
        }

        protected virtual void ServoProcessor()
        {
            while (true)
            {
                lock (lockitem)
                {
                    ServoHighPulse();
                    ServoLowPulse();
                }
                Thread.Sleep(2);
            }
        }


        private void ServoHighPulse()
        {
            servoPort.Write(true);
            DelayMicroSec(pulseWidth);
        }

        private void ServoLowPulse()
        {
            servoPort.Write(false);
            DelayMicroSec(max - pulseWidth);
        }

        /// <summary>
        /// Blocks thread for given number of microseconds
        /// </summary>
        /// <param name="microSeconds">Delay in microseconds</param>
        private void DelayMicroSec(int microSeconds)
        {
            DateTime startTime = DateTime.Now;

            int stopTicks = microSeconds * 10;

            TimeSpan divTime = DateTime.Now - startTime;
            while (divTime.Ticks < stopTicks)
            {
                divTime = DateTime.Now - startTime;
            }
        }
    }
}

Peter

 

Controlling a Stepper Motor with .NET MicroFramework

This post illustrates how you can control a unipolar stepper motor from .NET MicroFramework using very simple hardware.

The motor which I have scavenged from an old 5 1/4" floppy disk drive (do you remember those?) is controlled by a dedicated Stepper Motor control class written in C#.



You can start out with a look at the short video on YouTube that I made to show the motor running:

 


Update 2015.

The code running in the video, is as follows.

using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using System.Threading;

namespace PFJ.NETMF.Hardware.Motor
{
    public class StepperMotor2003
    {
        private byte[] pattern1 = { 1, 8, 4, 2};

        OutputPort port1;
        OutputPort port2;
        OutputPort port3;
        OutputPort port4;

        private int delay;
        public int Delay
        {
            get { return delay; }
            set { delay = value; }
        }

        private int index;

        public StepperMotor2003(Cpu.Pin Pin1, Cpu.Pin Pin2, Cpu.Pin Pin3, Cpu.Pin Pin4)
        {
            port1 = new OutputPort(Pin1, true);
            port2 = new OutputPort(Pin2, false);
            port3 = new OutputPort(Pin3, false);
            port4 = new OutputPort(Pin4, false);

            index = 0;
            SetPattern(pattern1[index]);

            this.delay = 2;
        }

        private void SetPattern(byte p)
        {
            switch (p)
            {
                case 1:
                    port1.Write(true);
                    port2.Write(false);
                    port3.Write(false);
                    port4.Write(false);
                    break;
                case 2:
                    port1.Write(false);
                    port2.Write(true);
                    port3.Write(false);
                    port4.Write(false);
                    break;
                case 4:
                    port1.Write(false);
                    port2.Write(false);
                    port3.Write(true);
                    port4.Write(false);
                    break;
                case 8:
                    port1.Write(false);
                    port2.Write(false);
                    port3.Write(false);
                    port4.Write(true);
                    break;
            }
        }

        public void StepRight()
        {
            index = index == 3 ? 0 : index += 1;

            SetPattern(pattern1[index]);
            Thread.Sleep(this.delay);
        }

        public void StepRight(int Steps)
        {
            int i = 0;
            for (int r = 0; r < Steps; r++)
            {
                SetPattern(pattern1[System.Math.Abs(i)]);
                i += 1;
                i = i % 4;
                Thread.Sleep(this.delay);
            }
        }

        public void StepLeft()
        {
            index = index == 0 ? 3 : index -= 1;

            SetPattern(pattern1[index]);
            Thread.Sleep(this.delay);
        }

        public void StepLeft(int Steps)
        {
            int i = 3;
            for (int r = 0; r < Steps; r++)
            {
                SetPattern(pattern1[System.Math.Abs(i)]);
                i = i == 0 ? 3 : i -= 1;
                Thread.Sleep(this.delay);
            }
        }

        public void Wait(int Delay)
        {
            Thread.Sleep(Delay);
        }
    }
}

Peter