# Arduino 的聲音測試 (一)
本系列之前的測試紀錄參考 :
# MicroPython on ESP8266 (二) : 數值型別測試
# MicroPython on ESP8266 (三) : 序列型別測試
# MicroPython on ESP8266 (四) : 字典與集合型別測試
# MicroPython on ESP8266 (五) : WiFi 連線與 WebREPL 測試
# MicroPython on ESP8266 (六) : 檔案系統測試
# MicroPython on ESP8266 (七) : 時間日期測試
# MicroPython on ESP8266 (八) : GPIO 測試
# MicroPython on ESP8266 (九) : PIR 紅外線移動偵測
# MicroPython on ESP8266 (十) : socket 模組測試
# MicroPython on ESP8266 (十一) : urllib.urequest 模組測試
# MicroPython on ESP8266 (十二) : urequests 模組測試
# MicroPython on ESP8266 (十三) : DHT11 溫溼度感測器測試
# MicroPython 使用 ampy 突然無法上傳檔案問題
# MicroPython on ESP8266 (十四) : 網頁伺服器測試
# MicroPython on ESP8266 (十五) : 光敏電阻與 ADC 測試
MicroPython 文件參考 :
# http://docs.micropython.org/en/latest/micropython-esp8266.pdf
# http://docs.micropython.org/en/latest/pyboard/library/usocket.html#class-socket
# http://docs.micropython.org/en/v1.8.7/esp8266/library/usocket.html#module-usocket
# https://gist.github.com/xyb/9a4c8d7fba92e6e3761a (驅動程式)
# WeMOS D1 Mini 開發板測試
其針腳編號 D0~D8 與 ESP8266 GPIO 之對應如下 :
板子腳位 | ESP8266 腳位 | 功能 |
D0 | GPIO16 | IO |
D1 | GPIO5 | IO, SCL |
D2 | GPIO4 | IO, SDA |
D3 | GPIO0 | IO, 內建 10K 上拉電阻 |
D4 | GPIO2 | IO, 內建 10K 上拉電阻與 LED |
D5 | GPIO14 | IO, SCK |
D6 | GPIO12 | IO, MISO |
D7 | GPIO13 | IO, MOSI |
D8 | GPIO15 | IO, SS, 內建 10K 上拉電阻 |
TX | TXD | UART 送端 |
RX | RXD | UART 收端 |
A0 | ADC | 類比輸入 (0~3.3V) |
ESP8266 GPIO 的 PWM 功能測試已紀錄在上述第八篇文章中, 簡言之, 就是利用 MicroPython 的 machine 模組之 PWM 類別, 傳入指定 GPIO 腳之 Pin 物件來建立 PWM 物件, 再呼叫 PWM 物件之 freq() 與 duty() 方法來調變輸出之方波, 例如 :
from machine import Pin, PWM
pwm2=PWM(Pin(2)) #建立 GPIO 2 的 PWM 物件
pwm2.freq(300) #設定 PWM 物件之頻率
pwm2.duty(512) #設定 PWM 物件之工作週期
其中 freq() 與 duty() 若未傳入參數則為 getter, 即讀取最近之設定值. 若要停止 PWM 功能, 則呼叫 deinit() 方法即可, 相當於 Arduino 的 noTone() 函數功能. PWM 物件之方法表列如下 :
參考官網文件 :
# PWM (pulse width modulation)
注意, ESP8266 的 GPIO 中, 只有 GPIO 16 (即 D1 Mini 的 D0) 不具 PWM 功能 :
"PWM can be enabled on all pins except Pin(16). There is a single frequency for all channels, with range between 1 and 1000 (measured in Hz). The duty cycle is between 0 and 1023 inclusive."
如果傳入 Pin(16) 給 PWM() 建構式無法建立 PWM 物件 :
>>> pwm=PWM(Pin(16))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: PWM not supported on pin 16
接下來我想複製 Arduino 聲音測試的範例, 改編為 MicroPython on ESP8266 版. 首先是讓蜂鳴器發出 1KHz 的 Bee Bee 聲, 硬體接線上只要將無源蜂鳴器的 + 端接在 D1 Mini 的 D2 腳 (GPIO 4), 另一端接地即可 (無源蜂鳴器是有極性的). 雖然蜂鳴器上有標示 5V 規格, 其實 3.3V 也是可以用的.
測試 1 : 使蜂鳴器發出 1KHz 的 Bee Bee 告警聲
#main.py or myapp.py
from machine import Pin,PWM
import time
def alarmBeep(pwm):
pwm.freq(1000) #設定頻率為 1KHz
pwm.duty(512) #設定工作週期為 50%
time.sleep(1) #持續時間 1 秒
pwm.deinit() #停止發聲
time.sleep(2) #持續時間 2 秒
pwm=PWM(Pin(4))
while True:
alarmBeep(pwm)
上面的程式裡, 我將發聲的程式碼寫成一個函數 alarmBeep(), 只要在無窮迴圈中呼叫此函數, 並將 PWM 物件傳給它即可.
測試 2 : 模擬鬧鐘鈴聲
from machine import Pin,PWM
import time
def alarmClockBeep(pwm):
for i in range(1,5): #4 次迴圈 (1~4)
pwm.freq(1000) #設定頻率為 1KHz
pwm.duty(512) #設定工作週期為 50%
time.sleep_ms(100) #持續時間 0.1 秒
pwm.deinit() #停止發聲
time.sleep_ms(200) #持續時間 0.2 秒
time.sleep_ms(800)
pwm=PWM(Pin(4))
while True:
alarmClockBeep(pwm)
這裡要注意的是 range(a, b) 是傳回 a ~ b-1 的整數, 所以 4 次迴圈需用 range(1, 5).
測試 3 : 模擬電話鈴聲
from machine import Pin,PWM
import time
def ringTone(pwm):
for i in range(1,11): #10 次迴圈 (1~10)
pwm.freq(1000) #設定頻率為 1KHz
pwm.duty(512) #設定工作週期為 50%
time.sleep_ms(50) #持續時間 50 毫秒
pwm.freq(500) #設定頻率為 500Hz
time.sleep_ms(50) #持續時間 50 毫秒
pwm.deinit() #停止發聲
time.sleep(2) #持續時間 2 秒
pwm=PWM(Pin(4))
while True:
ringTone(pwm)
這電話聲模擬得還真像.
測試 4 : 模擬警車鈴聲
from machine import Pin,PWM
import time
def policeSiren(pwm):
for i in range(150,1800):
pwm.freq(i)
pwm.duty(512)
time.sleep_ms(10)
pwm.deinit()
time.sleep_ms(1)
for i in range(1800,150):
pwm.freq(i)
pwm.duty(512)
time.sleep_ms(10)
pwm.deinit()
time.sleep_ms(1)
pwm=PWM(Pin(4))
while True:
policeSiren(pwm)
有點怪怪的, 原因是 ESP8266 GPIO PWM 的最高頻率只到 1000 Hz 而已, 而這程式卻要用到 1800 Hz.
測試 5 : 救護車的歐伊歐伊
from machine import Pin,PWM
import time
def ambulenceSiren(pwm):
pwm.freq(400)
pwm.duty(512)
time.sleep_ms(500)
pwm.freq(800)
time.sleep_ms(500)
pwm.deinit()
pwm=PWM(Pin(4))
while True:
ambulenceSiren(pwm)
接下來要演奏馬力歐一個小節, 各音符對應的頻率參考 :
# Arduino 的聲音測試 (一)
測試 6 : 馬力歐 (1)
from machine import Pin,PWM
import time
def mario(pwm):
pwm.freq(659) #E5
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep_ms(150)
pwm.freq(659) #E5
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep_ms(150)
pwm.freq(659) #E5
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep_ms(150)
time.sleep_ms(150)
pwm.freq(523) #C5
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep_ms(150)
pwm.freq(659) #E5
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep_ms(150)
time.sleep_ms(150)
pwm.freq(784) #G5
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep(3)
pwm=PWM(Pin(4))
while True:
mario(pwm)
注意, 只要呼叫過 deinit() 方法, 頻率與工作週期都會被清掉, 下一個音要再呼叫 freq() 與 duty() 重新設定. 直接使用頻率似乎非常亂, 應該使用音名來代表頻率數字, 但由於 Python 沒有像 C 語言那樣可用 define 定義常數, 只好用變數, 上面的程式可以改寫如下 :
測試 7 : 馬力歐 (2)
from machine import Pin,PWM
import time
E5=659
C5=523
G5=784
def mario(pwm):
pwm.freq(E5)
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep_ms(150)
pwm.freq(E5)
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep_ms(150)
pwm.freq(E5)
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep_ms(150)
time.sleep_ms(150)
pwm.freq(C5)
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep_ms(150)
pwm.freq(E5)
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep_ms(150)
time.sleep_ms(150)
pwm.freq(G5)
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep(3)
pwm=PWM(Pin(4))
while True:
mario(pwm)
上面的 mario() 有點長, 因為重複的部分很多, 可以模仿 Arduino 的 tone() 函數來精簡如下 :
測試 8 : 馬力歐 (3)
from machine import Pin,PWM
import time
E5=659
C5=523
G5=784
def tone(pwm,note,duration):
pwm.freq(note)
pwm.duty(512)
time.sleep_ms(duration)
pwm.deinit()
def mario(pwm):
tone(pwm,E5,150)
time.sleep_ms(150)
tone(pwm,E5,150)
time.sleep_ms(150)
tone(pwm,E5,150)
time.sleep_ms(150)
time.sleep_ms(150)
tone(pwm,C5,150)
time.sleep_ms(150)
tone(pwm,E5,150)
time.sleep_ms(150)
time.sleep_ms(150)
tone(pwm,G5,150)
time.sleep_ms(150)
time.sleep(3)
pwm=PWM(Pin(4))
while True:
mario(pwm)
上面我定義了一個 tone() 函數來模擬 Arduino 的 tone(), 這樣就能跟 Arduino 的程式一一對應了. 由於 ESP8266 的 GPIO 最高只能調變到 1000 Hz, C6 (1046 Hz) 以上的音名無法發出來, 所以要用 ESP8266 的 PWM 演奏音樂受到限制.
下列範例改編自 Arduino 的測試 9 :
測試 9 : Melody
from machine import Pin,PWM
import time
C0=18
CS0=17
D0=18
DS0=19
E0=21
F0=22
FS0=23
G0=25
GS0=26
A0=28
AS0=29
B0=31
C1=33
CS1=35
D1=37
DS1=39
B0=31
C1=33
CS1=35
D1=37
DS1=39
E1=41
F1=44
FS1=46
G1=49
GS1=52
A1=55
AS1=58
B1=62
C2=65
CS2=69
D2=73
DS2=78
E2=82
F2=87
FS2=93
G2=98
GS2=104
A2=110
AS2=117
B2=123
C3=131
CS3=139
D3=147
DS3=156
E3=165
F3=175
FS3=185
G3=196
GS3=208
A3=220
AS3=233
B3=247
C4=262
CS4=277
D4=294
DS4=311
E4=330
F4=349
FS4=370
G4=392
GS4=415
A4=440
AS4=466
B4=494
C5=523
CS5=554
D5=587
DS5=622
E5=659
F5=698
FS5=740
G5=784
GS5=831
A5=880
AS5=932
B5=988
note=(C4, G3, G3, A3, G3, 0, B3, C4)
duration=(4, 8, 8, 4, 4, 4, 4, 4)
def tone(pwm,note,duration):
pwm.freq(note)
pwm.duty(512)
time.sleep_ms(duration)
pwm.deinit()
def melody(pwm):
for i in range(0,8):
d=int(1000/duration[i])
tone(pwm, note[i], d)
p=int(d*1.3)
time.sleep_ms(p)
time.sleep(2)
pwm=PWM(Pin(4))
while True:
melody(pwm)
但是我測試結果發現倒數第二個音 B3 卻沒發出來, 反覆檢查程式沒錯啊! WHY?
測試 9 : 小蜜蜂
from machine import Pin,PWM
import time
C0=18
CS0=17
D0=18
DS0=19
E0=21
F0=22
FS0=23
G0=25
GS0=26
A0=28
AS0=29
B0=31
C1=33
CS1=35
D1=37
DS1=39
B0=31
C1=33
CS1=35
D1=37
DS1=39
E1=41
F1=44
FS1=46
G1=49
GS1=52
A1=55
AS1=58
B1=62
C2=65
CS2=69
D2=73
DS2=78
E2=82
F2=87
FS2=93
G2=98
GS2=104
A2=110
AS2=117
B2=123
C3=131
CS3=139
D3=147
DS3=156
E3=165
F3=175
FS3=185
G3=196
GS3=208
A3=220
AS3=233
B3=247
C4=262
CS4=277
D4=294
DS4=311
E4=330
F4=349
FS4=370
G4=392
GS4=415
A4=440
AS4=466
B4=494
C5=523
CS5=554
D5=587
DS5=622
E5=659
F5=698
FS5=740
G5=784
GS5=831
A5=880
AS5=932
B5=988
note=(G5, E5, E5, 0, F5, D5, D5, 0, C5, D5, E5, F5, G5, G5, G5, 0,
G5, E5, E5, 0, F5, D5, D5, 0, C5, E5, G5, G5, E5, 0, 0, 0,
D5, D5, D5, D5, D5, E5, F5, 0, E5, E5, E5, E5, E5, F5, G5, 0,
G5, E5, E5, 0, F5, D5, D5, 0, C5, E5, G5, G5, C5, 0, 0, 0)
duration=(4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4)
def tone(pwm,note,duration):
pwm.freq(note)
pwm.duty(512)
time.sleep_ms(duration)
pwm.deinit()
def littleBee(pwm):
for i in range(0,len(note)):
d=int(1000/duration[i])
tone(pwm, note[i], d)
p=int(d*1.3)
time.sleep_ms(p)
time.sleep(2)
pwm=PWM(Pin(4))
while True:
littleBee(pwm)
很奇怪, 還是會掉好幾個音, 不知哪裡有問題, 有空再研究.
參考 :
# ESP8266 first project: home automation with relays, switches, PWM, and an ADC (Good)
pwm2.freq(300) #設定 PWM 物件之頻率
pwm2.duty(512) #設定 PWM 物件之工作週期
其中 freq() 與 duty() 若未傳入參數則為 getter, 即讀取最近之設定值. 若要停止 PWM 功能, 則呼叫 deinit() 方法即可, 相當於 Arduino 的 noTone() 函數功能. PWM 物件之方法表列如下 :
PWM 方法 | 說明 |
freq([Hz]) | 傳入 0~1000 設定方波頻率, 否則為讀取 |
duty([cycle]) | 傳入 0~1023 設定 Duty cycle (512 為 50%), 否則為讀取 |
deinit() | 關閉 PWM 功能 |
參考官網文件 :
# PWM (pulse width modulation)
注意, ESP8266 的 GPIO 中, 只有 GPIO 16 (即 D1 Mini 的 D0) 不具 PWM 功能 :
"PWM can be enabled on all pins except Pin(16). There is a single frequency for all channels, with range between 1 and 1000 (measured in Hz). The duty cycle is between 0 and 1023 inclusive."
如果傳入 Pin(16) 給 PWM() 建構式無法建立 PWM 物件 :
>>> pwm=PWM(Pin(16))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: PWM not supported on pin 16
接下來我想複製 Arduino 聲音測試的範例, 改編為 MicroPython on ESP8266 版. 首先是讓蜂鳴器發出 1KHz 的 Bee Bee 聲, 硬體接線上只要將無源蜂鳴器的 + 端接在 D1 Mini 的 D2 腳 (GPIO 4), 另一端接地即可 (無源蜂鳴器是有極性的). 雖然蜂鳴器上有標示 5V 規格, 其實 3.3V 也是可以用的.
測試 1 : 使蜂鳴器發出 1KHz 的 Bee Bee 告警聲
#main.py or myapp.py
from machine import Pin,PWM
import time
def alarmBeep(pwm):
pwm.freq(1000) #設定頻率為 1KHz
pwm.duty(512) #設定工作週期為 50%
time.sleep(1) #持續時間 1 秒
pwm.deinit() #停止發聲
time.sleep(2) #持續時間 2 秒
pwm=PWM(Pin(4))
while True:
alarmBeep(pwm)
上面的程式裡, 我將發聲的程式碼寫成一個函數 alarmBeep(), 只要在無窮迴圈中呼叫此函數, 並將 PWM 物件傳給它即可.
測試 2 : 模擬鬧鐘鈴聲
from machine import Pin,PWM
import time
def alarmClockBeep(pwm):
for i in range(1,5): #4 次迴圈 (1~4)
pwm.freq(1000) #設定頻率為 1KHz
pwm.duty(512) #設定工作週期為 50%
time.sleep_ms(100) #持續時間 0.1 秒
pwm.deinit() #停止發聲
time.sleep_ms(200) #持續時間 0.2 秒
time.sleep_ms(800)
pwm=PWM(Pin(4))
while True:
alarmClockBeep(pwm)
這裡要注意的是 range(a, b) 是傳回 a ~ b-1 的整數, 所以 4 次迴圈需用 range(1, 5).
測試 3 : 模擬電話鈴聲
from machine import Pin,PWM
import time
def ringTone(pwm):
for i in range(1,11): #10 次迴圈 (1~10)
pwm.freq(1000) #設定頻率為 1KHz
pwm.duty(512) #設定工作週期為 50%
time.sleep_ms(50) #持續時間 50 毫秒
pwm.freq(500) #設定頻率為 500Hz
time.sleep_ms(50) #持續時間 50 毫秒
pwm.deinit() #停止發聲
time.sleep(2) #持續時間 2 秒
pwm=PWM(Pin(4))
while True:
ringTone(pwm)
這電話聲模擬得還真像.
測試 4 : 模擬警車鈴聲
from machine import Pin,PWM
import time
def policeSiren(pwm):
for i in range(150,1800):
pwm.freq(i)
pwm.duty(512)
time.sleep_ms(10)
pwm.deinit()
time.sleep_ms(1)
for i in range(1800,150):
pwm.freq(i)
pwm.duty(512)
time.sleep_ms(10)
pwm.deinit()
time.sleep_ms(1)
pwm=PWM(Pin(4))
while True:
policeSiren(pwm)
有點怪怪的, 原因是 ESP8266 GPIO PWM 的最高頻率只到 1000 Hz 而已, 而這程式卻要用到 1800 Hz.
測試 5 : 救護車的歐伊歐伊
from machine import Pin,PWM
import time
def ambulenceSiren(pwm):
pwm.freq(400)
pwm.duty(512)
time.sleep_ms(500)
pwm.freq(800)
time.sleep_ms(500)
pwm.deinit()
pwm=PWM(Pin(4))
while True:
ambulenceSiren(pwm)
接下來要演奏馬力歐一個小節, 各音符對應的頻率參考 :
# Arduino 的聲音測試 (一)
測試 6 : 馬力歐 (1)
from machine import Pin,PWM
import time
def mario(pwm):
pwm.freq(659) #E5
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep_ms(150)
pwm.freq(659) #E5
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep_ms(150)
pwm.freq(659) #E5
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep_ms(150)
time.sleep_ms(150)
pwm.freq(523) #C5
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep_ms(150)
pwm.freq(659) #E5
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep_ms(150)
time.sleep_ms(150)
pwm.freq(784) #G5
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep(3)
pwm=PWM(Pin(4))
while True:
mario(pwm)
注意, 只要呼叫過 deinit() 方法, 頻率與工作週期都會被清掉, 下一個音要再呼叫 freq() 與 duty() 重新設定. 直接使用頻率似乎非常亂, 應該使用音名來代表頻率數字, 但由於 Python 沒有像 C 語言那樣可用 define 定義常數, 只好用變數, 上面的程式可以改寫如下 :
測試 7 : 馬力歐 (2)
from machine import Pin,PWM
import time
E5=659
C5=523
G5=784
def mario(pwm):
pwm.freq(E5)
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep_ms(150)
pwm.freq(E5)
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep_ms(150)
pwm.freq(E5)
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep_ms(150)
time.sleep_ms(150)
pwm.freq(C5)
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep_ms(150)
pwm.freq(E5)
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep_ms(150)
time.sleep_ms(150)
pwm.freq(G5)
pwm.duty(512)
time.sleep_ms(150)
pwm.deinit()
time.sleep(3)
pwm=PWM(Pin(4))
while True:
mario(pwm)
上面的 mario() 有點長, 因為重複的部分很多, 可以模仿 Arduino 的 tone() 函數來精簡如下 :
測試 8 : 馬力歐 (3)
from machine import Pin,PWM
import time
E5=659
C5=523
G5=784
def tone(pwm,note,duration):
pwm.freq(note)
pwm.duty(512)
time.sleep_ms(duration)
pwm.deinit()
def mario(pwm):
tone(pwm,E5,150)
time.sleep_ms(150)
tone(pwm,E5,150)
time.sleep_ms(150)
tone(pwm,E5,150)
time.sleep_ms(150)
time.sleep_ms(150)
tone(pwm,C5,150)
time.sleep_ms(150)
tone(pwm,E5,150)
time.sleep_ms(150)
time.sleep_ms(150)
tone(pwm,G5,150)
time.sleep_ms(150)
time.sleep(3)
pwm=PWM(Pin(4))
while True:
mario(pwm)
上面我定義了一個 tone() 函數來模擬 Arduino 的 tone(), 這樣就能跟 Arduino 的程式一一對應了. 由於 ESP8266 的 GPIO 最高只能調變到 1000 Hz, C6 (1046 Hz) 以上的音名無法發出來, 所以要用 ESP8266 的 PWM 演奏音樂受到限制.
下列範例改編自 Arduino 的測試 9 :
測試 9 : Melody
from machine import Pin,PWM
import time
C0=18
CS0=17
D0=18
DS0=19
E0=21
F0=22
FS0=23
G0=25
GS0=26
A0=28
AS0=29
B0=31
C1=33
CS1=35
D1=37
DS1=39
B0=31
C1=33
CS1=35
D1=37
DS1=39
E1=41
F1=44
FS1=46
G1=49
GS1=52
A1=55
AS1=58
B1=62
C2=65
CS2=69
D2=73
DS2=78
E2=82
F2=87
FS2=93
G2=98
GS2=104
A2=110
AS2=117
B2=123
C3=131
CS3=139
D3=147
DS3=156
E3=165
F3=175
FS3=185
G3=196
GS3=208
A3=220
AS3=233
B3=247
C4=262
CS4=277
D4=294
DS4=311
E4=330
F4=349
FS4=370
G4=392
GS4=415
A4=440
AS4=466
B4=494
C5=523
CS5=554
D5=587
DS5=622
E5=659
F5=698
FS5=740
G5=784
GS5=831
A5=880
AS5=932
B5=988
note=(C4, G3, G3, A3, G3, 0, B3, C4)
duration=(4, 8, 8, 4, 4, 4, 4, 4)
def tone(pwm,note,duration):
pwm.freq(note)
pwm.duty(512)
time.sleep_ms(duration)
pwm.deinit()
def melody(pwm):
for i in range(0,8):
d=int(1000/duration[i])
tone(pwm, note[i], d)
p=int(d*1.3)
time.sleep_ms(p)
time.sleep(2)
pwm=PWM(Pin(4))
while True:
melody(pwm)
但是我測試結果發現倒數第二個音 B3 卻沒發出來, 反覆檢查程式沒錯啊! WHY?
測試 9 : 小蜜蜂
from machine import Pin,PWM
import time
C0=18
CS0=17
D0=18
DS0=19
E0=21
F0=22
FS0=23
G0=25
GS0=26
A0=28
AS0=29
B0=31
C1=33
CS1=35
D1=37
DS1=39
B0=31
C1=33
CS1=35
D1=37
DS1=39
E1=41
F1=44
FS1=46
G1=49
GS1=52
A1=55
AS1=58
B1=62
C2=65
CS2=69
D2=73
DS2=78
E2=82
F2=87
FS2=93
G2=98
GS2=104
A2=110
AS2=117
B2=123
C3=131
CS3=139
D3=147
DS3=156
E3=165
F3=175
FS3=185
G3=196
GS3=208
A3=220
AS3=233
B3=247
C4=262
CS4=277
D4=294
DS4=311
E4=330
F4=349
FS4=370
G4=392
GS4=415
A4=440
AS4=466
B4=494
C5=523
CS5=554
D5=587
DS5=622
E5=659
F5=698
FS5=740
G5=784
GS5=831
A5=880
AS5=932
B5=988
note=(G5, E5, E5, 0, F5, D5, D5, 0, C5, D5, E5, F5, G5, G5, G5, 0,
G5, E5, E5, 0, F5, D5, D5, 0, C5, E5, G5, G5, E5, 0, 0, 0,
D5, D5, D5, D5, D5, E5, F5, 0, E5, E5, E5, E5, E5, F5, G5, 0,
G5, E5, E5, 0, F5, D5, D5, 0, C5, E5, G5, G5, C5, 0, 0, 0)
duration=(4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4)
def tone(pwm,note,duration):
pwm.freq(note)
pwm.duty(512)
time.sleep_ms(duration)
pwm.deinit()
def littleBee(pwm):
for i in range(0,len(note)):
d=int(1000/duration[i])
tone(pwm, note[i], d)
p=int(d*1.3)
time.sleep_ms(p)
time.sleep(2)
pwm=PWM(Pin(4))
while True:
littleBee(pwm)
很奇怪, 還是會掉好幾個音, 不知哪裡有問題, 有空再研究.
參考 :
# ESP8266 first project: home automation with relays, switches, PWM, and an ADC (Good)
沒有留言:
張貼留言