Skip to content

Instantly share code, notes, and snippets.

@andywarburton
Created November 28, 2023 15:09
Show Gist options
  • Save andywarburton/80ceffbeb90c01b28167792a23ff2214 to your computer and use it in GitHub Desktop.
Save andywarburton/80ceffbeb90c01b28167792a23ff2214 to your computer and use it in GitHub Desktop.
LeeLoo.py
# Welcome to PB-01
import board
import time
import math
import random
#import supervisor
from os import listdir
from gc import collect
import busio
import displayio
import adafruit_displayio_ssd1306
from adafruit_display_text import label
import terminalio
import pwmio
from adafruit_motor import servo
import audiocore
import audiomixer
import audiobusio
from audiomp3 import MP3Decoder
# led animation stuff
import neopixel
from adafruit_led_animation.animation.blink import Blink
from adafruit_led_animation.animation.comet import Comet
from adafruit_led_animation.animation.chase import Chase
from adafruit_led_animation.animation.solid import Solid
from adafruit_led_animation.animation.pulse import Pulse
from adafruit_led_animation.sequence import AnimationSequence
from adafruit_led_animation.color import PURPLE, MAGENTA, WHITE, PINK, BLUE, AMBER, JADE, RED
from adafruit_led_animation.animation.colorcycle import ColorCycle
from adafruit_led_animation.animation.rainbow import Rainbow
from adafruit_led_animation.animation.rainbowchase import RainbowChase
from adafruit_led_animation.animation.rainbowsparkle import RainbowSparkle
from adafruit_led_animation.animation.sparkle import Sparkle
from adafruit_led_animation.animation.SparklePulse import SparklePulse
from adafruit_led_animation.group import AnimationGroup
from adafruit_led_animation.helper import PixelMap
print("\n\n------------------------------")
print("Welcome to BotOS")
print("------------------------------\n")
# NEOPIXEL SETUP
num_pixels = 29
pixels = neopixel.NeoPixel(board.GP16, num_pixels)
pixels.brightness = default_brightness = 0.05
neo_top = (2,3,4)
neo_base = (0,1)
neo_pupil = (5,5)
neo_eye = (6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)
neo_all = (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)
pixels_base = PixelMap(pixels, range(0,2), individual_pixels=True)
pixels_mouth = PixelMap(pixels, range(2,10), individual_pixels=True)
pixels_head = PixelMap(pixels, range(10,13), individual_pixels=True)
pixels_pupil = PixelMap(pixels, range(13,14), individual_pixels=True)
pixels_eye = PixelMap(pixels, range(14,29), individual_pixels=True)
animation_base = Pulse(pixels_base, speed=0.1, color=BLUE, period=3)
#animation_mouth = Chase(pixels_mouth, speed=0.1, color=WHITE, size=1, spacing=4)
animation_mouth = RainbowSparkle(pixels_mouth, speed=0.1, step=10)
animation_head = Pulse(pixels_head, speed=0.1, color=BLUE, period=3)
animation_pupil = Pulse(pixels_pupil, speed=0.1, color=RED, period=3)
animation_eye = Chase(pixels_eye, speed=0.09, color=RED, size=4, spacing=4, reverse=True)
#animation_eye = Comet(pixels_eye, speed=0.05, color=PURPLE, tail_length=10, bounce=True)
# OLED SETUP
displayio.release_displays()
i2c = busio.I2C(board.GP3, board.GP2)
display_bus = displayio.I2CDisplay(i2c, device_address=0x3C)
display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=128, height=32)
display.rotation = 180
screen = displayio.Group()
WIDTH = 128
HEIGHT = 32 # Change to 64 if needed
# SERVO SETUP
pwm = pwmio.PWMOut(board.GP7, duty_cycle=2 ** 15, frequency=200)
my_servo = servo.Servo(pwm)
servo_start = 0
my_servo.angle = servo_start
# AUDIO SETUP
DIN = board.GP28
BCLK = board.GP26
LRC = board.GP27
audio = audiobusio.I2SOut(BCLK, LRC, DIN)
mixer = audiomixer.Mixer(
voice_count=2,
sample_rate=22050,
channel_count=1,
bits_per_sample=16,
samples_signed=True,
)
# PUT THE VOLUME BACK UP IDIOT!
volume = 0.1
# prepare boot sound
boot = open("mp3_boot/Startup Powermac PCI.mp3", "rb")
boot_decoder = MP3Decoder(boot)
# FUNCTIONS
# create a clean file directory that I can use easily
def clean_dir(path):
#print(path)
file_list = []
for f in listdir(path):
if not f.startswith("."):
file_list.append(path + "/" + f)
return file_list
sounds = clean_dir("mp3")
# colours
blue = (0, 130, 255)
black = (0, 0, 0)
white = (80, 80, 80)
red = (255,0,0)
green = (0,255,0)
pink = (117, 20, 100)
def show_all_pixels(color=black, segment=neo_all):
for i in segment:
pixels[i] = color
pixels.show()
def blank_oled():
global screen
screen = displayio.Group()
display.show(screen)
def show_oled_message(text):
blank_oled()
text_area = label.Label(
terminalio.FONT, text=text, color=0xFFFFFF, x=0, y=15
) # y=HEIGHT//2-1
screen.append(text_area)
print("OLED:", text)
def flicker_leds(count):
for i in range(count):
#show_all_pixels(black)
#time.sleep(random.uniform(0.01, 0.3))
#time.sleep(0.5)
show_all_pixels(blue)
time.sleep(random.uniform(0.02, 0.2))
time.sleep(0.5)
show_all_pixels(white)
time.sleep(random.uniform(0.03, 0.1))
time.sleep(0.5)
def fade_leds(count, color, segment=neo_all, speed="normal"):
min = 0
max = 80
step = 2
if(speed == "fast"):
delay = 0.005
step = 5
elif(speed == "slow"):
delay = 0.2
step = 1
else:
delay = 0.05
for i in range(count):
for b in reversed(range(min,max,step)):
pixels.brightness = b/100
show_all_pixels(color)
pixels.show()
time.sleep(delay)
for b in range(min,max,step):
pixels.brightness = b/100
show_all_pixels(color)
pixels.show()
time.sleep(delay)
pixels.brightness = default_brightness
# My money don't
def jiggle_jiggle(count):
for i in range(count):
jiggle_max = 90
my_servo.angle = servo_start
for angle in range(servo_start, jiggle_max, 10): # from, to, increments
my_servo.angle = angle
time.sleep(0.02)
for angle in range(jiggle_max, servo_start, -10): # from, to, increments
my_servo.angle = angle
time.sleep(0.02)
my_servo.angle = servo_start
def play_random_sound():
sound = random.choice(sounds)
mp3 = open(sound, "rb")
decoder = MP3Decoder(mp3)
mixer = audiomixer.Mixer(voice_count=1, sample_rate=22050, channel_count=1, bits_per_sample=16, samples_signed=True)
print("Playing: ", sound)
# Have AudioOut play our Mixer source
audio.play(mixer)
# Play the first sample voice
mixer.voice[0].play(decoder)
mixer.voice[0].level = volume
while mixer.playing:
animation_mouth.animate()
print(".", end="")
time.sleep(0.1)
audio.stop()
mixer.voice[0].level = 0
print("\nStopped\n------------------------------")
def scroll_oled(text):
text = "really long boring text string to test text scrolling"
for i in text:
text = text[1:]
show_oled_message(text)
time.sleep(0.5)
##########################################
# END OF FUNCTIONS #
##########################################
def ear_sad():
my_servo.angle = 180
for angle in range(180, 0, 1): # from, to, increments
my_servo.angle = angle
time.sleep(0.03)
#scroll_oled("kdjflsjf lk sjdlfk jsld jlskdjf slkfj")
#time.sleep(30)
ear_sad()
# TURN OFF ALL THE THINGS
blank_oled()
show_all_pixels(black)
# BEGIN BOOT SEQUENCE
show_all_pixels(green, neo_top)
t = 0
for i in reversed(neo_eye):
t += 1
show_oled_message("|" * t)
pixels[i] = blue
pixels.show()
time.sleep(random.uniform(0.1, 1.5))
audio.play(mixer)
mixer.voice[0].play(boot_decoder)
mixer.voice[0].level = volume
while mixer.playing:
time.sleep(0)
audio.stop()
blank_oled()
show_oled_message("Welcome to PiBot OS")
time.sleep(2)
# END BOOT SEQUENCE
# clean up
collect()
blank_oled()
show_oled_message("I'm LEE-L00")
time.sleep(2)
actions = ("ears", "sound", "light", "oled", "light", "sound")
lights = ("fade", "show", "flicker")
lights = ("flicker")
words = ("happy", "why??", "who is??", "danger!", "he he he", "lolololol")
colors = (blue, white, red, green, pink)
while True:
animation_base.animate()
animation_head.animate()
animation_pupil.animate()
animation_eye.animate()
action = random.choice(actions)
light = random.choice(lights)
word = random.choice(words)
color = random.choice(colors)
if(action == "ears"):
jiggle_jiggle(random.randint(1,2))
if(action == "sound"):
play_random_sound()
if(action == "light"):
show_all_pixels(color, neo_pupil)
if(light == "fade"):
fade_leds(2, color)
if(light == "show"):
show_all_pixels(color, neo_all)
if(light == "flicker"):
flicker_leds(random.randint(2,4))
if(action == "oled"):
show_oled_message(word)
#time.sleep(random.randint(1,3))
collect()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment