零基础入门学用Arduino-基础知识篇 - YouTube
本篇學習完畢,接下來進入零基础入门学用Arduino-MeArm机械臂篇 - YouTube
重點記錄:
2022.02.09
- 全部成本大概台幣兩百元,裝在犀牛盾保護殻的包裝外盒實在有點醜,隨手弄了個封面:
2022.02.08
- 今天要 Flash ◄A08► 基於ESP8266(或8255) NodeMcu Lua WIFI 開發板 CP2102 | 蝦皮購物 的 Firmware 才發現它無法連接的原因,原來是這個小轉接頭的關係,把 USB 延長線直接插在 Mac mini 的 USB 上,與 Arduino IDE 的連接沒問題,於是把時鐘換上它,程式上傳後執行也無誤,就用熱熔膠把插線接頭處固定,然後裝在犀牛盾保護殻的包裝外盒裡,留下來做記念。
2022.02.07
- 麵包板及另購的◄A08► 基於ESP8266(或8255) NodeMcu Lua WIFI 開發板 CP2102 | 蝦皮購物到貨,才發現與早些時候買的 NodeMcu Lua WIFI 開發板 基於 ESP8266 wifi模組 無線開發 物聯網 無線傳輸 無線模組 | 蝦皮購物 是不一樣的,後者較寬,插上麵包板後無法引腳出來,前者較窄,才能上下各留一排插孔能夠插線:
- 結果 NodeMcu Lua WIFI 開發板 CP2102 (上圖右較窄的那塊)在 Arduino IDE 無法連接:
- 即使去下載了 Driver :CP210x USB to UART Bridge VCP Drivers - Silicon Labs 安裝後仍無法連接,進一步 Google 後,從這篇文章:NodeMCU/ESP8266 - Getting Started with Arduino IDE on macOS | by basspj | Medium 大概還需要 flash firmware 才能使用(等以後有需要時再來處理),只好改使用 V3.0 的另一塊較寬版,但無法插在麵包板上,因此以 F-M 杜邦線直接連 ESP8266 的接腳。
- 先叫出 Arduino IDE 裡 ESP8266 的 NTPClient 範例來了解如何改寫程式碼,有點複雜,Complier 都過不了,於是上網查,沒想到查到這篇文章:Getting Date & Time From NTP Server With ESP8266 NodeMCU ,不用了解 NTP 的原理,在 Arduino IDE 裡再多加個 NTP Client Library,把文章裡的範例拷貝過來,簡單修改一下就完成時鐘程式—很準確的時鐘(還有個不完善的地方就是沒有隨著秒跳動的 ":"),因為能夠透過 WI-FI 連上 NTP 伺服器即時校正時間:
- 程式碼:
#include <NTPClient.h> #include <ESP8266WiFi.h> #include <WiFiUdp.h> const char *ssid = "YOUR_SSID";//此處改為家裡基地台的 SSID const char *password = "YOUR_PASS";//輸入登入基地台的密碼 const long utcOffsetInSeconds = 28800;//台灣在 UTC+08:00 時區,所以 8*60*60 = 28800 char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; // Define NTP Client to get time WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds); // 以上是從範例程式拷貝過來的程式碼 const int dataPin = D5; // Arduino 原先 12 腳位對應 74HC595 pin 8 DS // 以shiftOut(dataPin,clockPin,MSBFIRST,Val) const int clockPin = D6; // Arduino 原先 9 腳位腳位對應 74HC595 pin 10 SHCP // 儲存 8 bits 資料後 const int latchPin = D7; // Arduino 原先 11 腳位腳位對應 74HC595 pin 9 STCP // 給予高電位後把上述資料 Out 到七段顯示器 const int digit0 = D1; // Arduino 原先 7 腳位腳位對應 7-Segment pin D4 // const int digit1 = D2; // Arduino 原先 6 腳位腳位對應 7-Segment pin D3 // 控制要顯示的位數 const int digit2 = D3; // Arduino 原先 5 腳位腳位對應 7-Segment pin D2 // const int digit3 = D4; // Arduino 原先 4 腳位腳位對應 7-Segment pin D1 // //以上因改用 ESP8266 後,腳位名稱也須跟著改變 //以下程式碼與前述所附完全相同,不再附上 ... ... ... . . . . . //簡單修改 void loop() 即完成準確的時鐘程式 void loop() { timeClient.update(); int hourntp = timeClient.getHours(); int minntp = timeClient.getMinutes(); int sensor_value = hourntp * 100 + minntp;//配合之前寫的程式 hourntp * 100 後得到千位及百位 seven_seg(sensor_value); delay(1); }
- 這支影片純欣賞:
- 如果也想做做看,這裡也有作者的教學:
2022.02.04
- 訂的麵包板還未到貨,ESP8266 無法接四位七段顯示器,加上花上不少時間好不容易接好的 74HC595 線路捨不得拆掉,於是把原先接在 Arduino 上的接線改接到擴充板上,將 Arduino 空出來,加上小塊的麵包板,剛好用來把買來的套件其他小配件做個驗貨:
2022.02.03
- 年初三,又下雨了,加上全家物流爆發群聚感染,蝦皮下訂的麵包板因為使用全家取付大概得等好一陣子, ESP8266要接上就再說了(因為電路上使用了 74HC595 可以節省腳位,所以 ESP8266 取代 Arduino 應該是可行的)。只好繼續玩其他的感測器,像是超聲波傳感器。
- 接上 Ultrasonic Sensor Module,只要接腳沒弄錯,函數引用正確,就可以正確顯示:
- 只是問題還是存在,最右邊位數還是最亮,其他三位數為了不閃爍,把 Dtime 設為 1 後變太暗了。起先還懷疑是線路的問題,但把Lesson 28 - 4 Digit 7 Segment Display - YouTube 附的範例上傳後,四個位數的亮度一樣,顯然自己按 Arduino - 4-Digit 7-Segment Display (EN) - YouTube 建立的程式有問題,應該是處理 Multiplexing 的程式結構部份,只得進入寫程式最傷腦的 Debug 模式……
- 檢視之前錄過的影片,接可變電阻那支影片並沒有出現最右邊的數字過亮的情形,而是四個位數都一樣,這意味著按Arduino - 4-Digit 7-Segment Display (EN) - YouTube 建立的程式並沒有問題,有可能就出現在 DHT11 溫濕度模塊、超聲波傳感器於讀取數據時出了問題。
- 總算找出問題所在,不是DHT11 溫濕度模塊、超聲波傳感器讀取數據的問題,而是程式seven_seg()函數的最後加入關掉四個數字的顯示即可:
- 2022.02.03
- 邏輯只要通了,後續大概就沒問題,拿掉可變電阻,換上同樣三隻腳位的 DHT11 溫濕度模塊,程式稍為改一下就能顯示溫度(因為顯示器位數只有四位,所以只叫用溫度的數據):
- 先把光碟所附的 DHT11 函數庫加入 Arduino IDE 裡。
- 叫出 DHT11 範例程式,把這段拷貝到自己的程式裡:
- 四位數的左邊兩位顯示溫度,右邊兩位數則固定顯示℃:
- 由於線路接法排列改變:
- 所以要顯示度,需要點亮 ABFG(如下圖),由上圖的排列得到二進位 1000 0111 ,換算成十六進位為 0X87:
- 需要自行在數字陣列再加入,由於是固定顯示,seven_seg()直接給固定值:
- choose_digit()裡也要加入:
- 由於線路接法排列改變:
- 直接拷貝 DHT11 範例程式是可以顯示出溫度,但是會閃爍地很厲害,花了不少時間才找出原來是 DHT11 的更新頻率為 1 秒 1 次(1Hz),程式碼放在 Void Loop()才會出問題,因此移出,獨立成一個函數,讀取感測器資料返回溫度數據:
- 這樣在 Loop()叫用後,顯示就不會有問題了(至於為何 seven_seg(tempA *100) 還要再乘 100,這是因為只有兩位數的溫度值傳入seven_seg() 函數時要顯示在千、百的位置):
- 其實還是有點閃爍,把原為 5 的 Dtime 改為 1 ,不再閃爍了:
- 不曉得為何最右邊的 C 特別亮?猜測可能是接在這個腳位的電晶體放大率與其他三個不同,又或者接在此腳位的電阻較小?
- 四根接 NPN 電晶體的 5K Ω(原電路圖為 4.7K,電阻稍大,所以比較暗),經量測後都差不多,誤差也不大,應該不是它造成的。
- 四根 NPN 電晶體拔下來以三用電錶量它們的 hFE 放大率,有三根差不多都在 270~280,只有一根為 160 ,將其換掉,改用一顆也是 270~280的,重新開啟,還是一樣!顯然 C 字母特別亮的原因也不是電晶體造成的,或許與整個電路有關,難解決,先不理它了。
- 看了許多遍 Lesson 28 - 4 Digit 7 Segment Display - YouTube 在GitHub 下載回來的原程式,始終無法完全弄懂,又礙於已接好他的線路,只好繼續礸研,特別是 shiftOut(dataPin,clockPin,MSBFIRST,Val) 這個函數,還是得請出 Google,找到這篇:Arduino中shiftOut怎麼用? - 台部落有著詳盡的解說,然後再看到這篇帖文:arduino中shiftOut()函数控制74hc595的的问题! - 求助区 - 极客工坊 - Powered by Discuz! ,突然豁然開朗,程式的思路其實很簡單,再度照著 Arduino - 4-Digit 7-Segment Display (EN) - YouTube 的流程把程式寫出,現在接上可變電阻,就可以把電阻值顯示在四位七段顯示器上,而且線路用的是Lesson 28 - 4 Digit 7 Segment Display - YouTube 改良過的,74HC595 用上了,所以在 Arduino 上用了較少的接腳:
- 程式碼:
const int dataPin = 12; // Arduino 腳位對應 74HC595 pin 8 DS // 以shiftOut(dataPin,clockPin,MSBFIRST,Val) const int clockPin = 9; // Arduino 腳位對應 74HC595 pin 10 SHCP // 儲存 8 bits 資料後 const int latchPin = 11; // Arduino 腳位對應 74HC595 pin 9 STCP // 給予高電位後把上述資料 Out 到七段顯示器 const int digit0 = 7; // Arduino 腳位對應 7-Segment pin D4 // const int digit1 = 6; // Arduino 腳位對應 7-Segment pin D3 // 控制要顯示的位數 const int digit2 = 5; // Arduino 腳位對應 7-Segment pin D2 // const int digit3 = 4; // Arduino 腳位對應 7-Segment pin D1 // byte SW0 = A0; int Dtime = 5; byte Number[]= //儲放數字值的陣列,由於作者重新排列過,電路也跟著配合,因此要沿用他的電路就必須採用。 { 0x5F, // = 0 0x44, // = 1 0x9D, // = 2 0xD5, // = 3 0xC6, // = 4 0xD3, // = 5 0xDB, // = 6 0x45, // = 7 0xDF, // = 8 0xC7, // = 9 0x20, // = Dp 0x00 // blank }; void seven_seg(int TimeVal){ unsigned char n3 = int (TimeVal/1000); unsigned char n2 = int ((TimeVal/100)%10); unsigned char n1 = int ((TimeVal/10)%10); unsigned char n0 = int (TimeVal%10); choose_digit(n3); pick_digit(4); delay(Dtime); choose_digit(n2); pick_digit(3); delay(Dtime); choose_digit(n1); pick_digit(2); delay(Dtime); choose_digit(n0); pick_digit(1); delay(Dtime); } void pick_digit(int digit){ digitalWrite(digit0,LOW); digitalWrite(digit1,LOW); digitalWrite(digit2,LOW); digitalWrite(digit3,LOW); switch(digit){ case 1: digitalWrite(digit0,HIGH); break; case 2: digitalWrite(digit1,HIGH); break; case 3: digitalWrite(digit2,HIGH); break; case 4: digitalWrite(digit3,HIGH); break; } } void choose_digit(char num){ switch(num){ default: digitalWrite(latchPin,LOW); shiftOut(dataPin,clockPin,MSBFIRST,Number[0]); digitalWrite(latchPin,HIGH); break; case 1: digitalWrite(latchPin,LOW); shiftOut(dataPin,clockPin,MSBFIRST,Number[1]); digitalWrite(latchPin,HIGH); break; case 2: digitalWrite(latchPin,LOW); shiftOut(dataPin,clockPin,MSBFIRST,Number[2]); digitalWrite(latchPin,HIGH); break; case 3: digitalWrite(latchPin,LOW); shiftOut(dataPin,clockPin,MSBFIRST,Number[3]); digitalWrite(latchPin,HIGH); break; case 4: digitalWrite(latchPin,LOW); shiftOut(dataPin,clockPin,MSBFIRST,Number[4]); digitalWrite(latchPin,HIGH); break; case 5: digitalWrite(latchPin,LOW); shiftOut(dataPin,clockPin,MSBFIRST,Number[5]); digitalWrite(latchPin,HIGH); break; case 6: digitalWrite(latchPin,LOW); shiftOut(dataPin,clockPin,MSBFIRST,Number[6]); digitalWrite(latchPin,HIGH); break; case 7: digitalWrite(latchPin,LOW); shiftOut(dataPin,clockPin,MSBFIRST,Number[7]); digitalWrite(latchPin,HIGH); break; case 8: digitalWrite(latchPin,LOW); shiftOut(dataPin,clockPin,MSBFIRST,Number[8]); digitalWrite(latchPin,HIGH); break; case 9: digitalWrite(latchPin,LOW); shiftOut(dataPin,clockPin,MSBFIRST,Number[9]); digitalWrite(latchPin,HIGH); break; } } void setup() { pinMode(latchPin,OUTPUT); pinMode(clockPin,OUTPUT); pinMode(dataPin,OUTPUT); pinMode(digit0,OUTPUT); pinMode(digit1,OUTPUT); pinMode(digit2,OUTPUT); pinMode(digit3,OUTPUT); digitalWrite(digit0,LOW); digitalWrite(digit1,LOW); digitalWrite(digit2,LOW); digitalWrite(digit3,LOW); pinMode(SW0, INPUT); digitalWrite(SW0, LOW); } void loop() { int sensor_value = analogRead(SW0); seven_seg(sensor_value); delay(1); }
- 程式總算有了進展,至於要改用 ESP8266,則還欠一片麵包板才能把接腳接出來,已在蝦皮下訂,等貨到後看看能否改寫成上網取得 NTP 時間,換算成所在時區,然後再以四位數字送進上述的函數,每隔 24 小時更新一次 NTP 時間(或許 ESP8266 的函數庫有內建的自動更新函數),如此就能得到一個很準確的時鐘了。
- 依照 Arduino - 4-Digit 7-Segment Display (EN) - YouTube 的流程把程式寫出後,只要傳一個四位數,就可以顯示在七段顯示器上,或許也可以把 DHT11 溫濕度模塊、超聲波傳感器接上來測試。
2022.02.01
- 按照前面的思路,除非重新修改線路,試過了,都行不通,最後只得從Lesson 28 - 4 Digit 7 Segment Display - YouTube 在GitHub 的原程式下載回來改寫。
- 把本為 16 進位計數器小改後成為十進位計數器,突然有個感覺,一堆線路加上一個計數器,不就像電影、電視劇裡壞蛋安放的炸彈一樣(如果改成倒數計數就更像了):
- 把原為 50 ms 的Delay 改為 100 ms,這樣最右邊的位數以 0.1 秒跳動,右邊算過來的第二位就是 1 秒跳動。
- 這樣的小改其實不算什麼,真正難的是很難搞懂原程式這段的寫法:
- 改寫的核心就在這段,需要改成函數,內含一個引數可以接收一個四位數字,然後顯示在七段顯示器上,並計時以每秒更新數字。
- 若能改寫成功,或許,加上 ESP8266 (甚至取代 Arduino Uno),上網取得 NTP 時間,換算成所在時區,然後再以四位數字送進上述的函數,就不需要再弄個設定時間的開關。最後每隔 24 小時更新一次 NTP 時間,如此就能得到一個很準確的時鐘了。
2022.01.30
- YouTube 知道我現在對 74HC595 有興趣,打開後進入首頁,演算法就在首頁幫我找了好幾支相關的影片,其中這支影片:How Shift Registers Work! - YouTube 說明地最清楚詳細。
- 完成麵包板上跳線的部分(接2N2222的 4.7KΩ以 5KΩ代替):
- 全部接線完成,就算再細心的接線,還是有兩個地方接錯,上傳十六進位計數的範例程式,結果中間兩位數不顯示,原先以為是電晶體的問題,這是因為用了兩個 2N2222a及兩個 2N2222,但顯示正常的兩個位數,剛好是分別是 2N2222a及 2N2222,表示不是電晶體的問題。當然也不是換成 5KΩ 的問題,不然四個位數都不會亮。再仔細查找,原來是接錯孔位,修正後就成功了。由於計數到最後近四分鐘,所以只剪輯的前後的部份才不會太長(影片中有三個開關的小麵包板是未來要加上的):
- 接線沒問題了,所以接下來拷貝十六進位計數的範例程式的開頭程式碼(定義腳位及顯示數字的部份,因為用的是他的電路圖),再以Arduino - 4-Digit 7-Segment Display (EN) - YouTube 的方式來編寫,最後參考 How to Make a Arduino Digital Clock : 5 Steps - Instructables 的電路(如下圖),加上三個開關來設定時鐘的時間,同時也改寫他的時鐘程式碼,寫成一個函數。或許還能自行建立一個函數庫,除了時鐘的顯示,像是溫度、距離……等等感測器讀取的值都可以叫用並顯示在七段顯示器上。(或許網路上也有各種感測器的函數庫可以下載,只要電路搭建好,函數叫用讀取即可顯示了。)
2022.01.29
決定開始來接線路及改寫程式:
- 電路決定使用 Lesson 28 - 4 Digit 7 Segment Display - YouTube 的電路圖,也順便學習 74HC595 (網路查到一顆也就不過四、五元),所以串接多個時也不傷財,重要的是可以節省 Arduino 的腳位:
- 若能改寫成功,是否要 3D 列印個外框呢?那就不必了,淘汰的手機下載個時鐘 app 就比這個棒很多,這只是學習的一個過程而已。
2022.01.28
- 把教學光碟的電路接好,以內附的範例程式來檢查是否有接錯。接好後,改了一點程式碼,上傳後測試沒有問題:
- 開始去讀程式碼後,問題就來了,也是燒腦的開始。如下圖,程式碼定義顯示數字的陣列,陣列裡的值與說明書裡列出的值怎麼對都對不上,難道是 74HC595 IC的關係?
- 查了 74HC595 的規格 ,第一頁就看到 shift register 這個詞,難道是值需要 shift ?
- 然後以「Four Digital Seven Segment Display with 74HC595」為關鍵字查到這支影片:Lesson 28 - 4 Digit 7 Segment Display - YouTube,並下載了作者在 Github 的程式碼及各項資料:GitHub - rmorenojr/ElegooTutorial: Elegoo tutorials - revised sketches and diagrams for each Elegoo Lesson,內有一個 Excel 檔,開啟後才知道原來套件附的教學光碟說明書那個表格是錯誤的:
- 這才又讓我想起說明書隨便挑了個 RGB Led 說明就看到明顯的錯誤(圖與文字說及後續的電路接法相反):
- 看來套件附的教學光碟說明書其他的部分想必也是錯誤很多,下次參考時要多加小心。
- 由於Lesson 28 - 4 Digit 7 Segment Display - YouTube 的接法是 74HC595 還要再接四個 PN2222 transistors,但買的套件只有兩個,等有時間時再上電子街買(露天一顆 10 元,網購免運又有低消),當下先把影片的內容搞懂。
- 目前的理解是影片的作者把教學光碟說明書的電路圖說成是垃圾,無法控制四位數字各別顯示,所以他改了電路圖,加了四顆 PN2222 當成可控制的開關來各別顯示數字,也附了計數的範例程式碼,等零件齊了後再來測試。
- 下午去廣華買了五顆 2N2222(使用上與 PN2222 同樣,查網路說還比較貴,也問了元華,沒有 PN2222),拿回後在放大鏡下仔細看,竟然有三顆是 2N2222a ,兩顆是 2N2222,以三用電錶量 hFE, 2N2222 約 230 倍, 2N2222a 約 260 倍,套件裡的 PN2222a 約 153倍。因此在這個 Project 只能使用兩顆 2N2222a 及兩顆 2N2222 。
- 對於增加的四個 NPN 電晶體,首先要搞清楚 EBC 三根接腳,用三用電錶量,找出後才發現網路找到的圖就有了:把印字平的部份面向自己,最左是 E ,中間 B,右邊 C:
- PN 2222 也一樣:
- 電晶體的原理老早還給老師了,找到這篇:把電晶體發動! @ 老音響資料庫/蘇桑部落格 :: 痞客邦 :: 複習一下。
- 買這個套件並非要玩樂高一樣,把接線依樣畫胡蘆,上傳程式可以運作就了事。這樣不算學習,尤其是若要改寫程式,勢必非得懂程式不可,把 Lesson 28 - 4 Digit 7 Segment Display - YouTube 仔細看了幾遍,現在零件也齊全了,但並不急著接線,因為附的範例程式對於 74HC595 不夠了解,看了 Lesson 27 - 74HC595 and 7-Segment Display - YouTube 還是不行,才又再找到這支影片:Lesson 24 - 74HC595 Shift Register - YouTube ,等徹底了解後再來實際連接電路並改寫程式碼。
關於 74HC595 的學習可以按底下順序來研究:
- 先從這兩支影片入門:【Arduino教學】實作08-74HC595(上) - YouTube 、【Arduino教學】實作09-74HC595(下) - YouTube 。
- 研讀這些文章:一個74HC595連接多個七段顯示器 - 超圖解系列圖書 、| Arduino教學 | 7段顯示器- 74HC595| 204 | JIMI陪你玩ROBOT、mBlock & Arduino(18)74HC595 與七段顯示器,、[Arduino範例] 使用74HC595移位暫存器,控制多個LED燈 。
- 再來研讀 移位暫存器 - 維基百科,自由的百科全書,這段話:「串入並出形式的移位暫存器經常與微處理器連接,這樣做的原因主要是需要的引腳數多於微處理器能夠提供的數量。通過使用移位暫存器,可以只依靠兩三個引腳,而被控制設備的控制位分別連接在移位暫存器的並行輸出端。由此,微處理器可以以串行的方式一次寫入這些設備的各個控制位。類似的,併入串出接法的移位暫存器在多個外部設備向微處理器傳輸數據時較為常用,外部設備以並行的方式將數據輸入到移位暫存器里,然後移位暫存器以串行的方式將數據一位一位地輸出給微處理器,這樣,外部設備的大量信息可以通過少數幾條線到達微處理器。」可以做個總結。
2022.01.27
- 真是「踏破鐵鞋無覓處,得來全不費工夫」,在蝦皮買的套件所附教學光碟的說明 PDF 裡就有共陰四位七段顯示器的電路圖,這下子要完成時鐘程式的改寫就向前邁進一大步:
- 前面雖已發覺錄製影片要使用 24P 的格式,但對於以 SONY A7s + Tamrom 90mm F2.8 微距鏡(早期底片時代的老鏡) + Atomos Ninja Flame ,以 S-Log2 格式錄製, 格式 4K 24P , ISO 3200,光圈 F4 ,快門 1/25 秒或 1/50 秒,加上可用光源(也就是抬燈調到最亮,盡量靠近目標,讓整個場景的亮度能夠趨於一致,但 Led 最亮時還是會過曝,顏色還是跑掉),想到可以使用可變 ND 濾鏡,才能在使用 ISO 3200 起跳的 S-Log2 格式時,光圈不用調得太小且快門能以 1/25 秒或 1/50 秒錄製,這樣紅色的 LED 燈才比較接近肉眼看到的顏色(還是沒有眼睛看到的紅)。
- 這支影片是以 1/25 秒拍攝:
- 這支影片是以 1/50 秒拍攝:
- 在玩 DJI mini 2 空拍時看到的教學影片都說快門速度要錄製格數的兩倍,即錄 24P ,快門最好設在 1/50 秒,但上述兩支影片或許是木眼,實在看不出有何差別,有可能因為空拍是動態的,而這些影片是靜態錄製的關係才會沒有影響。
底下為先前的記錄,後續的記錄以日期排序,日期新的在前面,如之前學天文攝影的「觀測日記」一樣。
- 關於發光二極體(LED):因為可通過的電流很小,這就是為何使用時要串聯電阻的原因,使其分壓約在 2V 左右。
- 零基础入门学用Arduino-基础知识篇-19 MC猜数字 - 1 电路搭建 - YouTube 需要使用到一位的共陰七段顯示器,但是蝦皮購買的套件規格上沒有註明是共陰還是共陽,也懶得問賣家,就用三用電錶測:
- 因為二極體單向導通的特性,三用電錶轉到 2K Ω 檔位,兩根跳線黏在電錶的探棒上,很容易就就測出蝦皮買的是「共陰」七段顯示器:
- 每支腳位代表那支二極體也能用三用電錶測出:
- 在接下來的 零基础入门学用Arduino-基础知识篇-19 MC猜数字 - 1 电路搭建 - YouTube 一系列影片,Arduino Uno 腳位與共陰七段顯示器的連接如下圖:
- 所以要顯示數字 0-9 時,要驅動(點亮)那些二極體,如下圖:
- 依上述兩圖,顯示數字 0-9 時對應的Arduino Uno 腳位就可以找出來:
二極體 | a | b | c | d | e | f | g |
---|---|---|---|---|---|---|---|
Arduino腳位 | 3 | 4 | 7 | 8 | 9 | 6 | 5 |
數字 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
二極體 | abcdef | bc | abdeg | abcdg | bcfg | acdfg | acdefg | abcf | abcdefg | abcdfg |
Arduino腳位 | 346789 | 47 | 34589 | 34578 | 4567 | 35678 | 356789 | 3467 | 3456789 | 345678 |
字母 | A | b | c | d | E | F |
---|---|---|---|---|---|---|
二極體 | abcefg | cdefg | deg | bcdeg | adefg | aefg |
Arduino腳位 | 345679 | 56789 | 589 | 45789 | 35689 | 3569 |
- 在練習零基础入门学用Arduino-基础知识篇-19 MC猜数字 - 1 电路搭建 - YouTube 時,照著影片的接法,LED 燈始終不亮,這才發現蝦皮買的套件裡的麵包板上下兩排是分成兩半的,兩支接地線不能分在兩邊。為了以後使用上的方便,需要再購買短跳線,如下圖的方式固定下來:
- 在接好 MC 猜數字的電路後,把 final 的範例程式上傳到 Arduino Uno 後,執行卻有問題,只能跑一次,無法像影片示範,可以一直執行。起先還以為是擴充板的問題,拆掉重接還是一樣,難道是Arduino Uno 板子的問題(用的是開發版),最後花了不少時間才解決(版子沒問題,擴充板也沒問題,是範例程式碼有點小問題):(註:原程式碼顯示隨機圖案,是為了混淆注意力,讓隨機圖案顯示時間由慢到快到慢,自己則再增加一段由慢到快的程式碼,更能增加混淆。)
- 再嚐試把電路也調整好(初始很亂):
- 有了這個練習,還能找到程式碼裡的小 Bug,對理解程式就有點信心。想到套件裡有個四位數的七段顯示器,不就可以用來當成時鐘用嗎?就當作一個挑戰吧!
- 首先要了解四位數的七段顯示器的規格,這可以從套件附的 CD 找到它是共陰的。
- 這篇文章:葉難: Arduino練習:四合一的七段顯示器 有接腳的說明及範例,但作者沒有加電阻,照抄連接怕燒壞顯示器。
- 這篇文章:mBlock & Arduino(17)四位數七段顯示器 就有電阻的接法:
- YouTube 看了相關的幾支影片,最後選定這支影片的方式來練習:How to make Digital Clock with 4 Digit Seven Segment Display - YouTube
- 下載了上述影片附的程式碼,一開頭就說明程式適合共陽四位數的七段顯示器,但影片電阻的接法與前述文章的接法一樣,於是先以影片說明的接線方式接好線及電阻,上傳程式碼,結果顯示得亂七八糟,按鈕也沒作用,顯然程式不適用於共陰四位數的七段顯示器。
- 改以mBlock & Arduino(17)四位數七段顯示器 的接線方式,但上傳的是葉難: Arduino練習:四合一的七段顯示器 的範例程式,顯示有問題,再仔細比較兩篇文章的接法是不同,最後換成後者的接法,但保留了前者的電阻接法,以後者的範例程式再次跑過就沒問題了。
- 好不容易試出來,雖然離完成時鐘還有不少路要走,還是值得留下記錄,拍段影片。由於是以 S-Log2 格式錄製,由於 ISO 3200 起跳,所以快門調成 1/60秒,無法錄下眼睛看到的情形,一直閃爍:
- 在葉難: Arduino練習:四合一的七段顯示器 提到「因為有4個七段顯示器,我們必須使用掃描的方式不斷地顯示每一個七段顯示器,只要掃描速度夠快,基於視覺暫留原理,人眼便無法察覺,以為所有數字皆為同時顯示。」,因此把快門改成 1/30 秒,才能錄下數字計數的情形(還是會閃爍,只是比較不嚴重):
- 剛好有空改以 24P 錄製,閃爍的問題幾乎看不到:
- 接下來的做法是以葉難: Arduino練習:四合一的七段顯示器 的接線方式,然後把 How to make Digital Clock with 4 Digit Seven Segment Display - YouTube 附的範例程式改寫,雖然共陰顯示器不適用,但時鐘顯示的流程應該都是一樣,讀懂程式的結構,或許就能改寫吧!就試試看囉!
- 葉難: Arduino練習:四合一的七段顯示器 裡面的範例程式,是個高手,寫得太精簡反而難懂,反而How to make Digital Clock with 4 Digit Seven Segment Display - YouTube 附的範例雖然較長,卻比較好弄懂,只是他用的是共陽的四位七段顯示器,如何改接成共陰的電路,對一個完全的電路新手實在是一大考驗。
- 畢竟不是電子本科,光一個共陽的電路要轉成共陰的電路接法,就想了兩天才想到可能可以解決的方法。四位七段顯示器,可以單獨用一個來想即可,而之前在零基础入门学用Arduino-基础知识篇-19 MC猜数字 - 1 电路搭建 - YouTube 已接過一位共陰七段的接法,再配合 Microsoft Word - ch8 七段顯示器實習.doc 裡面這段話的說明,應該有辦法接出來:
- 雖然懂得物理,但沒有實際的電路基礎,只好土法煉鋼胡搞瞎搞,
- 根據上圖的說明,把各段連接 220 Ω 限流電阻接+5V ,而D3、D2、D1、D0 任一腳接地,並拷貝一小段範例程式的程式碼來檢查接法是否正確:
- 做法是上傳程式後,把接地線一一接到 D3、D2、D1、D0,看那個顯示器能夠點亮(程式碼應該是要顯示 0 ,結果卻反相,顯然給的電位剛好相反;少拍了一張圖。另,Blog 上傳的圖片每次都會順序顛倒,懶得再排序):
- 改好後,可以正確顯示 0 (Blog 上傳的圖片每次都會順序顛倒,懶得再排序):
- 但仔細觀察 D3、D2、D1、D0 的腳位與找到的資料是相反的:
- 拷貝程式碼,讓顯示的數字為 5 :
- 這次把 D3、D2、D1、D0 的腳位全部接地,程式上傳後四位數全亮 5 :
- 至此,第一階段算成功了…….(沒有電路基礎,只能慢慢來,對於懂電路的人大概覺得很可笑吧)
進一步研究時才發現 How to make Digital Clock with 4 Digit Seven Segment Display - YouTube 他應該是引用這個人的做法,把四個一位數七段顯示器改成一個四位數七位數顯示器而已,原始作者的文章裡有詳細的說明:How to Make a Arduino Digital Clock : 5 Steps - Instructables ,值得後續好好研究。
- 目前已能用一個開關,以第 10 Pin 腳來顯示不同數字:
- 程式碼如下:
int segA = 2; //Display pin Aint segB = 3; //Display pin bint segC = 4; //Display pin cint segD = 5; //Display pin dint segE = 6; //Display pin eint segF = 7; //Display pin fint segG = 8; //Display pin gint segDP = 9;//Display pin dotint//int digit1 = 13; //控制顯示那一個位數//int digit2 = 12; //目前還不會用到//int digit3 = 11; ////int digit4 = 10; //void setup() {Serial.begin(9600);pinMode(segA, OUTPUT);pinMode(segB, OUTPUT);pinMode(segC, OUTPUT);pinMode(segD, OUTPUT);pinMode(segE, OUTPUT);pinMode(segF, OUTPUT);pinMode(segG, OUTPUT);pinMode(segDP, OUTPUT);//pinMode(digit1, OUTPUT);//pinMode(digit2, OUTPUT);//pinMode(digit3, OUTPUT);//pinMode(digit4, OUTPUT);}void loop() {#define SEGMENT_OFF LOW#define SEGMENT_ON HIGH#define DIGIT_ON HIGH#define DIGIT_OFF LOWconst int buttonPin1 = 10;//const int buttonPin2 = 11;//const int buttonPin3 = 12;int buttonState1 = 0;//int buttonState2 = 0;//int buttonState3 = 0;buttonState1 = digitalRead(buttonPin1);Serial.print(F("buttonState1 Start = "));Serial.println(buttonState1);//buttonState2 = digitalRead(buttonPin2);//buttonState3 = digitalRead(buttonPin3);if (buttonState1 == HIGH) {digitalWrite(segA, SEGMENT_ON);//顯示數字 5digitalWrite(segB, SEGMENT_OFF);digitalWrite(segC, SEGMENT_ON);digitalWrite(segD, SEGMENT_ON);digitalWrite(segE, SEGMENT_OFF);digitalWrite(segF, SEGMENT_ON);digitalWrite(segG, SEGMENT_ON);} else {digitalWrite(segA, SEGMENT_OFF);//熄掉數字 5digitalWrite(segB, SEGMENT_OFF);digitalWrite(segC, SEGMENT_OFF);digitalWrite(segD, SEGMENT_OFF);digitalWrite(segE, SEGMENT_OFF);digitalWrite(segF, SEGMENT_OFF);digitalWrite(segG, SEGMENT_OFF);digitalWrite(segA, SEGMENT_OFF);//顯示數字 1digitalWrite(segB, SEGMENT_ON);digitalWrite(segC, SEGMENT_ON);digitalWrite(segD, SEGMENT_OFF);digitalWrite(segE, SEGMENT_OFF);digitalWrite(segF, SEGMENT_OFF);digitalWrite(segG, SEGMENT_OFF);}digitalWrite(buttonPin1, DIGIT_ON);//還不懂這行的作用,不加,開關沒有作用,無法切換數字Serial.print(F("buttonState1 End = "));Serial.println(buttonState1);}
- 由於 MeArm 機械手臂及一些配件到貨,可以繼續 零基础入门学用Arduino-MeArm机械臂篇 - YouTube 的學習,四位數七段數顯示器時鐘程式碼的改寫就先告一段落。
沒有留言:
張貼留言
您可以留下意見,但 Luke 可能無法馬上回覆,尚請見諒。