空スケッチをいれてuno r3にesp01をtx,rxをクロスしないで接続する
ATを入れる際に、baudrateが115200でないと接続できんのを確かめた!
ソフトシリアルを使うときは9600にする必要があるらしいが以下のサンプルコードは
115200でesp01と通信しているようだ。。。ゼロからよくわかる!Arduino電子工作 より
空スケッチをいれてuno r3にesp01をtx,rxをクロスしないで接続する
ATを入れる際に、baudrateが115200でないと接続できんのを確かめた!
ソフトシリアルを使うときは9600にする必要があるらしいが以下のサンプルコードは
115200でesp01と通信しているようだ。。。ゼロからよくわかる!Arduino電子工作 より
まずserverにおりてgo run main.goでaddress with portをcheck
package main
// TinyGo Pico W HTTP Client
// Build with -scheduler=tasks
import (
"context"
"errors"
"io"
"log/slog"
"machine"
"net/netip"
"time"
"github.com/soypat/cyw43439"
"github.com/soypat/cyw43439/examples/cywnet"
"github.com/soypat/cyw43439/examples/cywnet/credentials"
"github.com/soypat/lneto/http/httpraw"
"github.com/soypat/lneto/ipv4"
"github.com/soypat/lneto/tcp"
)
const (
connTimeout = 5 * time.Second
tcpbufsize = 2030
// HTTPサーバーのIPアドレスとポート
serverAddrStr = "192.168.0.6:8080"
ourHostname = "tinygo-http-client"
)
// DHCPで要求するIPアドレス
var requestedIP = [4]byte{192, 168, 0, 99}
func main() {
// USBシリアル接続待ち
time.Sleep(2 * time.Second)
logger := slog.New(
slog.NewTextHandler(
machine.Serial,
&slog.HandlerOptions{
Level: slog.LevelInfo,
},
),
)
println("--- Pico W HTTP Client Start ---")
// ========================================
// Wi-Fi 初期化
// ========================================
devcfg := cyw43439.DefaultWifiConfig()
devcfg.Logger = logger
cystack, err := cywnet.NewConfiguredPicoWithStack(
credentials.SSID(),
credentials.Password(),
devcfg,
cywnet.StackConfig{
Hostname: ourHostname,
MaxActiveTCPPorts: 1,
},
)
if err != nil {
panic("WiFi setup failed: " + err.Error())
}
// ========================================
// ネットワーク処理開始
// ========================================
go loopForeverStack(cystack)
// ========================================
// DHCP
// ========================================
dhcpResults, err := cystack.SetupWithDHCP(
cywnet.DHCPConfig{
RequestedAddr: netip.AddrFrom4(requestedIP),
},
)
if err != nil {
panic("DHCP failed: " + err.Error())
}
logger.Info(
"DHCP complete",
slog.String(
"addr",
ipv4.String(dhcpResults.AssignedAddr4),
),
)
// ========================================
// HTTPサーバーアドレス
// ========================================
serverAddr, err := netip.ParseAddrPort(serverAddrStr)
if err != nil {
panic("Server address error: " + err.Error())
}
// ========================================
// TCPスタック
// ========================================
stack := cystack.StackAsync()
rstack := stack.StackRetrying(
cywnet.DefaultStackBackoff,
)
// ========================================
// TCP接続設定
// ========================================
var conn tcp.Conn
err = conn.Configure(
tcp.ConnConfig{
RxBuf: make([]byte, tcpbufsize),
TxBuf: make([]byte, tcpbufsize),
TxPacketQueueSize: 3,
// lneto v0.4.0 では必須 ここが重要げ
RWBackoff: cywnet.DefaultStackBackoff,
},
)
if err != nil {
panic("conn configure: " + err.Error())
}
// ========================================
// HTTP GET リクエスト作成
// ========================================
var hdr httpraw.HeaderV1
hdr.SetMethod("GET")
hdr.SetRequestTarget(
"/update?t=23&h=45",
)
hdr.SetProtocol("HTTP/1.1")
hdr.Set(
"Host",
serverAddr.String(),
)
hdr.Set(
"Connection",
"close",
)
reqbytes, err := hdr.AppendRequest(nil)
if err != nil {
panic("HTTP request error: " + err.Error())
}
logger.Info(
"http:ready",
slog.String("serveraddr", serverAddrStr),
)
// ========================================
// TCP接続・HTTP送信
// ========================================
rxBuf := make([]byte, 4096)
for {
time.Sleep(2 * time.Second)
// ランダムなローカルポート
localPort := uint16(stack.Prand32()>>17) + 1024
logger.Info(
"TCP dialing",
slog.String("server", serverAddrStr),
)
// TCP接続
err = rstack.DoDialTCP(
context.Background(),
&conn,
localPort,
serverAddr,
connTimeout,
3,
)
if err != nil {
logger.Error(
"TCP dial failed",
slog.String("err", err.Error()),
)
closeConn(&conn)
continue
}
logger.Info("TCP connected")
// ====================================
// HTTP GET送信
// ====================================
logger.Info(
"HTTP GET sending",
slog.String(
"path",
"/update?t=23&h=45",
),
)
_, err = conn.Write(reqbytes)
if err != nil {
logger.Error(
"HTTP write failed",
slog.String("err", err.Error()),
)
closeConn(&conn)
continue
}
// 送信完了待ち
err = conn.Flush()
if err != nil {
logger.Error(
"HTTP flush failed",
slog.String("err", err.Error()),
)
closeConn(&conn)
continue
}
// ====================================
// HTTPレスポンス受信
// ====================================
println("--- HTTP Response ---")
_ = conn.SetReadDeadline(
time.Now().Add(5 * time.Second),
)
for {
n, readErr := conn.Read(rxBuf)
if n > 0 {
_, _ = machine.Serial.Write(
rxBuf[:n],
)
}
if readErr != nil {
if !errors.Is(readErr, io.EOF) {
logger.Info(
"HTTP read finished",
slog.String("err", readErr.Error()),
)
}
break
}
if n == 0 {
break
}
}
println("\n--- HTTP Complete ---")
closeConn(&conn)
// 1回送信して終了
return
}
}
// ============================================
// TCP接続終了処理
// ============================================
func closeConn(conn *tcp.Conn) {
_ = conn.Close()
for i := 0; i < 50; i++ {
if conn.State().IsClosed() {
break
}
time.Sleep(100 * time.Millisecond)
}
conn.Abort()
}
// ============================================
// ネットワーク処理ループ
// ============================================
func loopForeverStack(stack *cywnet.Stack) {
for {
send, recv, _ := stack.RecvAndSend()
if send == 0 && recv == 0 {
time.Sleep(5 * time.Millisecond)
}
}
}
fseiigojp@fseigojpPC:~$ source circup-env/bin/activate
(circup-env) fseiigojp@fseigojpPC:~$ circup adafruit_requests
Usage: circup [OPTIONS] COMMAND [ARGS]...
Try 'circup --help' for help.
Error: No such command 'adafruit_requests'.
(circup-env) fseiigojp@fseigojpPC:~$ circup install adafruit_requests
Found device raspberry_pi_pico2_w at /run/media/fseiigojp/CIRCUITPY, running CircuitPython 10.3.1.
Downloading 'py' bundle for adafruit/Adafruit_CircuitPython_Bundle (20261028).
py:
Extracting: [####################################] 100%
OK
Downloading '10mpy' bundle for adafruit/Adafruit_CircuitPython_Bundle (20261028).
10.x-mpy:
Extracting: [####################################] 100%
OK
Using latest bundle for adafruit/Adafruit_CircuitPython_Bundle (20261028).
Using latest bundle for adafruit/CircuitPython_Community_Bundle (20261008).
Searching for dependencies for: ['adafruit_requests']
Ready to install: ['adafruit_connection_manager', 'adafruit_requests']
Installed 'adafruit_connection_manager'.
Installed 'adafruit_requests'.
(circup-env) fseiigojp@fseigojpPC:~$
以後は同一LANでかつ2.5GHz帯であることが重要
ーーーーーーーーーーーーーーーーーーーーーーーーー
settings.toml (設定ファイル)
同じくルート(CIRCUITPY ドライブの直下)に配置してください。これがないとWi-Fiにーーーcode.pyでmonitorはthonnyをもちいるーーーーーーーーーーー
import os
import ssl
import wifi
import socketpool
import adafruit_requests
# ----------------------------------------------------
# 1. Wi-Fiへの接続
# ----------------------------------------------------
print("Wi-Fiに接続中...")
try:
# settings.toml からWi-Fi情報を読み込んで接続
wifi.radio.connect(
os.getenv("CIRCUITPY_WIFI_SSID"),
os.getenv("CIRCUITPY_WIFI_PASSWORD")
)
print(f"接続成功! IPアドレス: {wifi.radio.ipv4_address}")
except Exception as e:
print(f"Wi-Fi接続エラー: {e}")
raise
# ----------------------------------------------------
# 2. ネットワークセッションのセットアップ
# --------------httpsのみでなくhttpにもアクセスできる--------------------------------------
pool = socketpool.SocketPool(wifi.radio)
ssl_context = ssl.create_default_context()
requests = adafruit_requests.Session(pool, ssl_context)
# ----------------------------------------------------
# 3. HTTP GET リクエストの送信
# ----------------------------------------------------
# テスト用のURL(JSONデータを返すパブリックAPI)
URL = "http://192.168.0.10:3000"
print(f"GETリクエストを送信中: {URL}")
try:
response = requests.get(URL)
print(f"ステータスコード: {response.status_code}")
print("-" * 40)
# パターンA: レスポンスを「テキスト」としてそのまま表示する場合
print("【テキストとして表示】")
print(response.text)
print("-" * 40)
# パターンB: レスポンスを「JSON」として解析して特定のデータを抜く場合
print("【JSONとして解析して表示】")
data = response.json()
print(f"送信元IP (origin): {data.get('origin')}")
print(f"ユーザーエージェント (headers): {data.get('headers', {}).get('User-Agent')}")
# 使い終わったらクローズ
response.close()
except Exception as e:
print(f"リクエストエラー: {e}")
print("-" * 40)
print("処理が完了しました。")
//-------------------------------------------------------------------------------------------
// Tested Module : ERC1602-4, EASTRISING TECHNOLOGY CO,.LTD.
// Drive IC : ST7032
// INTERFACE : I2C
// VDD : 2.7V-5.5V
// Tested with MCU : Arduino Uno, Attiny85@1mhz(5.0V), Attiny85@8mhz(5.0V) and ESP8266(3.3V)
//-------------------------------------------------------------------------------------------
#include <LCD_ST7032.h> // library managerでzipでなくて成功した
LCD_ST7032 lcd;
void setup() {
lcd.begin();
lcd.setcontrast(24); //contrast value range is 0-63, try 25@5V or 50@3.3V as a starting value
}
void loop() {
static int counter = 0;
// Write a piece of text on the first line...
lcd.setCursor(0, 0); //LINE 1, ADDRESS 0
lcd.print("HelloYou");
// Write the counter on the second line...
lcd.setCursor(1, 0);
lcd.print(counter/10, DEC);
lcd.write('.');
lcd.print(counter%10, DEC);
lcd.write(' ');
delay(500);
counter++;
}
// smpの有無は関係なし
---------------------------------------------------------
#include <Wire.h>
#include <Adafruit_BME280.h>
Adafruit_BME280 bme; // I2C接続
void setup() {
Serial.begin(115200);
while(!Serial);
// BME280のI2Cアドレスは一般的に 0x76 または 0x77
if (!bme.begin(0x76)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
}
void loop() {
Serial.print("Temperature = ");
Serial.print(bme.readTemperature());
Serial.println(" *C");
Serial.print("Pressure = ");
Serial.print(bme.readPressure() / 100.0F);
Serial.println(" hPa");
Serial.print("Humidity = ");
Serial.print(bme.readHumidity());
Serial.println(" %");
delay(1000);
}
---------------------------------------------------
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLEDの幅(ピクセル)
#define SCREEN_HEIGHT 64 // OLEDの高さ(ピクセル)※32の場合は32に変更
// SSD1306ディスプレイの宣言(リセットピンがない場合は -1)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void setup() {
Serial.begin(115200);
// SSD1306のI2Cアドレスは一般的に 0x3C
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // 起動失敗時はここでストップ
}
display.clearDisplay(); // 画面バッファをクリア
display.setTextSize(1); // 文字サイズ(1〜)
display.setTextColor(SSD1306_WHITE); // 文字色(白)
display.setCursor(0, 0); // 左上にカーソルを移動
display.println("Hello, Pico!");
display.println("SSD1306 OLED Test");
display.display(); // 実際に画面に描画を反映
}
void loop() {
// ループ処理(今回は静止画面のまま)
}
--------------以下は最初は動くがだんだんremote errorとなる。。。。tethering revenge
kill -9 $(lsof -t -i:3000)でいちいちportを閉じるのが重要だった
//$ mkdir thermo-server
// $ cd thermo-server
//$ npm init -y-----------原著どうり-----wifi環境よわく、tetheringで動かしてOKだった----------------------------
const express = require('express');
const ip = require('ip');
const app = express();
const addr = ip.address();
const port = 3000;
let temperature = '0.0';
let humidity = '0';
app.get('/update', (req, res) => {
if (req.query.t) temperature = req.query.t;
if (req.query.h) humidity = req.query.h;
res.status(200).send('OK');
});
app.get('/', (req, res) => {
res.setHeader('Content-Type', 'text/html');
res.send(`
<html>
<body>
<h1>${temperature}</h1>
<h1>${humidity}</h1>
</body>
</html>
`);
});
// go get tinygo.org/x/drivers
// tinygo flash -target pico . after set boot mode at pico
package main
import (
"fmt"
"machine"
"time"
"tinygo.org/x/drivers/sht3x"
)
func main() {
// シリアル通信(USB)の準備を待つためのディレイ
time.Sleep(2 * time.Second)
fmt.Println("--- SHT3x 温湿度センサー 開始 ---")
// 1. I2Cの初期化 (Picoの標準ピン GPIO4/GPIO5 を使用)
err := machine.I2C0.Configure(machine.I2CConfig{
Frequency: machine.TWI_FREQ_400KHZ, // 400kHz
SDA: machine.GP4, // Pin 6
SCL: machine.GP5, // Pin 7
})
if err != nil {
println("I2Cの初期化に失敗しました:", err.Error())
return
}
// 2. SHT3x ドライバーの初期化
// ※ アドレスはモジュールによって 0x44 (デフォルト) または 0x45 です。
// ※ 動かない場合は sht3x.AddressB (0x45) に変更してみてください。
sensor := sht3x.New(machine.I2C0)
sensor.Address = sht3x.AddressA // 0x44
// 3. 2秒ごとにデータを読み取って表示するループ
for {
// センサーから温度と湿度を読み取る
//(内部でSHT3xのコマンド送信、データ取得、CRCチェックが行われます)
temp, humi, err := sensor.ReadTemperatureHumidity()
if err != nil {
fmt.Println("データの読み取りに失敗しました:", err.Error())
} else {
// tinygoのドライバーは、温度を「ミリ度(1/1000℃)」、湿度を「1/100 %」で返します
// 例: 25000ミリ度 = 25.00℃
tCelsius := float64(temp) / 1000.0
hPercent := float64(humi) / 100.0
// シリアルモニターに出力
fmt.Printf("温度: %.2f °C | 湿度: %.2f %%\n", tCelsius, hPercent)
}
time.Sleep(2 * time.Second)
}
}
picocom -b 115200 --omap delbs -s "sz --xmodem" /dev/ttyACM0 で転送可能となる
ctl-a,ctl-xで終了
https://qiita.com/ksakabe/items/2ecfcfd346ef7f857b34 も参考になる
mmbasic picocomでpcからpicoへmmbasicを贈りたいPicoMite (MMBasic)
を実行中のRaspberry Pi PicoへPCからファイルを転送するには、Pico側のXMODEM RECEIVEコマンドと、picocom のXMODEM送信機能(Ctrl-A 続いて Ctrl-S) を組み合わせて使用します。あらかじめホストPC側に lrzsz(sxコマンド)をインストール。
1.転送の手順PicoMite側で受信待機picocomでPicoに接続します。MMBasicのプロンプトで次のように入力してEnterキーを押します。
XMODEM RECEIVE
コードは注意してご使用ください。(※画面が止まった/待機状態になったようになります)
picocomからファイルを送信キーボードの
Ctrl-A を押し、続けて Ctrl-Sを押します。画面下部に送信する、そのPCディレクトリのファイルのパス(ファイル名)を尋ねられるので、PC側のファイル名を入力してEnterキーを押すと転送が始まります。
cf 保存されたファイルの一覧を見る
(FILES)SDカードや内蔵フラッシュドライブに保存されているファイル名の一覧を表示します。basic FILES
2. ファイルの中身を画面に表示する
(TYPE)転送されたプログラムの内容が正しいか、テキストとして画面に表示して確認します。basic TYPE "try.bas"
3. プログラムをメモリに読み込んで実行する
(LOAD RUN)ファイルをメモリにロードして実行します。basic LOAD "try.bas" RUN
4.プログラムをメモリからセーブしてマイコンでfilesできるようにする
(SAVE) basic SAVE "filename.bas"
5.プログラムをその場で編集・確認する
(EDIT)PicoMite内蔵のフルスクリーンエディタでファイルを開きます。basic EDIT "try.bas"
F1 キー(またはCtrl+Q)を押すとメニューが出るので、保存して終了、または保存せずに終了を選べます。
6.メモリ上のプログラムを消去するにはbasic new,
フラッシュ上のプログラムを消去するにはbasic kill "filename.bas"
----------------------------------------------------------------------------
sudo picocom -b 115200 --omap delbs /dev/ttyACM0と,もう一つxterminalを立ち上げる
1. MMBasic 側で受信待機にする
XMODEM RECEIVE
XMODEM RECEIVE "foo.bas"
Ctrl+A を押した後、:exec !! sx foo.bas と入力するか、一度端末をバックグラウンドにして以下のようにリダイレクトします。 [1]sx foo.bas < /dev/ttyACM0 > /dev/ttyACM0
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
まずエディタからもどってRAM内容をsave "foo.bas"とする成功しているかfilesで確認する1. MMBasic(マイコン)側で送信コマンドを実行する- SDカードやフラッシュ内のファイルを送信する場合:basic
XMODEM SEND "foo.bas"
コードは注意してご使用ください。 - 現在メモリ(RAM)にあるプログラムをそのまま送信する場合:basic
XMODEM SEND
コードは注意してご使用ください。
2. PC(Linux)側で XMODEM 受信を実行する一般的なシリアルポート(例: /dev/ttyACM0)で直接やり取りする場合:
端末(ターミナル)を開き、以下のコマンドを実行してファイルを受け取ります。bashrx foo.bas < /dev/ttyACM0 > /dev/ttyACM0
コードは注意してご使用ください。