2026年9月24日木曜日

tinygo raspberry pi pico :: with esp01AT,ws2812

  // 以下で使っている バッククォート ` は、Goでは「raw string literal(生文字列)」を表す!

package main
import (
    "fmt"
    "machine"
    "time"
)
const (
    SSID     = "Pikara2-91d8e4"
    PASSWORD = "090e219cbdbf5"
)

func main() {
    // ==========================================
    // Raspberry Pi Pico
    //
    // GP0 = UART0 TX -> ESP-01 RX
    // GP1 = UART0 RX <- ESP-01 TX
    // ==========================================
    uart := machine.UART0
    uart.Configure(machine.UARTConfig{
        BaudRate: 115200,
        TX:       machine.GP0,
        RX:       machine.GP1,
    })
    fmt.Println("================================")
    fmt.Println("Pico + ESP-01 WiFi test")
    fmt.Println("================================")
    // ESP-01起動待ち
    fmt.Println()
    fmt.Println("ESP-01 startup wait...")
    time.Sleep(3 * time.Second)

    // 受信バッファをクリア
    clearUART(uart)

    // ==========================================
    // AT
    // ==========================================
    fmt.Println()
    fmt.Println("================================")
    fmt.Println(">> AT")
    fmt.Println("================================")
    if !sendAT(uart, "AT", 3*time.Second) {
        fmt.Println("AT command failed")
        return
    }
    // ==========================================
    // WiFi Stationモード
    // ==========================================
    fmt.Println()
    fmt.Println("================================")
    fmt.Println(">> AT+CWMODE=1")
    fmt.Println("================================")

    if !sendAT(uart, "AT+CWMODE=1", 3*time.Second) {
        fmt.Println("CWMODE command failed")
        return
    }

    // ==========================================
    // WiFiアクセスポイントへ接続
    // ==========================================

    fmt.Println()
    fmt.Println("================================")
    fmt.Println(">> AT+CWJAP")
    fmt.Println("================================")

    cmd := `AT+CWJAP="` + SSID + `","` + PASSWORD + `"`

    if !sendAT(uart, cmd, 20*time.Second) {
        fmt.Println("WiFi connection failed")
        return
    }

    // ==========================================
    // IPアドレス確認
    // ==========================================

    fmt.Println()
    fmt.Println("================================")
    fmt.Println(">> AT+CIFSR")
    fmt.Println("================================")

    sendAT(uart, "AT+CIFSR", 5*time.Second)

    // ==========================================
    // 完了
    // ==========================================

    fmt.Println()
    fmt.Println("================================")
    fmt.Println("WiFi connection test finished")
    fmt.Println("================================")

    // ==========================================
    // 以後ESP-01からの受信を表示
    // ==========================================

    fmt.Println()
    fmt.Println("Waiting for ESP-01 data...")

    for {
        readUART(uart)
        time.Sleep(100 * time.Millisecond)
    }
}

// ==================================================
// ATコマンド送信
//
// ESP-01の回答を表示しながら待つ
//
// OK
// ERROR
// WIFI CONNECTED
// WIFI GOT IP
// などをそのまま表示する
// ==================================================

func sendAT(uart *machine.UART, command string, wait time.Duration) bool {

    // 受信バッファをクリア
    clearUART(uart)

    fmt.Println("SEND:")
    fmt.Println(command)

    // ATコマンド送信
    _, err := uart.Write([]byte(command + "\r\n"))

    if err != nil {
        fmt.Println("UART write error")
        return false
    }

    fmt.Println("RESPONSE:")

    start := time.Now()

    for time.Since(start) < wait {

        // ESP-01からの回答を読む
        response := readUART(uart)

        if response != "" {

            // ------------------------------------------
            // エラー
            // ------------------------------------------

            if contains(response, "ERROR") {
                fmt.Println()
                fmt.Println("ESP-01 returned ERROR")
                return false
            }

            // ------------------------------------------
            // WiFi接続成功
            // ------------------------------------------

            if contains(response, "WIFI GOT IP") {
                fmt.Println()
                fmt.Println("WiFi connected!")
                return true
            }

            // ------------------------------------------
            // 通常のATコマンド成功
            // ------------------------------------------

            if contains(response, "\r\nOK\r\n") ||
                contains(response, "\nOK\r\n") ||
                contains(response, "\nOK") {

                fmt.Println()
                fmt.Println("Command OK")
                return true
            }
        }

        time.Sleep(10 * time.Millisecond)
    }

    fmt.Println()
    fmt.Println("Timeout")

    return false
}

// ==================================================
// ESP-01からデータを読む
//
// 戻り値:
//   受信した文字列
// ==================================================

func readUART(uart *machine.UART) string {

    buf := make([]byte, 64)

    result := ""

    for uart.Buffered() > 0 {

        n, err := uart.Read(buf)

        if err != nil {
            return result
        }

        if n > 0 {

            data := string(buf[:n])

            // ESP-01の回答を即時表示
            fmt.Print(data)

            result += data
        }
    }

    return result
}

// ==================================================
// UART受信バッファをクリア
// ==================================================

func clearUART(uart *machine.UART) {

    buf := make([]byte, 64)

    for uart.Buffered() > 0 {

        _, _ = uart.Read(buf)
    }

    // 少し待って追加データが来ないことを確認
    time.Sleep(20 * time.Millisecond)

    for uart.Buffered() > 0 {

        _, _ = uart.Read(buf)
    }
}

// ==================================================
// 文字列検索
//
// stringsパッケージを使わず簡単に検索
// ==================================================

func contains(s string, sub string) bool {

    if sub == "" {
        return true
    }

    if len(sub) > len(s) {
        return false
    }

    for i := 0; i <= len(s)-len(sub); i++ {

        if s[i:i+len(sub)] == sub {
            return true
        }
    }

    return false
}

 

古いtinygoだと文句いわれながらチャットくんにつくてもらった 3.3v駆動のws2812

 package main

import (
    "image/color"
    "machine"
    "time"

    "tinygo.org/x/drivers/ws2812"
)

const numLEDs = 5
const ledPin = machine.GP15

func main() {
    ledPin.Configure(machine.PinConfig{Mode: machine.PinOutput})

    // ビットバン駆動の初期化
    ws := ws2812.New(ledPin)

    leds := make([]color.RGBA, numLEDs)

    for {
        // 1. 赤色に点灯
        fill(leds, color.RGBA{R: 0xFF, G: 0x00, B: 0x00})
        // colorsToBytesで変換した []byte を Write に渡す
        ws.Write(colorsToBytes(leds))
        time.Sleep(time.Second)

        // 2. 緑色に点灯
        fill(leds, color.RGBA{R: 0x00, G: 0xFF, B: 0x00})
        ws.Write(colorsToBytes(leds))
        time.Sleep(time.Second)
    }
}

func fill(leds []color.RGBA, c color.RGBA) {
    for i := range leds {
        leds[i] = c
    }
}

0 件のコメント:

コメントを投稿