Read rc receiver and control esc
#1
Posted 25 December 2011 - 01:39 PM
#2
Posted 03 January 2012 - 11:39 AM
if you start an autonomous boot a good start would be to control a servo.
You need a class like this:
using System; using Microsoft.SPOT.Hardware; using SecretLabs.NETMF.Hardware; namespace Netduino.Extender { /// <summary> /// private static readonly Servo _Servo = new Servo(Pins.GPIO_PIN_D10); /// /// Debug.Print((data2 * 3).ToString()); /// _Servo.SetPulse(20000, data2 * 3); /// </summary> public class Servo { private PWM _Pwm; /// <summary> /// /// </summary> /// <param name="pin">Can be /// Pins.GPIO_PIN_D5 or ((Cpu.Pin)0x33), /// Pins.GPIO_PIN_D6 or ((Cpu.Pin)0x34), /// Pins.GPIO_PIN_D9 or ((Cpu.Pin)0x35), /// Pins.GPIO_PIN_D10 or ((Cpu.Pin)0x36). /// </param> public Servo(Cpu.Pin pin) { _Pwm = new PWM(pin); } public void SetDutyCycle(uint onInPercent) { _Pwm.SetDutyCycle(onInPercent); } /// <summary> /// To set a specific pulse width. /// </summary> /// <param name="completePeriodInNanoSeconds">For 50Hz servos: 20 ms</param> /// <param name="onTimePerPeriodInNanoSeconds">1 ms (left), und 2 ms (right)</param> public void SetPulse(uint completePeriodInNanoSeconds, uint onTimePerPeriodInNanoSeconds) { if (onTimePerPeriodInNanoSeconds > completePeriodInNanoSeconds) throw new InvalidOperationException(); _Pwm.SetPulse(completePeriodInNanoSeconds, onTimePerPeriodInNanoSeconds); } } }and you can call the contructor like this:
var servo = new Servo(Pins.GPIO_PIN_D5); or var servo = new Servo(Pins.GPIO_PIN_D6);because the Netduino has two pulse width outputs: digital pin 5 and 6.
The servo will be plugged in GND, +5V and digital pin 5 and 6.
Now you can use the SetPulse method to control the angle of the servo. Please read the XML comment of the method. Be aware of the 'ms' in the comment and the 'ns' in the method signature.
To read an RC receiver you have to record all pulses of a digital pin and interpret the length of the current pulse to get the angle. To do this task you have to connect the GND and the signal line to Netduino. The class could start like this
using System; using Microsoft.SPOT.Hardware; namespace Netduino.Extender { public sealed class PulseAnalyzer { private readonly InterruptPort _PulseInputPort; public PulseAnalyzer(Cpu.Pin dcfSignalPort, Cpu.Pin enableReceptionPort) { _PulseInputPort = new InterruptPort(dcfSignalPort, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth); _PulseInputPort.OnInterrupt += DcfInputPortOnInterrupt; } private void DcfInputPortOnInterrupt(uint data1, uint data2, DateTime time) { if (data2 != 0) { //Signal goes high //record the pulse } else { //Signal goes low //record the pulse } //analyze pulse with after a complete pulse was received } } }
Regards
Guido
#3
Posted 03 January 2012 - 01:13 PM
Hi hampee,
if you start an autonomous boot a good start would be to control a servo.
You need a class like this:
using System; using Microsoft.SPOT.Hardware; using SecretLabs.NETMF.Hardware; namespace Netduino.Extender { /// <summary> /// private static readonly Servo _Servo = new Servo(Pins.GPIO_PIN_D10); /// /// Debug.Print((data2 * 3).ToString()); /// _Servo.SetPulse(20000, data2 * 3); /// </summary> public class Servo { private PWM _Pwm; /// <summary> /// /// </summary> /// <param name="pin">Can be /// Pins.GPIO_PIN_D5 or ((Cpu.Pin)0x33), /// Pins.GPIO_PIN_D6 or ((Cpu.Pin)0x34), /// Pins.GPIO_PIN_D9 or ((Cpu.Pin)0x35), /// Pins.GPIO_PIN_D10 or ((Cpu.Pin)0x36). /// </param> public Servo(Cpu.Pin pin) { _Pwm = new PWM(pin); } public void SetDutyCycle(uint onInPercent) { _Pwm.SetDutyCycle(onInPercent); } /// <summary> /// To set a specific pulse width. /// </summary> /// <param name="completePeriodInNanoSeconds">For 50Hz servos: 20 ms</param> /// <param name="onTimePerPeriodInNanoSeconds">1 ms (left), und 2 ms (right)</param> public void SetPulse(uint completePeriodInNanoSeconds, uint onTimePerPeriodInNanoSeconds) { if (onTimePerPeriodInNanoSeconds > completePeriodInNanoSeconds) throw new InvalidOperationException(); _Pwm.SetPulse(completePeriodInNanoSeconds, onTimePerPeriodInNanoSeconds); } } }
Thanks for your help!
I already got a servo class. But its verry diferent from your code.
public class Servo { private PWM pin; private uint[] range = new uint[2]; private const uint maxDegree = 180, minDegree = 0; public Servo(Cpu.Pin servoPin) { pin = new PWM(servoPin); pin.SetDutyCycle(0); range[0] = 1000; range[1] = 2000; } public void move(double degree) { if (degree > maxDegree) degree = maxDegree; if (degree < minDegree) degree = minDegree; pin.SetPulse(20000, (uint)map((long)degree, minDegree, maxDegree, range[0], range[1])); } public void setRange(uint fullLeft, uint fullRight) { range[1] = fullLeft; range[0] = fullRight; } private long map(long x, long in_min, long in_max, long out_min, long out_max) { return (degree - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } }
I wrote it but it is highly influenced from some code on this forum so i dont take all credit.
unfortunately i havent had a chance to test it yet. But before i do so i thought i sould check with someone more experienced so i dont burn my board.
#4
Posted 03 January 2012 - 05:48 PM
#5
Posted 04 January 2012 - 05:07 AM
#6
Posted 04 January 2012 - 04:26 PM
I did this with a hobby grade RC car, and I have both a servo lib and ESC lib out here somewhere on the forums. If you do a search for "RWAR", you might be able to find some remains of the project.
I found a thread where you had released a great projekt with a ppm decoder class. I have modified it for my projekt and i am just about to test it.
But i would like if someone could confirm i wired right.
Now its wired pin d7 to reciver signal
pin d5 to servo signal
5v and the gnd next to 5v is connected to the reciver
and the +/- from the servo is also connected to reciver.
like this
#7
Posted 05 January 2012 - 12:00 AM
I strongly recommend to wire the +5V directly to a power supply. Maybe you can use a BEC (battery eliminator circuit) from the model.
I've read in another thread (a year ago) that the voltage regulator of the Netduino can not handle the current of the servo if it is blocked or if your program intructs it to go beyound an angle of +/-90 degree. Ground must still be connected to the Netduino and to the other power supply as well.
And I've found a link with specs about current:
How-much-current-can-I-draw-from-Netduino
800mA is the maximum of all loads. If your servo exceed these figures you may be damaging your board.
Regard
Guido
#8
Posted 05 January 2012 - 11:33 AM
Hi hampee,
I strongly recommend to wire the +5V directly to a power supply. Maybe you can use a BEC (battery eliminator circuit) from the model.
I've read in another thread (a year ago) that the voltage regulator of the Netduino can not handle the current of the servo if it is blocked or if your program intructs it to go beyound an angle of +/-90 degree. Ground must still be connected to the Netduino and to the other power supply as well.
And I've found a link with specs about current:
How-much-current-can-I-draw-from-Netduino
800mA is the maximum of all loads. If your servo exceed these figures you may be damaging your board.
Regard
Guido
Like this?
I'm sorry if my questions is stupid but i just dont want to start of by damaging my board.
#9
Posted 05 January 2012 - 11:51 AM
#10
Posted 01 February 2012 - 12:51 PM
As for now i have an infinite loop thats constantly is checking the read.
I am trying to make this eventbased so i can have an eventhandler calling a method with the new value if read has been changed but i cant get it to work.
Is it even posible to do it this way?
i have tried doing it like this
public delegate void readChanged(int read); public event readChanged read_changed; private InterruptPort pin; private long ticks; public int min, max; public int read { get { return read; } private set { read = value; read_changed(value); } } public rxReader(Cpu.Pin inputPin) { pin = new InterruptPort(inputPin, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth); pin.OnInterrupt += inputHandle_OnInterrupt; } void inputHandle_OnInterrupt(uint data1, uint state, DateTime time) { if (state == 0) read = (int)(time.Ticks - ticks) / 10; else ticks = time.Ticks; }
#11
Posted 01 February 2012 - 07:08 PM
#12
Posted 24 February 2012 - 03:58 PM
#13
Posted 27 February 2012 - 10:20 AM
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users