30個物聯網傳感器小實驗4:蜂鳴器播放星球大戰

無源蜂鳴器

  • 用途:

無源蜂鳴器用於釋放報警音

  • 代碼:
from gpiozero import Buzzer
import time
bz = Buzzer(2)

while True :
    bz.on()
    time.sleep(0.0005)
    bz.off()
    time.sleep(0.0005)
  • 效果:

將蜂鳴器正極接GPIO2號口,負極接GND地線,運行上述代碼,可以聽到急促的報警音。

有源蜂鳴器:播放MIDI音樂

  • 用途:

有源蜂鳴器可播放簡單的音調,比如MIDI音樂,像我們小時候經常玩的生日賀卡,裏面的生日快樂歌就是用有源蜂鳴器播放的。

  • 代碼:
from gpiozero import TonalBuzzer
from gpiozero.tones import Tone
import time
b = TonalBuzzer(2)
i=220
while True:
    i=i+20
    b.play(i)
    time.sleep(1)
  • 效果:

將蜂鳴器正極接GPIO2號口,負極接GND地線,運行上述代碼,運行上述代碼可以聽到音調逐漸升高。

  • 拓展:

當然,TonalBuzzer這個類可以播放音調的格式還有很多,比如下列音調的格式都是支持的:

>>> from gpiozero import TonalBuzzer
>>> from gpiozero.tones import Tone
>>> b = TonalBuzzer(17)
>>> b.play(Tone("A4"))
>>> b.play(Tone(220.0)) # Hz
>>> b.play(Tone(60)) # middle C in MIDI notation
>>> b.play("A4")
>>> b.play(220.0)
>>> b.play(60)

蜂鳴器播放星球大戰

  • 源碼

在網上找到了星球大戰主題曲的源碼,不幸的是用c寫的,不過也可以很輕鬆的看懂原理,我們來“品嚐”一下。

#include <wiringPi.h>
#include <stdio.h>

//Pin 11 on Raspberry Pi corresponds to BCM GPIO 17 and wiringPi pin 0 
//正極接GPIO17號口
#define BeepPin 8

//FREQUENCIES
//定義頻率
#define cL 129
#define cLS 139
#define dL 146
#define dLS 156
#define eL 163
...
...
//This function generates the square wave that makes the piezo speaker sound at a determinated frequency.
//生成特定頻率的聲音
void beep(unsigned int note, unsigned int duration)
{
  //This is the semiperiod of each note.
  long beepDelay = (long)(1000000/note);
  //This is how much time we need to spend on the note.
  long time = (long)((duration*1000)/(beepDelay*2));
  for (int i=0;i<time;i++)
  {
    //1st semiperiod
    digitalWrite(BeepPin, HIGH);
    delayMicroseconds(beepDelay);
    //2nd semiperiod
    digitalWrite(BeepPin, LOW);
    delayMicroseconds(beepDelay);
  }

  //Add a little delay to separate the single notes
  digitalWrite(BeepPin, LOW);
  delay(20);
}

//The source code of the Imperial March from Star Wars
//星球大戰主題曲音調鳴叫時長
void play()
{
  beep( a, 500);
  beep( a, 500);
  beep( f, 350);
  beep( cH, 150);
  ...
  ...

}

//開始播放
int main(void)
{
  //Check wiringPi setup
  if(-1 == wiringPiSetup())
  {
    printf("setup wiringPi failed!");
    return 1;
  }

  //Prepare GPIO0
  pinMode(BeepPin, OUTPUT);
  //Play the Imperial March
  play();

  return 0;
}
  • 編譯c源碼

編譯上述c源碼需要預先安裝好wiringpi這個庫,這裏推薦大家使用完整版的Raspbian,也就是官網上Raspbian Stretch with desktop and recommended software的版本,這樣的話這個庫已經是預置的。

編譯的命令如下:

$ gcc starwars.c -o starwars -lwiringPi -std=c99

編譯完成後,會生成一個starwar的可執行文件:

$ file starwars 
starwars: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=8789b91feaa4e5da5f942f1833c8c765347abeee, not stripped

然後直接執行這個可執行文件即可:

$ ./starwars

即可聽到星球大戰的主題曲。

上述源碼的完整版本請見:https://github.com/asukafight...

激光傳感器

最後再來介紹一個不相干的,激光傳感器。
小時候也經常玩這個,用這個來逗貓或者逗狗。

點亮激光傳感器的代碼跟之前的LED是一模一樣的,支持閃爍、淡入淡出等效果,在這裏不做贅述。

好了,本次介紹就到這裏,本文收錄在我的《手把手教你玩樹莓派》系列教程,立足於普及樹莓派搭配人工智能、物聯網和機器人的玩法,想要跟我一起學習的童鞋可以加我微信/微博ID:asukafighting,也可以直接看教程:https://github.com/asukafight...

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章