Created
November 28, 2023 15:09
-
-
Save andywarburton/80ceffbeb90c01b28167792a23ff2214 to your computer and use it in GitHub Desktop.
LeeLoo.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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