The Netduino forums have been replaced by new forums at community.wildernesslabs.co.
This site has been preserved for archival purposes only
and the ability to make new accounts or posts has been turned off.
This is a class I use on my other NETMF hardware to run my RC car based robot. It took very little effort to port to the Netduino, hopefully someone find it useful
/*
* Servo NETMF Driver
* Coded by Chris Seto August 2010
* <chris@chrisseto.com>
*
* Use this code for whatveer you want. Modify it, redistribute it, I don't care.
* I do ask that you please keep this header intact, however.
* If you modfy the driver, please include your contribution below:
*
* Chris Seto: Inital release (1.0)
* Chris Seto: Netduino port (1.0 -> Netduino branch)
* Chris Seto: bool pin state fix (1.1 -> Netduino branch)
*
*
* */
using System;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
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 pin, set it low and configure timings
/// </summary>
/// <param name="pin"></param>
public Servo(Cpu.Pin pin)
{
// Init the PWM pin
servo = new PWM((Cpu.Pin)pin);
servo.SetDutyCycle(0);
// Typical settings
range[0] = 1000;
range[1] = 2000;
}
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.SetDutyCycle(0);
}
/// <summary>
/// Set the servo degree
/// </summary>
public double Degree
{
set
{
/// Range checks
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]));
}
}
/// <summary>
/// Used internally to map a value of one scale to another
/// </summary>
/// <param name="x"></param>
/// <param name="in_min"></param>
/// <param name="in_max"></param>
/// <param name="out_min"></param>
/// <param name="out_max"></param>
/// <returns></returns>
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;
}
}
}
Example code:
using System.Threading;
using SecretLabs.NETMF.Hardware.Netduino;
using Servo_API;
namespace NetduinoServoDemo
{
public class Program
{
public static void Main()
{
Servo servo = new Servo(Pins.GPIO_PIN_D9);
while (true)
{
for (int i = 0; i <= 180; i++)
{
servo.Degree = i;
Thread.Sleep(10);
}
for (int i = 180; i >= 0; i--)
{
servo.Degree = i;
Thread.Sleep(10);
}
}
}
}
}
This is a class I use on my other NETMF hardware to run my RC car based robot. It took very little effort to port to the Netduino, hopefully someone find it useful
/*
* Servo NETMF Driver
* Coded by Chris Seto August 2010
* <chris@chrisseto.com>
*
* Use this code for whatveer you want. Modify it, redistribute it, I don't care.
* I do ask that you please keep this header intact, however.
* If you modfy the driver, please include your contribution below:
*
* Chris Seto: Inital release (1.0)
* Chris Seto: Netduino port (1.0 -> Netduino branch)
*
*
* */
using System;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
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 pin, set it low and configure timings
/// </summary>
/// <param name="pin"></param>
public Servo(Cpu.Pin pin)
{
// Init the PWM pin
servo = new PWM((Cpu.Pin)pin);
// See what the Netduino team say about this...
//servo.Set(false);
// Typical settings
range[0] = 1000;
range[1] = 2000;
}
public void Dispose()
{
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.Set(false);
}
/// <summary>
/// Set the servo degree
/// </summary>
public double Degree
{
set
{
/// Range checks
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]));
}
}
/// <summary>
/// Used internally to map a value of one scale to another
/// </summary>
/// <param name="x"></param>
/// <param name="in_min"></param>
/// <param name="in_max"></param>
/// <param name="out_min"></param>
/// <param name="out_max"></param>
/// <returns></returns>
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;
}
}
}
Example code:
using System.Threading;
using SecretLabs.NETMF.Hardware.Netduino;
using Servo_API;
namespace NetduinoServoDemo
{
public class Program
{
public static void Main()
{
Servo servo = new Servo(Pins.GPIO_PIN_D9);
while (true)
{
for (int i = 0; i <= 180; i++)
{
servo.Degree = i;
Thread.Sleep(10);
}
for (int i = 180; i >= 0; i--)
{
servo.Degree = i;
Thread.Sleep(10);
}
}
}
}
}
Good stuff - I was in the middle of writing my own by why reinvent the wheel?
Good stuff - I was in the middle of writing my own by why reinvent the wheel?
Thanks!
Nice, at least someone got some use out of it! Yeah, this class has been used and tested extensively, so it's all worked out. I will be updating the class in just a sec, too.
Nice, at least someone got some use out of it! Yeah, this class has been used and tested extensively, so it's all worked out. I will be updating the class in just a sec, too.
I just tried to use the class from the post, and I get an error while compiling "Error 1 The type or namespace name 'Cpu' could not be found (are you missing a using directive or an assembly reference?)"
While I am new to using C# this is not the first class library I have made so I am a little confused about why I am getting the error. I did copy and pasted the file from the post.
Any suggestion?
Did you include the Microsoft.SPOT.Hardware reference? You probably also need SecretLabs.NETMF.Hardware and SecretLabs.NETMF.Hardware.Netduino
So it was a problem with the way I created the project, not the source at all. Once I went to References under the solution explorer and added the Microsoft.SPOT.Hardware, it build just fine.
Like I said I am still a nubie when it comes to C#.
BTW: That and SecretLabs.NETMF.Hardware. Oops.
Thanks.
Hi Chris,
This is Hai, I am trying to make distance sensor driver works on netduino, but for some reasons it doesn't work, could you take a look and see if you can notice I did something wrong.
code has been removed due to it may spark legal issue -Hai
Thanks!
Here is exception:
The thread '<No Name>' (0x2) has exited with code 0 (0x0).
#### Exception System.ArgumentOutOfRangeException - CLR_E_OUT_OF_RANGE (1) ####
#### Message:
#### SecretLabs.NETMF.Hardware.AnalogInput::ADC_Enable [IP: 0000] ####
#### SecretLabs.NETMF.Hardware.AnalogInput::.ctor [IP: 0026] ####
#### SecretLabs.NETMF.Hardware.Netduino.Drivers.DistanceDetector::.ctor [IP: 0045] ####
#### Program::Main [IP: 0007] ####
A first chance exception of type 'System.ArgumentOutOfRangeException' occurred in SecretLabs.NETMF.Hardware.dll
An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in SecretLabs.NETMF.Hardware.dll
Hi Chris,
This is Hai, I am trying to modify FEZ's distance sensor driver to get it work on netduino, but it doesnt work, could you take a look and see if you can notice I did something wrong.
Thanks!
using System;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
namespace SecretLabs.NETMF.Hardware.Netduino.Drivers
{
class DistanceDetector: IDisposable
{
AnalogInput port;
float Y0 = 0;
float X0 = 0;
float Y1 = 0;
float X1 = 0;
float C = 0;
public enum SharpSensorType : byte
{
GP2Y0A21YK = 0,
GP2D120 = 1,
}
public void Dispose()
{
port.Dispose();
}
public DistanceDetector(Cpu.Pin pin, SharpSensorType type)
{
port = new AnalogInput((Cpu.Pin)pin );
port.SetRange(0, 330);
switch (type){
case SharpSensorType.GP2Y0A21YK:
Y0 = 10;
X0 = 315;
Y1 = 80;
X1 = 30;
break;
case SharpSensorType.GP2D120:
Y0 = 3;
X0 = 315;
Y1 = 30;
X1 = 30;
break;
}
C = (Y1 - Y0) / (1 / X1 - 1 / X0);
}
public float GetDistance()
{
return C / ((float)port.Read() + (float).001) - (C / X0) + Y0;
}
}
}
Usage:
DistanceDetector frontL = new DistanceDetector(Pins.GPIO_PIN_D0,DistanceDetector.SharpSensorType.GP2Y0A21YK);
while (true)
{
Debug.Print("L: " + frontL.GetDistance().ToString() );
Thread.Sleep(100);
}
Here is exception:
The thread '<No Name>' (0x2) has exited with code 0 (0x0).
#### Exception System.ArgumentOutOfRangeException - CLR_E_OUT_OF_RANGE (1) ####
#### Message:
#### SecretLabs.NETMF.Hardware.AnalogInput::ADC_Enable [IP: 0000] ####
#### SecretLabs.NETMF.Hardware.AnalogInput::.ctor [IP: 0026] ####
#### SecretLabs.NETMF.Hardware.Netduino.Drivers.DistanceDetector::.ctor [IP: 0045] ####
#### Program::Main [IP: 0007] ####
A first chance exception of type 'System.ArgumentOutOfRangeException' occurred in SecretLabs.NETMF.Hardware.dll
An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in SecretLabs.NETMF.Hardware.dll
Hi Hai, fancy seeing you here
It looks like you are using the wrong pin. The argument is out of range because you are using a digital pin. Try GPIO_PIN_A0
Hi there Hai, welcome to the community; thanks for your post!
DistanceDetector frontL = new DistanceDetector(Pins.GPIO_PIN_D0,DistanceDetector.SharpSensorType.GP2Y0A21YK);
Here is exception:
The thread '<No Name>' (0x2) has exited with code 0 (0x0).
#### Exception System.ArgumentOutOfRangeException - CLR_E_OUT_OF_RANGE (1) ####
#### Message:
#### SecretLabs.NETMF.Hardware.AnalogInput::ADC_Enable [IP: 0000] ####
#### SecretLabs.NETMF.Hardware.AnalogInput::.ctor [IP: 0026] ####
#### SecretLabs.NETMF.Hardware.Netduino.Drivers.DistanceDetector::.ctor [IP: 0045] ####
#### Program::Main [IP: 0007] ####
A first chance exception of type 'System.ArgumentOutOfRangeException' occurred in SecretLabs.NETMF.Hardware.dll
An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in SecretLabs.NETMF.Hardware.dll
Pins.GPIO_PIN_D0 is a digital pin. AnalogInput can only take readings from analog-capable pins. Did you mean to use Pins.GPIO_PIN_A0 (analog 0) instead?
One quick tip...
port = new AnalogInput((Cpu.Pin)pin );
You don't need to cast your pins with (Cpu.Pin). We use the Cpu.Pin type natively, even in the "Pins." enumeration--so you can just just say:
port = new AnalogInput(pin);
Nice to have you here!
Chris
EDIT: dang, Chris, you beat me in responding to Hai's post. Great stuff.
"EDIT: dang, Chris, you beat me in responding to Hai's post. Great stuff. "
Hahaha. 4 minutes later.
At any rate, Hai and I know each other from the TinyCLR site. Hai, I'll be coding up the PPM decoder later tonight, although it won't be released until tomorrow, since I am waiting for the RC truck's battery to charge 8.5 hours) to test it. When that's done, I'll package it all up and make a new thread for the Netduino branch of the hobby grade RC car control suite.
Hi CHRISes! :-)
Sorry I join the fun a litle late.
I did mix things up didn't I?...You guys are rock!!!! I did mean A0. It works now. Life is good again. I am waiting for your RX driver, also if neccessary post this driver in appropriate section so that people can find it easier? I recommend moderator to lock up that room to keep the library clean?
Thank you very much!!
RX / PPM decoder driver is done, I'm just waiting to test it. Looks like it will be another 7.5 hours.
Chris take your time, I am not in hurry.
I am planning to use my existing 3 Sharp sensors, 2 front + 1 back. I will see how it work with these sensor first and may end up getting a longer range one. Are you planning to get something more powerful/longer range?
Hi Hai,
Yeah, I'll be using a combination of Sharp IR and Parallax PING))) sensors. Each pair will be on it's own pan/tilt mount. I might have something like 4 pairs, one per corner.
Yeah, I'll be using a combination of Sharp IR and Parallax PING))) sensors. Each pair will be on it's own pan/tilt mount. I might have something like 4 pairs, one per corner.
Chris,
Did you get a chance to play with sensors on netduino the drive i posted early for some reasosn it returns same reading everytime, I am having some sort of issues with Netduino deployment so I am not sure if the issue is with sensor driver
I'm using a servo off an old helicopter (link) and no matter what I do, I can't get it to move using code. If I apply power to it, after about 2-3 secs it spins all the way to the right, is that what it's supposed to do?
I'm very new to all this in case you couldn't tell
I'm using a servo off an old helicopter (link) and no matter what I do, I can't get it to move using code. If I apply power to it, after about 2-3 secs it spins all the way to the right, is that what it's supposed to do?
I'm sure Chris will pitch in, but in the meantime one quick bit of info:
1. Motors work by applying power to them. The more power (or the higher dutycycle on the PWM) the faster they move, generally speaking.
2. Servos work by sending them short pulses every ## milliseconds. The length of the pulse dictates what angle the servo should move to. To move a servo all the way around, you'd send a 90 degree command followed by a 180 degree command, etc. (generally--pick your angles for what makes sense).
The beautiful thing about servos is that you get very precise movements when moving things like robot arms and you get very precise speeds when turning the servo like a motor. Oh, plus you can simply apply the proper voltage to the servo and just use the lines from the Netduino to act as data control lines.
Chris
P.S. I'm totally assuming that you are setting the dutycycle here like a motor and not using servo code--but I'm also probably totally off-base Hopefully this is helpful either way.