RP2040のPIOを理解するためいろいろテストしていて、文字列を入れるとモールス符号にして点滅するサンプルを作ってみた。
問題点としては、、点滅パターンをFIFOに入れるのだけど、FIFOでバッファしてしまって先読みのような状態になってcharacter間の空白がうまく働かない。空白をメイン側でwaitしているのがまずい。waitもPIO内で実装するように変えるべき。
#
# CW by PIO of RP2040
#
from machine import Pin
from rp2 import PIO, StateMachine, asm_pio
import utime
LED = 25
CODE = { 'A' : ".-",
'B' : "-...",
'C' : "-.-.",
'D' : "-..",
'E' : ".",
'F' : "..-.",
'G' : "--.",
'H' : "....",
'I' : "..",
'J' : ".---",
'K' : "-.-",
'L' : ".-..",
'M' : "--",
'N' : "-.",
'O' : "---",
'P' : ".--.",
'Q' : "--..",
'R' : ".-.",
'S' : "...",
'T' : "-",
'U' : "..-",
'V' : "...-",
'W' : ".--",
'X' : "-..-",
'Y' : "-.--",
'Z' : "--..",
}
@asm_pio(set_init=PIO.OUT_LOW)
def cw_out():
pull()
mov(x, osr)
# signal (dot or dash)
set(pins, 1)
label("dashloop")
set(y, 0xf)
label("waitloop0")
nop() [0x1f] # wait
jmp(y_dec, "waitloop0")
jmp(x_dec, "dashloop")
# space
set(pins, 0)
set(y, 0x14)
label("waitloop1")
nop() [0x1f] # wait
jmp(y_dec, "waitloop1")
sm = StateMachine(0, cw_out, freq = 6000, set_base=Pin(25))
sm.active(1)
def morse(str):
for ch in str:
print(ch, end="")
if ch == " ":
utime.sleep(3)
else:
morse_chr(ch)
utime.sleep(1.5)
def morse_chr(ch):
for ptn in CODE[ch]:
for ch in ptn:
if ch == '.':
sm.put(1)
elif ch == '-':
sm.put(4)
morse("A B C HELLO")