Capturing PWM on a Netduino

I have been trying to send signals to my Netduino from a R/C transmitter and capture and analyze those signals.  To that end, I have a Spektrum AR600 RC transmitter and receiver.  My first stop was the Netduino forms where there was one very helpful person named Hanzibal who answered my questions.  I also had to use this great article that explains how PWM works in an RC unit.

Basically, the RC receiver sends a pulse of electricity every 20 MS.  This pulse will one of three lengths: 1 millisecond, 1.5 millisecond, or 2 milliseconds.  As I understand the article, 1.5 milliseconds means that servo should stay in the same position it is currently in (do nothing), 1 millisecond means that it should move down a given number of degrees and 2 milliseconds means that the servo goes up a given number of degrees.  The servo itself determines the turn rate and if the servo is at its max, it will ignore the signal.

My first challenge is to set up my hardware that will:

  1. 1) not destroy the hardware I am using
  2. 2) capture the PWMs

Thanks for Hanizbal and some significant trial and error, I set up my Netduino like so:


You will notice that the RC receiver is powered by a 4.8 V battery pack versus the 3.3V or 5.0V output of the Netduino.

Some of the things I learned are:

You don’t need a ground from the RC receiver to the Netduino board.  The only wire you need to connect is the Signal wire from the RC receiver to the Digital I/O port.

This is not completely fool-proof.  Sometimes when I deploy with the RC receiver connected to the board, I get this:


I found that unplugging the Netduino cord and plugged it back into the Netduino, the code published.

With this in mind, I jumped into Visual Studio fired up a Netduino project.  I first looked at the PWM class


The problem is that the PWM class does not have a GetPulse method or EventHandler.  This is a limitation that is not present in the Arduino as documented in this post.

I then looked at the Interrupt Port class like this person did.  I created some code like this:

public static void Main()

    InterruptPort inputPort = new InterruptPort(Pins.GPIO_PIN_D0,
        true, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);

    inputPort.OnInterrupt += new NativeEventHandler(inputPort_OnInterrupt);


static void inputPort_OnInterrupt(uint data1, uint data2, DateTime time)
    Debug.Print(data2 + ":" + time.Millisecond + ":" + time.Ticks);

When I ran it with the RC receiver unplugged I got this:


Waiting for debug commands…

The thread ‘<No Name>’ (0x1) has exited with code 0 (0x0).

So the port was not receiving any signals or generating any kind of false signal.

When the RC receiver was plugged into the port, I got:














I then fiddled around with the InterruptMode and this is what I found:

  • InterruptEdgeLow= 0
  • InterruptEdgeLevelLow= None
  • InterruptEdgeHigh= 1
  • InterruptEdgeLevelHigh= None
  • InterruptEdge=Both 1 && 0
  • InterruptNone= Exception

So looking at the values of the interrupts, I can’t use time.Milliseconds because it is an Int32 – it doesn’t have the level of precision to read 1.5 MS.

I then took this dataset and calculated the difference in ticks between the 0 and the 1 for each group:


With 10,000 ticks in a millisecond, it means the neutral pulse is 1.2 MS, not 1.5 MS as I initially thought.

This looks promising because at least it appears to be consistent

The battery pack supplying the 4.8V to the RC receiver then died.  I disconnected the battery pack and plugged the receiver into the Netduino 5V output and ran the same experiment again:


So the Period Length depends on the amount voltage coming in.  Also, it the difference is no longer consistent.

I decided to run 1 more experiment – push the stick up and down with the 5V power source:



Sure enough, The PW does change.  The range is from 1.0016 to  2.  The problem is that there is a wide range of possible values for the Pulse Width:


I was expecting only 3 values.  This is showing values 1.0, 1.1, 1.2, etc…  Without a discrete value, there is no way of determining if the stick is going up or down – unless perhaps I can determine that anything under 1.5 is down and above is up?  More hacking is in order…

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: