Merge pull request #3096 from FoamyGuy/fruit_jam_examples

Fruit Jam CircuitPython examples
This commit is contained in:
foamyguy 2025-08-04 15:14:12 -05:00 committed by GitHub
commit a2a056457a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 645 additions and 0 deletions

View file

@ -0,0 +1,20 @@
# SPDX-FileCopyrightText: 2022 Kattni Rembor for Adafruit Industries
# SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries
# SPDX-License-Identifier: MIT
"""
CircuitPython Digital Input Example - Blinking an LED using the built-in button.
"""
import board
import digitalio
led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT
button = digitalio.DigitalInOut(board.BUTTON1)
button.switch_to_input(pull=digitalio.Pull.UP)
while True:
if not button.value:
led.value = False
else:
led.value = True

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

View file

@ -0,0 +1,314 @@
# SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries
# SPDX-FileCopyrightText: 2023 Liz Clark for Adafruit Industries
# SPDX-FileCopyrightText: Adapted from Phil B.'s 16bit_hello Arduino Code
#
# SPDX-License-Identifier: MIT
import gc
import math
from random import randint
import time
import displayio
import vectorio
import terminalio
import supervisor
import simpleio
from adafruit_bitmap_font import bitmap_font
from adafruit_display_text import label, wrap_text_to_lines
from adafruit_display_shapes.rect import Rect
from adafruit_display_shapes.circle import Circle
from adafruit_display_shapes.roundrect import RoundRect
from adafruit_display_shapes.triangle import Triangle
from adafruit_display_shapes.line import Line
display = supervisor.runtime.display
bitmap = displayio.Bitmap(display.width, display.height, 3)
red = 0xff0000
yellow = 0xcccc00
orange = 0xff5500
blue = 0x0000ff
pink = 0xff00ff
purple = 0x5500ff
white = 0xffffff
green = 0x00ff00
aqua = 0x125690
palette = displayio.Palette(3)
palette[0] = 0x000000 # black
palette[1] = white
palette[2] = yellow
palette.make_transparent(0)
tile_grid = displayio.TileGrid(bitmap, pixel_shader=palette)
group = displayio.Group()
def clean_up(group_name):
for _ in range(len(group_name)):
group_name.pop()
gc.collect()
def show_shapes():
gc.collect()
cx = int(display.width / 2)
cy = int(display.height / 2)
minor = min(cx, cy)
pad = 5
size = minor - pad
half = int(size / 2)
rect = Rect(cx - minor, cy - minor, size, size, stroke = 1, fill=red, outline = red)
tri = Triangle(cx + pad, cy - pad, cx + pad + half, cy - minor,
cx + minor - 1, cy - pad, fill=green, outline = green)
circ = Circle(cx - pad - half, cy + pad + half, half, fill=blue, stroke = 1, outline = blue)
rnd = RoundRect(cx + pad, cy + pad, size, size, int(size / 5), stroke = 1,
fill=yellow, outline = yellow)
group.append(rect)
group.append(tri)
group.append(circ)
group.append(rnd)
rect.fill = None
tri.fill = None
circ.fill = None
rnd.fill = None
time.sleep(2)
rect.fill = red
tri.fill = green
circ.fill = blue
rnd.fill = yellow
time.sleep(2)
clean_up(group)
del rect
del tri
del circ
del rnd
gc.collect()
def sine_chart():
gc.collect()
cx = int(display.width / 2)
cy = int(display.height / 2)
minor = min(cx, cy)
major = max(cx, cy)
group.append(Line(cx, 0, cx, display.height, blue)) # v
group.append(Line(0, cy, display.width, cy, blue)) # h
for i in range(10):
_n = simpleio.map_range(i, 0, 10, 0, major - 1)
n = int(_n)
group.append(Line(cx - n, cy - 5, cx - n, (cy - 5) + 11, blue)) # v
group.append(Line(cx + n, cy - 5, cx + n, (cy - 5) + 11, blue)) # v
group.append(Line(cx - 5, cy - n, (cx - 5) + 11, cy - n, blue)) # h
group.append(Line(cx - 5, cy + n, (cx - 5) + 11, cy + n, blue)) # h
for x in range(display.width):
y = cy - int(math.sin((x - cx) * 0.05) * float(minor * 0.5))
bitmap[x, y] = 1
group.append(tile_grid)
time.sleep(2)
clean_up(group)
def widget0():
gc.collect()
data = [31, 42, 36, 58, 67, 88]
num_points = len(data)
text_area = label.Label(terminalio.FONT, text="Widget Sales", color=white)
text_area.anchor_point = (0.5, 0.0)
text_area.anchored_position = (display.width / 2, 3)
group.append(text_area)
for i in range(11):
_x = simpleio.map_range(i, 0, 10, 0, display.width - 1)
x = int(_x)
group.append(Line(x, 20, x, display.height, blue))
_y = simpleio.map_range(i, 0, 10, 20, display.height - 1)
y = int(_y)
group.append(Line(0, y, display.width, y, blue))
prev_x = 0
_prev_y = simpleio.map_range(data[0], 0, 100, display.height - 1, 20)
prev_y = int(_prev_y)
for i in range(1, num_points):
_new_x = simpleio.map_range(i, 0, num_points - 1, 0, display.width - 1)
new_x = int(_new_x)
_new_y = simpleio.map_range(data[i], 0, 100, display.height - 1, 20)
new_y = int(_new_y)
group.append(Line(prev_x, prev_y, new_x, new_y, aqua))
prev_x = new_x
prev_y = new_y
for i in range(num_points):
_x = simpleio.map_range(i, 0, num_points - 1, 0, display.width - 1)
x = int(_x)
_y = simpleio.map_range(data[i], 0, 100, display.height - 1, 20)
y = int(_y)
group.append(Circle(x, y, 5, fill=None, stroke = 2, outline = white))
time.sleep(2)
clean_up(group)
def widget1():
gc.collect()
data = [31, 42, 36, 58, 67, 88]
num_points = len(data)
bar_width = int(display.width / num_points) - 4
x_mapped_w = display.width + 2
h_mapped_h = display.height + 20
text_area = label.Label(terminalio.FONT, text="Widget Sales", color=white)
text_area.anchor_point = (0.5, 0.0)
text_area.anchored_position = (display.width / 2, 3)
group.append(text_area)
for i in range(11):
_y = simpleio.map_range(i, 0, 10, 20, display.height - 1)
y = int(_y)
group.append(Line(0, y, display.width, y, blue))
for i in range(num_points):
_x = simpleio.map_range(i, 0, num_points, 0, x_mapped_w)
x = int(_x)
_height = simpleio.map_range(data[i], 0, 100, h_mapped_h, 0)
height = int(_height)
group.append(vectorio.Rectangle(pixel_shader=palette, width=bar_width,
height=display.height + 1, x=x, y=height, color_index = 2))
time.sleep(2)
clean_up(group)
def text_align():
gc.collect()
TEXT = "hello world"
text_area_top_left = label.Label(terminalio.FONT, text=TEXT, color=red)
text_area_top_left.anchor_point = (0.0, 0.0)
text_area_top_left.anchored_position = (0, 0)
text_area_top_middle = label.Label(terminalio.FONT, text=TEXT, color=orange)
text_area_top_middle.anchor_point = (0.5, 0.0)
text_area_top_middle.anchored_position = (display.width / 2, 0)
text_area_top_right = label.Label(terminalio.FONT, text=TEXT, color=yellow)
text_area_top_right.anchor_point = (1.0, 0.0)
text_area_top_right.anchored_position = (display.width, 0)
text_area_middle_left = label.Label(terminalio.FONT, text=TEXT, color=green)
text_area_middle_left.anchor_point = (0.0, 0.5)
text_area_middle_left.anchored_position = (0, display.height / 2)
text_area_middle_middle = label.Label(terminalio.FONT, text=TEXT, color=aqua)
text_area_middle_middle.anchor_point = (0.5, 0.5)
text_area_middle_middle.anchored_position = (display.width / 2, display.height / 2)
text_area_middle_right = label.Label(terminalio.FONT, text=TEXT, color=blue)
text_area_middle_right.anchor_point = (1.0, 0.5)
text_area_middle_right.anchored_position = (display.width, display.height / 2)
text_area_bottom_left = label.Label(terminalio.FONT, text=TEXT, color=purple)
text_area_bottom_left.anchor_point = (0.0, 1.0)
text_area_bottom_left.anchored_position = (0, display.height)
text_area_bottom_middle = label.Label(terminalio.FONT, text=TEXT, color=pink)
text_area_bottom_middle.anchor_point = (0.5, 1.0)
text_area_bottom_middle.anchored_position = (display.width / 2, display.height)
text_area_bottom_right = label.Label(terminalio.FONT, text=TEXT, color=white)
text_area_bottom_right.anchor_point = (1.0, 1.0)
text_area_bottom_right.anchored_position = (display.width, display.height)
group.append(text_area_top_middle)
group.append(text_area_top_left)
group.append(text_area_top_right)
group.append(text_area_middle_middle)
group.append(text_area_middle_left)
group.append(text_area_middle_right)
group.append(text_area_bottom_middle)
group.append(text_area_bottom_left)
group.append(text_area_bottom_right)
time.sleep(2)
clean_up(group)
def custom_font():
gc.collect()
my_font = bitmap_font.load_font("/Helvetica-Bold-16.pcf")
text_sample = "The quick brown fox jumps over the lazy dog."
text_sample = "\n".join(wrap_text_to_lines(text_sample, 28))
text_area = label.Label(my_font, text="Custom Font", color=white)
text_area.anchor_point = (0.0, 0.0)
text_area.anchored_position = (0, 0)
sample_text = label.Label(my_font, text=text_sample)
sample_text.anchor_point = (0.5, 0.5)
sample_text.anchored_position = (display.width / 2, display.height / 2)
group.append(text_area)
group.append(sample_text)
time.sleep(2)
clean_up(group)
del my_font
gc.collect()
def bitmap_example():
gc.collect()
blinka_bitmap = displayio.OnDiskBitmap("/blinka_computer.bmp")
blinka_grid = displayio.TileGrid(blinka_bitmap, pixel_shader=blinka_bitmap.pixel_shader)
gc.collect()
group.append(blinka_grid)
time.sleep(2)
clean_up(group)
del blinka_grid
del blinka_bitmap
gc.collect()
def sensor_values():
gc.collect()
text_x = "X: %d" % randint(-25, 25)
text_y = "Y: %d" % randint(-25, 25)
text_z = "Z: %d" % randint(-25, 25)
x_text = label.Label(terminalio.FONT, text=text_x, color=red)
x_text.anchor_point = (0.0, 0.0)
x_text.anchored_position = (2, 0)
y_text = label.Label(terminalio.FONT, text=text_y, color=green)
y_text.anchor_point = (0.0, 0.0)
y_text.anchored_position = (2, 10)
z_text = label.Label(terminalio.FONT, text=text_z, color=blue)
z_text.anchor_point = (0.0, 0.0)
z_text.anchored_position = (2, 20)
group.append(x_text)
group.append(y_text)
group.append(z_text)
for i in range(40):
if i == 10:
group.scale = 2
elif i == 20:
group.scale = 3
elif i == 30:
group.scale = 4
x_text.text = "X: %d" % randint(-50, 50)
y_text.text = "Y: %d" % randint(-50, 50)
z_text.text = "Z: %d" % randint(-50, 50)
time.sleep(0.1)
time.sleep(0.1)
clean_up(group)
group.scale = 1
display.root_group = group
while True:
show_shapes()
sine_chart()
widget0()
widget1()
text_align()
custom_font()
bitmap_example()
sensor_values()

