# 專題--燈籠牆實作

在前面的章節中我們介紹了許多的micro:bit的練習，如何運用在練習中建立的實例運用到實際的場域中呢？這次博雅教育中心的成果展裡面所展示的燈籠牆是其中的一個例子。先來看看照片：

![](/files/-LgSiVdSAlZrP-RNa8wc)

從照片中同學們應該可以看得出來，在這面牆上共有7串燈籠，每一燈籠串共有10個燈籠，在這個例子中每一串我們只使用了中間的8個燈籠，也就是每一串都有8個燈籠是可以由我們來分別控制它們的明滅動作的。

在組裝之前是這個樣子的：

![](/files/-LgSin16VYQwAJXIzzBL)

以及這個樣子：

![](/files/-LgSixcHTJA5yUiUY3B6)

由於每一串均需使用一個控制器，因此7串燈籠共使用了7個控制器，而由於每一個燈籠中使用的是12V的高亮度LED，這顆LED所供應的電流並不是micro:bit所能提供的，因此要控制這些燈的開關，就是繼電器控制模組派上用場的時候了。

每一個單獨的控制器如下所示：

{% embed url="<https://www.youtube.com/watch?v=mpl4TzdsYxM>" %}

在上面的控制器裡面使用了一個八路繼電器模組，每一個繼電器可以控制1個燈的明滅運用。這支影片示範的是讓八路繼電器模組可以使用2進位的方式從00000000計算到11111111，同學們有看出來嗎？

在燈籠牆的例子中使用的就是這樣控制模組，但是，如何才能控制這7個模組的運作呢？答案是透過micro:bit的無線電功能。

在每一個模組中，它都會一直不斷地偵測無線電訊號，如果一收到從無線電來的訊息之後，立刻剖析收到的字串，依照字串的內容來呈現出對應的燈號，其程式碼如下所示：

```python
from microbit import *
import radio
UNIT_NO = 3
relay = [pin0, pin1, pin2, pin3, pin4, pin6, pin7, pin8]
display.show(UNIT_NO)
sleep(2000)
display.off()
for r in relay:
    if UNIT_NO == 3:
        r.write_digital(0)
    else:
        r.write_digital(1)
radio.on()

while True:
    incoming = radio.receive()
    while incoming is None:
        incoming = radio.receive()
    if len(incoming) > 4:
        command, unit_no, digit = incoming.split(",")
        if int(unit_no) == UNIT_NO:
            if command == "go":
                for r in relay:
                    r.write_digital(0)
                bits = [0, 0, 0, 0, 0, 0, 0, 0]
                count = 0
                digit = int(digit)
                while digit > 1:
                    bits[count] = digit % 2
                    count += 1
                    digit = digit // 2
                bits[count] = digit
            for i, r in enumerate(reversed(bits)):
                if UNIT_NO == 3:
                    relay[i].write_digital(1-r)
                else:
                    relay[i].write_digital(r)
```

上述的程式中，UNIT\_NO代表的就是第幾串燈籠串，當收到屬於自己這串命令的時候，會把收到的命令剖析出來，每一個數字（放在digit變數中）先把它轉換成整數，之後把它從10進位轉換成2進位，再依序依照該位元是0或是1把訊號送給繼電器模組，以決定開關是打開還是關閉，也就是可以直接以數字的方式控制燈的明滅。以下是原始設計文字元的紙張：

![](/files/-Lh06Zlfe98DON2bV-55)

在7串燈籠的控制器都燒錄了之後，接下來就可以透過控制器去傳送要呈現的資訊給每一個燈籠串，其中一個範例如下：

```python
from microbit import *
import radio
bitmaps = {'?': [0, 64, 128, 138, 144, 96, 0],
'!': [0, 0, 0, 251, 0, 0, 0],
'l': [56, 124, 252, 63, 252, 124, 56],
'A': [7, 56, 72, 136, 72, 56, 7],
'B': [255, 255, 145, 145, 145, 105, 14],
'C': [60,66,129,129,129,129,70],
'D': [255,129,129,129,129,66,60],
'E': [255,137,137,137,137,137,137],
'F': [255,136,136,136,136,128,128],
'G': [60,66,129,137,137,138,79],
'H': [255,255,24,24,24,255,255],
'I': [129,129,129,255,129,129,129],
'J': [132,130,129,255,128,128,128],
'K': [0,255,8,24,36,66,129],
'L': [255,1,1,1,1,7,0],
'M': [255,192,112,53,112,192,255],
'N': [255,192,32,16,8,7,255],
'O': [60,66,129,129,129,66,60],
'P': [0,0,255,136,136,112,0],
'Q': [62,66,129,137,70,62,1],
'R': [127,200,136,136,140,114,1],
'S':[0,2,98,146,146,140,128],
'T':[128,128,128,255,128,128,128],
'U':[252,2,1,1,1,2,252],
'V':[224,56,14,3,14,56,224],
'W':[124,2,3,124,3,2,124],
'X':[193,66,36,24,24,36,199],
'Y':[192,32,16,15,16,32,192],
'Z':[195,131,133,137,145,161,199],
'9':[0,114,137,137,137,126,0],
'8':[0,110,145,145,145,110,0],
'7':[0,224,128,143,144,224,0],
'6':[0,126,137,145,145,78,0],
'5':[0,0,243,145,145,142,0],
'4':[0,24,40,72,255,8,0],
'3':[0,66,129,145,145,110,0],
'2':[0,97,131,133,137,113,0],
'1':[0,33,65,255,1,0,0],
'0':[0,126,129,129,129,126,0],
' ':[0, 0, 0, 0, 0, 0, 0],
'a':[255, 255, 255, 255, 255, 255, 255]}

radio.on()
RADIO_DELAY = 100

def ani_banner(banner, d):
    for char in banner:
        lines = bitmaps[char]
        for i, line in enumerate(lines, 1):
            radio.send("go,{},{}".format(i, line))
            sleep(RADIO_DELAY)
        sleep(d)
def ani_banner_shift(banner, d):
    all_chars = [0, 0, 0, 0, 0, 0]
    for char in banner:
        all_chars += bitmaps[char]
    all_chars += [0, 0, 0, 0, 0, 0, 0]
    for i in range(len(all_chars)-7):
        for j in range(i, i+7):
            radio.send("go,{},{}".format(j-i+1, all_chars[j]))
            sleep(RADIO_DELAY)
        sleep(d)

banners = ['lNKUST']
while True:
    if button_a.was_pressed():
        while True:
            display.show(Image.HAPPY)
#           ani_banner_shift("N K U S T ", 50)
#            sleep(2000)
            for banner in banners:
                ani_banner(banner, 1000)
            sleep(2000)
    else:
        display.show(Image.HEART)
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://nkust.gitbook.io/micro-bit/zuo.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
