// 以下で使っている バッククォート ` は、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
}
}