
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