# MicroPython操作每一顆LED

## 輪流點亮每一顆LED

micro:bit除了可以利用show和scroll來操作LED矩陣之外，每一個LED也都有自己的x, y座標，透過這些x, y座標即可獨立地操作每一顆LED的亮度，而操作這些個別的LED的指令是set\_pixel函數。請練習以下的程式：

```python
from microbit import *

for x in range(5):
    for y in range(5):
        display.set_pixel(x, y, 9)
        sleep(200)
```

在上面的程式中會從左上角的LED開始，由上而下，由左而右依序點亮每一顆LED，直到點亮全部的LED為止。請再練習以下的程式，比較看看和上一個程式執行結果有何不同：

```python
from microbit import *

for y in range(5):
    for x in range(5):
        display.set_pixel(x, y, 9)
        sleep(200)
```

仔細觀察上面兩個程式的差異，相信同學們對於LED矩陣的x, y座標就能夠有更加清楚的理解了。那麼，接下來，如果我們不想要填滿整個LED矩陣，而只是想讓那個LED在畫面上移動呢？答案是只要適時地加入display.clear()指令清除畫面即可，程式如下：

```python
from microbit import *

while True:
    for x in range(5):
        for y in range(5):
            display.clear()
            display.set_pixel(x, y, 9)
            sleep(200)
```

## 為每一顆LED編個別的號碼

如果不使用display.clear()的話，為了清除上一個LED，需要使用另外一個變數來記錄上一個LED的位置，為了避免記錄2個數字，我們只使用1個數字來代替每一個LED，實際要顯示時再進行數字的轉換：

```
from microbit import *
counter, old = 0, 0
while True:
    x = old % 5
    y = old // 5
    display.set_pixel(x, y, 0)

    x = counter % 5
    y = counter // 5
    display.set_pixel(x, y, 9)
    sleep(200)
    old = counter
    counter = counter + 1
    if counter > 24: 
        counter = 0
```

程式的邏輯是這樣的，把LED矩陣的最左上角那顆LED編號為0，它的右邊的編號是1，再來是2，也就是第一列（其實是第0列）的LED分別是0到4，第二列（其實在內部是第1列）為5到9，依此類推。原有以x, y座標編號的LED如下圖所示：

![](/files/-LePApdFpSdFrCX5MR2C)

我們以單一數字來編號的情形是以下這樣的：

![](/files/-LePBGkpEVj6X1jHD7AM)

對照兩者之間的差異，意思是在程式內部編號4的那顆LED實際要顯示的時候其座標是(4, 0)，編號5的那顆座標是(1,1)，編號24的那顆是(4, 4)，依此類推。假設要顯示編號是n的LED，則(x, y)座標轉換的公式如下：

$$
x = n % 5 \\
y = n // 5
$$

其中%是取餘數，而//則是取整數的意思。瞭解了上述的原理，相信同學們應該就可以理解上述程式的邏輯了。我們設定了2個變數分別是counter和old，一開始兩個變數都設為0（第2行），每一次要顯示新的LED之前要先把舊的LED關閉（第6行），在顯示了新的LED之後，就把新的LED編號記在old變數之中（第12行），之後再新增counter的內容（第13行）。

不過每一次在顯示LED的時候都要進行一次轉換（第4行到第5行以及第8行和第9行），比較方便的方法是設計一個副程式來專心做這件事，方法如下：

```python
from microbit import *

def setLED(number, value):
    x = number % 5
    y = number // 5
    display.set_pixel(x, y, value)
    
counter, old = 0, 0
while True:
    setLED(old, 0)
    setLED(counter, 9)
    sleep(200)
    old = counter
    counter = counter + 1
    if counter > 24: 
        counter = 0
```

雖然程式的行數看起來差不多，但是有了這個副程式setLED(number, value)，在主程式的邏輯就會更容易理解。有了這個編號的方式，就可以使用程式讓LED依自訂的順序點亮，例如要倒過來點亮（移動）也只要做些小改變就好了：

```python
from microbit import *

def setLED(number, value):
    x = number % 5
    y = number // 5
    display.set_pixel(x, y, value)
    
counter, old = 24, 24
while True:
    setLED(old, 0)
    setLED(counter, 9)
    sleep(200)
    old = counter
    counter = counter - 1
    if counter < 0: 
        counter = 24
```

## 電 子輪盤

以下是電子輪盤的程式碼：

```
from microbit import *

def setLED(number, value):
    x = number % 5
    y = number // 5
    display.set_pixel(x, y, value)

seq = [0, 1, 2, 3, 4, 9, 14, 19, 24, 23, 22, 21, 20, 15, 10, 5]
counter, old = 0, 0
while True:
    setLED(seq[old], 0)
    setLED(seq[counter], 9)
    sleep(100)
    old = counter
    counter = counter + 1
    if counter >= len(seq): 
        counter = 0
```

以下是正轉加上反轉的程式範例，不同於上面程式，這次我們利用for迴圈的方式來解決這個問題：

```python
from microbit import *

def setLED(number, value):
    x = number % 5
    y = number // 5
    display.set_pixel(x, y, value)

seq = [0, 1, 2, 3, 4, 9, 14, 19, 24, 23, 22, 21, 20, 15, 10, 5]
old = seq[0]
while True:
    for counter in seq:
        setLED(old, 0)
        setLED(counter, 9)
        sleep(100)
        old = counter
    for counter in reversed(seq):
        setLED(old, 0)
        setLED(counter, 9)
        sleep(100)
        old = counter
```

{% hint style="info" %}
其實上面這個程式的兩個內迴圈的內容幾乎是一樣的，但是old和counter這兩個變數所代表的意義是不一樣的，同學們可以看得出來嗎？
{% endhint %}

透過以上的顯示能力，接下來就可以搭配按鈕玩電子輪盤的遊戲了。


---

# 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/micropython-cao-zuo-guang.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.
