Hi,
I am quite new to PIO concept, I would like to make a simplex communication on one pin. To be more precise the pin concept is open-drain (external pull-up) and the communication is triggered by the Pico by pulling the line LOW. This is working in my PIO program, but after this pulse, the pin has to be set high ohmic in order that the peripheral can answer by pulling the wire LOW. If I look into the datasheet, I think this is possible with a sidestep.
Does anybody have an example switching the pin mode via sidestep in Python? Alternatively I would also have a look on an example just switching the output pin to high ohmic input...
Side-step pindirs missing?
Re: Side-step pindirs missing?
There has been a discussion about a DHT22 driver using pio. A sophisticated one is here: https://github.com/danjperron/PicoDHT22
I attached a more simple one below, which shows how to switch the direction of a pin, not using sideset. If I read your post correctly, that is what you need. If you want to use siedest instead, you might have to use a second pin for the start pulse and tie that to the data pin with a diode, allowing only the low level to pass.
I attached a more simple one below, which shows how to switch the direction of a pin, not using sideset. If I read your post correctly, that is what you need. If you want to use siedest instead, you might have to use a second pin for the start pulse and tie that to the data pin with a diode, allowing only the low level to pass.
Code: Select all
from machine import Pin
import rp2
import array
import time
import rp2_util
if True:
# the clock is set to 200 kHz or 5µs per tick
@rp2.asm_pio(
in_shiftdir=rp2.PIO.SHIFT_LEFT,
set_init=rp2.PIO.OUT_HIGH,
autopull=False,
autopush=True,
push_thresh=8
)
def DHT_pio():
pull() # get the number of clock cycles
mov(x, osr) # for the start pulse
set(pindirs, 1) # set to output
set(pins, 0)
label("start_pulse")
jmp(x_dec, "start_pulse") # test for more bits
set(pins, 1) [7] # and wait six ticks
set(pindirs, 0) # set back to input mode
wait(1, pin, 0)
label("wait_0")
wait(0, pin, 0)
label("wait_1")
wait(1, pin, 0)
nop() [7] # wait another 40 µs
in_(pins, 1) # get one bit
jmp(pin, "wait_0") # if one, wait for 0
jmp("wait_1") # Otherwise wait for the next bit
pin_base = Pin(10, Pin.OUT, value=1)
sm_freq = 200_000
sm_tick = 1_000_000 // sm_freq
sm = rp2.StateMachine(5, DHT_pio, freq=sm_freq,
set_base=pin_base, in_base=pin_base,
out_base=pin_base, jmp_pin=pin_base)
def run():
recv = array.array("H", bytearray(10))
sm.restart(DHT_pio)
# print(rp2_util.sm_restart(5, DHT_pio))
sm.put(1000 // sm_tick) # number of wait cycles for the start pulse
sm.active(1)
index = 0
for i in range(1000):
if sm.rx_fifo() > 0:
recv[index] = sm.get()
index += 1
if index == 5:
break
else:
time.sleep_ms(1)
else:
print("Acquistion error")
sm.active(0)
print([hex(i) for i in recv])
run()
Re: Side-step pindirs missing?
Thanks for the answer!
This is exactly what I was searching for. I think I can do it w/o sidestep and as my application is similar, I will be inspired by this source code
In general, did I get it wrong that the switching from IN to OUT is also possible with sidesteps? Is this function still missing in MicroPython?
KR,
Christof
This is exactly what I was searching for. I think I can do it w/o sidestep and as my application is similar, I will be inspired by this source code

In general, did I get it wrong that the switching from IN to OUT is also possible with sidesteps? Is this function still missing in MicroPython?
KR,
Christof
Re: Side-step pindirs missing?
The PIO hardware also allows side-set (not -step) to control the direction of pins. But as far as I can tell, that setting is not supported (yet) by MicroPython.
Re: Side-step pindirs missing?
Thanks, that's also what I've seen. Maybe we could add this to the to-do list, maybe I can do it when I have time to dig a little bit more in the MicroPython source code.
KR,
Christof
KR,
Christof