[RPi3] Entfernung über Ultraschallsensor messen

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
robin_
User
Beiträge: 48
Registriert: Montag 3. August 2020, 17:59

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:
JMP 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.
Da das aber für C++ ist, ist glaub ich genau das damit gemeint, also

Code: Alles auswählen

jmp_pin=Pin(ECHO_GPIO)
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:

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.
robin_
User
Beiträge: 48
Registriert: Montag 3. August 2020, 17:59

__deets__ hat geschrieben: Donnerstag 28. September 2023, 17:35 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.
Hat vielleicht auch was mit der Implementierung von Micropython zu tun...
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Bestimmt sogar. Aber cool, das es geklappt hat.
Antworten