ReadPulse can't work for measure frequency

I test ReadPulse to measure frequency and this not work for

var digitalSignalPin = GpioController.GetDefault().OpenPin(SC20260.Timer.Capture.Controller5.PB3);

I used sample from readpulse
you probably mixed up the controllers and it should be like this:

            public static class Capture
            {
                public static class Controller5
                {
                    public const int PA0 = 0;
                }
                public static class Controller2
                {
                    public const int PB3 = 19;
                }
            }

for

var digitalSignalPin2 = GpioController.GetDefault().OpenPin(SC20260.Timer.Capture.Controller2.PA0);

works fine

In addition, there are other problems:

  1. The OnReadPulseRed event appears only 1 time
  2. The measured frequency is not known, respectively, it is not known how many pulses to read
  3. The frequency calculation should probably be done like this:
 var freq = ((count-1) / microsecond) * 1000000; 

We will correct the controller but it doesn’t effect to the pin number. BP3 is still 19. Tell us more detail “doesn’t work” please? Doesn’t read the pulse, no event…?

Correct, there is only once event after issue a ReadPulse command.

Unless you tell us a reason to how more than one, we will add.

Correct, this is generic, no frequency. But there is “count”, from count, time, we will know the frequency.

no event

I’ve tried ReadPulse in finish sring of OnReadPulseReady event handler. The event did not appear again. Show an example of calling ReadPulse again

For different frequencies, you need to read a different number of pulses so that the measurement accuracy is the same. How can I find out the required number of pulses?
Maybe you add one more ReadPulse implementation with the “read time” parameter?

public void ReadPulse2(uint pulseReadTime, GpioPinEdge edge, bool waitForEdge);

Another problem is that if there are no impulses, then the event will never appear.

The way we intended this to work would be by calling read pulse repeatedly to continuously sample the frequency. Each time you read pulse you get an event with the sample. This can be a thread that samples once a second for example.

There is abort for that. And this generate an event after abort is called.

We have tried, event is fired as well on PB3. Do you use any interrupt on Px3 after that?

It should work but we will check.

There is another api Capture, does it help?

Of course. You can call Abort() any time.

For capture mode, you can set timeout also.

Confirm calling in event has a bug. We will find out. But in a loop will work. Thanks for point it out.

No. I checked again and PB3 does not work on my board FEZ Portal rev B. Here is my code

static void Main()
{
  var pwm2 = PwmController.FromName(SC20260.Timer.Pwm.Controller2.Id);
  var pwm2_4 = pwm2.OpenChannel(SC20260.Timer.Pwm.Controller2.PA3);
  pwm2.SetDesiredFrequency(10); //max = 60_000_000
  pwm2_4.SetActiveDutyCyclePercentage(0.5);
  pwm2_4.Start();

  var digitalSignalPin2 = GpioController.GetDefault().OpenPin(SC20260.Timer.Capture.Controller2.PA0);
  var digitalSignalPin5 = GpioController.GetDefault().OpenPin(SC20260.Timer.Capture.Controller5.PB3);
  var digitalSignal = new DigitalSignal(digitalSignalPin2);
  bool waitForEdge = true;
  digitalSignal.OnReadPulseReady += Digital_OnReadPulseReady;
  digitalSignal.ReadPulse(10, GpioPinEdge.RisingEdge, waitForEdge);
  Thread.Sleep(Timeout.Infinite);
}

private static Timer timerReadPulse = null;

static void timerReadPulseCallback(object o)
{
  DigitalSignal ds = (DigitalSignal)o;
  ds.ReadPulse(10, GpioPinEdge.RisingEdge, true);
}

private static void Digital_OnReadPulseReady(DigitalSignal sender, TimeSpan duration, uint count, GpioPinValue pinValue)
{
  var microsecond = ((double)duration.Ticks) / 10;
  var freq = ((count-1) / microsecond) * 1000000;

  Debug.WriteLine("GpioPinValue = " + ((pinValue == GpioPinValue.High) ? "High" : "Low"));
  Debug.WriteLine("PulseCount = " + count);
  Debug.WriteLine("Duration microsecond = " + microsecond);
  Debug.WriteLine("freq = " + freq / 1000.0 + " KHz");

  if (timerReadPulse == null)
    timerReadPulse = new Timer(timerReadPulseCallback, sender, 100, -1);
  else
    timerReadPulse.Change(100, -1);
}

I noticed that the pwm2.SetDesiredFrequency (10) method is quite slow to execute. Why?

My code

    var pwm2 = PwmController.FromName(SC20260.Timer.Pwm.Controller2.Id);
    var pwm2_4 = pwm2.OpenChannel(SC20260.Timer.Pwm.Controller2.PA3);
    pwm2.SetDesiredFrequency(100); //max = 60_000_000
    pwm2_4.SetActiveDutyCyclePercentage(0.5);
    pwm2_4.Start();

    var digitalSignalPin = GpioController.GetDefault().OpenPin(SC20260.Timer.Capture.Controller2.PA0);
    var digitalSignal = new DigitalSignal(digitalSignalPin);
    bool waitForEdge = false;// Start capturing as soon as Capture is called
    digitalSignal.OnCaptureReady += Digital_OnCaptureReady;
    digitalSignal.Capture(100, GpioPinEdge.RisingEdge, waitForEdge, TimeSpan.FromSeconds(1.5));

    private static void Digital_OnCaptureReady(DigitalSignal sender, uint[] buffer, uint count, GpioPinValue pinValue)
    {
        if (count == 0)
        {
            Debug.WriteLine("no data was captured!");
            return;
        }
        for (int i = 0; i < count; i++)
        {
            Debug.WriteLine("Sample [" + i + "]: " + buffer[i] + " ns");
        }
    }

I received:
Sample [0]: 1087964 ns
Sample [1]: 1410886 ns

Sample [99]: 1410886 ns

from index=1 to 99 samples are the same. Why?

Shouldn’t they be the same? Aren’t you measuring a fixed frequency?

I don’t understand … what does mean “array of timestamps of individual durations”? Can this array be used to measure frequency?

This are reading how long it took from one edge to another. They selected rising edges. This means your frequency is generating 1.4ms… 1/1.4ms is your frequency.

What frequency did you use in your test?

pwm2.SetDesiredFrequency(100); //100 Hz

1/1.4 not equal 100 Hz

if
pwm2.SetDesiredFrequency(10); //10 Hz
then
1/1.223606
what is it?

We are looking into it, please try higher frequency in your test for now, like 1Mhz.

Meanwhile we have updated the docs to clarify abort https://docs.ghielectronics.com/software/tinyclr/tutorials/signal-control.html

Try 500Hz or higher.

About PB3 pin, we see you are using PA3 which is shared same controller with PB3. Try to use different pin instead of PA3.

Works, but accuracy decreases with decreasing frequency. This is bad :frowning: I need to measure from 10 Hz

Ok. Now works PB3. I changed PA3 to PJ11

You are using a preview :slight_smile: of course we will fix it.