micro:bit來報數

micro:bit沒有網路功能,但具有群組廣播的功能,如能善用這個功能,也可以幫每一個手頭擁有的micro:bit定址。今日的micro:bit程式作品便是讓micro:bit來報數。先選定一個micro:bit當作是伺服器,其他的micro:bit開機後按A鍵,便能向伺服端的micro:bit註冊,再由伺服端micro:bit給定一個流水編號傳送給client端的micro:bit便完成了定址的動作。伺服端的micro:bit按A鍵可以讓client的micro:bit從1開始報數,按B可以讓client的micro:bit倒數報數。若clinet端的某幾個micro:bit關掉了或是移走了,伺服端的micro:bit可以按A+B鍵,讓剩下的micro:bit重新取得編號來定址。

讓micro:bit定址有什麼好處?能夠定址讓我們可以一對多的控制所有的micro:bit,一起組合成某種大型的LED圖案或是動畫,或是clinet端裝上擴展板,伺服端就能控制某個client的馬達前進或後退,或是完成更多群組化的機器人動作。

client端的板子會呈現自己的流水編號,伺服端的板子則會呈現現在受控制的板子數量

編號定址過的micro:bit可程式呈現組合後的動畫,或是可受伺服端的micro:bit控制

將底下的程式碼貼上makecode的javascript上,即可以積木的方式呈現

micro:bit報數程式控制方式

client端:按A鍵會向伺服器micro:bit取得自己的編號

伺服端:

  1. 按A鍵會從1開始報數
  2. 按B鍵會倒數報數
  3. A+B鍵會重新設定micro:bit的client端的編號(有需要時才會用到)
  4. 按P0腳位會呈現簡單動畫:會出現向右的箭頭由1號一直傳遞到最後一號
  5. 按P2腳位會呈現簡單動畫:會出現向左的箭頭由最後一號傳遞到1號


程式內容:以javascrip的語法呈現,可把它貼上makecode的網站便會以積木的型態來呈現

伺服端程式如下:

let show = 0
let countBits = 0
let myBits: string[] = []
let bitsTemp: string[] = []
let temp = 0
input.onButtonPressed(Button.A, () => {
    radio.sendValue("clear", 0)
    basic.pause(1)
    temp = 0
    show = 1
    radio.sendValue("count", 0)
})
radio.onDataPacketReceived( ({ receivedString: name, receivedNumber: bitValue }) =>  {
    if (bitValue == -1) {
        myBits.push(name)
        radio.sendValue(name, countBits)
        countBits += 1
        if (temp == 0) {
            basic.showNumber(countBits)
        }
    }
    if (name == "getShow") {
        radio.sendValue("show", show)
    }
})
input.onButtonPressed(Button.AB, () => {
    temp = 1
    bitsTemp = []
    countBits = 0
    basic.showNumber(countBits)
    show = 0
    bitsTemp = myBits
    myBits = []
    radio.sendValue("reset", -1)
    basic.pause(1)
    radio.sendValue("show", show)
    basic.pause(1)
    for (let index = 0; index <= bitsTemp.length - 1; index++) {
        radio.sendValue("response", parseInt(bitsTemp[index]))
        basic.pause(1)
    }
    basic.showNumber(countBits)
    show = 1
    radio.sendValue("show", show)
    basic.pause(1)
    temp = 0
})
input.onPinPressed(TouchPin.P0, () => {
    radio.sendValue("clear", 0)
    basic.pause(200)
    radio.sendValue("arrowR", 0)
})
input.onPinPressed(TouchPin.P2, () => {
    radio.sendValue("clear", 0)
    basic.pause(200)
    radio.sendValue("arrowL", countBits - 1)
})
input.onButtonPressed(Button.B, () => {
    radio.sendValue("clear", 0)
    basic.pause(1)
    temp = 0
    show = 1
    radio.sendValue("countDown", countBits - 1)
})
basic.showLeds(`
    # # # # #
    # # # # #
    # # # # #
    # # # # #
    # # # # #
    `)
radio.setGroup(1)
show = 0
countBits = 0
temp = 0


client端的程式如下:

let myIndex = 0
let show = false
input.onButtonPressed(Button.A, () => {
    radio.sendValue("getShow", 0)
    basic.pause(50)
    radio.sendValue("" + control.deviceSerialNumber(), myIndex)
})
radio.onDataPacketReceived( ({ receivedString: name, receivedNumber: value }) =>  {
    if (name == "count" && value == myIndex) {
        show = true
        basic.pause(300)
        radio.sendValue("count", value + 1)
        showMyNum()
    }
    if (name == "countDown" && value == myIndex) {
        show = true
        basic.pause(300)
        if (myIndex > 0) {
            radio.sendValue("countDown", value - 1)
        }
        showMyNum()
    }
    if (name == "" + control.deviceSerialNumber()) {
        myIndex = value
        showMyNum()
    }
    if (name == "show") {
        show = value == 1
        showMyNum()
    }
    if (name == "response" && value == control.deviceSerialNumber()) {
        radio.sendValue("" + control.deviceSerialNumber(), myIndex)
    }
    if (name == "reset") {
        myIndex = value
        showMyNum()
    }
    if (name == "clear") {
        basic.clearScreen()
    }
    if (name == "arrowR" && value == myIndex) {
        basic.showArrow(ArrowNames.East)
        radio.sendValue("arrowR", value + 1)
        basic.clearScreen()
    }
    if (name == "arrowL" && value == myIndex) {
        basic.showArrow(ArrowNames.West)
        if (myIndex > 0) {
            radio.sendValue("arrowL", value - 1)
        }
        basic.clearScreen()
    }
})
function showMyNum()  {
    if (myIndex < 0) {
        basic.showString("?")
    } else {
        if (show) {
            basic.showNumber(myIndex + 1)
        } else {
            basic.showIcon(IconNames.Triangle)
        }
    }
}
basic.showString("?")
radio.setGroup(1)
myIndex = -1
show = false
radio.sendValue("getShow", 0)