课程_35 MicroPython:音乐机器
- Micro:bit Tinker Kit 组件
入门
编译前准备
- 掌握Micro:bit Tinker Kit
- 下载Mu编辑器 https://codewith.mu/
项目01:音乐机器
引脚布局
- 蜂鸣器:Pin0
- ADKeypad:Pin2
关于ADKeypad的小注释 按下按钮时,ADKeypad返回模拟信号。按下的每个按钮将返回一个唯一的整数值,范围从0(表示0V)到1023(表示3V)。
但是,在不同的时间按下每个按钮会给出一小部分值并且不同的ADKeypads可能会再次给出不同的信号,这种情况并不少见。因此,在此示例代码中,我们提供了一系列可能的值,按下时ADKeypad的按钮可能会返回。
您可以随意测试ADKeypad在按下时可能返回的值,并更改示例代码中的值 .
from microbit import *
import music
#pins ADKeypad_pin = pin2 Buzzer_pin = pin0 while True: // buttonA if ADKeypad_pin.read_analog() > 0 and ADKeypad_pin.read_analog() < 10: music.play('f3:4', pin=Buzzer_pin)
//buttonB if ADKeypad_pin.read_analog() > 45 and ADKeypad_pin.read_analog() < 55: music.play('g3:4', pin=Buzzer_pin)
// buttonC if ADKeypad_pin.read_analog() > 90 and ADKeypad_pin.read_analog() < 100: music.play('a3:4', pin=Buzzer_pin)
// buttonD if ADKeypad_pin.read_analog() > 136 and ADKeypad_pin.read_analog() < 139: music.play('b3:4', pin=Buzzer_pin)
// buttonE if ADKeypad_pin.read_analog() > 535 and ADKeypad_pin.read_analog() < 545: music.play('c2:4', pin=Buzzer_pin)
项目02:智能灯
引脚布局
- PIR传感器:Pin0
- LED:Pin1
from microbit import *
#pins
PIR_pin = pin0
LED_pin = pin1
while True:
# if PIR Sensor detects motion, turn on LED
if PIR_pin.read_digital():
LED_pin.write_digital(1)
else: LED_pin.write_digital(0)
项目03:Electro-Theremin
引脚布局
- 蜂鸣器:Pin0
- 电位器:Pin1
from microbit import *
import music
#pins
Potentiometer_pin = pin1
Buzzer_pin = pin2
# values for mapping
highest_p_note = 1023
lowest_p_note = 1
highest_note = 988
lowest_note = 131
potentiometer_note = 0
modified_note = lowest_note
#modify the note
def modify_note(p_value): # p is potentiometer
new_note = (p_value-lowest_p_note)/(highest_p_note-lowest_p_note)*(highest_note-lowest_note)+ lowest_note
return int(new_note)
while True:
potentiometer_note = Potentiometer_pin.read_analog()
display.show(potentiometer_note)
modified_note = modify_note(potentiometer_note)
music.pitch(modified_note, pin = Buzzer_pin)
项目04:简单报警箱
引脚布局
- 碰撞传感器:Pin0
- LED:Pin8
- OLED:I2C行(位于BoB的底部)
from microbit import *
import time
import math
# Adapted from https://github.com/fizban99/microbit_ssd1306
OLED_ADDR = 0x3c
oled_screen = bytearray('b\x40') + bytearray(512)
def oled_initialize():
for c in ([0xae], [0xa4], [0xd5, 0xf0], [0xa8, 0x3f], [0xd3, 0x00], [0 | 0x0], [0x8d, 0x14], [0x20, 0x00], [0x21, 0, 127], [0x22, 0, 63], [0xa0 | 0x1], [0xc8], [0xda, 0x12], [0x81, 0xcf], [0xd9, 0xf1], [0xdb, 0x40], [0xa6], [0xd6, 1], [0xaf]): i2c.write(OLED_ADDR, b'\x00' + bytearray(c)) def oled_set_pos(col=0, page=0): i2c.write(OLED_ADDR, b'\x00' + bytearray([0xb0 | page])) c1, c2 = col * 2 & 0x0F, col >> 3 i2c.write(OLED_ADDR, b'\x00' + bytearray([0x00 | c1])) i2c.write(OLED_ADDR, b'\x00' + bytearray([0x10 | c2])) def oled_clear_screen(c=0): global oled_screen oled_set_pos() for i in range(1, 513): oled_screen[i] = 0 oled_draw_screen()
def oled_draw_screen():
global oled_screen
oled_set_pos() i2c.write(OLED_ADDR, oled_screen) def oled_add_text(x, y, text): global oled_screen for i in range(0, min(len(text), 12 - x)): for c in range(0, 5): col = 0 for r in range(1, 6): p = Image(text[i]).get_pixel(c, r - 1) col = col | (1 << r) if (p != 0) else col ind = x 10 + y 128 + i 10 + c 2 + 1 oled_screen[ind], oled_screen[ind + 1] = col, col oled_set_pos(x 5, y) ind0 = x 10 + y * 128 + 1 i2c.write(OLED_ADDR, b'\x40' + oled_screen[ind0 : (ind+1)])
#allow overflow to go onto the next line
def oled_add_text_new_line(x, y, text):
length_text = len(text)
separated_text = []
counter = 0
num_of_lines = math.ceil(length_text/12)
letters_in_line = 12
for line in range(0,num_of_lines):
separated_text.append([])
#separated_text[line].append(y*(line+1))
for l in range(0,letters_in_line):
separated_text[line].append(text[letters_in_line*line+l])
counter +=1
if counter == length_text:
break
#draw letters for i in range(0,len(separated_text)): oled_add_text(x,y+i,separated_text[i])
# Screen divided into 12 columns and 4 rows
oled_initialize()
oled_clear_screen()
# Start Simple Alarm Box Code here
#pins
CrashSensor_pin = pin0
LED_pin = pin8
#set up crash sensor
CrashSensor_pin.set_pull(CrashSensor_pin.PULL_UP)
#other variables
has_text = False
while True:
if CrashSensor_pin.read_digital() == 1:
if has_text == False : #checks if oled screen has the message already, if not add it
oled_add_text_new_line(0, 0, "Your treasure is safe")
has_text = True
LED_pin.write_digital(1)
else:
#clear oled screen
oled_clear_screen()
has_text = False
#make LED blink
LED_pin.write_digital(0)
time.sleep(0.1)
LED_pin.write_digital(1)
time.sleep(0.1)
项目05:工厂监测设备
引脚布局
- 蜂鸣器:Pin0
- 土壤湿度传感器:Pin1
- OLED:I2C行(位于BoB的底部)
from microbit import *
import time
import math
import music
# Adapted from https://github.com/fizban99/microbit_ssd1306
OLED_ADDR = 0x3c
oled_screen = bytearray('b\x40') + bytearray(512)
def oled_initialize():
for c in ([0xae], [0xa4], [0xd5, 0xf0], [0xa8, 0x3f], [0xd3, 0x00], [0 | 0x0], [0x8d, 0x14], [0x20, 0x00], [0x21, 0, 127], [0x22, 0, 63], [0xa0 | 0x1], [0xc8], [0xda, 0x12], [0x81, 0xcf], [0xd9, 0xf1], [0xdb, 0x40], [0xa6], [0xd6, 1], [0xaf]):
i2c.write(OLED_ADDR, b'\x00' + bytearray(c))
def oled_set_pos(col=0, page=0):
i2c.write(OLED_ADDR, b'\x00' + bytearray([0xb0 | page]))
c1, c2 = col * 2 & 0x0F, col >> 3 i2c.write(OLED_ADDR, b'\x00' + bytearray([0x00 | c1])) i2c.write(OLED_ADDR, b'\x00' + bytearray([0x10 | c2]))
def oled_clear_screen(c=0):
global oled_screen oled_set_pos() for i in range(1, 513): oled_screen[i] = 0 oled_draw_screen()
def oled_draw_screen():
global oled_screen
oled_set_pos()
i2c.write(OLED_ADDR, oled_screen)
def oled_add_text(x, y, text):
global oled_screen
for i in range(0, min(len(text), 12 - x)): for c in range(0, 5): col = 0 for r in range(1, 6): p = Image(text[i]).get_pixel(c, r - 1) col = col | (1 << r) if (p != 0) else col ind = x 10 + y 128 + i 10 + c 2 + 1 oled_screen[ind], oled_screen[ind + 1] = col, col oled_set_pos(x 5, y) ind0 = x 10 + y * 128 + 1 i2c.write(OLED_ADDR, b'\x40' + oled_screen[ind0 : (ind+1)])
#allow overflow to go onto the next line
def oled_add_text_new_line(x, y, text):
length_text = len(text)
separated_text = []
counter = 0
num_of_lines = math.ceil(length_text/12)
letters_in_line = 12
for line in range(0,num_of_lines):
separated_text.append([])
#separated_text[line].append(y*(line+1))
for l in range(0,letters_in_line):
separated_text[line].append(text[letters_in_line*line+l])
counter +=1
if counter == length_text:
break
#draw letters
for i in range(0,len(separated_text)): oled_add_text(x,y+i,separated_text[i])
# Screen divided into 12 columns and 4 rows
oled_initialize()
oled_clear_screen()
# Start Plant Monitoring Device Code here
#pins
Buzzer_pin = pin0
MoistureSensor_pin = pin1
Servo_pin = pin8
#other variables
healthWarning = False
oled_add_text_new_line(0, 0, "Your plant is in good condition")
while True:
if MoistureSensor_pin.read_analog() <50:
if healthWarning == False : #checks if oled screen has the message already, if not add it
oled_clear_screen()
oled_add_text_new_line(0, 0, "Moisture level is: %d" % MoistureSensor_pin.read_analog())
oled_add_text_new_line(0, 2, "Water your plant!")
healthWarning = True
music.play('b3:1', pin = Buzzer_pin)
else:
#clear oled screen
if healthWarning == True:
oled_clear_screen()
healthWarning = False
oled_add_text_new_line(0, 0, "Your plant is in good condition")