View file

@ -0,0 +1,71 @@
# SPDX-FileCopyrightText: 2021-2023 Kattni Rembor for Adafruit Industries
# SPDX-License-Identifier: MIT
"""CircuitPython I2C possible pin-pair identifying script"""
import board
import busio
from microcontroller import Pin
def is_hardware_i2c(scl, sda):
try:
p = busio.I2C(scl, sda)
p.deinit()
return True
except ValueError:
return False
except RuntimeError:
return True
def get_unique_pins():
exclude = [
getattr(board, p)
for p in [
# This is not an exhaustive list of unexposed pins. Your results
# may include other pins that you cannot easily connect to.
"NEOPIXEL",
"DOTSTAR_CLOCK",
"DOTSTAR_DATA",
"APA102_SCK",
"APA102_MOSI",
"LED",
"SWITCH",
"BUTTON",
"ACCELEROMETER_INTERRUPT",
"VOLTAGE_MONITOR",
"MICROPHONE_CLOCK",
"MICROPHONE_DATA",
"RFM_RST",
"RFM_CS",
"RFM_IO0",
"RFM_IO1",
"RFM_IO2",
"RFM_IO3",
"RFM_IO4",
"RFM_IO5",
"TFT_I2C_POWER",
"NEOPIXEL_POWER",
"USB_HOST_DATA_MINUS"
]
if p in dir(board)
]
pins = [
pin
for pin in [getattr(board, p) for p in dir(board)]
if isinstance(pin, Pin) and pin not in exclude
]
unique = []
for p in pins:
if p not in unique:
unique.append(p)
return unique
for scl_pin in get_unique_pins():
for sda_pin in get_unique_pins():
if scl_pin is sda_pin:
continue
if is_hardware_i2c(scl_pin, sda_pin):
print("SCL pin:", scl_pin, "\t SDA pin:", sda_pin)

