Main Site Documentation

Need help with hooking event on pin input

So I’ve got movement on a servo (different thead). Now it’s time for a next step in my explorations. I’m trying to determine the pulse width of a PWM signal from an RC receiver.
I am staring at this bit of code which I wrote based on a tutorial. Nothing happens, the event does not fire, while I see a nice block wave on my scope with a frequency of exactly 50Hz and a pulse width of exactly 1ms.
What am I doing wrong?

class Program
{
    private static long _pulseWidth;
    private static long _currentPulse;

    static void Main()
    {
        var gpio = GpioController.GetDefault();

        var signalIn = gpio.OpenPin(FEZ.GpioPin.D2);
        signalIn.SetDriveMode(GpioPinDriveMode.InputPullDown);
        signalIn.ValueChanged += Signal_ValueChanged;
        _pulseWidth = 0;
        while (true)
        {
            Debug.WriteLine($"{DateTime.Now.Second} {_pulseWidth}");
            Thread.Sleep(100);
        }
    }

    private static void Signal_ValueChanged(GpioPin sender, GpioPinValueChangedEventArgs e)
    {
        if (e.Edge == GpioPinEdge.RisingEdge)
        {
            _currentPulse = e.Timestamp.Ticks;
        }
        else
        {
            var thisWidth = e.Timestamp.Ticks - _currentPulse;
            if (thisWidth < _currentPulse - 1000 || thisWidth > _currentPulse + 1000)
            {
                _pulseWidth = thisWidth;
            }
        }
    }

}

Thanks for your help,
Egbert

Is the Signal_ValueChanged() event actually firing?
If so, have you debugged the ranges your getting in the condition statement

if (thisWidth < _currentPulse - 1000 || thisWidth > _currentPulse + 1000)

Yes I have. I have put a breakpoint on the outer if statement. Nothing happens.
Sometimes the program doesn’t seem to start. It seems to help if I connect the pin after start up. That’s the only moment I have seen the event fire.
Do you know how many ticks there are in a millisecond? I have chosen this window because I have seen a very big number coming by, much bigger than 1000.

reload firmware?

Firmware is up to date.
I will try a second board. I bought serveral. If that does not work I may try an Arduino I have laying around. The thought of separating the data acquisition process - I wish to monitor three PWM signals - from the rest is appealing.

Reloading the current firmware is worth a try.

Are you sure your wiring is correct?

Just tested your code, here it works.
Try once more to let the automatic of VS create the eventhandler.
means: signalIn.ValueChanged += then 2 x tab
sometimes VS doesn’t correctly assign the eventhandler.
You took the Pin between D1 and D3 and intermittently connect it to 3.3 Volts (best through a 10 KOhm resistor)?

1 Like

Good to know that the code works.
Well, good to SEE that the code works. Simulating a signal with 3.3V like you said makes the code work here too! Great idea!
I guess the signal is the cause of my problem, which I can’t imagine:
Period: 20.0ms
Pulse width: 1.010ms
Amplitude: 3.285V
I have added two pics of the same signal:

I hope you know what may be wrong with the signal. I am certainly a step further.

Regards,
Egbert

1 Like

Happy to hear that it works now.

However I don’t understand what kind of problem you still have. Please tell a bit more in detail.

If you want to decode pulses of a RF Receiver with the FEZ perhaps this links can help you:
-https://old.ghielectronics.com/community/codeshare/entry/1060

However I think that handling pulses of RF receivers can be challenging for a device running managed code. Sometimes it may be better to attach a small MCU like an Arduino for the RF Decoding and use something like the FEZ to manage and transmit the received measurements.

Do you know how many ticks there are in a millisecond?

use: var ticksms = System.TimeSpan.TicksPerMillisecond;

1 Like

I like what you say!
Solutions I find in the big Arduino community look easy. So I have been thinking to try to read the signals with an Arduino Uno I have laying around instead. Then I could connect the Arduino to the Fez with I2C or UART.
I wish to capture three RC receiver signals, do calculations on them and send ten new signals to servos. Separating the intensive work (handling six events every 20ms or so) from the calculations and the controlling of ten servos is appealing. Now you are saying the same thing I may go that way. Although I’m curious whether it would have worked, this marshalling of handling events and doing the synchronous work on one processor.
Why would it be harder to read RC receiver signals with a device running managed code? Because of the managing that is being done in the background?

I will read the linked post later today.

“Managed code” is synonymous with “management overhead” - so it’s arguably easier to program more complex capabilities, but you lose the real-time, run 100% flat-out that something like an Arduino gives.

1 Like

Back in the dark ages i used a Netduino Mini to read 4 RC channels which worked ok. A more modern STM32F4 would be far better :slight_smile:

Did you do this with events?

Clear. But the eventargs of the event have a timestamp. Could comparing the timestamps of the rising and falling edges not be considered lineair?

I cant remember to be honest as it was back in 2011…its one thing to revisit on the todo list…but the todo list is very long… :flushed:

The problem is that the events induced by the RF receiver come very often, esp. when the receiver is not sending there come masses of spikes due to noise. Your device must be able to handle all these events in time. So you should ban any Debug.Write commands from the code segment while the device is listening to the input. Debug.Write is time consuming and the interrupts will congest in their internal queue until your program evtl. crashes. So evtl. disable further interrupts while handling the actual one (where it is possible without missing important input signals). Which timespans do you expect for the signals from your RF receiver? How often will your RF-transmitters send new values.
Evtl. you should consider to use RFM69 modules.
-https://old.ghielectronics.com/community/codeshare/entry/1096
@Justin evtl. has some of them to sell, or you can have a look at the Moteinos (Arduino boards with integrated Rfm69).

RC receiver in question is the kind used for model cars or airplanes. First step is to get the electronics working. Second is to build a model. That is yet to be decided.
Three channels:
1 Does not change very often and when it does it doesn’t hurt if it takes a few 10ths of a second before it is processed
2 Does not change at all in 60% of the cases. This depends on channel 1. In the other 40% we need prompt action.
3 Expected to change all the time and needs prompt action.
My plan now is to go for a second board (Arduino) for gathering the signals. Values can be requested by the main board by I2C.
I think I will settle for polling the channels first. When I poll ch. 1 not as frequent as 2 and 3 and 2 only when needed, I think I can update ch. 3 20 times a second or so.
I’m studying on interrupts. But these interrupts may go off at the same time and ‘millis’ and ‘micros’ are not as lineair as desired, so I’ve learned. I think advanced approaches get in to the register of the processor.