Merge pull request #45 from jepler/background-morse
add morse code background example
This commit is contained in:
commit
89e2dfa5cd
1 changed files with 104 additions and 0 deletions
104
examples/pioasm_background_morse.py
Normal file
104
examples/pioasm_background_morse.py
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
# SPDX-FileCopyrightText: 2022 Jeff Epler, written for Adafruit Industries
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
"""Demonstrate background writing, including loop writing, with morse code.
|
||||
|
||||
On any rp2040 board with board.LED, this will alternately send 'SOS' and 'TEST'
|
||||
via the LED, demonstrating that Python code continues to run while the morse
|
||||
code data is transmitted. Alternately, change one line below to make it send
|
||||
'TEST' forever in a loop, again while Python code continues to run.
|
||||
|
||||
The combination of "LED status" and duration is sent to the PIO as 16-bit number:
|
||||
The top bit is 1 if the LED is turned on and 0 otherwise. The other 15 bits form a delay
|
||||
value from 1 to 32767. A subset of the morse code 'alphabit' is created, with everthing
|
||||
based on the 'DIT duration' of about 128ms (1MHz / 32 / 4000).
|
||||
|
||||
https://en.wikipedia.org/wiki/Morse_code
|
||||
"""
|
||||
|
||||
import time
|
||||
import array
|
||||
from board import LED
|
||||
from rp2pio import StateMachine
|
||||
from adafruit_pioasm import Program
|
||||
|
||||
# This program turns the LED on or off depending on the first bit of the value,
|
||||
# then delays a length of time given by the next 15 bits of the value.
|
||||
# By correctly choosing the durations, a message in morse code can be sent.
|
||||
pio_code = Program(
|
||||
"""
|
||||
out x, 1
|
||||
mov pins, x
|
||||
out x, 15
|
||||
busy_wait:
|
||||
jmp x--, busy_wait [31]
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
# The top bit of the command is the LED value, on or off
|
||||
LED_ON = 0x8000
|
||||
LED_OFF = 0x0000
|
||||
|
||||
# The other 15 bits are a delay duration.
|
||||
# It must be the case that 4 * DIT_DURATION < 32768
|
||||
DIT_DURATION = 4000
|
||||
DAH_DURATION = 3 * DIT_DURATION
|
||||
|
||||
# Build up some elements of morse code, based on the wikipedia article.
|
||||
DIT = array.array("H", [LED_ON | DIT_DURATION, LED_OFF | DIT_DURATION])
|
||||
DAH = array.array("H", [LED_ON | DAH_DURATION, LED_OFF | DIT_DURATION])
|
||||
# That is, two more DAH-length gaps for a total of three
|
||||
LETTER_SPACE = array.array("H", [LED_OFF | (2 * DAH_DURATION)])
|
||||
# That is, four more DAH-length gaps (after a letter space) for a total of seven
|
||||
WORD_SPACE = array.array("H", [LED_OFF | (4 * DIT_DURATION)])
|
||||
|
||||
# Letters and words can be created by concatenating ("+") the elements
|
||||
E = DAH + LETTER_SPACE
|
||||
O = DAH + DAH + DAH + LETTER_SPACE
|
||||
S = DIT + DIT + DIT + LETTER_SPACE
|
||||
T = DIT + LETTER_SPACE
|
||||
SOS = S + O + S + WORD_SPACE
|
||||
TEST = T + E + S + T + WORD_SPACE
|
||||
|
||||
# 8 slots of the shortest possible led-off time
|
||||
# A background write is 'complete' as soon as all data has been placed
|
||||
# in the StateMachine's FIFO. This FIFO has either 4 or 8 entries.
|
||||
# By adding 8 very short "led off" times, we can have our 'sm.writing' test
|
||||
# tell us when the actual letter data has all been
|
||||
FILLER = array.array("H", [LED_OFF | 1]) * 8
|
||||
|
||||
sm = StateMachine(
|
||||
pio_code.assembled,
|
||||
frequency=1_000_000,
|
||||
first_out_pin=LED,
|
||||
pull_threshold=16,
|
||||
auto_pull=True,
|
||||
out_shift_right=False,
|
||||
)
|
||||
|
||||
# To simply repeat 'TEST' forever, change to 'if True':
|
||||
if False: # pylint: disable=using-constant-test
|
||||
print("Sending out TEST forever", end="")
|
||||
sm.background_write(loop=TEST)
|
||||
while True:
|
||||
print(end=".")
|
||||
time.sleep(0.1)
|
||||
|
||||
# But instead, let's alternate SOS and TEST, forever:
|
||||
|
||||
while True:
|
||||
for plain, morse in (
|
||||
("SOS", SOS),
|
||||
("TEST", TEST),
|
||||
):
|
||||
print(f"Sending out {plain}", end="")
|
||||
sm.background_write(morse + FILLER)
|
||||
while sm.writing:
|
||||
print(end=".")
|
||||
time.sleep(0.1)
|
||||
print()
|
||||
print("Message all sent to StateMachine")
|
||||
time.sleep(1)
|
||||
print()
|
||||
Loading…
Reference in a new issue