2022年6月26日 星期日

[fChart, Python] 以 fChart 馭 Python:迴圈結構(5/11)

以 fChart 馭 Python:

迴圈結構(5/11)

Line:ted2016.kpvs
Email:Lct4246@gmail.com
FBhttp://gg.gg/TedLeeFB/
Bloghttp://gg.gg/TedLeeBlog/

June 26, 2022
88x31.png[1]

接續著本 fChart 系列前文《以 fChart 馭 Python:練 fChart 了沒?(1/11)》(https://reurl.cc/oeDGN3),我們將針對圖1 的「10 大項目之 4」的 26 個實例(可從此處 下載),從
原始問題描述以流程圖表達解法
再對照流程圖寫出 Python 語法程式
的過程詳細說明整個問題解決(problem solving)過程。

圖 1:10 大項目之 4

2022年6月10日 星期五

[micro:bit, maker] 小彼特一筆畫完

 小彼特一筆畫完

Line:ted2016.kpvs
Email:Lct4246@gmail.com
FBhttp://gg.gg/TedLeeFB/
Bloghttp://gg.gg/TedLeeBlog/

June 10, 2022
88x31.png[1]


馬上實作,拿在手上感受

我:你可以自己畫出一筆點亮所有 LED 燈嗎?
孩:可以,馬上用筆畫出兩種。
我:那能畫出所有可能點亮的方法嗎?
孩:A…(搔頭狀),沒辦法。
我:我也沒辦法,可能性有很多,而且我畫完四個也累了。但是,電腦不怕累,可以一直工作。我可以把任務交給它,讓他發揮專長。接著從口袋拿出小彼特展示給他看。頓時,小孩的眼睛閃閃發光,問說這怎麼辦到的?
─── 小彼特的超級優點就是:馬上實作,拿在手上感受。

問題說明

從小彼特的中心點出發,找出任一條可連接 25 顆 LED 的畫法,但已畫過的點不能再重複經過(圖 1 為四種可能的畫法)。讀者們可以使用圖 2 的學習單動手畫畫看,也可以相互比一比,看看誰能畫出最多種不同的走法。

圖 1:從中心點出發的四種畫法

圖 2:一筆畫完學習單

問題分析

首先,我們以圖 3 座標軸的第一象限來定位小彼特板子上的這 25 顆 LED。圖 4 為一筆畫完的走法分析,其中,圖 4 左黃色座標格表示圖 4 右選擇的走法。

圖 3:小彼特 25 顆 LED 定位座標軸

圖 4:走法分析

麥客友( Escher Hsieh)的解方

我們在這篇 FB 分享文章(https://reurl.cc/QLkDa2)提到使用小彼特來實作的概念後,麥客友 Escher 立刻以遞迴(recursion)的程式設計技巧實作(implement)出這個問題的解法(https://reurl.cc/anDmvD)。
程式的想法很簡單:
邊往前畫邊灑下麵包屑作記號(遞迴),走不通就沿著麵包屑返迴(backtrack)再重新找路。其中,下一步的選擇順序(order) 如圖 5 中 1~4 的逆時鐘(counter clockwise)方向所示,即調整對應的 x 或 y 座標。

圖 5:尋路順序 

Ted Lee 的解析

首先,以圖 6 的方式定義了五個一維陣列 list0~4[] 代表小彼特板載 25 顆 LED 的狀態:

1 表示尚未走過;
0 表示已走過。

圖 6:陳列的初始狀態

另外,程式中定義了以下四個副程式來處理深度優先(Depth-First Search,DFS) [2] 的尋路方式:
  1. setLED():設定 LED  (x, y) 是否被畫到(記錄變數 value = 0)。
  2. findPath():遞迴找路副程式,這是這隻程式的菁華所在。它的設計邏輯是:
    往上下左右四個方向去甞試畫畫看。
    如果可以將 25 顆 LED 畫盡,那就是找到了一種畫法。
    否則,代表此路不通,退回前若干步後再換一條沒走過的路重試。
  3. shwoPath():顯示找出的一筆畫完路徑(path)
  4. getLED():取得 LED (x, y) 的值(有畫到 (x, y), value = 0;否則,value = 1)。
其中,它們之間的呼叫關係(call sequence)整理於圖 7 所示。

圖 7:副程式之間呼叫關係

最後,我們將 Escher 的程式碼再整理加註於此(https://reurl.cc/9GY3lx)供讀者細細詳參。

MakeCode 中的程式碼追蹤(code trace)技巧


上小節所整理的敘述除向原作者請益的結論之外,我們是用 MakeCode 裡的小瓢蟲(debugger)進入單步執行(single-step execution)除錯模式(debug mode)來一步步模擬與追蹤程式的執行過程──這個程式「 閱讀」技巧目非常、超級重要,精熟它必定有助於讀懂他人程式碼的思考邏輯(圖 8)。其中,讀者可以比較一下由積木程 JavaScript 進入除錯模式的差異性。後者才有中斷點(breakpoints)可以插入觀察。

圖 8:MakeCode 的除錯模式

還可以怎麼玩

可能有讀者會和筆者一樣,小時候有玩過一筆畫一個圖案(https://reurl.cc/YvoNX4)或寫一個字(https://reurl.cc/NAm91p)。一筆畫問題資訊科學(Computer Science,CS)領域有一個古典的研究叫尤拉路徑(Eulerian path)https://reurl.cc/anDm9Q),而資訊科學家(computer scientists)也就從此開展出一串圖論(Graph Theory)問題的新研究領域,有興趣的讀者可以從此處再繼續深入研究之。

延伸思考

麥客友的參考作品給了我們一個思考的方向。讀者們,我們是否還能夠再進一步改良(improve)它呢?
  1. 從 (2, 2) 出發,共有幾種不同畫法?
  2. 隨機選出發點 (x, y),x, y = 0~4?
  3. 為什麼程式找到路後不會停?能讓它停下來嗎?
  4. 能隨機找路嗎?

註:教學情境的營造──有溫度的畢典
疫情肆虐讓許多學校都只能辦遠距畢典。xx 的孩子們,你們的身體內都流淌著遠征探索的血液,xx 特使團將出動 SNG(Satellite News Gathering)車到每位畢業生家裡現場採訪,請規畫一條不重複而且能串連每個家庭的完美路線。

2022年6月4日 星期六

[micro:bit, maker] 猛龍搶珠

 猛龍搶珠 [1]

Line:ted2016.kpvs
Email:Lct4246@gmail.com
FBhttp://gg.gg/TedLeeFB/
Bloghttp://gg.gg/TedLeeBlog/

Jun 4, 2022
88x31.png[2]

讓金龍爭奪隨機出現的龍珠。

從觀察中建立編程邏輯直覺

請讀者們觀察本文最開頭的 GIF 動畫,比參照題目的要求,拿張白紙動手寫出/畫出該動畫可能的操作流程,而這個流程就是本文的編程邏輯。

設計

龍珠(LED 亮度最亮)會隨機出現在 5*5 的 LED 矩陣(matrix)上。
按 A 以列為主(row major),則由左到右,再由上到下搜尋;
按 B 以行為主(column major)則由上到下,再由左到右尋找。

程式解說

程式一開始時讓 micro:bit 出現開機的愛心圖示,然後讓按鈕控制變數 sw 設定成 -1,其中,
接著,按下 A 時清除畫面後開始由左到右、由上到下尋找龍珠,尋找的流程如圖 1 所示(我們利用 micro:bit 的重複執行 forever() 函式的特性,按鈕按下時在事件積木中設定對應 sw 旗標(flag)值,然後等到輪到 forever() 取得執行權時即進入圖 1 的執行邏輯。)此外,讀者們可以動動腦再想一想:圖 1 的流程圖中有幾個迴圈呢?為什麼?
另一方面,按下 B 的處理邏輯和 A 相同,可參考圖 1 的做法修改之。

圖 1:按鈕 A 的控制流程


完整程式碼如圖 2 所示,讀者可連至自行下載。

圖 2:完整程式碼

挑戰

舉出其他搜尋(search)的方法,例如:由右到左,再由上往下。並修改範例程式來實現(implement)你的想法!

學習參考

本單元配合南一書局七年級資訊科技第二冊 6-3 節的重複結構(repetitive structure)

2022年6月1日 星期三

[micro:bit, maker] 拆地雷

 拆地雷 [1]

Line:ted2016.kpvs
Email:Lct4246@gmail.com
FBhttp://gg.gg/TedLeeFB/
Bloghttp://gg.gg/TedLeeBlog/

Jun 1, 2022
88x31.png[2]


micro:bit 上滿佈著 25 顆地雷,請趕快通報掃雷小組盡速來拆除

圖 1micro:bit 5*5 雷區

從觀察中建立編程邏輯直覺

請讀者們觀察本文最開頭的 GIF 動畫,比參照題目的要求,拿張白紙動手寫出/畫出該動畫可能的操作流程,而這個流程就是本文的編程邏輯。

設計

按 A+B 重新開局。
按 A 後再按 B 隨機選出要拆除的第 (i, j) 顆地雷,i, j = 0~4。其中,micro:bit 的 LED 矩陣座標系統定位如圖 2:

圖 2:LED 矩陣座標系統

程式解說

完整程式碼如圖 3,以下我們來詳細說明程式的設計邏輯:

1. 開局:按鈕 A+B。如圖 3,在按鈕的ㄈ字形事件處理(event handling)積木(blocks) 內置入將 25 顆 LED 全部點亮的積木。思考:要不要先將所有 LED 清除再點亮呢?為什麼?
2. 拆彈定位:按下鈕 A 隨機選 0~4 的 X 座標位置 i;按下按鈕 B 隨機(random)選 0~4 的 Y 座標 j。
3. 拆除炸彈:當 (i, j)是亮著(請參考 MakeCode 的積木使用說明文件)時將之關閉,表示該炸彈已清除。

圖 3:完整程式碼

挑戰

加上計時功能,設定一分鐘內要全數拆完 25 顆地雷才算過關。或者,讓 micro:bit 上的地雷改為每次玩時是隨機佈 n 顆地雷,n = 1~25。註:感謝黃教授提供「暗雷」玩法,我們修改規則如下:

按 A+B 時 25 顆 LED 全亮(表示雷區範圍)開局並隨機產生 1~25 顆暗雷。
按 A 時,掃雷大隊依序移動探雷。
按 B 確認是否找到地雷。若是誤判,則發出錯誤音效。否則,將 LED 變暗表示該顆地雷已被成功拆除。

相關作品

這段影片中,我們使用了信標(beacon)技術來尋找炸彈並拆除它。相關的程式碼都放在影片留言處。
另外,我們仿做了賴盈志老師的手作做品,也實際動手做出了一個版本

學習參考

本單元配合南一書局七年級資訊科技第二冊 6-2 節選擇結構(selective structure)

2022年5月14日 星期六

[micro:bit, maker] 小彼特(micro:bit)創客(maker)趣之燈條篇

   小彼特(micro:bit)創客(maker)趣之燈條篇 [1]

Line:ted2016.kpvs
Email:Lct4246@gmail.com
FBhttp://gg.gg/TedLeeFB/
Bloghttp://gg.gg/TedLeeBlog/

May 14, 2022
88x31.png[2]

以小彼特做為機電整合控制的開發板一直是這塊板子想要引導年輕學子培養數位創意(digital creativity)願景(vision)
本場分享以「燈」為主題,從曼陀羅(Mandala)創意思考工具觀察其在生活中的相關應用場景,並結合小彼特的各種控制方法來開展出創客創作的設計思考(design thinking)
因為疫情嚴峻,主辦單位不得不臨時改採遠距的方式舉辦。而筆者也以 MakeCode 便於同時開發傳送與接受廣播遙控程式的 Multi Editor 介面並配合微軟創意獨具的燈條模擬環境來展式電控程式的開發流程。
最後,我們也整理了數件過往專案合作的中大型作品來展示燈條的一系列創作集。

從曼陀羅玩起

我們使用試算表(speeadsheet)繪製了雙層九宮格的曼陀羅,最中心的內層是用來發想燈條在日常生活中應用到的場合。依序將想到的答案填入外環的八個格子時,試算表會立即將之顯示到第二外層以開展出可以用小彼特來控制的方式。
完成這個曼陀羅的腦力激盪的同時等同於設計了在某個場景下操做燈條的方法(圖 1),例如:遙控聖誕樹彩燈。

圖 1:生活中的燈條及其控制之雙層曼陀羅

專案架構

每一個大程式專案都是從小的程式片斷所積累,或者說:大程式是可以拆解(decompose)為若干功能獨立(functional dependent)的小程式。

首先,我們會先介紹燈條控制的三個基本動作(燈條控制三部曲)。接著,是廣播的控制邏輯(廣播控制三部曲)。最後,將前兩項組成「遙控燈」的操作。

燈條控制三部曲

燈條控制的完整程式範例如圖 2 所示,讀者們可以從這裡下載。

圖 2:燈條控制三部曲

因為燈條屬於小彼特的外接硬體,如圖 3 所示,在使用前需要先加入美商 Adafruit 為它撰寫的擴充積木包(extension blocks)。註:新像素(neopixel)為其內部用語。

圖 3:燈條擴充積木

相同地,我們 Arduino 界最富盛名的 Blink 來測試小彼特開發的軟硬體平台:

步驟一:在 on start 中初始化(initialize)燈條物件 strip,積木最右的格式參數用預設值(default),中間的參數要配合硬體上燈珠數(讀者可以試試大於或小於實際燈珠數會如何?),最左邊的參數是燈條接在小彼特的哪一隻接腳(pin)上(因為小彼特預設 P0 腳是和板載的(built-in)蜂鳴器(buzzer)共線路,強烈建議保留給它專門用來控制聲音之用。
步驟二:設定燈條要顯示的顏色。
步驟三:關閉燈條。

註:為了教學統一起見,只要燈條顏色有異動就請加上 show 積木!

廣播控制三部曲

我們採用十分適合廣播程式開發的雙拼工具 MakeCode Multi Editor(使用這個相同功能的網站 BuildBee 亦可)。完整的範例程式可參考圖 4 所示。

圖 4:廣播三部曲

在圖 4 中,我們設定共同的廣播群組代碼為 13。當 Tx 按下 A 時傳送 ("TedLee",  14);Rx 收到後,確認發送者是 TedLee 後,就播出 hello 音效(sound effect)

步驟一:設定廣播群組(group),群組代碼為 0~255,共 256 組。

依照圖 4 寫好 Tx 和 Rx 之後,在 MakeCode Multi Editor 中用模擬器(simulator)直接測試:當 Tx 按下 A 時,Rx 就播出 hello──讀者們應該會和我們一樣跳起來:居然可以在同一畫面上模擬出廣播的收送結果啊!

註:很神奇的,在 MakeCode Multi Editor 上編輯的程式 Tx 和 Rx,會存到瀏灠器快取(cache)中,打開 MakeCode 時就會看到它們,如圖 5 所示。

圖 5:MakeCode Multi Ediot 和 MakeCode 均存在同一瀏灠器快取處

加在一起:遙控燈

將以上兩小節的參考程式合併後就可以像圖 6 一般輕鬆地組成一隻使用廣播來遙控燈條的程式了(在 Rx 中,我們再進一步地將燈條控制改用 blink() 函式(function) 來處理)。其中,歷史總是分分合合。然而,程式也只不過是拼拼湊湊罷了:

數個基元小程式 ---合併---> 大程式

大程式 ---拆解(dempose)---> 數個基元小程式


圖 6:廣播遙控燈條

創客作品集

筆者雖然身在教學現場,但仍不斷期許自己能多方面應用所學,並能將之回饋到教學上。因此,卡路里大作戰這件作品是我們和台北市仁愛國中楊昌珣老師的跨領域(cross disipline)合作專案產出。我們依照男、女國中的體型分成四個類型來計算跑步一分鐘所消耗的卡路里(carloine)熱量。
氣有多長這件創作是用來將音量以燈條做視覺化(visualization)呈現。
聖誕樹是將燈條固定在以 PP 板設計的聖誕樹造形上,並以編程來實現各種燈條的閃爍樣式(patterns)
最後,和新北市三重區明志國中共同開發酷跑遊台灣大型教具,在一分鐘之內,會不斷的累加三位環台跑者的步伐(已發表專文於《「酷跑遊台灣」之機電整合分享:新北市108年資訊科技教育成果展專案》)。

附錄 1:燈條原理

我們選用的是 WS2812B 可程化(programmable)的 +5V 軟管燈條(圖 7),它的資料手冊(datasheet)可從這裡查看。其中,我們可以看到燈條上的每顆燈珠 VDD(電源)、VSS(接地)是全部各自串聯在一起,而 24 位元(RGB 3 色,每色 256 階)控制訊號是以 DIN - DOUT - DIN - DOUT …相接。註:因為我們是要接到小彼特上自行設定燈條樣式,所以,要找像 WS2812B 這類型的燈條才符於使用。 讀者若不清楚它們的採購方式,可在本文下方留言版中詢問,或者到我們的臉書社團上來一起討論。

圖 7:WS2812B 軟管燈條


附錄 2:燈條還可以怎麼玩?

文末,我們想邀請有興趣的讀者們一起來想想這個用 Arduino 控制的光彈效果是否也能改用小彼特來實現呢?或者,像我們在《讓我們Py在一起:手勢控制PowerPoint放映切換》所展示的,能否用手勢(gestures)來控燈呢?歡迎大家在本文下方的留言版中一起討論,或者也可以到我們的臉書社團上一起來分享。

2022年5月8日 星期日

[Arduino, Maker] 「防疫大作戰」之機電整合分享:新北市三重區明志國中 2020 科技專案

  「防疫大作戰」之機電整合分享:

新北市三重區明志國中 2020 科技專案 [1]

Line:ted2016.kpvs
Email:Lct4246@gmail.com
FBhttp://gg.gg/TedLeeFB/
Bloghttp://gg.gg/TedLeeBlog/

May 8, 2022
88x31.png[2]


繼前文《「酷跑遊台灣」之機電整合分享:新北市108年資訊科技教育成果展專案》,本文仍以科技專案系列之機電整合技術分享為前題,揭露筆者於筆者 2020 年二月獲新北市三重區明志國中戴春城校長邀請,和進修部林耀坤主任創客達師(master maker)共同合作產出的作品(圖 1)。
本專案透過 Arduino 程式設計與感測器連結,發展出創新的機電整合課程。老師們使用 PBL 教學法指導學生自製闖關道具,運用課堂所學習到的數學及藝文關鍵素養,再結合健康促進之新冠病毒防疫議題,發展出動手實作的 STEAM 課程,以達到跨領域的學習目標,並具有寓教於樂的功能。

圖 2:筆者近四年來和明志國中的共同創作專案及作品

專案說明

明志國中為新北市 108 學年度國民中學科技領域輔導小組召集學校,亦為新北市程式教育示範學校,為作表率本校將在本展中展示結合科技、健體、社會、數學、藝文等跨領域課程之闖關活動「防疫大作戰」(圖 2)。
本專案由戴春成校長(圖 2 左1)領銜,協同進修部林耀坤主任(圖 2 右2)與筆者組成的專案小組指導若干學生們共同策畫與執行。

圖 2:防疫大作戰展示實景

操作方式為病毐聖戰士們手握如圖 3 中的重裝武器一同站立於黃色發射線後準備撃潰黑暗的病毐軍團。

圖 3:聖戰士們手持防禦性重兵器並齊立於黃色發起線後誓言要摧毀頑強的病毐大軍

每一回合按下圖 4 病毒轉盤左下的紅色按鈕(戴口罩小朋友頭頂左上方處)後藍色的病毒本體開始運轉。左上角的燈板會開始倒數計時兩分鐘。當聖戰士將子彈撃穿病毒的本體後,它就會中彈受傷。此時右上角的燈板就會累計聖戰上的戰績。

圖 4:囂張的病毒正在世界各地轉動肆虐著

專案架構

本專案依各自功能可區分為機構設計、機電整合電路設計與機電整合控制程式設計三大區塊。詳細說明如 1、2 及 3 小節所示。

1. 機構設計

本專案的機構設計乃由耀坤主任親自操刀,共分為射撃裝置和病毒轉盤兩件。 圖 5 中左二學生手持雷切製成的射撃槍即為射撃裝置一。它以內置的彈簧拉力來撃發乒乓球。此外,右一及右二學生手持的桶狀簡易射撃裝置是以回收的洋芋片罐加裝汽球以做為射撃的動力的來源。

圖 5:射撃裝置機構

圖 6 的病毒轉盤融合了耀坤主任精湛的木工技藝以及美術專長特製而成。轉盤上頭裝有計時和計分的燈板各一組。接著是以軸心連接後方齒輪的藍色病毒 COVID-19 模型。

圖 6:病毒轉盤

在病毒轉盤背後,上方是電路控制室。它剛好座落在圖 6 燈板的正後方。中間綠色小齒輪和 AC 馬達相接而形成齒輪動力組,藉此帶動和綠色大齒輪串在一起的圖 6 藍色病毒模型,內部中空相連情形如圖 8 所示。其中,圖 9 及圖 10 為耀坤主任親自指導學生以木工製作大小齒輪組的過程。
此外,圖 7 綠色大齒輪下方的集球溝內埋有一只細長柄的微動開關(micro switch)做計分偵測之用。

圖 7:齒輪動力組

圖 8:病毒轉盤的內部中空結構

圖 9:連接 AC 馬達的小齒輪

圖 10:帶動前方藍色病毒的大齒輪

2. 機電整合電路設計

本專案需求功能三:
  1. 計時:按下啟動按鈕後開始倒數 2 分鐘(120秒)並於燈板上顯示剩餘時間。
  2. 計分:有球進洞後需計分並於燈板上顯示累計得分。
  3. 重置(reset):按下啟動按鈕後轉動病毒轉盤重新開局。
由於我們尋獲的燈板是以 UART 和 Nano 開發板通信,而一塊 Nano 板只有一個 UART 通信通道。因而我們以 sss(signal to scoring Nano)接線來串接(cascade)計時 Nano(圖 11)和計分 Nano(圖 12)。 在圖 10的計時線路中,按鈕採下拉(pull down)設計以維持準確的電壓準位。和燈板以 D0(Rx)和 D1(Tx)兩支接腳進行序列傳輸。最後,使用一顆繼電器(relay)來控制病毒轉盤組的 AC 慢速馬達。 在圖 12 的計分電路中,燈板的接法和計時線路相同。三路的微動開關也是採用下拉的設計來處理。 整體的接線以模組化(modularized)的方式來佈局(layout),方便除錯和後續教學解說。完成後的電路控制箱如圖 13 和圖 14 所示。專案的所有材料清單如表 1 所示。

表 1:材料清單

品名

單位

數量

用途

1

NanoFT232晶片)

2

計分及計時燈板控制

2

mini USB傳輸線

2

計分及計時燈板控制

3

Lumex LDM-6432-P5-BLE4-1燈板

2

計分及計時燈板控制

4

麵包板

2

計分及計時燈板控制

5

延長線

1

電源供應控制

6

(藍)FB-002-34雙孔USB充電器

2

電源供應

7

杜邦(10cm

1

系統接線

8

杜邦(20cm

1

系統接線

9

單心線

1

系統接線

10

繼電器

1

AC馬達控制

11

按鈕開關

1

系統啟動按鈕

12

微動開関

1

計分感應

13

10KΩ電阻

2

啟動按鈕、計分感應電路


圖 11:計時接線圖

圖 12:計分接線圖

圖 13:電路控制箱

圖 14:電路控制箱近照

3. 機電整合控制程式設計

由於第 2 小節的模組化硬體設計,我們也以計時和計分來撰寫相對應的控制程式。這兩隻程式設計的流程圖如圖 15 所示。

圖 15:計時與計數程式的流程圖

計時程式在處理完按鈕彈跳(debounce)的機械特性後才進入計時燈板刷新(refresh)與繼電器控制馬達的程式邏輯。完整程式碼如下:

#define relay_pin 3

#define sss_pin 12

 

const int buttonPin = 2;    // the number of the pushbutton pin

 

// Variables will change:

//int ledState = HIGH;         // the current state of the output pin

int buttonState;             // the current reading from the input pin

int lastButtonState = LOW;   // the previous reading from the input pin

 

// the following variables are unsigned longs because the time, measured in

// milliseconds, will quickly become a bigger number than can be stored in an int.

unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled

unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

 

void ini() {

  lastButtonState = LOW;

  lastDebounceTime = 0;

}

 

void setup() {

  pinMode(relay_pin, OUTPUT);

  pinMode(buttonPin, INPUT);

  pinMode(sss_pin, OUTPUT);

 

  Serial.begin(115200);                 //設定UART

  delay(1000);

 

  Serial.print("atd0=()");              //清除畫面

  while (Serial.read() != 'E') {}       //等待燈板完成動作

 

  Serial.print("at2b=(0)");             //設定為覆蓋模式

  while (Serial.read() != 'E') {}       //傳送指令終止的字元

} //end of setup()

 

void loop() {

  // read the state of the switch into a local variable:

  int reading = digitalRead(buttonPin);

 

  // check to see if you just pressed the button

  // (i.e. the input went from LOW to HIGH), and you've waited long enough

  // since the last press to ignore any noise:

 

  // If the switch changed, due to noise or pressing:

  if (reading != lastButtonState) {

    // reset the debouncing timer

    lastDebounceTime = millis();

  }

 

  if ((millis() - lastDebounceTime) > debounceDelay) {

    // whatever the reading is at, it's been there for longer than the debounce delay, so take it as the actual current state:

 

    // if the button state has changed:

    if (reading != buttonState) {

      buttonState = reading;

 

      // only toggle the LED if the new button state is HIGH

      if (buttonState == HIGH) {

        //Spin the wheel

        digitalWrite(relay_pin, HIGH);

 

        //Score counting

        digitalWrite(sss_pin, HIGH);

 

        //Time counting

        //Serial.print("atef=(4)");               //設定文字顏色為綠色

        //while (Serial.read() != 'E') {}

 

        //Serial.print("at83=(1,0,Count:)");      //顯示8x16字型 Count: 字串

        //while (Serial.read() != 'E') {}

 

        Serial.print("atef=(32)");               //設定數字顏色為0Black3B4G32R

        while (Serial.read() != 'E') {}

 

        for (int i = 120; i > 0; i--) {

          Serial.print("atd0=()"); //清除畫面

          while (Serial.read() != 'E') {} //等待燈板完成動作

 

          Serial.print("at83=(1,3,");         //傳送部分指令

          Serial.print((String)i);                    //傳送指令中變動的部分

          Serial.write(')');                  //傳送指令終止的字元

          while (Serial.read() != 'E') {}

 

          delay(950);

 

          //Serial.print("atd0=()");              //清除畫面

          //while (Serial.read() != 'E') {}       //等待燈板完成動作

        } //end of for loop

 

        digitalWrite(sss_pin, LOW);

        digitalWrite(relay_pin, LOW);

      } //end of if

    } //end of if

  } //end of if

 

  // save the reading. Next time through the loop, it'll be the lastButtonState:

  lastButtonState = reading;

 

  //ini();

} //end of loop()


啟動按鈕被按下後,計時程式就會收到計時線路傳來的 sss 信號。當微動開關被聖戰士射入的乒乓球按壓後才進入計分燈板更新計分的程式邏輯。完整程式碼如下:

#define sss_pin 12

#define micro_sw_pin A0

 

int i = 0;

int x = 0;

 

float debounce_time = 1;

int start_time = 0;

int end_time = 0;

 

void setup() {

  pinMode(micro_sw_pin, INPUT);

  pinMode(sss_pin, INPUT);

 

 

  Serial.begin(115200);                 //設定UART

  delay(1000);

 

  Serial.print("atd0=()");              //清除畫面

  while (Serial.read() != 'E') {}       //等待燈板完成動作

 

  Serial.print("at2b=(0)");             //設定為覆蓋模式

  while (Serial.read() != 'E') {}       //傳送指令終止的字元

} //end of setup()

 

void loop() {

  while (digitalRead(sss_pin)) {

    Serial.print("atef=(4)");               //設定數字顏色為0Black3B4G32R

    while (Serial.read() != 'E') {}

 

    //Serial.print("atd0=()");

    //while (Serial.read() != 'E') {}

 

    x = analogRead(micro_sw_pin);

    if (x < 10) {

      //scoring();

      //i=10;

      ++i;

 

      Serial.print("atd0=()"); //清除畫面

      while (Serial.read() != 'E') {} //等待燈板完成動作

 

      Serial.print("at83=(1,3,");         //傳送部分指令

      Serial.print(i);                    //傳送指令中變動的部分

      Serial.write(')');                  //傳送指令終止的字元

      while (Serial.read() != 'E') {}

      delay(500);

    } //end of if

  } //end of while

 

  i=0;

} //end of loop()

 

void scoring() {

  //i=11;

  //int x = 0;

 

  //x = analogRead(micro_sw_pin);

  //Serial.println(x);

 

  start_time = millis();

 

  while (x <10) {

    //i=12;

    //Serial.print("start_time=");

    //Serial.println(start_time);

 

    if (x > 1000) {

      //i=13;

      end_time = millis();

      //Serial.print("end_time=");

      //Serial.println(end_time);

      //break;

    } //end of if

 

    x = analogRead(micro_sw_pin);   

  } //end of while

 

  //i = end_time - start_time;

  if ((end_time - start_time) > debounce_time ) {

    //i=14;

    //Serial.print("i=");

    //Serial.println(++i);

    ++i;

 

    start_time = 0;

    end_time = 0;

  }

}

未來擴充

本專案已展示了一個可供跨領課程的教具與多方融入多元教學雛型。當然,後續還能有不少可擴充及延伸的可能性,例如:燈板字體大小的調整、增加的燈光與音效、重置機制的安排、將控制電路洗成 PCB 板、…。筆者亦期待本專案能起一拋磚引玉之功效,提供有志於此類教學者一個起點的參考。