View file

@ -0,0 +1,36 @@
# SPDX-FileCopyrightText: 2025 Liz Clark, Tim Cocks for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import array
import math
import time
import audiocore
from adafruit_fruitjam.peripherals import Peripherals
fruit_jam = Peripherals()
# use headphones
fruit_jam.dac.headphone_output = True
fruit_jam.dac.dac_volume = -10 # dB
# or use speaker
# dac.speaker_output = True
# dac.speaker_volume = -20 # dB
# generate a sine wave
tone_volume = 0.5
frequency = 440
sample_rate = fruit_jam.dac.sample_rate
length = sample_rate // frequency
sine_wave = array.array("h", [0] * length)
for i in range(length):
sine_wave[i] = int((math.sin(math.pi * 2 * i / length)) * tone_volume * (2**15 - 1))
sine_wave_sample = audiocore.RawSample(sine_wave, sample_rate=sample_rate)
while True:
fruit_jam.audio.stop()
time.sleep(1)
fruit_jam.audio.play(sine_wave_sample, loop=True)
time.sleep(1)

View file

@ -0,0 +1,28 @@
# SPDX-FileCopyrightText: 2025 Liz Clark, Tim Cocks for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import audiocore
from adafruit_fruitjam.peripherals import Peripherals
fruit_jam = Peripherals()
# use headphones
fruit_jam.dac.headphone_output = True
fruit_jam.dac.dac_volume = -10 # dB
# or use speaker
# dac.speaker_output = True
# dac.speaker_volume = -20 # dB
# set sample rate & bit depth, use bclk
fruit_jam.dac.configure_clocks(sample_rate=44100, bit_depth=16)
with open("StreetChicken.wav", "rb") as wave_file:
wav = audiocore.WaveFile(wave_file)
print("Playing wav file!")
fruit_jam.audio.play(wav)
while fruit_jam.audio.playing:
pass
print("Done!")

