[RPi3] Entfernung über Ultraschallsensor messen
Ok, also die Doku ist da ganz klar anders (Datenblatt), da gibt's null, und die Negation, und fuer immediate Argumente hat er halt nur 5 Bit Platz, also sind das maximal 31. Warum das sich dann so komisch verhaelt, keine Ahnung.
So, ich habs nun doch noch hinbekommen. Problem war: Man muss jmp_pin beim initialisieren setzen. Hatte ich glaub ich vorhin sogar erwähnt, dass das in dem Rust-Code drin war. Hab ich in keinem Beispiel gefunden, gibts aber.
Laut Data sheet: beim init der SM hinzufügen.
Genauigkeit ist ganz ok, hab jetzt mal grob 12cm anstelle von 11 gemessen, das reicht für meine Anwendung dicke + der Sensor kostet auch 2 €.
Für interessierte, auf diesem Fetzen kann man aufbauen:
Laut Data sheet:
Da das aber für C++ ist, ist glaub ich genau das damit gemeint, alsoJMP PIN branches on the GPIO selected by EXECCTRL_JMP_PIN, a configuration field which selects one out of the maximum
of 32 GPIO inputs visible to a state machine, independently of the state machine’s other input mapping. The branch is
taken if the GPIO is high.
Code: Alles auswählen
jmp_pin=Pin(ECHO_GPIO)
Genauigkeit ist ganz ok, hab jetzt mal grob 12cm anstelle von 11 gemessen, das reicht für meine Anwendung dicke + der Sensor kostet auch 2 €.
Für interessierte, auf diesem Fetzen kann man aufbauen:
Code: Alles auswählen
from machine import Pin
import rp2
import time
import micropython
import machine
"""
Pico runs at 125 MHz. The min. state machine (sm) frequency is 1908 Hz.
If the frequency is set to 1MHz, it should result in one cycle every 1 us, thats enough accuracy.
TRIGGER -> Set pin
ECHO -> Input pin
- Set trigger to HIGH for 10us
- Count duration of ECHO beeing HIGH
"""
TRIGGER_GPIO = 28
ECHO_GPIO = 22
SOUND_VELOCITY_M_S = 343
FREQUENCY = 10_000_000
micropython.alloc_emergency_exception_buf(100)
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW, out_init=rp2.PIO.OUT_LOW)
def measure_distance():
wrap_target()
set(pins, 1) [29] # lasts 10 us
nop() [29]
nop() [29]
nop() [9]
set(pins, 0)
mov(y, 31) # y's value is: 4_294_967_295
wait(1, pin, 0) # wait until input pin at location 0 is HIGH
label("count")
jmp(y_dec, "decrement")
label("decrement")
jmp(pin, "count")
mov(isr, y)
push()
wrap()
def calc_dist_m(time_sec_both_ways):
return SOUND_VELOCITY_M_S * time_sec_both_ways / 2
def main(sm:rp2.StateMachine):
"""Read the output FIFO."""
while True:
diff_step = 2**32 - 1 - sm.get() # 2^32 -1 is the start value of the state machine's register
# each cycle lasts 1/freq = 0.5 us
# We have 2 cycles per diff_step
echo_time = diff_step * 2 * (1 / FREQUENCY) # diff_steps * num_cycles_per_step * cycle_time
dist_m = calc_dist_m(echo_time)
print(dist_m)
time.sleep(0.1)
if __name__ == "__main__":
rp2.PIO(0).remove_program()
sm = rp2.StateMachine(0, measure_distance, freq=FREQUENCY, set_base=Pin(TRIGGER_GPIO, Pin.OUT), in_base=Pin(ECHO_GPIO, Pin.IN), jmp_pin=Pin(ECHO_GPIO))
sm.active(1)
main(sm)
Zuletzt geändert von robin_ am Donnerstag 28. September 2023, 19:08, insgesamt 1-mal geändert.
Hat vielleicht auch was mit der Implementierung von Micropython zu tun...