mutex.inoではtask1が優先的に実行されるが間違いではないとのこと
nomutex.inoではtask1とtask2が交互実行されたがMutexがきかんのがわかった
-----------------eventgroup.ino OK on raspico -----------------------
------------message buffer on pico------------------------
mutex.inoではtask1が優先的に実行されるが間違いではないとのこと
nomutex.inoではtask1とtask2が交互実行されたがMutexがきかんのがわかった
-----------------eventgroup.ino OK on raspico -----------------------
// 以下で使っている バッククォート ` は、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
}
}
毎回以下は一緒
kaluma bundle ./index.js 依存ライブラリがあろうとなかろうと
kaluma flash ./index.js --bundle こう書かんといかんようになっている
kalumas shell で .hi がでたらコードが自動開始される 実行は.loadでおこなう
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
コードと回路が以下にある
avascript.plainenglish.io/physical-computing-with-javascript-3-8-reading-state-of-switch-106137a2f9d6 :: reading state of button
const LED = 15;
const BTN = 14;
pinMode(LED,OUTPUT);
pinMode(BTN,INPUT_PULLUP);
setWatch(() => {
digitalToggle(LED);
},BTN,FALLING,10);
-------------------------------------------------------------------------
https://javascript.plainenglish.io/physical-computing-with-javascript-4-8-led-dimming-403696103d2f :: led dimming
const LED = 15;
const POT = 26;
setInterval(() => {
let v = analogRead(POT);
analogWrite(LED,v);
},100);
------------------以下はraspicoにした、raspicowはうまくいかん、リベンジ--------
https://github.com/niklauslee/dht で成功
const pin = 15;
const {DHT} = require('dht');
const dht = new DHT(pin, DHT.DHT11);
let result = dht.read();
if (result) {
console.log(result);
console.log("Humidity: " + dht.humidity + " %");
console.log("Temperature: " + dht.temperature + " C");
} else {
console.log('Failed to read');
}
kaluma shellで.loadするとOKだった
-----------------------------------------------------------
https://github.com/pankleks/picomqtt をインストしてnode_modules/picomqttにもぐる そこでkaluma bundle ./index.js --bundleしてブートモードにせずにkaluma shell & .load
const WiFi = require("wifi").WiFi,
{ PicoMQTT } = require("./picomqtt.min");
const wifi = new WiFi();
wifi.connect({ ssid: "your-ssid", password: "your-password" }, (ex) => {
if (ex)
console.error(ex);
else {
console.log("wifi connected");
const mqtt = new PicoMQTT("broker.hivemq.com", { clientId: board.uid });
mqtt.on("connected", () => {
console.log("mqtt connected");
mqtt.subscribe("test/topic");
mqtt.publish("test/topic", "you should get this");
mqtt.publish("test/topic", "you should also get this");
mqtt.unsubscribe("test/topic");
mqtt.publish("test/topic", "you should not get this");
});
mqtt.on("message", (msg) => {
console.log(`mqtt message -> ${msg.topic}: ${msg.message}`);
});
mqtt.on("error", (ex) => {
console.log(`mqtt error -> ${ex.message || ex}`);
});
mqtt.on("disconnected", (reconnect) => {
console.log(`mqtt disconnected, reconnect = ${reconnect}`);
// if reconnect is true, mqtt will try to reconnect
});
mqtt.connect();
setTimeout(() => {
mqtt.disconnect(); // stop mqtt
}, 1000 * 120);
}
});
wifi connected
mqtt connected
mqtt message -> test/topic: you should get this
mqtt message -> test/topic: you should also get this
mqtt disconnected, reconnect = false
Webサーバーを一切含めず「PHPコマンド(CLI)単体」だけを再度インストールし直す ということでよろしいでしょうか?それであれば、以下のコマンドを順に実行してください。1. パッケージリストの更新bashsudo apt update
コードは注意してご使用ください。2. PHP(CLI)単体のみをインストール余計なWebサーバー系パッケージを連動させず、PHPの実行環境だけをピンポイントで導入します。bashsudo apt install --no-install-recommends php-cli php-common -y
コードは注意してご使用ください。3. インストールの確認bashphp -v
コードは注意してご使用ください。この後、PHPの動作テストを行いますか?それとも、特定の拡張モジュール(mbstringやcurlなど)が必要、あるいはComposer(パッケージ管理ツール)の導入に進みますか?これはアンインストもできますかはい、こちらもapt purge コマンドを使うことで完全にアンインストールできます。手順は先ほどと同様に、設定ファイルごと綺麗に削除します。1. PHP(単体)の完全削除bashsudo apt purge php-cli php-common -y
コードは注意してご使用ください。2. 残った不要な設定やライブラリの自動削除bashsudo apt autoremove --purge -y
コードは注意してご使用ください。3. 削除の確認「そのようなファイルやディレクトリはありません」または「command not found」と表示されれば削除完了です。bashphp -v
コードは注意してご使用ください。もしPHPの代わりに別のプログラミング言語(Python、Node.js、Go言語など)を試してみたい場合や、Dockerなどの仮想環境でPHPを動かしたい場合は、いつでも手順をご案内しますので教えてください!
php built-in server使いたいPHPのビルトイン(組み込み)サーバーは、特別な設定なしでコマンド1つで起動できる開発用の簡易Webサーバーです。起動の手順ターミナル(コマンドプロンプト)を開きます。公開したいファイル(ドキュメントルート)があるディレクトリに移動します。次のコマンドを実行します。bashphp -S localhost:8000
コードは注意してご使用ください。ブラウザで http://localhost:8000 にアクセスします。主なオプションドキュメントルートを指定する (-t)公開フォルダを分ける場合は -t オプションを使います。bashphp -S localhost:8000 -t public
コードは注意してご使用ください。サーバーを終了するターミナルで Ctrl + C を押します。詳しい仕様や機能については、PHP公式マニュアルのビルトインウェブサーバー を確認してください。もしよければ、表示させたいプロジェクトの構成(フォルダの場所など)を教えていただければ、具体的なコマンドをご案内します。PHPPHP: ビルトインウェブサーバー - Manualビルトインウェブサーバーでは、次のような機能を使用することができます。 * **ドキュメントルートの指定** `-t` ...QiitaPHPビルトインウェブサーバーで簡易Webサーバを立てる #PHP - QiitaPHP にはビルトインウェブサーバーがあり、コマンドを使って簡易Webサーバーを立てることができます。ローカル環境でHT...Read the DocsPHP ビルトインサーバーの利用 - Read the DocsPHP ビルトインサーバーの利用¶. PHP5.4.0 以降では、PHP の組み込みの Web サーバーを開発用に使うこ...すべて表示他のマイコンからgetするには他のマイコン(M5Stack、ESP32、Arduino、Raspberry Pi Pico Wなど)から同じネットワーク内にあるPHPビルトインサーバーにGETリクエストを送る場合、「サーバー側の起動IPのアドレス」と「マイコン側のプログラム」の2つの設定が必要です。1. サーバー側の準備(重要)マイコンからアクセスさせる場合、localhost ではなく 0.0.0.0(またはPCのローカルIPアドレス)を指定してサーバーを起動する必要があります。localhost のままだと、PCの外部からの接続をすべて遮断してしまいます。ターミナルで以下のように起動してください:bashphp -S 0.0.0.0:8000
コードは注意してご使用ください。※これにより、同じWi-Fi(ルーター)に繋がっている他のデバイスからのアクセスを受け付けられるようになります。2. PCのローカルIPアドレスを確認するマイコンに指定するためのPCのIPアドレス(192.168.x.x など)を調べます。Windows (コマンドプロンプト): ipconfig を実行し「IPv4 アドレス」を確認。Mac / Linux (ターミナル): ifconfig または ip a を実行し en0 や wlan0 の inet を確認。3. マイコン側のコード例 (ESP32 / Arduino IDE)以下は、Wi-Fi機能を備えたマイコン(ESP32など)でPHPサーバーからデータをGETする典型的なコード例です。cpp#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "あなたのWi-FiのSSID";
const char* password = "あなたのWi-Fiのパスワード";
// PCのローカルIPアドレスとポート、取得したいファイル名を指定
const char* serverUrl = "http://192.168.1";
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWi-Fi Connected!");
}
void loop() {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
// GETリクエストを送信
http.begin(serverUrl);
int httpResponseCode = http.GET();
if (httpResponseCode > 0) {
String payload = http.getString();
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
Serial.print("Response: ");
Serial.println(payload); // PHPが返したテキストを表示
} else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
http.end();
}
delay(10000); // 10秒ごとに実行
}
http://jh7ubc.web.fc2.com/Raspberry_Pi/Raspberry_Pi_Pico/Pi_Pico_AQM0802A.htmlを参考に結線した やはりmpyは事例豊富、mmbasicとかkalumajsは英語サイトだけ
pico-sdkはむずい、かわりにluaをesp8266でリベンジ、言語勉強はvlangをリベンジ
まあarduinolang,micropython,tinygoで困らんけどね PIC&Raspberry Piは休眠。。。。
from machine import Pin, I2C
import utime
# I2C
i2c = I2C(
0,
freq=100000,
scl=Pin(17),
sda=Pin(16)
)
addr = 0x3e
buf = bytearray(2)
# コマンド送信
def write_cmd(cmd):
buf[0] = 0x00
buf[1] = cmd
i2c.writeto(addr, buf)
# 文字送信
def write_char(char):
buf[0] = 0x40
buf[1] = char
i2c.writeto(addr, buf)
# 文字列表示
def lcd_print(text):
for c in text:
write_char(ord(c))
# カーソル位置
def LCD_cursor(x, y):
if y == 0:
write_cmd(0x80 + x)
if y == 1:
write_cmd(0xc0 + x)
# LCDクリア
def LCD_clear():
buf[0] = 0x00
buf[1] = 0x01
i2c.writeto(addr, buf)
utime.sleep(0.002)
# LCDホーム
def LCD_home():
buf[0] = 0x00
buf[1] = 0x02
i2c.writeto(addr, buf)
utime.sleep(0.002)
# LCD初期化
def LCD_init():
orders = [
0x38,
0x39,
0x14,
0x73,
0x56,
0x6c,
0x38,
0x0c,
0x01
]
utime.sleep(0.04)
for order in orders:
write_cmd(order)
utime.sleep(0.002)
# =========================
# メイン
# =========================
LCD_init()
LCD_clear()
LCD_home()
lcd_print("JH7UBC")
num = 0
while True:
LCD_cursor(0, 1)
lcd_print(str(num))
num = num + 1
utime.sleep(1)
ーーーーーーーーーーーーーーーーーーーーーーーー
import machine
import time
import dht
# GPIO4番ピンにデータ線を接続した場合
sensor = dht.DHT11(machine.Pin(4))
while True:
try:
# センサーからデータを計測
sensor.measure()
# 温度(摂氏)と湿度(%)を取得
temp = sensor.temperature()
hum = sensor.humidity()
print(f"温度: {temp} ℃, 湿度: {hum} %")
except Exception as e:
print("読み取りエラー:", e)
# 2秒ごとに取得(DHT11は1秒に1回制限)
time.sleep(2)
package main
import (
"machine"
"time"
)
func main() {
// 右ボタン(WIO_KEY_A)を入力ピン(プルアップ)として設定
buttonRight := machine.WIO_KEY_A // この書き方が正当
buttonRight.Configure(machine.PinConfig{Mode: machine.PinInputPullup})
// ブザーを出力ピンとして設定
for {
// ボタンは押されると「Low (false)」になります
if !buttonRight.Get() {
// ボタンが押されている間、簡易的にソフトウェアPWM(オン・オフ)で音を鳴らす
buzzer.High()
time.Sleep(1 * time.Millisecond)
buzzer.Low()
time.Sleep(1 * time.Millisecond)
} else {
// ボタンが離されているときはブザーを止める
buzzer.Low()
time.Sleep(10 * time.Millisecond)
// チャタリング防止とCPU負荷軽減 この時間はinput getができないのでチャタ防止となる
}
}
}
---------------------------------------------------
p158 code
package main
import(
"machine"
"time"
)
func main(){
pwm := machine.TCC0
pwm.Configure(machine.PWMConfig{})
channelA,_:=pwm.Channel(machine.BUZZER_CTR)
notes:=[]uint64{440,494,523,585,659,698,783}
i:=0
for{
pwm.SetPeriod(1e9/notes[i])
pwm.Set(channelA,pwm.Top()/2)
time.Sleep(100*time.Millisecond)
pwm.Set(channelA,0)
i=(i+1)%len(notes)
}
}
チャットくんに聞いてdht driverのヴァージョンに沿って以下に成功
package main
import (
"fmt"
"machine"
"time"
"tinygo.org/x/drivers/dht"
)
func main() {
// DHT11 DATA → Pico GP0
pin := machine.GP0
sensor := dht.New(pin, dht.DHT11)
for {
// 温度と湿度を同時に取得
temp, hum, err := sensor.Measurements()
if err != nil {
fmt.Printf("DHT11 Error: %v\n", err)
} else {
fmt.Printf(
"Temperature: %d.%d C, Humidity: %d.%d %%\n",
temp/10,
temp%10,
hum/10,
hum%10,
)
} // DHT11は最低でも約1秒空ける
time.Sleep(2 * time.Second)
}
}
flashはうまくいかんしboot modeはしばしば壊れ再起動が必要なんで
ubunt24 8G memoryでやることにした ubuntu26 26G memoryは再起動が遅い!
chap7をルートにしてgo mod init しておく
tinygo build -target wioterminal -o main.uf2 ./access_test/などとやる
できたはuf2をboot modeにしたwioterminalにコピペ
tinygo monitor /dev/ttyACM0 とやると結果を見ることができる
arduiniIDE2ではスムーズにいくブートモードへの移行(IDEが勝手にやってくれる)
tinygoではブートモードにリセットで移行しても失敗おおいのでubuntu再起動が必須となる
中華MINIーPCは再起動も起動も遅いんでtinygo on wioterminalは。。。。
一方raspicoでブートモードボタンおしながら指し直しブートモードにすると
tinygo flash -target pico main.goがあっさり成功 中華ミニPCで十分いける
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
ambd_flash_toolはウィンドウズでないと成功しなかった
https://github.com/sago35/tinygobook/blob/main/README.md にあるとおり
--branch JPでgit cloneが重要だった ウィンドウズでもウブンツでも
tinygo flashはできなかったが、ウブンツではブートモードの移行に失敗多く
システム再起動が多かったが、ウィンドウズではばっちりだった
いまのウィンドウズでは容量がすくなくarduinoでいろいろlibをいれるとレッドになりそ
よってtingyo専用やな 場合によってはwsl2もやめんといかんかも
------------------------go and tinygo 入れ直し----------------------------
sudo rm -rf /usr/local/go
sudo apt-get remove --purge tinygo
sudo rm -rf /usr/local/bin/tinygo /usr/local/lib/tinygo
package main
import (
"machine"
)
func main() {
pwm := machine.TCC0
pwm.Configure(machine.PWMConfig{})
channelA , _ := pwm.Channel(machine.BUZZER_CTR)
pwm.SetPeriod(uint64(1e9) / 440)
pwm.Set(channelA, pwm.Top()/2)
select{} // 何もせず、永久に停止状態で待つ
}
~
https://zenn.dev/askua/articles/05e143091c150c :: tinygo for pico
esp01でat commandつかっていく picowはめんどげ