View file

@ -0,0 +1,18 @@
# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries
# SPDX-License-Identifier: MIT
"""CircuitPython status NeoPixel red, green, blue example."""
import time
import board
import neopixel
pixel = neopixel.NeoPixel(board.NEOPIXEL, 5)
pixel.brightness = 0.3
while True:
pixel.fill((255, 0, 0))
time.sleep(0.5)
pixel.fill((0, 255, 0))
time.sleep(0.5)
pixel.fill((0, 0, 255))
time.sleep(0.5)

View file

@ -0,0 +1,21 @@
# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries
# SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries
# SPDX-License-Identifier: MIT
"""CircuitPython status NeoPixel rainbow example."""
import time
import board
from rainbowio import colorwheel
import neopixel
pixel = neopixel.NeoPixel(board.NEOPIXEL, 5)
pixel.brightness = 0.3
def rainbow(delay):
for color_value in range(255):
pixel.fill(colorwheel(color_value))
time.sleep(delay)
while True:
rainbow(0.02)

View file

@ -0,0 +1,40 @@
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT
"""
CircuitPython Essentials SD Card Read Demo
The SD Card is automatically mounted by CircuitPython on the Fruit Jam.
"""
import os
def print_directory(path, tabs=0):
for file in os.listdir(path):
stats = os.stat(path + "/" + file)
filesize = stats[6]
isdir = stats[0] & 0x4000
if filesize < 1000:
sizestr = str(filesize) + " bytes"
elif filesize < 1000000:
sizestr = "%0.1f KB" % (filesize / 1000)
else:
sizestr = "%0.1f MB" % (filesize / 1000000)
prettyprintname = ""
for _ in range(tabs):
prettyprintname += " "
prettyprintname += file
if isdir:
prettyprintname += "/"
print("{0:<40} Size: {1:>10}".format(prettyprintname, sizestr))
# recursively print directory contents
if isdir:
print_directory(path + "/" + file, tabs + 1)
print("Files on filesystem:")
print("====================")
print_directory("/sd")

