This was my proof of concept PIO code for MicroPython which was intended to demonstrate how it worked using the Pico on-board LED, which should work when used with a real IR LED.
The PIO worked but I never got round to fixing the maths and timing bugs in the code, tightening things up so I pushed cycle accurate values to the PIO. May be of some interest though.
The PIO worked but I never got round to fixing the maths and timing bugs in the code, tightening things up so I pushed cycle accurate values to the PIO. May be of some interest though.
Code:
from machine import Pinfrom rp2 import asm_pio, PIO, StateMachineimport timeOUTPUT_LED_PIN = "LED"led = Pin(OUTPUT_LED_PIN, Pin.OUT)@asm_pio(sideset_init = PIO.OUT_LOW)def IrBlast(): # Get the LED delay count and store it away in our 'Y' register pull() .side(0) mov(y, osr) # This is our main loop label("MainLoop") # Read the number of on cycles we need inot 'osr' pull() # The On part label("OnPart") # On loop mov(x, y) .side(1) label( "LedOnLoop") jmp(x_dec, "LedOnLoop") # Off loop mov(x, y) .side(0) label( "LedOffLoop") jmp(x_dec, "LedOffLoop") # Repeat the required number of n cycles, decrement 'osr' mov(x, osr) jmp(x_dec, "RepeatOnPart") jmp("OffPart") label("RepeatOnPart") mov(osr, x) jmp("OnPart") # The off part label("OffPart") pull() mov(x, osr) label( "OffLoop") jmp(x_dec, "OffLoop") # Handle next pair jmp("MainLoop")# Find a free state machine or use one we hope isn't already being usedtry : sm_number = PIO.FindFreeStateMachine()except : sm_number = 2# Run the state machine at 1 MHz so timing is in microsecondssm_frequency = 1000000# Initialise the state machine and set it runningsm = StateMachine(sm_number, IrBlast, freq=sm_frequency, sideset_base=led)sm.active(True)# For this demo we are using the on-board LED so timings are extended so we# can see the effects. When the LED is on it flashes at 2 HZ, 250ms on and# 250 ms off, a cycles takes 500 ms. We will therefore need 2 cycles per# one second period.# The first thing we need to pass to the PIO program is the LED modulation# high and low delay count for the PIO code. For a 2 Hz LED carrier the LED# is high and low for 250 ms, 250000 us. The PIO delay loops take 1 cycle# so the dleat count is the same.hz = 2delayCount = int(sm_frequency / hz / 2)print(delayCount)sm.put(delayCount)# Now we create a list of what we want to send.ir = []# We add a pair of items for each interaction, how many pulses of IR we# send for the on period, and how many cycles to delay with IR off after# that.## For our demo using the on-board LED we will have an initial two second# on period, a one second off period, then another one second on and one# second off## For a two second on period, 2000000 us, it is 8 cycles of outputting# 2 Hz carrieronTimeUs = 2000000onCycles = int(onTimeUs / delayCount)# For an off time of one second, 1000000 us, the PIO takes 1 cycle per# microsecond so the off cyles needed is the same.offTimeUs = 1000000offCycles = offTimeUs# We add that to our list of what to sendir.append([onCycles, offCycles])# We repeat thse same for our subsequent one second on one second offonTimeUs = 1000000onCycles = int(onTimeUs / delayCount)offTimeUs = 1000000offCycles = offTimeUsir.append([onCycles, offCycles])# We simply blast that out with a five second gap between blasts## | 2 s |1 s|1 s|1 s| | 2 s |# |-------|---|---|---|-- - - --|-------|## ___||||||||____||||_______ _ _ __||||||||___while True: print("TX") for onCycles, offCycles in ir: print(" ", onCycles, offCycles) sm.put(onCycles) sm.put(offCycles) time.sleep(5)
Statistics: Posted by hippy — Tue Mar 26, 2024 7:42 pm