Zu Weihnachten habe ich mir bisl Zeit genommen und wollte etwas mit Servo und NETMF machen. Brauche immer ein Projekt welches auch Sinn macht… Naja ob das Resultat sinnig ist, darf jeder selber Entscheiden.

Eigentlich sollte ich das Projekt unter Homeautomation einstellen, da es mir jeden Tag Zeit spart. Denn wir lieben Kinderschokolade :^)

Bevor ich aber jedes Mal alles rauskrame, dachte ich mir wäre doch ein Roboter, welcher mir die Arbeit abnimmt, sinnvoll.

Lego

Gesagt getan, endlich wieder mit Legos etwas bauen, passt irgendwie zu Weihnachten.

Bau 1 Bau 2

Bau Vorne Bau Hinten

Bau 3 Schalter

 

Rückansicht Seitlich Links

Seitlich Rechts Vorne

Folgende Komponenten wurden verbaut:

Gesamtkosten ca. 56€ was nicht gerade billig ist. Achja, Lego hatte ich schon, sonst wären es wahrscheinlich locker über 100€.

Das programmieren des Servos ist nicht ganz so einfach mit NETMF aufgrund fehlender Libraries für die Taktzeiten… hab mir bisl was zusammengesucht, denke aber ist nicht das beste Setup, da hier viel manuell gerechnet wurde (Clocktime). Da ist wohl ein nicht NETMF Controller besser.

Aber es funktioniert wie es sollte und schaut auch gut aus :^)

using Gadgeteer;
using Servo_API;
using Button = Gadgeteer.Modules.GHIElectronics.Button;

namespace Program
{
    public partial class Program
    {
        Servo servo; 
        private bool IsRunning;

        void ProgramStarted()
        {
            Debug("Set it UUUUP!");

            // Setup
            Mainboard.SetDebugLED(true);
            button.ButtonPressed += ButtonOnButtonPressed;
        }

        private void ButtonOnButtonPressed(Button sender, Button.ButtonState state)
        {
            if (!IsRunning)
            {
                Debug("Chocolate!");
                
                ledLeft.FadeOnce(Color.Red);
                ledRight.FadeOnce(Color.Red);

                IsRunning = true;

                servo = new Servo(extender);
                servo.Degree = -180;
                servo.Dispose();

                IsRunning = false;

                Debug("Bedtime!");                
            }
        }

        void Debug(string text)
        {
            Microsoft.SPOT.Debug.Print("==> " + text);
        }
    }
}
// Orginal http://stackoverflow.com/questions/22699174/netduino-class-servo-4-3-1

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

namespace Servo_API
{
    public class Servo : IDisposable
    {
        /// <summary>
        /// PWM handle
        /// </summary>
        private PWM servo;

        /// <summary>
        /// Timings range
        /// </summary>
        private int[] range = new int[2];

        /// <summary>
        /// Set servo inversion
        /// </summary>
        public bool inverted = false;

        /// <summary>
        /// Create the PWM Channel, set it low and configure timings
        /// </summary>
        public Servo(Module module)
        {
            // Init the PWM pin
            // servo = new PWM((Cpu.PWMChannel)channelPin, 20000, 1500, PWM.ScaleFactor.Microseconds, false);
            Socket SocketExtender = Socket.GetSocket(4, true, module, "socketExtender");
            servo = new PWM(SocketExtender.PWM9, 20000, 1500, PWM.ScaleFactor.Microseconds, false);
            servo.Period = 20000;

            // Typical settings
            range[0] = 900;
            range[1] = 2100;
        }

        public void Dispose()
        {
            disengage();
            servo.Dispose();
        }

        /// <summary>
        /// Allow the user to set cutom timings
        /// </summary>
        /// <param name="fullLeft"></param>
        /// <param name="fullRight"></param>
        public void setRange(int fullLeft, int fullRight)
        {
            range[1] = fullLeft;
            range[0] = fullRight;
        }

        /// <summary>
        /// Disengage the servo. 
        /// The servo motor will stop trying to maintain an angle
        /// </summary>
        public void disengage()
        {
            // See what the Netduino team say about this... 
            servo.DutyCycle = 0; //SetDutyCycle(0);
        }

        /// <summary>
        /// Set the servo degree
        /// </summary>
        public double Degree
        {
            set
            {
                // Range checksJa
                if (value > 180)
                    value = 180;

                if (value < 0)
                    value = 0;

                // Are we inverted?
                if (inverted)
                    value = 180 - value;

                // Set the pulse
                //servo.SetPulse(20000, (uint)map((long)value, 0, 180, range[0], range[1]));
                servo.Duration = (uint)map((long)value, 0, 180, range[0], range[1]);
                servo.Start();
                Thread.Sleep(360);
            }
        }


        private long map(long x, long in_min, long in_max, long out_min, long out_max)
        {
            return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
        }
    }
}