View file

@ -0,0 +1,25 @@
# SPDX-FileCopyrightText: 2017 Limor Fried for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""
CircuitPython Essentials SD Card Write Demo
The SD Card is automatically mounted by CircuitPython on the Fruit Jam
"""
import time
import microcontroller
# Use the filesystem as normal! Our files are under /sd
print("Logging temperature to filesystem")
# append to the file!
while True:
# open file for append
with open("/sd/temperature.txt", "a") as f:
t = microcontroller.cpu.temperature
print("Temperature = %0.1f" % t)
f.write("%0.1f\n" % t)
# file is saved
time.sleep(1)

View file

@ -0,0 +1,72 @@
# SPDX-FileCopyrightText: 2019 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT
from os import getenv
import adafruit_connection_manager
import adafruit_requests
import board
from digitalio import DigitalInOut
from adafruit_esp32spi import adafruit_esp32spi
# Get wifi details and more from a settings.toml file
# tokens used by this Demo: CIRCUITPY_WIFI_SSID, CIRCUITPY_WIFI_PASSWORD
ssid = getenv("CIRCUITPY_WIFI_SSID")
password = getenv("CIRCUITPY_WIFI_PASSWORD")
print("ESP32 SPI webclient test")
TEXT_URL = "http://wifitest.adafruit.com/testwifi/index.html"
JSON_URL = "http://wifitest.adafruit.com/testwifi/sample.json"
# If you are using a board with pre-defined ESP32 Pins:
esp32_cs = DigitalInOut(board.ESP_CS)
esp32_ready = DigitalInOut(board.ESP_BUSY)
esp32_reset = DigitalInOut(board.ESP_RESET)
spi = board.SPI()
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
pool = adafruit_connection_manager.get_radio_socketpool(esp)
ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp)
requests = adafruit_requests.Session(pool, ssl_context)
if esp.status == adafruit_esp32spi.WL_IDLE_STATUS:
print("ESP32 found and in idle mode")
print("Firmware vers.", esp.firmware_version)
print("MAC addr:", ":".join("%02X" % byte for byte in esp.MAC_address))
for ap in esp.scan_networks():
print("\t%-23s RSSI: %d" % (ap.ssid, ap.rssi))
print("Connecting to AP...")
while not esp.is_connected:
try:
esp.connect_AP(ssid, password)
except OSError as e:
print("could not connect to AP, retrying: ", e)
continue
print("Connected to", esp.ap_info.ssid, "\tRSSI:", esp.ap_info.rssi)
print("My IP address is", esp.ipv4_address)
print("IP lookup adafruit.com: %s" % esp.pretty_ip(esp.get_host_by_name("adafruit.com")))
print("Ping google.com: %d ms" % esp.ping("google.com"))
# esp._debug = True
print("Fetching text from", TEXT_URL)
r = requests.get(TEXT_URL)
print("-" * 40)
print(r.text)
print("-" * 40)
r.close()
print()
print("Fetching json from", JSON_URL)
r = requests.get(JSON_URL)
print("-" * 40)
print(r.json())
print("-" * 40)
r.close()
print("Done!")