Compare commits

...

3 commits

Author SHA1 Message Date
foamyguy
17d3868ed6
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
2025-07-24 11:24:41 -05:00
foamyguy
2a5d7e81e7 fix docs build 2025-07-24 10:05:15 -05:00
foamyguy
5932bf058c add sd_check(), play_file(), stop_play(), show_QR(), hide_QR() portalbase APIs. Fix for status_led pin already in use. Fix for caption text is None 2025-07-24 09:01:55 -05:00
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,7 +207,8 @@ class FruitJam(PortalBase):
print("Init caption")
if caption_font:
self._caption_font = self._load_font(caption_font)
self.set_caption(caption_text, caption_position, caption_color)
if caption_text is not None:
self.set_caption(caption_text, caption_position, caption_color)
if text_font:
if text_position is not None and isinstance(text_position[0], (list, tuple)):

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