Import the code

This commit is contained in:
Nils Freydank 2022-11-28 22:49:02 +01:00
parent fb23a0a479
commit d5c1a51a67
Signed by: nfr
GPG Key ID: 0F1DEAB2D36AD112
3 changed files with 217 additions and 0 deletions

70
light.py Normal file
View File

@ -0,0 +1,70 @@
# SPDX-License-Identifier: MIT
#
# Little christmas candle
#
# Author: Nils Freydank <nils.freydank@datenschutz-ist-voll-doof.de>
# Year: 2022
# Copyright: MIT
import machine
import time
pin_led1 = machine.Pin(22)
pin_led2 = machine.Pin(10)
pin_led3 = machine.Pin(8)
def _get_new_duty(
factor: int, signed_step_width: int, limit_lower: int, limit_upper: int
) -> Tuple[int, int]:
duty_fac: int = factor
duty_fac += signed_step_width
if duty_fac > limit_upper:
duty_fac = limit_upper
signed_step_width = (-1) * signed_step_width
elif duty_fac < limit_lower:
duty_fac = limit_lower
signed_step_width = (-1) * signed_step_width
return duty_fac, signed_step_width
def flicker() -> None:
pwm_led1 = machine.PWM(pin_led1)
pwm_led2 = machine.PWM(pin_led2)
pwm_led3 = machine.PWM(pin_led3)
pwm_led1.freq(1_000)
pwm_led2.freq(1_000)
pwm_led3.freq(1_000)
duty_fac_led1: int = 0
signed_step_width_led1: int = 1
duty_fac_led2: int = 0
signed_step_width_led2: int = 1
duty_fac_led3: int = 0
signed_step_width_led3: int = 1
delay_s: float = 0.01
while True:
duty_fac_led1, signed_step_width_led1 = _get_new_duty(
duty_fac_led1, signed_step_width_led1, 240, 250
)
pwm_led1.duty_u16(duty_fac_led1**2)
duty_fac_led2, signed_step_width_led2 = _get_new_duty(
duty_fac_led2, signed_step_width_led2, 0, 200
)
pwm_led2.duty_u16(duty_fac_led2**2)
duty_fac_led3, signed_step_width_led3 = _get_new_duty(
duty_fac_led3, signed_step_width_led3, 30, 100
)
pwm_led2.duty_u16(duty_fac_led3**2)
time.sleep(delay_s)
# vim:fileencoding=utf-8:ts=4:syntax=python:expandtab

18
main.py Normal file
View File

@ -0,0 +1,18 @@
# SPDX-License-Identifier: MIT
#
# Little christmas candle
#
# Author: Nils Freydank <nils.freydank@datenschutz-ist-voll-doof.de>
# Year: 2022
# Copyright: MIT
import _thread
from light import flicker
from music import play_music
if __name__ == "__main__":
_thread.start_new_thread(flicker, ())
play_music()
# vim:fileencoding=utf-8:ts=4:syntax=python:expandtab

129
music.py Normal file
View File

@ -0,0 +1,129 @@
# SPDX-License-Identifier: MIT
#
# Little christmas candle
#
# Author: Nils Freydank <nils.freydank@datenschutz-ist-voll-doof.de>
# Year: 2022
# Copyright: MIT
import json
import machine
import time
pin_piezo = machine.Pin(12)
def _note_to_freq(note_name: str) -> int:
"""
Translate note names from strings into frequency values.
"""
freq: int = 0
# frequencies, see e.g.
# https://en.wikipedia.org/wiki/Piano_key_frequencies
note_names: dict = {
"c4": 262,
"cis4": 277,
"d4": 294,
"e4": 330,
"f4": 349,
"fis4": 370,
"g4": 392,
"a4": 440,
"b4": 466,
"h4": 494,
"c5": 523,
"cis5": 554,
"d5": 587,
"e5": 659,
"f5": 698,
"fis5": 740,
"g5": 784,
"a5": 880,
"b5": 923,
"h5": 988,
"c6": 1047,
}
try:
freq = note_names[note_name]
except KeyError:
freq = -1
print(f"exc in _note_to_freq() for {note_name}.")
return freq
def _len_to_second(len_name: str, len_scaling: float = 0.6) -> float:
time: float = 0.0
len_names = {
"_t": 0.125 * len_scaling, # thirty-second note or pause
"_s": 0.25 * len_scaling, # sixteenth note or pause
"_e": 0.5 * len_scaling, # eight note or pause
"_q": 1.0 * len_scaling, # quarter note or pause
"_h": 2.0 * len_scaling, # half note or pause
"_f": 4.0 * len_scaling, # whole note or pause
}
try:
for elem in len_name.split("+"):
time += len_names[elem.replace(" ", "")]
except KeyError:
time = 0.0
print(f"exc in _len_to_second() for {elem}.")
print("Do you have a typo there, e.g. 'a' + 'b' instead of 'a + b'?")
return time
def play_note(note_name: str, duration: str, loud: bool = False) -> int:
if loud:
duty_cycle: int = 16_000
else:
duty_cycle: int = 400
real_pwm_freq: int = 0
pwm_piezo = machine.PWM(pin_piezo)
pwm_piezo.freq(_note_to_freq(note_name))
real_pwm_freq = pwm_piezo.freq()
pwm_piezo.duty_u16(duty_cycle)
time.sleep(_len_to_second(duration))
pwm_piezo.duty_u16(0)
time.sleep(0.05)
return real_pwm_freq
def pause(duration: str) -> None:
time.sleep(_len_to_second(duration))
time.sleep(0.05)
def play_music(file_name: str = "o-tannenbaum.json") -> None:
data: dict = {}
try:
with open(file_name, "r") as f:
data = json.load(f)
try:
if data["metadata"]["format"] == "json-0.1.0":
for notes in data["music"]:
for note in notes.keys():
if note == "0":
pause(notes[note])
else:
play_note(note, notes[note])
elif data["metadata"]["format"] == "json-0.2.0":
pass
except:
print(f"play_oh_tannnebaum() failed to parse {data}.")
except FileNotFoundError:
print("Could not load the JSON file containing the song's details.")
# vim:fileencoding=utf-8:ts=4:syntax=python:expandtab