Rust に付け焼き刃で入門する 3
Rust に付け焼き刃で入門する 2 の続き。
4. 所有権を理解する
Rust 独特の機能。「Rust を手っ取り早く解説」系の記事では、あまりよく挙動がわからなかったので、しっかり理解したい。
4.1. 所有権とは
所有権とは? - The Rust Programming Language 日本語版
プログラムが動作するにつれて、 定期的に使用されていないメモリを検索するガベージコレクションを持つ言語もありますが、他の言語では、 プログラマが明示的にメモリを確保したり、解放したりしなければなりません。Rustでは第3の選択肢を取っています: メモリは、コンパイラがコンパイル時にチェックする一定の規則とともに所有権システムを通じて管理されています。 どの所有権機能も、実行中にプログラムの動作を遅くすることはありません。
GC でも malloc/free でもない第3の方法が所有権 ownership システム。
この章の後半でスタックとヒープを交えて所有権の一部が解説されるので、ここでちょっと予行演習をしておきましょう。
- スタック:高速。LIFO。既知で固定サイズのデータに限る
- ヒープ:低速。使いたいときは領域を確保 allocate して、そのポインタを返す
いきなり結構低レベルな話になってきた。このあたりの概念は Rust に特有ということでもない。
コードが関数を呼び出すと、関数に渡された値(ヒープのデータへのポインタも含まれる可能性あり)と、 関数のローカル変数がスタックに載ります。関数の実行が終了すると、それらの値はスタックから取り除かれます。
ここも一般的なコールスタックの話。
一度所有権を理解したら、あまり頻繁にスタックとヒープに関して考える必要はなくなるでしょうが、 ヒープデータを管理することが所有権の存在する理由
なるほど。
- Rustの各値は、所有者と呼ばれる変数と対応している。
- いかなる時も所有者は一つである。
- 所有者がスコープから外れたら、値は破棄される。
このルールは明快なので、「手っ取り早く解説」系の記事でも読んで覚えている。
変数は、宣言された地点から、現在のスコープの終わりまで有効になります。
よくある感じ。スコープが何を指すかの説明がないが、とりあえずは { ... }
を思い描いておけばいいんだろうか。
Rustには、 2種類目の文字列型、
String
型があります。この型はヒープにメモリを確保するので、 コンパイル時にはサイズが不明なテキストも保持することができるのです。
ちなみに、もう一方の型(文字列リテラルの型)は &str
型のようだ。両者の名前が似ていて最初は???という感じだったが、よくある区別。
変数がスコープを抜ける時、Rustは特別な関数を呼んでくれます。[…] Rustは、閉じ波括弧で自動的に
drop
関数を呼び出します。
デストラクタ的な。
他の言語を触っている間に"shallow copy"と"deep copy"という用語を耳にしたことがあるなら、 データのコピーなしにポインタと長さ、許容量をコピーするという概念は、shallow copyのように思えるかもしれません。 ですが、コンパイラは最初の変数をも無効化するので、shallow copyと呼ばれる代わりに、 ムーブとして知られているわけです。
shallow copy だけだと二重解放の問題が起きるので、shallow copy っぽいことをしつつ、古い変数の方は無効にする。これがムーブ。なるほど、そういうことか。
ムーブによって「いかなる時も所有者は一つである」というルールが満たされる。すると、後は「所有者がスコープから外れたら、値は破棄される」というルールだけ用意しておけば、二重解放や、解放し忘れに悩まされることがなくなる。
Rustでは、 自動的にデータの"deep copy"が行われることは絶対にないわけです。それ故に、あらゆる自動コピーは、実行時性能の観点で言うと、 悪くないと考えてよいことになります。
ふむ。自動コピー automatic copy ってのは後で出てくるのかな。
型が
Copy
トレイトに適合していれば、代入後も古い変数が使用可能になります。
ルールはそんなに単純じゃなかった。他の言語も deep copy と shallow copy が混ざったりするので、それと同じだといえば同じだが。プリミティブだけでなく、例えば (i32, i32)
も Copy
らしい。
関数に変数を渡すと、 代入のようにムーブやコピーされます。
関数に変数を渡すと関数にムーブされる、というのはなんか独特な感じ。関数にムーブされた変数は、その関数を抜けるときに drop
される。変数が Copy
だったら、関数に渡すとムーブではなくコピーされる。参照渡しと値渡しのようなものではあるが…。
関数から値を返した場合は、drop
されずに呼び出し元(の新たな変数)にムーブされる。
4.2. 参照と借用
参照と借用 - The Rust Programming Language 日本語版
fn main() { let s1 = String::from("hello"); // s1 を渡すと calculate_length にムーブしてしまうが、次の println! でもう一度使いたいので、関数から返してもらう必要がある let (s2, len) = calculate_length(s1); println!("The length of '{}' is {}.", s2, len); } fn calculate_length(s: String) -> (String, usize) { let length = s.len(); (s, length) }
受け取った変数をいちいち返すのは煩雑なので、参照 reference という仕組みがある。
fn main() { let s1 = String::from("hello"); let len = calculate_length(&s1); println!("The length of '{}' is {}.", s2, len); } fn calculate_length(s: &String) -> usize { s.len() }
変数名や型注釈に &
をつける。C言語っぽい記法(忘れていたが、C の &
はアドレス演算子という名前らしい)。
この
&s1
という記法により、s1
の値を参照する参照を生成することができますが、これを所有することはありません。所有してないということは、指している値は、参照がスコープを抜けてもドロップされないということです。
意味の取りづらい日本語だが、原文を見てみるに、「&s1
って書くと s1
の参照を作ることができるけど、参照 &s1
は変数 s1
を所有するわけじゃないよ。参照 &s1
があるスコープを抜けたとしても、&s1
が参照している変数 s1
はドロップされないよ。&s1
は s1
を所有していないからね。」ということらしい。
関数の引数に参照を取ることを借用と呼びます。
borrowing。
変数が標準で不変なのと全く同様に、参照も不変なのです。
&foo
は不変。&mut foo
で渡せば、可変になる。
ところが、可変な参照には大きな制約が一つあります: 特定のスコープで、ある特定のデータに対しては、 一つしか可変な参照を持てないことです。
さらに不変な参照をしている間は、可変な参照をすることはできません。
競合を防ぐため。納得できる。一方で、不変な参照だけであれば、いくつも同時に作ることができる。
対照的にRustでは、コンパイラが、 参照がダングリング参照に絶対ならないよう保証してくれます
浮いた参照にならないように、コンパイルエラーにしてくれる。
4.3. スライス型
スライス型 - The Rust Programming Language 日本語版
所有権のない別のデータ型は、スライスです。
なるほど? 「別の」ということは、参照とも違う扱いなんだろうか。Python のスライスみたいなものかな?
for (i, &item) in bytes.iter().enumerate() {
このへんも Python っぽい。
let s = String::from("hello"); let slice = &s[3..]; // "lo"
s
が String
型のとき、文字列スライス &s[3..]
は &str
型。スライスとして表現することによって、元の変数に対する変更などをコンパイラでチェックすることができる。
let s = "Hello, world!";
ここでの
s
の型は、&str
です: バイナリのその特定の位置を指すスライスです。 これは、文字列が不変である理由にもなっています。要するに、&str
は不変な参照なのです。
な、なるほど…。そういう扱いなのか。
所有権まわりのメリットはだいぶ理解できた。

プログラミング言語Rust 公式ガイド (アスキードワンゴ)
- 作者:Steve Klabnik,Carol Nichols,尾崎 亮太
- 発売日: 2019/07/05
- メディア: Kindle版
Rust に付け焼き刃で入門する 2
Rust に付け焼き刃で入門する 1 の続き。
3. 一般的なプログラミングの概念
3.1. 変数と可変性
変数と可変性 - The Rust Programming Language 日本語版
不変のメリットについての説明は、特に Rust に限ったことではない。
不変な変数とは別に、定数もある。型注釈は必須。
const MAX_POINTS: u32 = 100_000;
3.2 データ型
データ型 - The Rust Programming Language 日本語版
Rust は静的型付き言語。型推論してくれるので、型注釈は必要なところでだけで良い。
整数型や論理値型など、プリミティブな型はスカラー型と呼ぶ。整数にはサイズがある。ローレベルな感じ。迷ったら Rust のデフォルトである i32
型を使えば良いとのこと(最速なので)。浮動小数点型の方は f64
。いわゆる double。演算子は普通な感じ。
bool
型は true
と false
。
char
型は Unicode スカラー値の一つ。'a'
のようにシングルクォートで囲む。文字列 "a"
とは別。
タプルの要素の型は一致しなくてよい。destructring も可能。要素には、x.0
のようにドットでアクセス。
配列 array は同じ型の要素からなり、固定長。他の言語でいうような可変長のリストは、ベクタ vector を使う。配列の要素には x[0]
のようにしてアクセス。範囲外へのアクセスは実行時エラー panic になる。
3.3 関数
関数 - The Rust Programming Language 日本語版
ソースコード中で
another_function
をmain
関数の後に定義していることに注目してください; 勿論、main
関数の前に定義することもできます。コンパイラは、関数がどこで定義されているかは気にしません。 どこかで定義されていることのみ気にします。
なるほど。JavaScript だと巻き上げ hoisting が起きるけど、Rust はどうなんだろう。
fn main() { println!("Hello, world!"); another_function(); } let num = 42; fn another_function() { println!("{}", num); }
これだとerror: expected item, found keyword `let`
というエラーになった。そもそもここには let
を置けないので、let
と関数定義の順序を気にする必要はない様子。また、
fn main() { println!("Hello, world!"); another_function(); let num = 42; fn another_function() { println!("{}", num); } }
は can't capture dynamic environment in a fn item
というエラーになった。関数定義の順序を気にしないといけないようなコードは、そもそも文法的に許されていないようだ。
関数シグニチャにおいて、各仮引数の型を宣言しなければなりません。
はい。
文とは、なんらかの動作をして値を返さない命令です。 式は結果値に評価されます。
変数宣言や関数定義は文。プロック {}
は式。式にセミコロンをつけると文になる。
戻り値に名前を付けはしませんが、 矢印(
->
)の後に型を書いて確かに宣言します。Rustでは、関数の戻り値は、関数本体ブロックの最後の式の値と同義です。return
キーワードで関数から早期リターンし、値を指定することもできますが、多くの関数は最後の式を暗黙的に返します。
Rust では、ブロックの最後の式の値を戻り値とみなす。式なのでセミコロンはつけない(つけると文になってしまう)。慣れるまではうっかりセミコロンを消したり、つけたりしてしまいそうだ。ただ、戻り値の型が食い違っていたらコンパイルエラーで気づけるので、そこまで神経質にならなくても良さそう。
戻り値なしの場合は空のタプル -> ()
で型を表現できるが、この場合に限って、戻り値の型注釈を省略できるっぽい。
3.4. コメント
//
でコメントを書ける。
3.5. フロー制御
フロー制御 - The Rust Programming Language 日本語版
if
は式なので、値を返す。条件は bool
型である必要がある。アームの {}
は省略不可。else
, else if
も使えるが、各アームが返す型は同じでなければならない。ユニオン型にはなってくれないようだ。
各アームが返す型は同じでなければならないので、値を返す式として使う場合は else
が必ず必要。
let a = if cond { 100 } else { 0 }; // OK let a = if cond { 100 }; // NG
無限ループは loop
。条件付きループは while
。コレクション(イテレータ?)に対するループは for ... in
。break
と continue
もある。このあたりは普通な感じ。
ループは式なんだろうか? break
から値は返せるんだろうか? …特にこのページには記述がなかった。

プログラミング言語Rust 公式ガイド (アスキードワンゴ)
- 作者:Steve Klabnik,Carol Nichols,尾崎 亮太
- 発売日: 2019/07/05
- メディア: Kindle版
Rust に付け焼き刃で入門する 1
数十分〜数時間で手っ取り早く掴む系
- A half-hour to learn Rust - fasterthanli.me
- 「Rust を書けるように」というよりかは、「Rust を読めるように」なる解説。"A half-hour" とあるが、30分では収まりきらない
- Rust入門 - とほほのWWW入門
- Rust ツアー - 目次
- A Tour of Go の Rust 版。ブラウザ上の playground で Rust を実行しながら進められる。上の2つよりかは詳しめ。後半部分は日本語未翻訳。
- What is Rust? · Learn With Jason
- ライブコーディング形式で教わる動画。といっても初歩の初歩だけで終わってしまう。
ざくっと見てみたところ、所有権・借用や、ライフタイムの扱いがややこしそうな印象。コンパイルエラーのメッセージが親切なのはとても嬉しい。Hello World を書こうとすると、いきなりマクロ println!
が出てきて「!」となる。
The Rust Programming Language
公式のこのドキュメントがまずはおすすめらしいので、以降はこれに沿って勉強してみる。TRPL あるいは the book と呼ばれているとのこと。
1. 事始め
事始め - The Rust Programming Language 日本語版
1.1. インストール
普段は Homebrew を使うことが多いが、今回はとりあえず公式にしたがってインストールする。
$ curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
デフォルトのままで動いた。
$ rustup --version rustup 1.23.1 (3df2264a9 2020-11-30) info: This is the version for the rustup toolchain manager, not the rustc compiler. info: The currently active `rustc` version is `rustc 1.50.0 (cb75ad5db 2021-02-10)` $ rustc --version rustc 1.50.0 (cb75ad5db 2021-02-10) $ cargo --version cargo 1.50.0 (f04e7fab7 2021-02-04)
公式のパッケージマネージャー cargo
が一緒にインストールされるのも、楽でうれしい。
1.2. Hello, World!
hello_world/main.rs
に hello world を書く。VS Code にはデフォルトで Rust のシンタックスハイライトが入っているようだ。
rustc
でコンパイルしたら、実行ファイルのバイナリができた。
$ rustc main.rs $ file main main: Mach-O 64-bit executable x86_64 $ ./main Hello, world!
1.3 Hello, Cargo!
$ cargo new
プロジェクトの作成。Git リポジトリの作成までやってくれる$ cargo check
検証$ cargo build [--release]
ビルド$ cargo run
(ビルド+)実行
cargo
があるので、rustc
でコンパイルする機会はあまりなさそう?
2. 数当てゲームをプログラムする
数当てゲームをプログラムする - The Rust Programming Language 日本語版
VS Code で写経。そのままだとフォーマットや補完ができなかったので、拡張機能を入れた。
let
で変数の作成。immutable の方が無標になっているのはありがたい。
::new
行にある::
という記法は、new
がString
型の関連関数であることを表しています。
関連関数というのは聞き慣れない言葉。英語だと associated function。スタティックメソッドと同じようなものらしい。
io::stdin().read_line(&mut guess)
read_line
に、String
型の変数 guess
の参照を渡している。C 言語のポインタっぽい。可変であることが &mut
で明示的に示されている。
Result
型に関しては、列挙子はOk
かErr
です。
Haskell の Either
など、関数型でよくあるアレ。エラー処理が書きやすくなるのでありがたい。エラー処理が漏れていると、コンパイル時に検出できるのもうれしい。
0.3.14
という数字は、実際には^0.3.14
の省略記法で、これは、「バージョン0.3.14と互換性のある公開APIを持つ任意のバージョン」を意味します。
Cargo の依存の指定。実際に、手元の環境では 0.3.23
がインストールされた様子。ちなみに、クレート crate というのは木箱のことらしい。
次に、別の
use
行を追加しています:use rand::Rng
ですね。Rng
トレイトは乱数生成器が実装するメソッドを定義していて、 このトレイトがスコープにないと、メソッドを使用できないのです。
これはわかりにくい気がする。…が、試しに use rand::Rng
をコメントアウトしてビルドしてみたら、
help: the following trait is implemented but not in scope; perhaps add a `use` for it: | 4 | use crate::rand::Rng;
という親切なメッセージが出てきた。これだったら大丈夫そうだ。
match
式は、複数のアーム(腕)からできています。
パターンマッチ。
Rustでは、新しい値でguessの値を覆い隠す(shadow)ことが許されているのです。 この機能は、値を別の型に変換したいシチュエーションでよく使われます。
最初はこのシャドーイングの使いみちがわからなかったけど、そういうことか。immutable な変数が基本なので、混乱も起きなさそう。
loop
, continue
, break
については、特に変わったところはなし。

- 作者:Steve Klabnik,Carol Nichols
- 発売日: 2019/06/28
- メディア: 単行本
PlatformIO IDE を使って ESP-WROOM-02 の開発をする
昨日作った ESP-WROOM-02 の実験用ボードを使って、温湿度センサー DHT11 からデータを取得したい。以前 NodeMCU で DHT11 を使ってみた記事はこちら。
これまでは、Visual Studio Code extension for Arduino を使って VS Code 上で開発していた。しかし、
というような不満があった。そこで、今回は PlatformIO を使ってみる。
PlatformIO のデスクトップ IDE は、VS Code の拡張機能として動く1。
VSCode — PlatformIO 5.1.1a1 documentation
インストールとプロジェクト作成
ということで、VS Code 上で拡張機能「PlatformIO IDE」と検索し、インストールした。しばらく時間がかかるが、完了すると「Finish! Please restart VSCode.」というメッセージが出てくるので、VS Code を再起動する。
右下の 🏠 アイコンをクリックすると PlatformIO のホーム画面が開く。[New Project] をクリック。
プロジェクト作成のウィザートが開くので、適当な名前をつける。Board は ESP-WROOM-02 (Espressif)
を選択。下図のようなファイル構成のプロジェクトが作成された。
ビルド・書き込み
src/main.cpp
に簡単なプログラムを書く。初期状態で補完も効いていて使いやすい。
画面下部の ✔️ アイコンをクリックするとビルドが走る。ショートカットキーは Ctrl+Opt+B。
また、➡️ アイコンをクリックすると(ビルド+)書き込み(upload)が行われる。ショートカットは Ctrl+Opt+U。
しかし、自分の場合は上のように OSError: [Errno 16] Resource busy: '/dev/cu.usbserial-2'
というエラーが出てうまく行かなかった。別のポートが選択されている様子。自分の場合は、前の記事でシリアル通信を試したように、ESP-WROOM-02 には /dev/tty.usbserial-DM02NA6M
でアクセスできる。そこで、プロジェクトの設定ファイル platformio.ini
を編集して upload_port
を明示的に指定した。
--- a/platformio.ini +++ b/platformio.ini @@ -12,3 +12,4 @@ platform = espressif8266 board = esp_wroom_02 framework = arduino +upload_port = /dev/tty.usbserial-DM02NA6M
再度書き込みを試したら成功。
ちなみに、前回作成した実験用ボードでは、
というボタン操作をする必要があるので注意。
シリアルモニター
こちらも、monitor_port
と monitor_speed
をあらかじめ指定しておく。
--- a/platformio.ini +++ b/platformio.ini @@ -13,3 +13,5 @@ platform = espressif8266 board = esp_wroom_02 framework = arduino upload_port = /dev/tty.usbserial-DM02NA6M +monitor_port = /dev/tty.usbserial-DM02NA6M +monitor_speed = 115200
画面下部の 🔌 アイコンをクリックするとシリアルモニターが開く。ショートカットキーは Ctrl+Opt+S
。
自分の場合、一度ブレッドボード上のリセットボタンを押して再起動しないと、出力が表示されなかった。
ライブラリを依存関係に追加して使う
次に、温湿度センサー DHT11 を使うためのライブラリを追加する。ちなみに、以前 VS Code の Arduino 拡張機能で開発していたときは、Arduino IDE のライブラリマネージャーからインストールする必要があった。
PlatformIO では、Libraries のページから検索できる。dht11
を検索窓に入力すると、DHT sensor library が出てくるので、クリック。
ライブラリの詳細画面が表示されるので、そこから [Add to Project] をクリック。
インストール先のプロジェクトを選択して [Add] で追加する。
platformio.ini
の lib_deps
に依存が追加された。
--- a/platformio.ini +++ b/platformio.ini @@ -15,3 +15,4 @@ framework = arduino upload_port = /dev/tty.usbserial-DM02NA6M monitor_port = /dev/tty.usbserial-DM02NA6M monitor_speed = 115200 +lib_deps = adafruit/DHT sensor library@^1.4.1
バージョンも指定されているので、他のプログラミング言語の依存管理みたいに、再現性のあるビルドができる。
しかし、このライブラリを使ったコード(後掲)をビルドしようと思ったら、Adafruit_Sensor.h: No such file or directory
というエラーが出た。
依存の依存 Adafruit Unified Sensor も自分でインストールする必要があるらしい。先ほどと同じく、GUI から検索して追加した結果。
--- a/platformio.ini +++ b/platformio.ini @@ -15,4 +15,6 @@ framework = arduino upload_port = /dev/tty.usbserial-DM02NA6M monitor_port = /dev/tty.usbserial-DM02NA6M monitor_speed = 115200 -lib_deps = adafruit/DHT sensor library@^1.4.1 +lib_deps = + adafruit/DHT sensor library@^1.4.1 + adafruit/Adafruit Unified Sensor@^1.1.4
これでビルドができるようになった。
完成
DHT11 は以下のモジュールを使った。モジュール上に抵抗も実装されている。
この DHT11 モジュールの出力を、ESP-WROOM-02 の IO4 ピンに接続した。
プログラムは、先日 NodeMCU で使ったものと DHTPIN
以外は同様。
#include <Arduino.h> #include "DHT.h" #define DHTPIN 4 // IO4 ピンからセンサーの値を得る #define DHTTYPE DHT11 // DHT 11 を使う DHT dht(DHTPIN, DHTTYPE); void setup() { Serial.begin(115200); dht.begin(); } void loop() { float t = dht.readTemperature(); float h = dht.readHumidity(); Serial.println("Temperature: " + String(t, 1) + "°C\tHumidity: " + String(h, 0) + "%"); delay(2000); }
取得した値がシリアルモニターに無事表示されている。
-
一応、他のエディタにもある程度対応はしている様子。↩
ESP-WROOM-02 DIP化キットで実験用ボードを作る
この前の記事で触れた『超特急Web接続!ESPマイコン・プログラム全集』という本を読んだ。もともとやりたかった、電池駆動の方法も載っている。原理というよりも、実際の利用例が回路図やサンプルコードとともにたくさん掲載されている。自分のような素人でも、とりあえず真似をすればすぐに作れそうな感じ。サポートページと GitHub リポジトリは以下の通り。
- 超特急Web接続!ESPマイコン・プログラム全集 サポートページ by 国野 亘
- bokunimowakaru/esp: ボクにもわかるIoTモジュールESP-WROOM-02 ESP-WROOM-32
第1章では、ESP-WROOM-02 書き込み用・実験用のボードをブレッドボード上に実装する。初心者なので、まずはこれに従ってそのまま作ることにした。
ちなみに、今まで違いがよく分かっていなかったが、
- ESP8266EX:Wi-Fi 機能搭載のマイコン
- ESP-WROOM-02:ESP8266EX にフラッシュメモリとアンテナをつけたもの
- ESP-WROOM-02 DIP化キット:ブレッドボード上で扱いやすくするために、ESP-WROOM-02 に足(ピンヘッダ)をつけたもの
ということらしい。なるほど。
はんだ付け
ブレッドボードを使うので基本的にははんだ不要だが、ESP-WROOM-02 DIP化キットと、USB シリアル変換モジュール AE-FT234X のピンヘッダははんだ付けをする必要がある。はんだ付けに必要な道具を持っていなかったので、ネット上の情報を参考にしつつ、適当に一式買い揃えた。今後どこまで使うかまだ分からないので、手頃なものを。
セラミック式の方が温度の立ち上がりが良くて使いやすいとのことだったので、ハッコーDASH FX650-81 にした。温度調節可能なものの方がおすすめらしいが、そこまでいくと数千円高くなってしまう。こて先は C2 型が使いやすいとのこと。それに加えて、安定感のあるほどほどのこて台を。
鉛入りのはんだと、不要なはんだを取り除くための吸い取り線。
このあたりの動画を参考にしてピンヘッダをはんだ付けした。
ブレッドボードに実装
部品は秋月電子で注文。全部で2,000円弱で、それに送料が500円。ちなみに、ESP-WROOM-02 DIP化キット自体は650円。サポートページにレギュレータの代替品についての参考資料という PDF があったので、それを参考にしてレギュレータを TA48033Sに置き換えた。一緒に使う電解コンデンサ・セラミックコンデンサも買ったのだが、秋月電子の TA48033S にはそれらが同梱されていたので、別で買う必要はなかったようだ。
14行目右から (-) に伸びている緑の線は不要な気がするが、何か意味があるんだろうか?
タクトスイッチは Osoyoo のキットに入っていたものを使い回せばいいかと思っていたが、いざ組んでみると一回り大きかった。なので、本で紹介されている実験用ボードの配線とは若干ずれている。
レギュレータと USB シリアル変換モジュールを差し込めば、こんな感じ。
ちなみに、最初は試したときは次のシリアル通信ができなくて焦った。テスターで電圧を調べたら、レギュレータの向きが逆だったことが発覚。正しい向き(刻印面が左を向く。ピンは上から入力、GND、出力の順)に差し直したら正常に動くようになった。
Mac からシリアル通信をする
USB シリアル変換モジュール AE-FT234X を、USB ケーブルで MacBook に接続。すると、USB シリアル変換モジュールの青い LED が点灯した。かなりまぶしい。Mac の System Information を開いてみると、FT230X Basic UART
としてちゃんと認識されている。自分の環境では、ドライバのインストールは不要だった。
$ ls -l /dev/*usbserial* crw-rw-rw- 1 root wheel 18, 5 2 6 19:09 /dev/cu.usbserial-DM02NA6M crw-rw-rw- 1 root wheel 18, 4 2 6 19:09 /dev/tty.usbserial-DM02NA6M
Mac からシリアル通信をしたい場合は、screen
コマンドを使えばいいらしい。
$ screen /dev/tty.usbserial-DM02NA6M 115200
最初は何も表示されないが、リセット(上のタクトスイッチ)を1秒程度押して離すと、再起動されて ready
と出る。購入直後の ESP8266 では、AT コマンドというものが使えるらしい。試しに AT
と入力してみると、OK
という応答が返ってくる。
AT
の後の改行は、Enter を押してから Ctrl+J も入力する必要があるので注意。ESP8266 は CR+LF を期待しているようだ。
AT+GMR
コマンドを使うと、バージョン情報が表示される。
AT+GMR AT version:1.6.2.0(Apr 13 2018 11:10:59) SDK version:2.2.1(6ab97e9) compile time:Jun 7 2018 19:34:26 Bin version(Wroom 02):1.6.2 OK
ただしこの AT コマンド、Arduino IDE でプログラムを書き込むと使えなくなる。ということで、深入りはしないことにする。
![超特急Web接続!ESPマイコン・プログラム全集[CD-ROM付き] (ボード・コンピュータ・シリーズ) 超特急Web接続!ESPマイコン・プログラム全集[CD-ROM付き] (ボード・コンピュータ・シリーズ)](https://m.media-amazon.com/images/I/51LqNI7iaaL.jpg)
超特急Web接続!ESPマイコン・プログラム全集[CD-ROM付き] (ボード・コンピュータ・シリーズ)
- 作者:国野 亘
- 発売日: 2019/01/22
- メディア: 単行本