Page 1 of 1

Input capture of PWM signal 40KHz

Posted: Mon Jul 20, 2020 11:46 am
by Madril
On pyboard D with STM32F722 I want to implement input capture for PWM signal with frequency aroound 40KHz curent implementation of my code is below:

Code: Select all

import pyb


class IC_Channel:
    def __init__(self, pin_name, timer, channel):
        self.channel = channel
        self.rising = 0
        self.falling = 0
        self.high_time = 0
        self.low_time = 0
        self.period = 0
        self.icpin = pyb.Pin(pin_name)
        self.timer_channel = timer.channel(channel, pyb.Timer.IC, pin=self.icpin, polarity=pyb.Timer.BOTH,
                                           callback=self.callback)
        self.tick = (timer.prescaler() + 1) / timer.source_freq()

        if timer in (2,5):
            self.overflow = 0x0fffffff
        else:
            self.overflow = 0x0fff

    def callback(self, tim):
        '''
        Callback function for the input capture channel
        :param tim: timer of the callback source
        :return:
        '''
        # Read the GPIO pin to figure out if this was a rising or falling edge
        if self.icpin.value():
            # Rising edge - start of the pulse
            self.rising = self.timer_channel.capture()
            self.low_time = (self.rising - self.falling) & self.overflow
        else:
            # Falling edge - end of the pulse
            self.falling = self.timer_channel.capture()
            self.high_time = (self.falling - self.rising) & self.overflow

        self.period = self.high_time + self.low_time

    def get_freq(self):
        '''
        Get frequency of the input capture channel
        :return:
        '''
        if(self.period > 0):
            freq = 1 / (self.period * self.tick)
        else:
            freq = 0
        return (freq)

    def get_period(self):
        '''
        Get period of the input capture channel
        :return:
        '''
        return (self.period * self.tick)

    def get_high_time(self):
        '''
        Get time (high state) of the input capture channel
        :return:
        '''
        return (self.high_time * self.tick)

    def get_low_time(self):
        '''
        Get time (low state) of the input capture channel
        :return:
        '''
        return (self.low_time * self.tick)
For now it always returns 0 for frequencys that is higher than 9,6KHz is there way to do this measurments for higher frequencies do I need to use specific pin and timer for example?

Re: Input capture of PWM signal 40KHz

Posted: Tue Jul 21, 2020 5:02 am
by jimmo
What frequency is the timer running at?

Re: Input capture of PWM signal 40KHz

Posted: Tue Jul 21, 2020 5:45 am
by Madril
Timer is 84MHz and prescaler is set to 83

Re: Input capture of PWM signal 40KHz

Posted: Tue Jul 21, 2020 10:19 pm
by dhylands
I have an example that runs on the original pyboard:
https://github.com/dhylands/upy-example ... ic_test.py

It should work on the STM32F7.

I was only testing a 50 Hz signal at the time.

This was part of an example that is documented more over here:
http://wiki.micropython.org/platforms/b ... r-Examples

Re: Input capture of PWM signal 40KHz

Posted: Tue Jul 21, 2020 10:23 pm
by dhylands
On the original pyboard, I don't think its fast enough to capture 40kHz using straight python. That's only 25 usec per cycle.

If the F7 is running at a faster MHz, and you use viper or asm mode, then you might be able to do it, but I doubt you can do anything useful on a continuous basis (i.e. capturing every cycle at 40 kHz).

I would try at a lower frequency to get things working and then ramp up the frequency to see where your limits are.

Re: Input capture of PWM signal 40KHz

Posted: Wed Jul 22, 2020 8:29 am
by pythoncoder
It might help if you explained what is the overall purpose. At risk of stating the obvious, one option might be to apply the PWM signal to an ADC via a CR network...