Merge pull request #6 from FoamyGuy/more_portalbase_stuff
Some checks failed
Build CI / test (push) Has been cancelled

More portalbase APIs, fixes for status_led and caption text
This commit is contained in:
foamyguy 2025-07-24 11:24:41 -05:00 committed by GitHub
commit 17d3868ed6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 105 additions and 7 deletions

View file

@ -162,7 +162,7 @@ class FruitJam(PortalBase):
network = Network(
status_neopixel=self.peripherals.neopixels
if status_neopixel is None
if status_neopixel is None or status_neopixel == board.NEOPIXEL
else status_neopixel,
esp=esp,
external_spi=spi,
@ -191,14 +191,14 @@ class FruitJam(PortalBase):
# Convenience Shortcuts for compatibility
# self.sd_check = self.peripherals.sd_check
# self.play_file = self.peripherals.play_file
# self.stop_play = self.peripherals.stop_play
self.sd_check = self.peripherals.sd_check
self.play_file = self.peripherals.play_file
self.stop_play = self.peripherals.stop_play
self.image_converter_url = self.network.image_converter_url
self.wget = self.network.wget
# self.show_QR = self.graphics.qrcode
# self.hide_QR = self.graphics.hide_QR
self.show_QR = self.graphics.qrcode
self.hide_QR = self.graphics.hide_QR
if default_bg is not None:
self.graphics.set_background(default_bg)
@ -207,6 +207,7 @@ class FruitJam(PortalBase):
print("Init caption")
if caption_font:
self._caption_font = self._load_font(caption_font)
if caption_text is not None:
self.set_caption(caption_text, caption_position, caption_color)
if text_font:

View file

@ -66,3 +66,34 @@ class Graphics(GraphicsBase):
if supervisor.runtime.display is None:
request_display_config(640, 480)
super().__init__(supervisor.runtime.display, default_bg=default_bg, debug=debug)
def qrcode(self, qr_data, *, qr_size=1, x=0, y=0, hide_background=False): # noqa: PLR0913 Too many arguments in function definition
"""Display a QR code
:param qr_data: The data for the QR code.
:param int qr_size: The scale of the QR code.
:param x: The x position of upper left corner of the QR code on the display.
:param y: The y position of upper left corner of the QR code on the display.
:param hide_background: Hide the background while showing the QR code.
"""
super().qrcode(
qr_data,
qr_size=qr_size,
x=x,
y=y,
)
if hide_background:
self.display.root_group = self._qr_group
self._qr_only = hide_background
def hide_QR(self):
"""Clear any QR codes that are currently on the screen"""
if self._qr_only:
self.display.root_group = self.root_group
else:
try:
self._qr_group.pop()
except (IndexError, AttributeError): # later test if empty
pass

View file

@ -26,12 +26,19 @@ Implementation Notes
"""
import os
import adafruit_sdcard
import adafruit_tlv320
import audiobusio
import audiocore
import board
import busio
import digitalio
import displayio
import framebufferio
import picodvi
import storage
import supervisor
from digitalio import DigitalInOut, Direction, Pull
from neopixel import NeoPixel
@ -140,6 +147,35 @@ class Peripherals:
self._audio = audiobusio.I2SOut(board.I2S_BCLK, board.I2S_WS, board.I2S_DIN)
self._sd_mounted = False
sd_pins_in_use = False
SD_CS = board.SD_CS
# try to Connect to the sdcard card and mount the filesystem.
try:
# initialze CS pin
cs = digitalio.DigitalInOut(SD_CS)
except ValueError:
# likely the SDCard was auto-initialized by the core
sd_pins_in_use = True
# if placeholder.txt file does not exist
if "placeholder.txt" not in os.listdir("/sd/"):
self._sd_mounted = True
if not sd_pins_in_use:
try:
# if sd CS pin was not in use
# try to initialize and mount the SDCard
sdcard = adafruit_sdcard.SDCard(
busio.SPI(board.SD_SCK, board.SD_MOSI, board.SD_MISO), cs
)
vfs = storage.VfsFat(sdcard)
storage.mount(vfs, "/sd")
self._sd_mounted = True
except OSError:
# sdcard init or mounting failed
self._sd_mounted = False
@property
def button1(self) -> bool:
"""
@ -175,3 +211,30 @@ class Peripherals:
@property
def audio(self):
return self._audio
def sd_check(self):
return self._sd_mounted
def play_file(self, file_name, wait_to_finish=True):
"""Play a wav file.
:param str file_name: The name of the wav file to play on the speaker.
:param bool wait_to_finish: flag to determine if this is a blocking call
"""
# can't use `with` because we need wavefile to remain open after return
self.wavfile = open(file_name, "rb")
wavedata = audiocore.WaveFile(self.wavfile)
self.audio.play(wavedata)
if not wait_to_finish:
return
while self.audio.playing:
pass
self.wavfile.close()
def stop_play(self):
"""Stops playing a wav file."""
self.audio.stop()
if self.wavfile is not None:
self.wavfile.close()

View file

@ -30,6 +30,8 @@ autodoc_mock_imports = [
"framebufferio",
"picodvi",
"audiobusio",
"audiocore",
"storage",
"terminalio",
]

View file

@ -12,3 +12,4 @@ adafruit-circuitpython-esp32spi
adafruit-circuitpython-requests
adafruit-circuitpython-bitmap-font
adafruit-circuitpython-display-text
adafruit-circuitpython-sd