如果您對(duì)秘密信息感興趣,那么對(duì)您來(lái)說(shuō)摩爾斯電碼將會(huì)是一種有趣的交流方式。然而,摩爾斯電碼的特性使其非常適合于通過(guò)Arduino來(lái)編寫和生成消息。在本指南中,我們將向您展示如何創(chuàng)建一種可以將您輸入的文本自動(dòng)轉(zhuǎn)換為可聽(tīng)的摩爾斯電碼信息的設(shè)備。
摩爾斯電碼工作原理
摩爾斯電碼發(fā)明于19世紀(jì),使用非常簡(jiǎn)單的長(zhǎng)短脈沖序列(通常為電和劃)來(lái)遠(yuǎn)距離發(fā)送消息。通過(guò)將字母表中的字母編碼為電和劃的組合,信息可以只用一個(gè)單一的電子或聲音信號(hào)來(lái)表達(dá)。
為了說(shuō)明這是如何工作的,我們將使用一個(gè)簡(jiǎn)單的蜂鳴器將文本轉(zhuǎn)換為可聽(tīng)的摩爾斯電碼信號(hào)。通過(guò)使用Arduino IDE中的串行監(jiān)視器,您在計(jì)算機(jī)上輸入的信息可以被轉(zhuǎn)換為摩爾斯電碼音調(diào)。值得注意的是,只需要進(jìn)行少量修改,同樣的方法就可以用于通過(guò)LED傳達(dá)信息,因?yàn)檫@兩種設(shè)備都可以被快速打開(kāi)和關(guān)閉。
所需組件
在硬件方面,您不需要太多組件來(lái)完成該項(xiàng)目工作。但是,如果您是編碼新手,那么您可能會(huì)希望能夠分塊進(jìn)行該項(xiàng)目。這不是很復(fù)雜的代碼,但是您需要了解數(shù)組 和 switch cases 語(yǔ)句的工作原理。請(qǐng)記住要點(diǎn),然后進(jìn)行接下來(lái)的工作。
您需要的物理組件如下所示:
Arduino Uno | |
一個(gè)面包板 | |
Arduino IDE | |
一個(gè)蜂鳴器 |
您還需要一些標(biāo)準(zhǔn)電線。
大多數(shù)入門電子套件都帶有我們上面列出的所有部件,所以如果您有一個(gè)套件,請(qǐng)?jiān)陂_(kāi)始這個(gè)項(xiàng)目前查看是否具有這些組件。
接線
這個(gè)項(xiàng)目的接線十分簡(jiǎn)單。本項(xiàng)目中所具有的功能大部分都通過(guò)代碼來(lái)實(shí)現(xiàn),所以我們不用將接線考慮在內(nèi)。在接線部分,請(qǐng)將蜂鳴器的電源線連接到引腳8,然后將蜂鳴器的地線連接到GND。
這樣就完成了!這很簡(jiǎn)單。現(xiàn)在,讓我們繼續(xù)進(jìn)行代碼部分。
代碼
這個(gè)項(xiàng)目的代碼可能比您以往看到的要長(zhǎng),主要是因?yàn)樾枰獙?duì)摩爾斯電碼脈沖進(jìn)行編碼。不過(guò)不要太擔(dān)心。一旦您把它分解開(kāi)來(lái),就會(huì)發(fā)現(xiàn)各部分都是很基礎(chǔ)的代碼。首先,以下是您可以直接上傳到Arduino的完整代碼。
int buzzer = 8; // Assign buzzer to pin 8
int note = 1000; // Set the pitch for the buzzer tone
int timeUnit = 100; // This variable will be used to measure dots, dashes, breaks, and pauses
char input; // Variable to save the input to
void setup () {
Serial.begin(9600);//for the connect with the boared
}
void loop () {
if (Serial.available()) {
input = Serial.read();//read the input
if (input == ‘a(chǎn)’ || input == ‘A’) {lA();}//if the input is a or A go to function lA
if (input == ‘b’ || input == ‘B’) {lB();}//same but with b letter
if (input == ‘c’ || input == ‘C’) {lC();}
if (input == ‘d’ || input == ‘D’) {lD();}
if (input == ‘e’ || input == ‘E’) {lE();}
if (input == ‘f’ || input == ‘F’) {lF();}
if (input == ‘g’ || input == ‘G’) {lG();}
if (input == ‘h’ || input == ‘H’) {lH();}
if (input == ‘i’ || input == ‘I’) {lI();}
if (input == ‘j’ || input == ‘J’) {lJ();}
if (input == ‘k’ || input == ‘K’) {lK();}
if (input == ‘l’ || input == ‘L’) {lL();}
if (input == ‘m’ || input == ‘M’) {lM();}
if (input == ‘n’ || input == ‘N’) {lN();}
if (input == ‘o’ || input == ‘O’) {lO();}
if (input == ‘p’ || input == ‘P’) {lP();}
if (input == ‘q’ || input == ‘Q’) {lQ();}
if (input == ‘r’ || input == ‘R’) {lR();}
if (input == ‘s’ || input == ‘S’) {lS();}
if (input == ‘t’ || input == ‘T’) {lT();}
if (input == ‘u’ || input == ‘U’) {lU();}
if (input == ‘v’ || input == ‘V’) {lV();}
if (input == ‘w’ || input == ‘W’) {lW();}
if (input == ‘x’ || input == ‘X’) {lX();}
if (input == ‘y’ || input == ‘Y’) {lY();}
if (input == ‘z’ || input == ‘Z’) {lZ();}
if (input == ‘ ‘) {wordPause();}
Serial.println (input);
}
}
//Letter functions
void lA () {dot();dash();letterPause();}//letter A in morse code!
void lB () {dash();dot();dot();dot();letterPause();}//same for B
void lC () {dash();dot();dash();dot();letterPause();}
void lD () {dash();dot();dot();letterPause();}
void lE () {dot();letterPause();}
void lF () {dot();dot();dash();dot();letterPause();}
void lG () {dash();dash();dot();letterPause();}
void lH () {dot();dot();dot();dot();letterPause();}
void lI () {dot();dot();letterPause();}
void lJ () {dot();dash();dash();dash();letterPause();}
void lK () {dash();dot();dash();letterPause();}
void lL () {dot();dash();dot();dot();letterPause();}
void lM () {dash();dash();letterPause();}
void lN () {dash();dot();letterPause();}
void lO () {dash();dash();dash();letterPause();}
void lP () {dot();dash();dash();dot();letterPause();}
void lQ () {dash();dash();dot();dash();letterPause();}
void lR () {dot();dash();dot();letterPause();}
void lS () {dot();dot();dot();letterPause();}
void lT () {dash();letterPause();}
void lU () {dot();dot();dash();letterPause();}
void lV () {dot();dot();dot();dash();letterPause();}
void lW () {dot();dash();dash();letterPause();}
void lX () {dash();dot();dot();dash();letterPause();}
void lY () {dash();dot();dash();dash();letterPause();}
void lZ () {dash();dash();dot();dot();letterPause();}
void dot() //Emit sound for 100 milliseconds
{
tone(buzzer, note, timeUnit);
delay(timeUnit * 2);
}
void dash() //Emit sound for 300 milliseconds
{
tone(buzzer, note, timeUnit * 3);
delay(timeUnit * 4);
}
void letterPause() //Delay between letters for 300 milliseconds
{
delay(timeUnit * 3);
}
void wordPause()
{
delay (timeUnit * 7);
}
現(xiàn)在,我們來(lái)了解一下這段代碼的重要部分,從一些基本設(shè)置開(kāi)始。
int buzzer = 8; // Assign buzzer to pin 8
int note = 1000; // Set the pitch for the buzzer tone
int timeUnit = 100; // This variable will be used to measure dots, dashes, breaks, and pauses
char input; // Variable to save the input to
void setup () {
Serial.begin(9600);//for the connect with the boared
}
在這一部分中,我們將初始化引腳8上的蜂鳴器,并確定蜂鳴器發(fā)出的音調(diào)所對(duì)應(yīng)的音符變量。接下來(lái),我們給代表持續(xù)時(shí)間的變量timeUnit賦值100毫秒,這將用于確定所有信息的持續(xù)時(shí)間。例如,一個(gè)點(diǎn)是一個(gè)時(shí)間單位,而一個(gè)劃是三個(gè)時(shí)間單位。我們還將使用它來(lái)設(shè)置一個(gè)字母中符號(hào)之間的時(shí)間間隔(一個(gè)單位)、兩個(gè)字母之間的時(shí)間間隔(三個(gè)單位)和兩個(gè)單詞之間的時(shí)間間隔(七個(gè)單位)。
在setup()部分,我們還將初始化串行監(jiān)視器,這樣的話您就可以輸入要發(fā)送到Arduino的信息了。這要求您的項(xiàng)目需要通過(guò)USB保持與計(jì)算機(jī)之間的連接。
void loop () {
if (Serial.available()) {
input = Serial.read();//read the input
if (input == ‘a(chǎn)’ || input == ‘A’) {lA();}//if the input is a or A go to function lA
if (input == ‘b’ || input == ‘B’) {lB();}//same but with b letter
if (input == ‘c’ || input == ‘C’) {lC();}
if (input == ‘d’ || input == ‘D’) {lD();}
if (input == ‘e’ || input == ‘E’) {lE();}
if (input == ‘f’ || input == ‘F’) {lF();}
if (input == ‘g’ || input == ‘G’) {lG();}
if (input == ‘h’ || input == ‘H’) {lH();}
if (input == ‘i’ || input == ‘I’) {lI();}
if (input == ‘j’ || input == ‘J’) {lJ();}
if (input == ‘k’ || input == ‘K’) {lK();}
if (input == ‘l’ || input == ‘L’) {lL();}
if (input == ‘m’ || input == ‘M’) {lM();}
if (input == ‘n’ || input == ‘N’) {lN();}
if (input == ‘o’ || input == ‘O’) {lO();}
if (input == ‘p’ || input == ‘P’) {lP();}
if (input == ‘q’ || input == ‘Q’) {lQ();}
if (input == ‘r’ || input == ‘R’) {lR();}
if (input == ‘s’ || input == ‘S’) {lS();}
if (input == ‘t’ || input == ‘T’) {lT();}
if (input == ‘u’ || input == ‘U’) {lU();}
if (input == ‘v’ || input == ‘V’) {lV();}
if (input == ‘w’ || input == ‘W’) {lW();}
if (input == ‘x’ || input == ‘X’) {lX();}
if (input == ‘y’ || input == ‘Y’) {lY();}
if (input == ‘z’ || input == ‘Z’) {lZ();}
if (input == ‘ ‘) {wordPause();}//the space
Serial.println (input);//print the latter saved in the input var
}
}
在這部分代碼中,我們將依次讀取進(jìn)入串行監(jiān)視器的字母,并立即運(yùn)行下面相應(yīng)的函數(shù)。每行用來(lái)確定輸入字母的大小寫版本(摩爾斯電碼中沒(méi)有大小寫區(qū)分),或者行中是否有空格。根據(jù)收到的字母信息,代碼將調(diào)用對(duì)應(yīng)該字母的函數(shù)。
//Letter functions
void lA () {dot();dash();letterPause();}//letter A in morse code!
void lB () {dash();dot();dot();dot();letterPause();}//same for B
void lC () {dash();dot();dash();dot();letterPause();}
void lD () {dash();dot();dot();letterPause();}
void lE () {dot();letterPause();}
void lF () {dot();dot();dash();dot();letterPause();}
void lG () {dash();dash();dot();letterPause();}
void lH () {dot();dot();dot();dot();letterPause();}
void lI () {dot();dot();letterPause();}
void lJ () {dot();dash();dash();dash();letterPause();}
void lK () {dash();dot();dash();letterPause();}
void lL () {dot();dash();dot();dot();letterPause();}
void lM () {dash();dash();letterPause();}
void lN () {dash();dot();letterPause();}
void lO () {dash();dash();dash();letterPause();}
void lP () {dot();dash();dash();dot();letterPause();}
void lQ () {dash();dash();dot();dash();letterPause();}
void lR () {dot();dash();dot();letterPause();}
void lS () {dot();dot();dot();letterPause();}
void lT () {dash();letterPause();}
void lU () {dot();dot();dash();letterPause();}
void lV () {dot();dot();dot();dash();letterPause();}
void lW () {dot();dash();dash();letterPause();}
void lX () {dash();dot();dot();dash();letterPause();}
void lY () {dash();dot();dash();dash();letterPause();}
void lZ () {dash();dash();dot();dot();letterPause();}
在main loop()之外的部分,我們將為每個(gè)字母定義函數(shù)。在這一部分中,我們需要根據(jù)國(guó)際摩爾斯電碼標(biāo)準(zhǔn)為每個(gè)字母添加模板。為簡(jiǎn)單起見(jiàn),我們將使用dot()、dash()和letterPause()函數(shù)來(lái)創(chuàng)建模板,并在稍后定義這些函數(shù)的作用。每個(gè)命令用分號(hào)分隔開(kāi)即可,但是為了使代碼更清楚,我們將每個(gè)函數(shù)單獨(dú)放到一行中。
void dot() //Emit sound for 100 milliseconds
{
tone(buzzer, note, timeUnit);
delay(timeUnit * 2);
}
void dash() //Emit sound for 300 milliseconds
{
tone(buzzer, note, timeUnit * 3);
delay(timeUnit * 4);
}
void letterPause() //Delay between letters for 300 milliseconds
{
delay(timeUnit * 3);
}
void wordPause()
{
delay (timeUnit * 7);
}
接下來(lái),我們將定義在上一部分中使用的函數(shù)。首先,dot()用于播放我們?cè)谧钌厦娲a中所指定的聲音一個(gè)時(shí)間單位。雖然tone()命令可以播放一個(gè)時(shí)間單位的聲音,但是如果過(guò)早在此調(diào)用該函數(shù),可能會(huì)發(fā)生搶占,因此我們將添加一個(gè)delay()命令,以防止草圖在兩個(gè)時(shí)間單位內(nèi)移動(dòng)到下一行代碼。為什么是兩個(gè)時(shí)間單位?因?yàn)槿绱艘粊?lái),tone()可以在第一個(gè)時(shí)間單位完成命令的運(yùn)行,然后將第二個(gè)時(shí)間單位作為元素之間的暫停。
例如,對(duì)于由一個(gè)點(diǎn)組成的字母“E”,您應(yīng)該聽(tīng)到100毫秒的蜂鳴聲,然后靜音100毫秒。對(duì)于由三個(gè)點(diǎn)組成的字母“S”,您會(huì)聽(tīng)到蜂鳴,靜音,蜂鳴,靜音,蜂鳴,靜音,每個(gè)持續(xù)100毫秒。
我們?cè)赿ash()命令中做了類似的工作,但這次我們將播放三個(gè)時(shí)間單位(300毫秒)的聲音,然后暫停運(yùn)行四個(gè)時(shí)間單位。三個(gè)單位讓聲音完成播放,第四個(gè)時(shí)間單位用于元素之間的暫停。
我們還將定義letterPause() 和wordPause()函數(shù)。前者完全由三個(gè)時(shí)間單位延遲組成,它用于在消息的每個(gè)字母之間設(shè)置300毫秒靜音,讓您可以將不同的字母區(qū)分開(kāi)來(lái)。后者是最長(zhǎng)的延遲時(shí)間,七個(gè)時(shí)間單位,或者700毫秒。這將在監(jiān)視器讀取到一個(gè)空格時(shí)運(yùn)行,表明一個(gè)新單詞的開(kāi)始。
當(dāng)您的草圖上傳完成并且開(kāi)始運(yùn)行Arduino,請(qǐng)?jiān)谀腎DE的工具部分打開(kāi)串行監(jiān)視器。輸入一些單詞并按下回車鍵,您應(yīng)該會(huì)聽(tīng)到蜂鳴器發(fā)出相應(yīng)的摩爾斯電碼音調(diào)。如果您想自己調(diào)整草圖,可以嘗試添加描述數(shù)字的函數(shù)。
DevicePlus 編輯團(tuán)隊(duì)
設(shè)備升級(jí)版適用于所有熱愛(ài)電子和機(jī)電一體化的人。
審核編輯黃宇
評(píng)論