chakokuのブログ(rev4)

テック・コミック・ごくまれにチャリ

Pico(RP2040)のPIOでモールス点滅サンプルを作ってみた

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")