Raspberry Pi Pico and 433MHz Data Radio

Well its been a minute since I’ve toyed around with electronics, but a $4 Raspberry Pi Pico board arriving in the mail changed that.

This board packs a boat load of utility for $4, just check out the data sheet and check out all them I2C and SPI pins!

I dusted off the last components I tinkered with, along with a handful of wires. After a couple days of tinkering, I ended up with a 433MHz radio packet receiver.

With this setup I can listen on all them 433MHz radio frequencies; for example, I have another RFM69 broadcasting unencrypted messages at 433.0MHZ using CircuitPython & a Trinket M0:

import time
import board
import busio
import digitalio
import adafruit_rfm69

FREQ = 433.0

spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)

cs = digitalio.DigitalInOut(board.D1)
reset = digitalio.DigitalInOut(board.D0)

rfm69 = adafruit_rfm69.RFM69(spi, cs, reset, FREQ)

# keep message length 21 characters or lower,
# and stay at 3 lines or under
messages = [
'''Welcome to
nessy radio!
''',
'''The passcode is:
slippery panda
''',
]

counter = 0
while True:
    for message in messages:
        rfm69.frequency_mhz = FREQ
        rfm69.tx_power = 20
        rfm69.send(message)
        print('%s - sent %s' % (message, counter))
        time.sleep(5)
        counter = counter + 1

This code merely broadcast our messages, one at a time every 5 seconds:

# keep message length 21 characters or lower,
# and stay at 3 lines or under
messages = [
'''Welcome to
nessy radio!
''',
'''The passcode is:
slippery panda
''',
]

Using the Raspberry Pi Pico and a USB battery I’m able to pick up the data packets anywhere in my house!

According to Adafruit, the range for the RFM69:
Range of approx. 500 meters, depending on obstructions, frequency, antenna and power output

That means I should my Raspberry Pi Pico setup should be able to receive this message within 1640.42 feet!? Wow, I’ll need to test this.

Any ways, here is the code I ended up demoing on the Pico, happy hacking, and happy Pi day ūüėČ

import time
import board
import busio
import digitalio

import adafruit_ssd1306
import adafruit_rfm69

# basic on board led
led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT
led.value = False  # turn off led

# buttons
button_left = digitalio.DigitalInOut(board.GP20)
button_left.switch_to_input(pull=digitalio.Pull.DOWN)
button_right = digitalio.DigitalInOut(board.GP21)
button_right.switch_to_input(pull=digitalio.Pull.DOWN)
button_go = digitalio.DigitalInOut(board.GP13)
button_go.switch_to_input(pull=digitalio.Pull.DOWN)

# i2c oled display
i2c = busio.I2C(scl=board.GP15, sda=board.GP14)
display = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3d)
display.fill(0)
display.show()

# radio
FREQ = 433.0
spi = busio.SPI(board.GP2, MOSI=board.GP3, MISO=board.GP0)
cs = digitalio.DigitalInOut(board.GP1)
reset = digitalio.DigitalInOut(board.GP4)
rfm69 = adafruit_rfm69.RFM69(spi, cs, reset, FREQ)

# uncomment to enable encryption
# rfm69.encryption_key = (
#     b"\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08"
# )

listen = False
count = 0
msg = ''
while True:

    if not listen:
        if button_left.value:
            FREQ = round(FREQ + 0.1, 1)
            rfm69.frequency_mhz = FREQ

        if button_right.value:
            FREQ = round(FREQ - 0.1, 1)
            rfm69.frequency_mhz = FREQ

    if button_go.value:
        if listen:
            listen = False
            led.value = False
        else:
            listen = True
            led.value = True

    # base ui
    display.fill(0)
    display.text("Radio: %sMhz" % FREQ, 0, 0, 1)
    display.text(msg, 0, 20, 1)
    display.text(str(count), 55 - len(str(count)), 55, 1)
    display.text("<Up>", 0, 55, 1)
    display.text("<Down>", 93, 55, 1)
    display.show()

    if listen:
        packet = rfm69.receive()
        if packet is not None:
            packet_text = str(packet, 'ascii')
            msg = packet_text
            print('Received: {0}'.format(packet_text))
            count = count + 1

Wireless Chat using NRF24L01+ 2.4GHz RF Transceiver on Arduino & Raspberry Pi Ubuntu Linux

After a bit of success implementing an Arduino 2.4GHz Transceiver, I was encouraged to explore a more familiar environment, something with Python and Linux in the mix.

After a short period of research I landed on the circuitpython-nrf24l01 pypi project page, and quickly began digging through their examples.

It wasn’t long after I had a working prototype that mirrored my Arduino code quite closely:

Components

import sys
import select

from circuitpython_nrf24l01 import RF24
import board
import digitalio as dio

# addresses needs to be in a buffer protocol object (bytearray)
address = b'Nessy'

# change these (digital output) pins accordingly
ce = dio.DigitalInOut(board.D4)
csn = dio.DigitalInOut(board.D5)

# using board.SPI() automatically selects the MCU's
# available SPI pins, board.SCK, board.MOSI, board.MISO
spi = board.SPI()  # init spi bus object

# initialize the nRF24L01 on the spi bus object
nrf = RF24(spi, csn, ce, ask_no_ack=False, data_rate=250)
nrf.dynamic_payloads = False # this is the default in the TMRh20 arduino library
nrf.payload_length = 32

# get username
username = input('Enter Username: ')

# set address of RX node into a TX pipe
nrf.open_tx_pipe(address)

# set address of TX node into a RX pipe
nrf.open_rx_pipe(1, address)

nrf.listen = True

print('Welcome %s' % username)
while True:

    # handle write
    if select.select([sys.stdin,],[],[],0.0)[0]:
        nrf.listen = False
        for line in sys.stdin:
            msg = b'[%b] %b' % (username.encode(), line.rstrip().encode())
            nrf.send(msg)
            break

    # handle recieve
    if not nrf.listen:
        nrf.listen = True

    if nrf.any():
        # retreive the received packet's payload
        buffer = nrf.recv()
        data = buffer.decode().replace('\x00', '')
        print(data)

Using Magic the Gathering Art for D&D Ideas

Recently I’ve spent a bit time reading some of¬†Dragon+ Magazine¬†articles, one¬†particularly grabbed my attention.¬†Using Magic Cards as D&D Items presents a very interesting way to craft items, using Magic the Gathering cards, one can gain inspiration for their next +1 Dagger, or even an Elven Stronghold.

I think the reason I so quickly latched on to this idea was because Magic the Gathering and Dungeons & Dragons are two of my favorite games, plus I really dig the¬†Ixala art work, I mean who hasn’t fantasized about riding a dinosaur to work.

Now I absolutely own tons of Magic the Gathering cards, and I could easily grab a handful and start coming up with an epic dungeon delve, but I thought, why not include a little bit of technology.

Lucky for me, I was able to recycle much of the work I did on Dungeon Brawl to make Magic Inspiration. So just what exactly is Magic Inspiration? Using this application, a Game Master can easily gain inspiration using Magic the Gathering artwork. Then when the ideas come flooding in, weave an amazing story.

It’s time to give credit where credit is due, this application was only made possible using¬†Scryfall‘s bulk data. These people truly provide an awesome dataset!

Anyways, please feel free to grab the application from my Github, and let me know what you think.

Until next time. . .