UCUq sans interface (headless) #
Cliquez sur l’encart pour lancer le programme. Pour réduire l’encart, cliquez à nouveau sur son en-tête.
Vous pouvez modifier le programme directement dans l’éditeur et la relancer avec le bouton Run.
Remise à zéro globale (Golf) #
import ucuq
ucuq.HD44780_I2C(16, 2, ucuq.SoftI2C(6, 7))
ucuq.SSD1306_I2C(128, 64, ucuq.I2C(8,9))
ucuq.WS2812(8, 20).fill([30,30,30])
ucuq.PWM(5, freq=500).setNS(0)
SSD1306 (OLED,Golf) #
PRENOM = """
"""
import ucuq, datetime
oled = ucuq.SSD1306_I2C(128, 64, ucuq.I2C(8, 9))
def display(prenom, y):
if prenom:
oled\
.text("Bien le bonjour,", 0, y)\
.text(f"{prenom} !", 0, y+10)\
.text("Merci pour votre", 0, y+45)\
.text("participation !", 0, y+55)\
.show()
else:
oled\
.text("Test accompli le", 0, y+20)\
.text(f"{datetime.datetime.now().strftime("%d/%m/%Y %H:%M")}", 0, y+40)\
.show()
for i in range(64):
oled.fill(0)
display(ucuq.toASCII(PRENOM.strip()), 64-i)
Buzzer (Golf) #
FREQ = 440
import ucuq
buzzer = ucuq.PWM(5, freq=FREQ, u16 = 32000)
ucuq.sleep(1)
buzzer.setU16(0)
WS2812 (LEDs RGB, Golf) #
R = 0
G = 30
B = 0
import ucuq
ucuq.WS2812(8, 20).fill([R,G,B]).write()
HD44780 (LCD, Golf) #
NAME = """
"""
import datetime, ucuq, unicodedata
LINE_1 = 'Ravi de vous rencontrer, '
LINE_2 = 'Comment va ?'
DELAY = 0.25
LCD = ucuq.HD44780_I2C(16, 2, ucuq.SoftI2C(6, 7)).backlightOn()
PADDING = ' ' * 15
def display(name):
if name := name.strip():
name = ''.join(c for c in unicodedata.normalize('NFD', name) if unicodedata.category(c) != 'Mn')
Message = ''.join([str(x) for x in [PADDING, LINE_1, name, ',', PADDING[: int(15 - len(name))]]])
LCD.clear()
for j in range(len(Message) - 15):
LCD.moveTo(0,0)
LCD.putString((Message[int((j + 1) - 1) : int(j + 16)]))
ucuq.sleep(DELAY)
LCD.moveTo(0,1)
LCD.putString(LINE_2)
else:
LCD\
.putString("Hello, World!")\
.moveTo(0,1)\
.putString(f"{datetime.datetime.now().strftime("%d/%m/%Y %H:%M")}")\
.backlightOn()
display(NAME)
SH1106 (OLED, Hotel) #
PRENOM = """
"""
import ucuq, datetime
oled = ucuq.SH1106_I2C(128, 64, ucuq.I2C(8, 9))
def display(prenom, y):
if prenom:
oled\
.text("Bien le bonjour,", 0, y)\
.text(f"{prenom} !", 0, y+10)\
.text("Merci pour votre", 0, y+45)\
.text("participation !", 0, y+55)\
.show()
else:
oled\
.text("Test accompli le", 0, y+20)\
.text(f"{datetime.datetime.now().strftime("%d/%m/%Y %H:%M")}", 0, y+40)\
.show()
for i in range(64):
oled.fill(0)
display(ucuq.toASCII(PRENOM.strip()), 64-i)
Buzzers (Hotel) #
Frère Jacques #
import ucuq, re, math
VOICES = (
"C44D44E44C44C44D44E44C44E44F44G45E44F44G45G43.A42G43F43E44C44G43.A42G43F43E44C44C44G34C45C44G34C45C44D44E44C44C44D44E44C44E44F44G45E44F44G45G43.A42G43F43E44C44G43.A42G43F43E44C44C44G34C45C44G34C45",
"R6R6C44D44E44C44C44D44E44C44E44F44G45E44F44G45G43.A42G43F43E44C44G43.A42G43F43E44C44C44G34C45C44G34C45C44D44E44C44C44D44E44C44E44F44G45E44F44G45G43.A42G43F43E44C44G43.A42G43F43E44C44C44G34C45C44G34C45",
"R6R6R6R6C44D44E44C44C44D44E44C44E44F44G45E44F44G45G43.A42G43F43E44C44G43.A42G43F43E44C44C44G34C45C44G34C45C44D44E44C44C44D44E44C44E44F44G45E44F44G45G43.A42G43F43E44C44G43.A42G43F43E44C44C44G34C45C44G34C45",
)
NOTE_MAP = {
'C': -9, 'C#': -8, 'Db': -8, 'D': -7, 'D#': -6, 'Eb': -6,
'E': -5, 'F': -4, 'F#': -3, 'Gb': -3, 'G': -2, 'G#': -1, 'Ab': -1,
'A': 0, 'A#': 1, 'Bb': 1, 'B': 2
}
b = []
b.append(ucuq.PWM(13, freq=440, u16=32000))
ucuq.sleep(0.5)
b[0].setU16(0)
b.append(ucuq.PWM(2, freq=550, u16=32000))
ucuq.sleep(0.5)
b[1].setU16(0)
b.append(ucuq.PWM(7, freq=660, u16=32000))
ucuq.sleep(0.5)
b[2].setU16(0)
ucuq.sleep(1)
def note_to_freq(note_str, octave):
if note_str == 'R':
return 0 # silence
if len(note_str) == 2 and note_str[1] in('b','#'):
note_key = note_str
else:
note_key = note_str[0]
if note_key not in NOTE_MAP:
return 0
note = 12 * (int(octave) + 1) + NOTE_MAP[note_key]
return 440.0 * (2 ** ((note - 57) / 12.0))
def duration_to_seconds(duration, base, dots=0):
value = 1 / (2 ** (4 - duration))
total = value
for _ in range(dots):
value /= 2
total += value
return base * total
def parse_note_string(note_str, base):
match = re.match(r'([A-Z][b#]?)(\d)(\d)(\.*)', note_str)
if not match:
match = re.match(r'(R)(\d)(\.*)', note_str)
if not match:
return None
octave = 0
note, duration, dots = match.groups()
else:
note, octave, duration, dots = match.groups()
return note_to_freq(note, int(octave)), duration_to_seconds(int(duration), base, len(dots)),
def extract_notes(voice_str):
return re.findall(r'([A-Z][b#]?\d\d\.*|R\d\.*)', voice_str)
def generate_polyphonic_events_one_voice_per_event(voices, tempo, callback):
voice_notes = [extract_notes(v) for v in voices]
raws = []
for a in voice_notes:
raw = []
for b in a:
raw.append(parse_note_string(b, 60.0 / tempo))
raw.append((0, 0))
raws.append(raw)
indexes = [0 for _ in raws]
freqs = [0 for _ in raws]
delays = [0 for _ in raws]
while any(i != None for i in indexes):
events = []
delay = 100000
for i in range(len(indexes)):
if indexes[i] != None:
if delays[i] == 0:
freqs[i], delays[i] = raws[i][indexes[i]]
indexes[i] += 1
events.append((i, freqs[i]))
delay = min(delay, delays[i])
callback(events, delay)
for i in range(len(indexes)):
if indexes[i] != None and indexes[i] >= len(raws[i]):
indexes[i] = None
else:
delays[i] -= delay
def callback(events, duration):
if duration:
id = ucuq.sleepStart()
for event in events:
buzzer = b[event[0]]
buzzer.setU16(0)
if event[1] != 0:
buzzer.setFreq(int(event[1])).setU16(10000 + 25000 * event[0])
if duration:
ucuq.sleepWait(id, duration)
generate_polyphonic_events_one_voice_per_event(VOICES, 120, callback)
Fugue #
import ucuq, re, math
VOICES = (
"R6R7R7R7R7R7R7R7R7R6R3A53G53A53F53A53E53A53D53A53C#53A53D53A53E53A53F53A53A43A53B43A53C#53A53D53A53C#53A53D53A53E53A53F53A53E53A53D53A53C53A53Bb43A53C53A53D53G53Bb43G53E53G53D53G53C53G53Bb43G53A43G53Bb43G53C53F53A43F53D53F53C53F53Bb43F53A43F53G43F53A43F53Bb43E53G43E53C#53E53Bb43E53A43E53G43E53F43E53G43E53A43D53F43D53E43E53E43E53F43D53F43D53Bb43C#53Bb43C#53A43D53F43D53E43E53E43E53F43D53F43D53R3D53C#53D53B43D53C#53B43C#55R5R3D53C#53D53F53D53C#53B43C#55E55.D55C#54C55Bb45A45A45G45G45F#44A45Eb54D55R4G54",
"R6R7R6R3D53C53D53Bb43D53A43D53G43D53F#43D53G43D53A43D53Bb43D53D43D53E43D53F#43D53G43D53F#43D53G43D53A43D53Bb44D53R3Bb43R3D53R3Eb54G43R3Eb53R3G43R3C54A43R3C53R3A43R3D54F43R3D53R3F43R3Bb44G43R3Bb43R3G43R3C#54E43R3C#53R3E43R3A44F43R3A43R3F43R3G44C#43R3G43R3C#43R3F44D43R3F43R3D43R3E44Bb33R3E43R3Bb33R3A33..R1A33..R1A33..R1A33..R1A33..R1A33..R1A33..R1A33..R1A33..R1A33..R1A33..R1A33..R1A33..R1A33..R1A33..R1A33..R1A35D45D45R5C45C45C45R5Bb35Bb35Bb35R5A35A35A35R4D44C#44C#44D44D44E45R4D44C#44C#44D44D44E45R5R3A43G43A43E43G43F43E43F45D45A33A43G43A43C#43G43F43E43F45E45D44A45G45.F#45F45Eb45.D44F#44C55Bb43A43Bb43Bb43",
"R3A43G43A43F43A43E43A43D43A43C#43A43D43A43E43A43F43A43A33A43B33A43C#43A43D43A43C#43A43D43A43E43A43F44F#44G44C44Bb34A34Bb34C44D44F#34G34A34Bb34A34Bb34F#34G33G43G33G43D43G43D43G43C43Eb43C43Eb43C43Eb43C43Eb43C43F43C43F43C43F43C43F43Bb33D43Bb33D43Bb33D43Bb33D43Bb33E43Bb33E43Bb33E43Bb33E43A33C#43A33C#43A33C#43A33C#43F33D43F33D43F33D43F33D43E33Bb33E33Bb33E33Bb33E33Bb33D33A33D33A33D33A33D33A33E33G33E33G33E33G33E33G33F33..R1E33..R1D33..R1G33..R1F33..R1E33..R1F33..R1C#33..R1D33..R1C#33..R1D33..R1E33..R1F33..R1E33..R1F33..R1C#33..R1D35F35G35R5C35E35F35R5Bb25D35E35R5A25C#35D35R4F34Bb34Bb34A34A34G35R4A34Bb34Bb34A34A34G#35R6.R7R3D43C#43D43A33A33G33A33F#33D43C#43D43G33F43Eb43D43C#43E43A33C#43D33Eb43D43C43B33D43G33B33C33D43C43Bb33A33C43F#33A33D33C43Bb33A33Bb33A43G43F#43G43Bb33A33G33"
)
NOTE_MAP = {
'C': -9, 'C#': -8, 'Db': -8, 'D': -7, 'D#': -6, 'Eb': -6,
'E': -5, 'F': -4, 'F#': -3, 'Gb': -3, 'G': -2, 'G#': -1, 'Ab': -1,
'A': 0, 'A#': 1, 'Bb': 1, 'B': 2
}
b = []
b.append(ucuq.PWM(13, freq=440, u16=10000))
ucuq.sleep(0.5)
b[0].setU16(0)
b.append(ucuq.PWM(2, freq=550, u16=10000))
ucuq.sleep(0.5)
b[1].setU16(0)
b.append(ucuq.PWM(7, freq=660, u16=10000))
ucuq.sleep(0.5)
b[2].setU16(0)
ucuq.sleep(1)
def note_to_freq(note_str, octave):
if note_str == 'R':
return 0 # silence
if len(note_str) == 2 and note_str[1] in('b','#'):
note_key = note_str
else:
note_key = note_str[0]
if note_key not in NOTE_MAP:
return 0
note = 12 * (int(octave) + 1) + NOTE_MAP[note_key]
return 440.0 * (2 ** ((note - 57) / 12.0))
def duration_to_seconds(duration, base, dots=0):
value = 1 / (2 ** (4 - duration))
total = value
for _ in range(dots):
value /= 2
total += value
return base * total
def parse_note_string(note_str, base):
match = re.match(r'([A-Z][b#]?)(\d)(\d)(\.*)', note_str)
if not match:
match = re.match(r'(R)(\d)(\.*)', note_str)
if not match:
return None
octave = 0
note, duration, dots = match.groups()
else:
note, octave, duration, dots = match.groups()
return note_to_freq(note, int(octave)), duration_to_seconds(int(duration), base, len(dots)),
def extract_notes(voice_str):
return re.findall(r'([A-Z][b#]?\d\d\.*|R\d\.*)', voice_str)
def generate_polyphonic_events_one_voice_per_event(voices, tempo, callback):
voice_notes = [extract_notes(v) for v in voices]
raws = []
for a in voice_notes:
raw = []
for b in a:
raw.append(parse_note_string(b, 60.0 / tempo))
raw.append((0, 0))
raws.append(raw)
indexes = [0 for _ in raws]
freqs = [0 for _ in raws]
delays = [0 for _ in raws]
while any(i != None for i in indexes):
events = []
delay = 100000
for i in range(len(indexes)):
if indexes[i] != None:
if delays[i] == 0:
freqs[i], delays[i] = raws[i][indexes[i]]
indexes[i] += 1
events.append((i, freqs[i]))
delay = min(delay, delays[i])
callback(events, delay)
for i in range(len(indexes)):
if indexes[i] != None and indexes[i] >= len(raws[i]):
indexes[i] = None
else:
delays[i] -= delay
def callback(events, duration):
if duration:
id = ucuq.sleepStart()
for event in events:
buzzer = b[event[0]]
buzzer.setU16(0)
if event[1] != 0:
buzzer.setFreq(int(event[1])).setU16(10000 + 25000 * event[0])
if duration:
ucuq.sleepWait(id, duration)
generate_polyphonic_events_one_voice_per_event(VOICES, 160, callback)