RPi-Pico Frequenz- und Pulslängenmesser                 


Elektronik-Labor  Projekte  Mikrocontroller  Raspberry            




Andreas hat dieses Programm als Hilfe im Elektronik-Labor entwickelt. Es liefert eine sehr genau Frequenzmessung und zusätzlich die Anzeige der Periodendauer und  eine Messung der relativen Pulslängen. Ich musste nur den Eingang auf GP3  anpassen, damit es auf meinem vorhandenen Aufbau mit dem OLED-Display lief. Das Programm erzeugt PWM-Signale mit unterschiedlichen Pulslängen an GP2, sodass man ein geeignetes Testsignal messen kann, wenn man GP2 und GP3 verbindet.

from machine import I2C, Pin, time_pulse_us, PWM, Timer, freq as CPU_Freq
from ssd1306 import SSD1306_I2C
from utime import ticks_ms, ticks_diff, sleep_us, sleep

class PWM_FREQ():
    def __init__(self, pin, freq = 1000, task = 50):
        self.pwm_pin = PWM(Pin(pin))
        self.pwm_pin.freq(freq)
        self.pwm_pin.duty_u16(0)
        self.pwm_freq = freq
        self.pwm_task = task

    def run(self, freq = None, task = None, duration = None):
        frequency = (self.pwm_freq if freq == None else freq)
        takting = (self.pwm_task if task == None else task)
        self._start(frequency, takting)
        if duration != None:
            self.timer = Timer(period = duration, mode = Timer.ONE_SHOT,
                               callback=lambda t: self._stopp())
       
    def stopp(self, waits = None):
        self._stopp()
        if waits != None:
            t_start = ticks_ms()
            while t_start + int(waits) > ticks_diff(ticks_ms(), t_start):
                pass
           
       
    def _start(self, freq, task):
        self.pwm_pin.freq(freq)
        self.pwm_pin.duty_u16(int(65535 / 100 * task))
        self.pwm_freq = freq
        self.pwm_task = task
       
    def _stopp(self):
        self.pwm_pin.duty_u16(0)

class Frequency():
    def __init__(self, pin):
        self.messure_pin = pin
        self.freq = 0
        self.hi = 0
        self.low = 0
        self.periode = 0
       
    def messure(self, counter = 100):
        self.input = Pin(self.messure_pin, Pin.IN, Pin.PULL_DOWN)
        sleep_us(20)
        self.on_time = sum([time_pulse_us(self.input, 1, 1_000_000)\
                        for _ in range(counter + 1)][1:]) / counter
        self.input = Pin(self.messure_pin, Pin.IN, Pin.PULL_UP)
        self.off_time = sum([time_pulse_us(self.input, 0, 1_000_000)\
                        for _ in range(counter + 1)][1:]) / counter
        self.periode = self.on_time + self.off_time
        self.freq = 1 / (self.periode / 10 **6)
        self.hi = (self.on_time * 100 / self.periode)
        self.low = (self.off_time * 100 / self.periode)
       
def Display(led, freq, periode, hi, low):
    led.fill(0)
    led.text(f'Freq: {freq:4.2f} Hz',1,8)
    led.text(f'P: {periode:6.1f} us',1,19)
    led.text(f'Hi  {hi:3.1f} %', 1, 30)
    led.text(f'Low {low:3.1f} %', 1, 39)
    led.show()

FREQENCY = (50,100,250,333,1500,10000)
TASK = tuple([5 * i for i in range(1,20)])

CPU_Freq(125_000_000)   
oled = SSD1306_I2C(128, 64, I2C(0, sda = Pin(0), scl = Pin(1), freq = 100_000))

pwm = PWM_FREQ(2, freq = 100)
fc = Frequency(3)

led_timer = Timer()
led_timer.init(period= 2_000, mode=Timer.PERIODIC,\
               callback=lambda t: Display(oled, fc.freq, fc.periode, fc.hi, fc.low))

mes_timer = Timer()
mes_timer.init(period= 5_000, mode=Timer.PERIODIC,\
               callback=lambda t: fc.messure())

for fr in FREQENCY:
    for pe in TASK:
        print('Freq : ',fr,' Hz ', pe, ' %')
        pwm.run(freq = fr, task = pe)
        sleep(2)




Ein Test mit einem Sinusgenerator und einem zweiten Frequenzzähler zeigte, dass Messergebnisse bis ca. 30 kHz sehr genau sind. Damit hat man ein brauchbares Messgerät im gesamten NF-Beriech.Für HF-Messungen siehe auch: RPi Pico Frequenzzähler bis 65 MHz


Elektronik-Labor  Projekte  Mikrocontroller  Raspberry