天下一反省会!

電子工作、プログラミング、読書など

\今月のイチオシ記事/

おススメ記事1
おススメ記事2
おススメ記事3
おススメ記事4

M5stack関連製品を使う際にシリアルモニタが表示できない症状の解決方法

先日、M5AtomS3およびM5Dialを入手したので、さっそく使ってみようと思ったのですが...

"Serial.println()"してるのにシリアルモニタに何も表示されない!!

あれこれ調べた結果、なんとか解決方法を見つけ出したので、備忘録としてここにまとめておきます。

※ArduinoIDEを使用する場合と、PlatformIOを使用する場合の2パターンについて解説します。

本記事の結論

シリアルモニタがうまく動作しない場合は以下の操作を試してみてください。

対処法Arduino IDEを使用する場合
"USB CDC On Boot" の設定を "Enabled"にする


PlatformIOを使用する場合
platformio.iniファイルに以下の文言を追加する
build_flags =
-D ARDUINO_USB_MODE=1
-D ARDUINO_USB_CDC_ON_BOOT=1

以下に、詳しい操作の流れを紹介します。

Arduino IDEを使用する場合の対処法

まずはいつも通り、M5製品(今回はM5AtomS3を使いました)をPCに接続し、ボード名とポート番号の指定を行います。

ボード名とポート番号の指定
M5製品をPCにつなぎ、ポート番号とボード名を指定する

次に、Arduino IDE上部のツールバーから下図のように、"ツール"→"USB CDC On Boot"→”Enabled”を選択する

USB CDC On BootをEnabledに設定
"USB CDC On Boot"の項目を"Enabled"に設定する

これでシリアルモニタに文字が表示されるようになります。

PlatformIOを使用する場合の対処法

症状発生時の様子

シリアルモニタを開こうとすると、以下の画像のように"--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H"と表示されたまま何も起こらず、シリアルモニタに文字が表示されない。

platformIOのシリアルモニタが動かない様子
PlatformIOのシリアルモニタが停止し、文字が表示されない

解決方法

プロジェクトフォルダ内の"platformio.ini"ファイルを開き、以下の文言をファイル末尾に追加し、保存してください。


gist00b176dde269a0eed941011b70db428d

platformio.iniファイルに文言を追加する
platformio.iniファイルに文言を追加する

その後、プログラムをM5製品に書き込んでからシリアルモニタを開けば、シリアルモニタに文字がしっかりと表示されます。

シリアルモニタに文字が表示された
プログラムを書き込み実行すると、シリアルモニタに文字が表示された

参考にしたサイト

症状の改善に至るまでに参考にしたサイトを紹介しておきます。

lang-ship.com

community.platformio.org

Arduinoにフォトリフレクタ”RPR-220”を繋いで使う方法を紹介!

Arduinoでフォトリフレクタ”RPR-220”を使ってみました。

回路の組み立て方やArduinoスケッチ、実際に動作させたときの様子などについてまとめておきます。

フォトリフレクタとは

フォトリフレクタの外観
フォトリフレクタの外観

フォトリフレクタは光を用いたセンサの一種です。赤外線LEDとフォトトランジスタという2つの素子が組み込まれています。

赤外線LEDから放たれた光が物体に当たった際の反射光をフォトトランジスタで受け取ることで、物体を検出することができます。

フォトリフレクタはライントレーサーのライン検出などに用いられることが多いです。

フォトリフレクタをArduinoに接続してみよう

まずは動作方法を確認

フォトリフレクタは次のような手順を経て動作します。

フォトトランジスタの動作

①赤外線LEDを光らせる

②LEDの前に物体が近づくと光が反射され、フォトトランジスタに光が入射する

③光が入射した場合、フォトトランジスタ側に電流が流れる

④フォトトランジスタに流れた電流値を測定することで、物体との距離や、物体の色を識別できる


この一連の動作を行うためには、LEDを光らせる回路フォトトランジスタの出力を測定する回路を組めばよいことになります。

回路を組んでみる

今回はこちらに示す回路を組んでみることにします。

フォトリフレクタ用の回路図
フォトリフレクタ用の回路図

簡単に回路図の説明をします。

図の5Vと書かれた部分はArduinoの5Vピンを表しています。

5Vピンを赤外線LEDとフォトトランジスタにそれぞれ接続することで、LEDとトランジスタに電気を供給します。

抵抗値についてはいろいろな値を試した結果、一番動作が安定した値(LED側400Ω、フォトトランジスタ側2kΩ)にすることにしました。

配線してみる

電子回路が設計できたので、次は配線を行っていきます。

今回扱うフォトリフレクタには足が4本生えているため、どの足をどこにつなげばよいか調べる必要があります。

そこで、フォトリフレクタ(RPR-220)のデータシートを読んでみます。

データシートはこちらから↓
www.rohm.co.jp

データシートを見ると、4本の足のうち、1番と2番の足がLEDの端子、3番と4番の端子がフォトトランジスタの端子になっているようです。

フォトリフレクタRPR-220のピン配置(Rohm社データシートより引用)


この図の指示に従って配線すると、1番・4番の足にArduinoの5Vピンを、2番・3番ピンをそれぞれ抵抗を経由してArduinoのGNDピンに接続すればよいことになります。


最終的な配線図は次のようになりました。

フォトリフレクタをArduinoに接続する際の配線図
フォトリフレクタをArduinoに接続する際の配線図

フォトリフレクタの動作をチェックしてみる


では実際にArduinoにフォトリフレクタ回路を接続し、動作を確認してみます。

上図の抵抗R2のフォトリフレクタ側の足とArduinoのアナログピンを接続すれば、R2における電圧降下の量を読み取ることができます。

Arduinoには次のようなプログラムを書き込みました。


gistc0887693ccf1fc19bca256b9020feca6


フォトリフレクタに黒い紙を近づけると以下のような結果になりました。

フォトリフレクタに黒い紙を近づけた場合の表示
フォトリフレクタに黒い紙を近づけた場合の表示

次に、白い紙を近づけて値を確認してみます。

白い紙を近づけた場合の表示
白い紙を近づけた場合の表示


以上の結果をまとめるとこのようになります。

フォトリフレクタの動作まとめ表示される値が小さい場合→黒色を検出している
表示される値が大きい場合→白色を検出している


この性質を用いることで、白い紙の上に書かれた黒線を検出するなどの処理を行うことができます。

2000円以下で買えるRaspberry Pi 4B 用冷却ファン付きケースがコスパ最強だったので紹介します!

Amazonに売っているラズパイ冷却用ケースの中で一番評価が高そうな製品を購入し、しばらく使ってみたところ、結構いい製品だったので紹介します。

本記事の結論

今回はこちらのラズパイ用冷却ファン+ヒートシンク付きケース(Miuzei社製)を購入し、実際に使ってみました。

価格はamazonで1989円(2023年8月現在)でした。


この製品を使う中で気づいた良い点・悪い点について簡単にまとめてみました。

この製品の良い点

・組み立て方が図で示された説明書が入っているため、組み立てが比較的容易。

・デスクトップ画面時の温度は35℃前後となり、ファン・ヒートシンクがない場合に比べ、しっかりと冷却されていた。

・ファンの強さは2段階に対応(動作電圧3.3Vまたは5V)

・ファンの音については、3.3Vで駆動させた場合はかなり静かで、まったく気にならないレベル。(私はかなり騒音に敏感なタイプなのですが、ストレスなく使えています。

・底部に取り付ける用の滑り止めが付属している

・天板が透明なアクリル板であるため、ケース内の様子が目視できる

この製品の良くない点

カメラ用端子やGPIOピンはアクセス用の穴が設けられているものの、穴から端子までの距離が長いため、非常に使用しにくい
⇒(2023/08/30追記)ケース上面のアクリル板を一部加工することによってGPIOに容易にアクセスできるようになりました! 加工に関する詳しい解説はこちら!

・上記のデメリット故、ファンの強さを変更するのに手間がかかる

結局のところ、この製品を買って問題ないのか

総括すると、GPIO端子やカメラ用端子を多用しない人には超おススメできる製品だと思います。価格の割に造りがしっかりしており、見た目もよいため,
私もかなり気に入っています。

ただし、GPIOピンを頻繁に使う予定のある方は、こちらのケースを一部加工することを検討したほうがいいでしょう。 加工に関する詳しい解説はこちら!


製品の組み立ての流れ

ここからは、ケースの組み立て完了までの流れを紹介します。

内容物はこちらの通り。

届いた製品の内容物
届いた製品の内容物。ドライバーも付属してました。

このような説明書が入っていました。図と番号で組み立て手順が示されているため、かなり分かりやすかったです。

付属の説明書の写真
付属の説明書。組み立て手順が図と番号で示されており、わかりやすい。


説明書の指示通りに組み立てていきます。まずはファンの取り付けから。

付属のネジを用いて、アクリル天板にファンを固定します。

アクリル天板と冷却ファン
アクリル天板と冷却ファン

続いてヒートシンクの取り付け。取り付ける箇所は全部で4か所です。

ヒートシンク裏面についた両面テープで、指定の箇所に張り付けていきます。

ラズパイ本体にヒートシンクを取り付けた様子
ラズパイ本体にヒートシンクを取り付けた様子

最後に、ファンから延びるジャンパ線をラズパイのGPIO(GNDと5Vピンまたは3.3Vピン)に差し、ケースを組み立ててネジ留めします。

ファンの電源ケーブルをGPIOにさしておく
ファンの電源ケーブルをGPIOに差しておく
ケースの完成写真
すべてのパーツをネジ留めして完成!

(2023/08/30追記)ケース上面の加工について

この製品の上面にはGPIOアクセス用の穴が設けられていますが、穴が非常に狭いため、非常に取り扱いにくくなっています。

そこで、ケース上面のアクリル板の一部をカットし、穴を広げてみます。

切断する部分はこの箇所です。赤線で示した箇所を切断するだけです。

GPIOピンの取りまわし改善のためアクリル板の一部をカットする
GPIOピンの取りまわし改善のため、アクリル板の一部をカットする

私はバンドソーを用いて切断しましたが、バンドソーが用意できない方は、糸ノコで加工するのがおすすめです。

糸鋸はamazonで900円くらいで売っているようです。


切断後の外観がこちら。切断部にはバリが生じてしまったため、ヤスリをかけて滑らかにしました。

加工後のケース外観
加工後のケース外観

実際にGPIOピンにジャンパワイヤを差そうとしてみると、加工前に比べて指が奥まで入るようになり、とても扱いやすくなりました!

GPIOピン部の穴が広がったため、手が奥まで入るようになった
GPIOピン部の穴が広がったため、手が奥まで入るようになった

もしもGPIOピンを多用する予定のある方は、ケースの加工も検討してみてはいかがでしょうか。

まとめ

初めてラズパイのケースを購入しましたが、今のところはこちらの製品を選んで正解だったかなと思っています。

とはいえ、長時間使用していくと不満点や劣化等が見つかるかもしれないので、気づいたことがあればその都度追記したいと思います。


【Raspberry Pi 4】VNCリモート接続時に予測変換のウィンドウが画面外にはみ出てしまう場合の対処法について

症状について

Raspberry Pi 4Bを VNC viewerを用いてリモート操作しているとき、下の図のように予測変換のウインドウが画面左上に表示されてしまう症状が発生しました。

VNCリモート接続すると予測変換ウィンドウが見切れてしまう
VNC接続すると、変換候補ウィンドウが左上に表示され、見切れてしまう

解決方法

ラズパイと適当なモニターをHDMI接続したところ、症状が改善しました。

実際に、ラズパイとfullHD(1920×1080)モニターをHDMI接続した状態で、 VNC viewerからリモート接続してみると、予測変換ウィンドウは次のようになります。

適当なモニターとHDMI接続すると、正常に表示される
ラズパイとモニターをHDMI接続した状態でVNC接続すると、予測変換ウィンドウは正常な位置に表示されるようになった


同じような症状で苦しんでいる方は、とりあえずラズパイをHDMIで何かしらのモニターと接続した後、VNCリモート接続することで症状が改善するかどうか試してみるといいかもしれません。

何か気付いたことがあれば、また追記します。

おまけ:実行した環境

使用したラズパイの予測変換ツール→FcitxとMozc (初回起動時のセットアップで自動的にインストールされるやつ)

配線等について
①デスクトップPC⇔モニターをHDMIケーブルで接続
②ラズパイ⇔モニター’(①でPCと接続したものと同じモニター)をHDMIケーブルで接続
③ラズパイ⇔デスクトップPCをVNC viewerでリモート接続

【電子工作】100均で買えるコスパ最強パーツケースを紹介します!


こんな人におススメ・小さなサイズの部品をきれいに収納したい
・仕切りが着脱できるケースを探している
・収納にお金をかけたくない

今回の結論!

電子部品などの小さいパーツを収納するなら、ダイソーの”セクションケース”や"SIKIRIシリーズ"がおススメです!


例えば、下の写真のように散らかったパーツケースの中身も...

散らかったパーツケース
散らかったパーツケース

今回紹介するパーツケースを用いればこの通り!どの部品がどこに入っているか一目で分かります!

100均の収納ケース
部品の種類、数が一目瞭然!

電子工作をやっている方には特におススメなパーツケースです!


購入はこちらから(ダイソー公式通販サイトへのリンクです)

セクションケース(29.5cm×19cm)jp.daisonet.com
SIKIRI 30jp.daisonet.com

ダイソーで買えるおススメのパーツケース2選

セクションケース

セクションケースの写真
セクションケースの外観。この他にもいくつかサイズが用意されています

こちらのセクションケースの最大の特徴は、ケース内のの1つ1つのマスを区切っている仕切りにあります。

なんと、これらの仕切りは自由に着脱することが可能で、マスの大きさやレイアウトを自分好みにカスタマイズすることができるんです!

例えば下の写真のように、電池ケースや小型のリモコンなど、1つのマスには入りきらないようなサイズのパーツも、仕切りを外してマスを広げればピッタリ収納することができます!

マスの大きさのカスタマイズ例
マスの大きさのカスタマイズ例

SIKIRIシリーズ

SIKIRIシリーズはセクションケースよりもさらに小さいマスが並んだケースになっています。(仕切りは取り外せません)

このケースの一番の特徴は、1つ1つのマスの縁にカーブがついているという点です!

パッケージには下のようなイラストで説明がされています。

SIKIRIケースのイラスト
SIKIRIケースの説明イラスト

このカーブのおかげで、細かい部品の取り出しが非常に容易になり、ストレスフリーに使うことができます!

さらに個人的に推したいポイントが、容器の薄さです!

物差しで測ってみると、なんと厚さは約4cmでした。

これだけ薄いので、複数枚重ねて置いたり、立てた状態で棚に収納したときにかさばらすに済みます!

まとめ

今回紹介したケースはどちらもダイソーで購入できます。気になった方はお店で手に取ってみてはいかがでしょうか。

また、ダイソーのオンラインストアでも取り扱いがあるようなのでリンクを貼っておきます。

セクションケース(29.5cm×19cm)jp.daisonet.com
SIKIRI 30jp.daisonet.com

PS4コントローラのR2ボタンの押し込み量に応じて、サーボモータの角度を変化させる仕組みを紹介


以前の記事にて紹介した"pythonプログラムでps4コントローラーの入力を受け取る方法"の応用例として、PS4コントローラーのR2ボタンの押し込み量によって、サーボモーターの角度を変化させる方法について紹介します。

この記事はこんな人におススメ・PS4コントローラーを電子工作に活用したい
・サーボモーターの角度を細かく操作したい

この記事を読めばこんな感じのものが作れます

今回やりたいことをざっくり説明

今回は、PS4コントローラーのR2ボタンの押し込み量に応じて、サーボモーターの角度が変化するような仕組みを作ります。

そのために、次のようなシステムを組むことにします。

1. pythonプログラムでPS4コントローラーの入力を受け取る
2. pythonプログラムで受け取ったコントローラーの入力を、wifi経由でESP32に送信
3. 受け取った入力に応じて、ESP32からサーボモーターへパルスを送信し、サーボを動かす


このシステムを作成するためには、①PS4コントローラーの入力をpythonで受け取る方法、②pythonプログラムとESP32の間でwifi通信を行う方法、という2つの前提知識が必要になります。

これら2つの方法については過去の記事にて紹介していますので、そちらを参考にしてください。

①PS4コントローラーの入力をpythonで受け取る方法に関する記事
potala123.hatenablog.com


②pythonプログラムとESP32の間でwifi通信を行う方法に関する記事
potala123.hatenablog.com

今回使用するプログラム

pythonプログラム

pythonプログラムでは、①ps4コントローラーの入力を認識する、②入力に応じた命令文を、ESP32にwifi経由で送信する
という2つの役割を担っています。

なお、今回はpygameというライブラリを用いてPS4コントローラーの入力を認識します。pygameライブラリの導入方法についてはこちらの記事にて紹介しています。

potala123.hatenablog.com

プログラムは以下の通りです。

import pygame
import time
import socket
import math

def sendMessage(message):
    message += "\n"#文末に改行コードを追加
    client.sendall(bytes(message, encoding='ASCII'))#文字列をバイトに変換し送信(文字コードはASCIIを使用)
    print("サーバーへデータ送信")



#pygame初期化部分

pygame.init()
j = pygame.joystick.Joystick(0)
j.init()
print("pygame初期化完了")

#wifi設定部分

ip_address = '192.168.1.17' #サーバー(ESP32のIPアドレス)
port = 5000 #ポート番号
buffer_size = 4092 #一度に受け取るデータの大きさを指定
conection_status = False

try:
    #クライアント用インスタンスを生成
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # サーバーに接続を要求する(IPアドレスとポート番号を指定)
    client.connect((ip_address, port))

    while conection_status == False: #ESP32との接続が確立されるまで続ける
        data = client.recv(buffer_size) #サーバから送られてきたデータを読み取り(上限4092ビット)
        if data.decode() == "ready": #ESP32から接続完了の合図を受け取ったら
            conection_status = True #Trueに変更しループから出る
            print("サーバとの接続完了")
    print("コントローラーを操作してください")

    while True:#以下ループ
        events = pygame.event.get()
        for event in events:
            if event.type == pygame.JOYBUTTONDOWN: #ボタンが押された場合
                if j.get_button(7):
                    print("R2が押されました")
                    print("R2の押し込み量")
                    while j.get_axis(4) > -1:
                        events = pygame.event.get()
                        print(math.floor(j.get_axis(4)*100))
                        sendMessage("R2A:"+str(math.floor(j.get_axis(4)*100)))
                        time.sleep(0.05)

except KeyboardInterrupt:
    sendMessage("exit")
    client.close()
    print("ソケット通信を終了")
    print("プログラムを終了します")
    j.quit()

使用しているライブラリはpygameを除けばpython標準ライブラリなので、pygameを入れた環境であればコピペするだけで動きます。

pythonプログラムの簡単な解説

コントローラーの入力を受け取る部分や、ESP32と通信を行う部分に関する説明は先ほど紹介した過去記事を参考にしてください。

上のプログラムではまず初めに、j.get_axis(4)でR2の押し込み量(-1~1で表される。離した時-1,最大押し込みで1)を取得します。

ここで取得した値は小数点以下の桁数が非常に多く、扱いずらいです。そこで、取得した値に100をかけた後math.floor()とすることで小数点以下を四捨五入し、2~3桁の整数に変換しています。(例:取得した値が0.453222....の時、45を出力、取得した値が-1の時、-100を出力)


その後"sendMessage"メソッドで整数値をESP32に送信します。

以降はESP32側で、受け取った整数の値によってサーボモーターの角度を変更する処理を行っていきます。

ESP32用プログラム

ESP32側のプログラムは以下の通りです。(今回はArduino言語を使用しました)

//#ESP32-python(DUALSHOCK4使用)

//ライブラリのインクルード
#include <WiFi.h>
#include <ESP32Servo.h>      // Servoライブラリの読み込み

const char* ssid     = "aterm-23841f-g";//ルーターのSSID
const char* password = "14b3384e2cc60";//ルーターのパスワード
WiFiServer server(5000);//ポート番号5000でサーバーとして使用する
String message;
String oneLetter;
Servo myservo;          // Servoオブジェクトの宣言
const int SV_PIN = 13;   // サーボモーターをデジタルピン13に
int servo_angle = 0;//サーボ角度用変数(電源ON時にゼロ度に初期化)

void setup()
{
    Serial.begin(115200);//ビットレート115200でシリアル通信を開始
    Serial.println();
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);

    WiFi.begin(ssid, password);//アクセスポイントに接続

    while (WiFi.status() != WL_CONNECTED) {//接続が完了しない場合"・"を打って待機
        delay(500);
        Serial.print(".");
    }
//接続が完了したら以下の内容を表示
    Serial.println("");
    Serial.println("WiFi connected.");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());//自身のIPアドレスを表示
    
    server.begin();//サーバー開始
    
    myservo.attach(SV_PIN, 500, 2400);  // サーボの割当(パルス幅500~2400msに指定)
    myservo.write(servo_angle);//サーボ角度を0度にリセット
    delay(100);

}

int value = 0;

void loop(){
 WiFiClient client = server.available();//サーバーに接続され、読み取り可能なデータがあるクライアントを取得

  if (client) {//クライアントの情報が取得出来た場合(クライアントに対しサーバーが開かれている場合)
    Serial.println("New Client.");
    if (client.connected()){
    message = "ready";
    client.print(message);//クライアントへメッセージを送信
    }
    String currentLine = "";//クライアントから得たデータを格納するための文字列を用意
    String orderCode = "";//命令文の種類を格納
    int orderAmount[2];//命令文の数値を格納するための要素数2の配列
    int ref = 0;//配列の要素数カウント用
    while (client.connected()) {            // client.connected()は接続時True,切断時Falth
      if (client.available()) {             // client.abalableは読み込み可能なバイト数(接続先のサーバーによってクライアントに書き込まれたデータの量)を返す
        char c = client.read();  //クライアントから送信されたデータを1バイトだけ読み取る
        if (c == '\n') {                    // 読み取った文字が改行コード(/n)だった場合
          if (currentLine == "exit"){
            client.stop();//サーバーとの接続を切断
            Serial.println("Client Disconnected.");
          }else{
            orderAmount[ref] = currentLine.toInt();;
            currentLine = "";//文字列の初期化
            if (orderCode == "R2A"){
              Serial.println("R2押し込み量");
              Serial.println(orderAmount[0]);
              Serial.println("サーボ角度");
              //Serial.print(round(0.9*(orderAmount[0]+100)));
              //Serial.print("度");
              myservo.write(round(0.9*(orderAmount[0]+100)));
            }
            ref = 0;//初期化
            orderCode = "";//初期化
            currentLine = "";//文字列の初期化
          }
        } else if (c == ':') {
          orderCode = currentLine;
          currentLine = "";//文字列の初期化
        } else if (c == ',') {
          orderAmount[ref] = currentLine.toInt();
          ref += 1;
          currentLine = "";//文字列の初期化
        } else if (c != '\r') {  // 受け取った文字が改行コードではない場合(普通の文字の場合)
          currentLine += c;      //変数currentLineに受け取った文字を追加する
        }
      }
    }
  }
}

ESP32プログラムの簡単な解説

ESP32側のプログラムでは、先ほど紹介したpythonプログラムから受け取った整数に対して次のような処理を行うことで、サーボモータの回転角を決定しています。

受け取った整数の処理手順1.受け取った整数(-100~100)に100を加えることで,整数の範囲を0~200にする(ボタンを押していないとき0,最大押し込み時200)
2.今回はサーボモーターの角度が、R2を押していないとき0°、最大押し込み時に180°となるようにしたいので、180/200×受け取った整数、すなわち、”0.9×受け取った整数”とすることで、R2ボタンの押し込み量をサーボモーターの角度に変換する

改善できそうな点

R2ボタンの押し込み量をわずかに変化させた場合にサーボモーターの動きがカクついてしまったり、そもそも全体的に動きがもっさりしているような感じがしました。

サーボへ指示を出す頻度を変えたり、サーボ回転角を決定する仕組みを工夫すれば、もっさり感やカクつきが低減できるかもしれないです。

ESP32とPC(pythonプログラム)間で、wifi経由で通信する方法を解説します!

今回はESP32とpythonプログラムの間でwifi経由で通信を行う方法について紹介します。

この記事はこんな人におススメ・ESP32をPCからwifi経由で動かしたい
・ESP32をpythonプログラムを用いて遠隔操作する方法を知りたい

今回の目標

ESP32をサーバ、pythonプログラムをクライアントとして、ESP32ーpythonプログラム間でwifi経由で通信(ソケット通信)を行います。
pythonプログラムから任意のメッセージを送信し、ESP32のシリアルモニタにメッセージを表示します。

使用するプログラムの紹介

ESP32用プログラム(サーバ側)

Arduino側には次のようなスケッチを使用します。

このスケッチはESP32のボードマネージャのサンプルプログラム"simpleWifiServer"を一部改変することで作成しました。

//#ESP32-PC間通信用プログラム(ESP32側)

//ライブラリのインクルード
#include <WiFi.h>

const char* ssid     = "yourSsid";//適宜ネットワークのSSIDに書き換えてください
const char* password = "yourPassword";//適宜ネットワークのパスワードに書き換えてください
WiFiServer server(5000);//ポート番号5000でサーバーとして使用する
String message;
String oneLetter;
void setup()
{
    Serial.begin(115200);//ビットレート115200でシリアル通信を開始
    Serial.println();
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);

    WiFi.begin(ssid, password);//アクセスポイントに接続

    while (WiFi.status() != WL_CONNECTED) {//接続が完了しない場合"・"を打って待機
        delay(500);
        Serial.print(".");
    }
//接続が完了したら以下の内容を表示
    Serial.println("");
    Serial.println("WiFi connected.");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());//自身のIPアドレスを表示
    
    server.begin();//サーバー開始

}

int value = 0;

void loop(){
 WiFiClient client = server.available();//サーバーに接続され、読み取り可能なデータがあるクライアントを取得

  if (client) {//クライアントの情報が取得出来た場合(クライアントに対しサーバーが開かれている場合)
    Serial.println("New Client.");
    String currentLine = "";//クライアントから得たデータを格納するための文字列を用意
    while (client.connected()) {            // client.connected()は接続時True,切断時Falth
      if (client.available()) {             // client.available()は読み込み可能なバイト数(接続先のサーバーによってクライアントに書き込まれたデータの量)を返す
        char c = client.read();  //クライアントから送信されたデータを1バイトだけ読み取る
        if (c == '\n') {                    // 読み取った文字が改行コード(/n)だった場合
          Serial.print("クライアントからのメッセージ: ");
          Serial.println(currentLine);//改行コードまでのメッセージを出力
          message = "hello,client! by server";
          client.print(message);//クライアントへメッセージを送信
          client.stop();//サーバーとの接続を切断
          Serial.println("Client Disconnected.");
        } else if (c != '\r') {  // 受け取った文字が改行コードではない場合(普通の文字の場合)
          currentLine += c;      //変数currentLineに受け取った文字を追加する
        }
      }
    }
  }
}

ESP32スケッチの説明

上で示したスケッチについて簡単に説明します。

まずスケッチの最初の部分について。

//#ESP32-PC間通信用プログラム(ESP32側)

//ライブラリのインクルード
#include <WiFi.h>

const char* ssid     = "yourSsid";//適宜ルーターのSSIDに書き換えてください
const char* password = "yourPassword";//適宜ルーターのパスワードに書き換えてください
WiFiServer server(5000);//ポート番号5000でサーバーとして使用する
String message;
String oneLetter;

の部分では、スケッチ内で使用するWifiライブラリや各種変数の定義を行います。
ネットワークのssidやパスワードもここで設定します。

次に、setup関数の中身について説明します。

void setup()
{
    Serial.begin(115200);//ビットレート115200でシリアル通信を開始
    Serial.println();
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);

の部分では、シリアル通信を開始し、ESP32の接続情報をシリアルモニタ上に表示する準備を行っています。

次に、

    WiFi.begin(ssid, password);//アクセスポイントに接続

でESP32をネットワークに接続します。

    while (WiFi.status() != WL_CONNECTED) {//接続が完了しない場合"・"を打って待機
        delay(500);
        Serial.print(".");
    }

の部分では、ESP32がネットワークに接続されるのを待ちます。ネットワークに接続されると、変数WiFi.status()の値が WL_CONNECTEDになります。

その後、

//接続が完了したら以下の内容を表示
    Serial.println("");
    Serial.println("WiFi connected.");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());//自身のIPアドレスを表示
    
    server.begin();//サーバー開始

}

の部分で、ネットワークへの接続が完了したことと、自身のIPアドレスをシリアルモニタ上に表示します。最後に server.begin()とすることで、ESP32はサーバとして動作し始めます。
|

次にloop関数の中身について説明します。

WiFiClient client = server.available();

の部分では、サーバに接続してきたクライアントの情報を変数clientに格納します。

次に、

if (client) {//クライアントの情報が取得出来た場合
    Serial.println("New Client.");
    String currentLine = "";//クライアントから得たデータを格納するための文字列を用意

の部分では、if (client)という条件分岐があります。これは、新たにサーバーに接続してきたクライアントがいた場合のみ、以降の処理を行う、という意味です。

変数String currentLineは、サーバクライアント間でメッセージをやり取りするために用意された空の文字列です。


その後、

 while (client.connected()) {            // client.connected()は接続時True,切断時Falth
      if (client.available()) {             // client.available()は読み込み可能なバイト数(接続先のサーバーによってクライアントに書き込まれたデータの量)を返す
        char c = client.read();  //クライアントから送信されたデータを1バイトだけ読み取る
        if (c == '\n') {                    // 読み取った文字が改行コード(/n)だった場合
          Serial.print("クライアントからのメッセージ: ");
          Serial.println(currentLine);//改行コードまでのメッセージを出力
          message = "hello,client! by server";
          client.print(message);//クライアントへメッセージを送信
          client.stop();//サーバーとの接続を切断
          Serial.println("Client Disconnected.");
        } else if (c != '\r') {  // 受け取った文字が改行コードではない場合(普通の文字の場合)
          currentLine += c;      //変数currentLineに受け取った文字を追加する

の部分はサーバクライアント間の通信が維持されている場合のみ実行します。


この部分ではクライアントから送られてきたメッセージを受信し、シリアルモニタ上に表示するまでの一連の処理を行います。


なお、今回はクライアントからサーバーへ送信するメッセージの末尾に改行コード("\n")を付け加えることで、メッセージの文末が分かりやすいような工夫がされています。


まず、サーバーはクライアントから送られてきたデータを先頭から1バイトずつ読み取っていき、読み取った文字が通常の文字であれば変数currentLineに加えます。


これをくり返し行うことでメッセージを1文字ずつ読み込み、メッセージの文末を表す改行コード"\n"が読み込まれたところで、変数currentLineの中身をシリアルモニタ上に表示します。


この部分を説明した図を作成したので下に載せておきます。

クライアント→サーバ間でのメッセージ送受信を説明する図
クライアント→サーバ間でのメッセージ送受信

最後に、メッセージの受信が無事に行えたことをクライアントに伝えるために、

message = "hello,client! by server";
client.print(message);//クライアントへメッセージを送信

の部分でクライアントへメッセージを送信し、

client.stop();//クライアントとの接続を切断

でクライアントとの通信を切断します。

pythonプログラム(クライアント側)

クライアントとして、次のようなpythonプログラムを使用しました。

#ESP32-PC間通信用プログラム(PC側)

#socketライブラリをインポート
import socket

ip_address = '192.168.10.115' #サーバー(ESP32のIPアドレス)
port = 5000 #ポート番号
buffer_size = 4092 #一度に受け取るデータの大きさを指定
recieve_message = ""
recieve_status = True

#クライアント用インスタンスを生成
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# サーバーに接続を要求する(IPアドレスとポート番号を指定)
client.connect((ip_address, port))

# サーバにデータを送信する
message = input("送信するメッセージを入力してください\n→")
message += "\n"#文末に改行コードを追加
client.sendall(bytes(message, encoding='ASCII'))#文字列をバイトに変換し送信(文字コードはASCIIを使用)
print("サーバーへデータ送信")


#サーバーからの応答を受信
data = client.recv(buffer_size) #サーバから送られてきたデータを読み取り(上限4092ビット)
print("サーバからのメッセージ")
print(data.decode())#受け取ったデータ(バイト形式)を読める形式にデコードして表示

#通信を終了
client.close()
print("ソケット通信を終了")

python用プログラムの説明

import socket

の部分で、今回用いるsocketライブラリをインポートします。

socketライブラリは、今回用いるソケット通信を行うために必要なライブラリです。

ソケット通信は通信方法の一種で、簡単に言えば、相手のIPアドレスとポート番号を指定して通信を行う方法のことです。


これは私たちが郵便物を送る際に送り先の住所と郵便番号を記入するのと似ていますね。


次の部分では、各変数の設定を行っています。

ip_address = '192.168.10.115' #サーバー(ESP32のIPアドレス)
port = 5000 #ポート番号
buffer_size = 4092 #一度に受け取るデータの大きさを指定
recieve_message = ""
recieve_status = True

ipアドレスの欄は、適宜お使いのESP32のipアドレスに変更してください。

その他の変数については、特に変更する必要はありません。


次の部分、

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

では、socketクラスのインスタンスを生成しています。

また、インスタンスを生成する際に引数を2つ与える必要があり、ここでは通信に用いるプロトコルの指定を行っています。

この部分に関して詳しく解説してある記事があったので、リンクを載せておきます。

qiita.com



次に、サーバーに接続を要求するために、

client.connect((ip_address, port))

とします。

サーバーとの接続が確立されたら、いよいよサーバに向けてメッセージを送る処理に入ります。

メッセージを送信する処は次のようになります。

message = input("送信するメッセージを入力してください\n→")
message += "\n"#文末に改行コードを追加
client.sendall(bytes(message, encoding='ASCII'))#文字列をバイトに変換し送信(文字コードはASCIIを使用)
print("サーバーへデータ送信")


まずinput関数を用いてサーバーへ送信するメッセージを決定したのち、メッセージの文末に改行コード"\n"を付け加えておきます。

これは上でも解説したように、メッセージを受信したときにメッセージの文末がどこなのかを簡単に判別できるように付け加えられています。

その後、client.sendall(bytes(message, encoding='ASCII'))とすることで、接続先のサーバーに変数messageの中身を送信します。

なお、引数のencoding='ASCII'は、送信時に使用する文字コードとしてASCIIを選択するために与えています。


その後、サーバーから送られてくるメッセージを受け取るために、

data = client.recv(buffer_size) #サーバから送られてきたデータを読み取り(上限4092ビット)
print("サーバからのメッセージ")
print(data.decode())#受け取ったデータ(バイト形式)を読める形式にデコードして表示

という処理を行います。

サーバから送られてくるメッセージは、そのまま読める文字ではなくバイト形式で送られてくるので、print(data.decode())とすることで、バイト形式から読める形式に変換してから、コマンドプロンプト上に出力します。


最後に

client.close()

として、サーバーとの通信を切断します。

実行例

まずはESP32をネットワークに接続します。

ネットワークのssidとパスワードが正しく入力されていれば、電源投入時に自動でネットワークに接続します。

接続が完了すると、ESP32に割り当てられたIPアドレスがシリアルモニタに表示されます。

ネットワーク接続時のシリアルモニタの表示
ネットワーク接続時のシリアルモニタ


次にクライアント側として機能するpythonプログラムを起動します。


プログラムを起動すると、送信するメッセージの入力受付画面となるので、メッセージを入力しEnterを押します。

その後、メッセージがサーバーに正常に送られると、サーバーからの返信がコマンドプロンプトに表示されます。

メッセージが正常に送信された後のコマンドプロンプト
メッセージが正常に送信された後のコマンドプロンプト


この時、ESP32のシリアルモニタには、クライアントから送られてきたメッセージが表示されます。

メッセージ受信後のシリアルモニタ
メッセージ受信後のシリアルモニタ


以上をもって、ESP32-python間でwifi経由でメッセージをやり取りすることができました!

まとめ

今回は、wifi経由でESP32-python間のメッセージのやり取りを行う方法について紹介しました。

今回は文字の送受信のみ行いましたが、これを応用すれば、pythonプログラムからLEDやモーターなどの電子部品を動かすことも可能です。

今回の記事で不明な点があったらお気軽にコメント欄等からご質問ください!

ものづくりの祭典"Maker Faire Tokyo 2022"に行ってきました!

電子工作のアイデアやモチベーションを補給すべく、東京ビッグサイトにて開催されたMaker Faire Tokyo 2022に行ってきました!

会場前に設置された看板
Maker Faire Tokyo 2022 会場前の看板

今回はMaker Faire Tokyo 2022の良かったところについて紹介します。


この記事はこんな人におススメ・電子工作に興味がある人
・電子工作を始めてみたけれど、作りたいものが思い浮かばないという人
・MFTokyoについて知りたい人

Maker Faire Tokyoってなに?

Maker Faire Tokyoは、技術系サークルや企業など、様々な分野で活躍する"メイカー"たちが制作した作品が展示されるイベントです。


作品の分野としては、ロボットから音楽系、宇宙関連など非常に幅広い分野の作品が展示されているため、自分の興味のある分野はもちろん、今まで触れてこなかった分野の面白さにも気づくことができます

Maker Faire Tokyoのここがすごい!

作者から直接話を聞くことができる

Maker Faire Tokyoの1番すごいところは、ただ展示物を見るだけではなく、作品を作った人から直接いろんなお話が聞けるというところ。


展示されている作品のそばには制作者さんがいる場合が多いので、「この作品はどのように作ったんですか」とか「個々の仕組みはどうなっているんですか」といった質問を制作者さんに気軽にすることができます。


電子工作を始めたばかりの人にとっては、その道の先輩方から電子工作のノウハウを教えていただける貴重な機会となっています(私も倒立振子の制御方法についていろいろと教えていただきました)。


電子工作の可能性の広さを実感できる


Maker Faire Tokyoではさまざまなテーマの作品が展示されています。その中でも特に多いのがArduinoやM5stackなどのマイコンを用いた作品です。


とはいえ、マイコンを用いて何を実現するか、という部分については非常に幅が広いです。


マイコンを用いて電車ジオラマの運行システムを制御する人もいれば、GPSを利用したラジコンを開発している人もいるし、4足歩行ロボットを作成している人もいます。


さらに、サーボモーターや加速度センサなどの電子部品も、作品ごとにさまざまな使われ方がされています。


もしあなたが今、「電子工作で作りたいものが思い浮かばない」という状態に陥っているのであれば、それはマイコンや電子部品にはどのような使い道があるか、どれくらいのことができるのか、という知識量が不足しているからかもしれません。



そこで、現場で先輩方の作品を見て、各パーツの役割や組み合わせ方などを制作者の方から教われば、頭の中に電子工作のアイデアの素が蓄積されていくことでしょう。

まとめ

電子工作のアイデアの幅を広げたい方は、一度MFTokyoへ行ってみるのがいいと思います。


今年のMaker Faire Tokyoに参加できなかった方も、Twitterなどで#MFTokyo2022 で検索すれば、会場の雰囲気や作品の様子などをある程度知ることができると思います。


もし興味がわいたら、ぜひ来年のMaker Faire Tokyoを訪れてみてはいかかでしょうか。

wifi・bluetoothに接続可能! ESP-WROOM-32D開発ボードを解説

今回は、WifiBluetoothに接続可能かつ、Arduinoとして利用できるマイコン、"ESP-WROOM-32D開発ボード"を紹介します!

ArduinoWifiBluetooth経由で操作したいと考えている方はぜひ参考にしてください!


この記事はこんな人におススメArduinoWifiBluetoothに接続したい
・ESP32をwifiに接続する方法を知りたい

ESP-WROOM-32とは?

ESP-WROOM-32(以降、ESP32とします)は、WifiBluetooth用の通信機能を搭載したマイコンです。


最大の特徴は、Arduinoと同じように扱えるということ。実はESP32はArduinoIDEからスケッチの書き込みを行うことができ、言語についても、Arduinoと全く同じ言語を使用することができます。


そのため、これまでArduinoを使ってきた方であれば、ESP32を使い始めるにあたって、新たに開発環境を構築したり、別のプログラミング言語を習得する必要はないんです(超便利)!



そして、今回紹介するESP32開発ボードはESP32をより扱いやすくするよう、各ピンヘッダやUSBケーブルのコネクタなどが搭載されています。


今回使用するESP-WROOM-32D開発ボードは秋月電子通商のページから購入できます。

akizukidenshi.com



ESP32を使うメリット

ESP32を使うメリットとしては、以下のようなものが挙げられます。

Arduinoと同じように使うことができる

ESP32はArduinoIDEから専用のボードマネージャを導入することで、通常のArduinoと同じように動かすことができます。

新たにプログラミング言語を習得する必要もありません。

そのため、これまでArduino用に作ってきたスケッチも、大半はESP32でも動作します。

単体でwifi,bluetoothに接続可能

ArduinoにはWifi,Bluetooth機能が標準搭載されておらず、別売りのwifiシールドなどと組み合わせて使う必要があります。

これに対し、ESP32は本体に通信機能が内蔵されているため、単体で無線通信を行うことができます。

Arduinowifiボードよりも安い

ESP32はArduinowifi通信を行うために必要なwifiシールドよりも安価で入手できます。

価格を比較するとこんな感じ。


ESP-WROOM-32D開発ボード ¥1,480(税込)(秋月電子
akizukidenshi.com

ESP-WROOM-02 Wi-Fi シールド ¥2,750(税込)(スイッチサイエンス)
www.switch-science.com

Wifiシールドを買うよりも1000円以上お得になるため、個人的にはESP32開発ボードを購入することをおススメします!

ESP32をWifiに接続してみよう

ここからは実際にESP32をWifiに接続し、PCやスマートフォンwebブラウザ上から操作する方法を紹介します。

手順① ArduinoIDEのインストール

今回は開発環境としてArduinoIDEを使用します。ArduinoIDEの導入がお済みでない方はこちらの記事を参考にインストールを行ってください。

www.indoorcorgielec.com

手順② ESP32用ボードマネージャをインストール

初めに、ArduinoIDEを開き、左上から、ファイル→環境設定 をクリックします。

ファイル→環境設定をクリック



環境設定ウィンドウが表示されたら”追加のボードマネージャのURL”の欄に以下のURLを入力し、右下のOKボタンを押してください。

”追加のボードマネージャのURL”の欄に以下のURLを入力してくださいhttps://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json


追加のボードマネージャのURLの欄に、指定のURLを入力する



次に、ツール→ボード→ボードマネージャをクリックします。

ボードマネージャを開く



ボードマネージャのウィンドウが表示されたら、上部にある欄に"ESP32"と入力してください。
下の画像と同じパッケージが表示されたら、インストールボタンを押します。

ボードマネージャの検索欄に&quot;ESP32&quot;と入力し、インストールを行う



インストールが完了したらボードマネージャを閉じ、ツール→ボード→ESP32 Arduino→ESP32 Dev Module を選択します。

ESP32 Dev Moduleを選択する




ウィンドウ右下の表示が"ESP32 Dev Module"となれば成功です!

設定が完了すると、右下の表示が&quot;ESP32 Dev Module&quot;になる



手順③ サンプルスケッチを開く

ESP32をWifiに接続するためのサンプルスケッチを書きこんでいきます。

まず、ファイル→スケッチ例→(ESP32用のスケッチ例)Wifi→SimpleWifiServer を選択します。

SimpleWifiServerのスケッチ例を選択




サンプルスケッチが開かれたら、少し下にスクロールし、画像に示す箇所にssidとパスワードを入力します。

なお、この時接続するネットワークには2.4GHz帯のものを選択してください
("yourssid"の部分と"yourpasswd"の部分をそれぞれ接続したいネットワークのssidとパスワードに書き換えてください)

ssidとパスワードを入力する



手順④ LED点灯用の回路を組む

ssidとパスワードの入力が完了したら、LEDを点灯させるための回路を組みます。

今回使用するサンプルスケッチでは5番pinが出力となっているので、使用するピンは5番ピンとGNDになります。

以下のような回路を組んでください。5番pin→抵抗→LED→GNDの順で接続します。

今回使用する回路の図
5番pin→抵抗→LED→GNDの順でつなぐ

手順⑤ ESP32にスケッチを書きこむ

ESP32にスケッチを書きこむために、ESP32とPCをUSBケーブルで接続します。

ESP32開発ボードの端子は"microUSB type-b"端子なので、片側が通常のUSB端子、もう片側がmicroUSB type-b端子となっているケーブルを使用してください。


参考としてAmazonで販売しているケーブルのリンクを載せておきます。


PCと接続したら、スケッチの書き込みを行う前にシリアルモニタを開いておきます。

シリアルモニタを開く




スケッチの書き込みを実行すると、シリアルモニタには次のような表示がされます。

Wifi経由でESP32を操作する際には、シリアルモニタに表示されるESP32のIPアドレスが必要になります。

手順⑥ ブラウザからESP32を操作する

ESP32のIPアドレスをブラウザの検索欄に入力し検索すると、次のようなページが表示されます(今回の場合は 192.168.10.115で検索)。


IPアドレスを入力すると表示されるページ


上の"here"という部分をクリックすると5ピンの出力がHIGHとなりLEDが点灯し、下の"here"という部分をクリックすればLEDが消灯します。


手順は以上になります。wifi経由でESP32を操作し、LEDの点灯・消灯を切り替えることができました!

まとめ

今回はESP32の特徴や、ESP32をwifi経由で操作する方法を紹介しました。ArduinoWifiに接続したいと考えている方はESP32の導入をぜひご検討ください!

【Arduino入門】タクトスイッチの使い方を宇宙一詳しく解説する

"宇宙一詳しく説明するシリーズ"第2弾です。

※この記事は、第1回の続きとなります。第1回はこちらから↓
potala123.hatenablog.com




今回は、電子工作でよく用いることになる"スイッチ"の取り扱い方について解説します。


この記事は次のような方に向いていると思います。

・スイッチを用いた回路を組みたいけれど、使い方がよく分からない
・スイッチを押している間だけ回路に電気が流れる仕組みを作りたい


それではやっていきましょう!

本記事で使用する道具

・Arduino Uno R3 1個
・ブレッドボード 1枚
・ジャンパワイヤ  数本
・LED 1個
・タクトスイッチ 1個 
(参考:秋月電子通商 https://akizukidenshi.com/catalog/g/gP-03647/


【予備知識】タクトスイッチって何?

まず初めに、今回作成する回路の要である"タクトスイッチ"について解説します。

タクトスイッチは、以下の画像のような小さなスイッチです。足が4本生えており、真ん中にはボタンが1つ取り付けられています。
(画像はAmazon商品ページから拝借しました。画像元リンクは以下。)
www.amazon.co.jp


タクトスイッチ

タクトスイッチには次のような2つの特徴があります。

①上下の足はつながっている
②左右の足はつながっていないが、ボタンを押した時のみつながる。

順番に見ていきましょう。まず1つ目の特徴である"上下の足はつながっている"ということについて。
図で見るとこんな感じです。


スイッチの上下の足が実際につながっているのか、確かめてみましょう。

次のような回路を組んでください。この回路は、第1回で扱った回路にスイッチを1つ追加したものになります。


もしスイッチの上下の足がつながっているなら、13ピンの出力をHIGHにした時、LEDは点灯するはずです。

そこで、次のようなスケッチを書き、実行してみます。(このスケッチは、第1回で書いたものと全く同じスケッチです)

void setup() {
pinMode(13,OUTPUT);

}

void loop() {
digitalWrite(13,HIGH);

}

実行した結果は次のようになりました。



LEDが点灯しました。よって、"スイッチの上下の足はつながっている"ということが確かめられました。

では次に、2つ目の特徴である"左右の足はつながっていないが、ボタンを押した時のみつながる"ということについて検証してみます。



配線を少し変えて、次のような回路を組んでください。


スケッチは先ほどと同じものを使います。


実行してみると次のようになります。

LEDは点灯していません。でもスイッチのボタンを押してみると...

LEDが点灯しました! これで"スイッチの左右の足はつながっていないが、ボタンを押した時のみつながる"ということが確かめられました。

このことから、タクトスイッチは"押していないときはOFF,押している間はON"というスイッチであることが分かります。


これで、タクトスイッチの特徴は完ぺきに理解することができました。次回は、このスイッチ回路をより実用的なものにしていくことについて考えていきます。



何かご質問等あれば、コメント欄にどうぞ!


第3回はこちら

potala123.hatenablog.com

【Arduino入門】LEDを光らせる手順を宇宙一丁寧に解説します!

今回は、Arduinoを用いてLEDを光らせる方法について解説します。

この記事はこんな人におススメ・電子工作に興味がある
Arduinoを入手したけれど、使い方が分からない
Arduinoの動作の仕組みをざっくり知りたい


そもそもArduinoって何?

一応初心者向けの記事なので、Arduinoそのものについても簡単に解説します。必要ない方は飛ばしていただいて構いません。

Arduinoはざっくり言うと「すごく小さいコンピューター」です。Arduinoに命令(プログラム)を与えると、その通りに実行してくれます。Arduinoは教育現場でも用いられることが多く、電子工作入門用としても適しているといえます。


Arduinoには"ピン"と呼ばれる穴がたくさん開いており、ピンと外部のLEDやモーターなどの部品を導線で接続することで、それらの部品を操ることができます。

今回はArduinoのピンとLEDを導線で接続することで、LEDを光らせてみます。

今回使うもの

Arduino Uno R3  1個(Arduinoの中でも、一番基本的なモデルです。Amazonで売ってます。)
・ジャンパワイヤ 数本(導線です)
・ブレッドボード 1枚 (ブレッドボードについては後ほど説明します)
・LED 1個


これらの道具を1つも持っていないという方は、Amazonで買えるArduino入門セットがおススメです。入門セットには、Arduino本体はもちろん、ブレッドボードやジャンパワイヤはもちろん、LEDやモーター、各種センサーなど、初心者には十分すぎるほど多種類のパーツが含まれています。(私もこれを使っています)


購入はこちらから!(私が購入したものと全く同じ商品です)


LEDを光らせるためには?

いよいよ本題に入ります。今回はArduinoのピンからLEDへ電源を供給し、LEDを光らせてみようと思います。

つまり、今からやるべきことの流れは次のようになります

ArduinoとLEDのつなぎ方を決める

ArduinoのピンからLEDへ電源を供給する命令(プログラム)を書く

③実行する


それではまず、①ArduinoとLEDのつなぎ方を決める からやっていきましょう。

ArduinoとLEDのつなぎ方を決める

今回はArduinoとLEDを次の図のようにつなぐことにします。

今回使用する回路の図

上の図について解説します。まず、Arduinoの13ピンとLEDをジャンパワイヤで接続します。上の図だと、赤い導線の部分です。この時、ブレッドボードを経由して接続するのですが、ブレッドボードの仕組みについても軽く理解しておく必要があります。


ブレッドボードには無数の穴が開いていますが、実は、同じ縦の列に空いた穴は内部でつながっているんです。

図で見るとこんな感じ。


ここで注意したいのは、”同じ横の列に並んでいる穴同士はつながっていない”ということ。

ブレッドボードに関しては、使っていくうちに慣れてくるものなので、解説はこの辺でとどめておきます。

とにかく、"同じ縦列の穴同士は内部でつながっている"ということだけ頭に入れておいてください。

さて、13ピンから伸びるワイヤとLEDの片足は同じ縦列の穴に刺さっています。つまり今、13ピンとLEDの片足が接続されているということです。

次にLEDの左側の脚を見てみます。左側の脚は抵抗の右足と同じ縦列に、そして抵抗の左足はArduinoのGNDピンから伸びるワイヤと同じ縦列に刺さっています。

以上をまとめると、Arduinoの13ピン→LEDの右足→LEDの左足→抵抗の右足→抵抗の左足→GNDピンという流れでつながっているということになります。

LEDの注意点

もしかしたらお気づきの方もいるかもしれませんが、LEDに生えている2本の脚は微妙に長さが異なっているんです。

長い方をアノード、短い方をカソードと呼ぶのですが、初心者の方は別に覚えなくていいです。

それよりも留意しておいていただきたいのが、”LEDは長い足にプラス、短い脚にマイナスを繋ぐ”というルールです。

実は、LEDは長い脚側から短い脚側という向きでしか電気を流すことができません。

なので、LEDの脚の向きを間違えると、電源を供給しても点灯しない、ということがあります。

”LEDは長い脚をプラス側につなぐ”ということを覚えておいてください。

Arduinoへの命令文、「スケッチ」を書いてみる

配線は無事に終わりました。あとはArduinoに「13ピンから電源を供給せよ」という命令をするだけです。

そして、命令をするためにはプログラムを書く必要があります。

Arduinoの場合、プログラムのことを「スケッチ」と呼ぶ文化があるので、以降、プログラムのことはスケッチと呼ぶことにします。


さて、スケッチを書き込むためには、Arduinoの公式サイトにて提供されている"Arduino IDE"と呼ばれるソフトが必要になります。


ダウンロードは非常に簡単なうえ、Arduino公式が提供しているソフトなので安全性も担保されています。

ダウンロード方法については、私が参考にしたサイトを紹介しておきます。

www.indoorcorgielec.com


Arduino IDEをダウンロード出来たら、いよいよスケッチの作成に入ります。


とはいえ、今回はLEDを光らせるだけのシンプルなスケッチなので、内容は非常にあっさりしています。


今回用いるスケッチを下に載せておきます。コピー&ペーストしてお使いください。

void setup() {
pinMode(13,OUTPUT);

}

void loop() {
digitalWrite(13,HIGH);

}

スケッチの内容と意味について、詳しく見てみましょう。まず冒頭の、

void setup() {
pinMode(13,OUTPUT);
}

の部分について。void setup()とはArduinoの電源がオンになった瞬間に1度だけ実行される命令のことです。

電源オン時に真っ先に1度だけ実行してほしい命令(初期設定など)はvoid setup()の中に書くとよいでしょう。

今回はvoid setup()の中にpinMode(13,OUTPUT);と書いてあります。


これはpinModeという命令で、Arduinoのピンに役割を割り当てる命令文です。

pinMode(13,OUTPUT); を日本語に直すと、”13ピンにOUTPUTという役割を割り当ててね”という命令文になります。

なお、OUTPUTとは日本語で"出力"という意味で、つまり13ピンを電源出力用に設定するよという意味です。


それでは次の部分についてみてみましょう。

void loop() {
digitalWrite(13,HIGH);
}


void loop()の部分では,void setup()の実行後、void loop()内に書かれた命令を何回も繰り返し実行します。

今回の場合、void loop()内にはdigitalWrite(13,HIGH);という命令が書いてあります。

digitalWriteとはデジタル信号(すなわち電源のON,OFF)を指定したピンから出力するという命令です。

digitalWrite(13,HIGH); という命令を日本語で表すと、”13ピンからHIGH(5Vという意味です)を出力する”となります。


スケッチの解説は以上になります。それでは、Arduinoにスケッチを書き込んで、動作を見てみましょう。

スケッチをArduinoに書き込み、実行してみる

まずは、パソコンとArduinoを図のような端子のケーブルで接続してください。(上で紹介した入門セットにはケーブルが付属しています。)

作成したスケッチをArduinoに書き込むためには、Arduino IDE上にある矢印マークのボタンをクリックします。

下の画像を参考にしてください。


矢印ボタンをクリックすると書き込み作業が始まります。

書き込みが正常に完了するとした図のように、画面下の方に”ボードへの書き込みが完了しました”と表示されます。


※もしスケッチに不備があるなどの原因でエラーが生じた場合、次のように赤色で警告されます。

エラーが出た場合の表示。赤色で警告文が表示されている。


スケッチを書き込んだ後、LEDが点灯したら成功です!


何かわからない点があればコメント欄で質問いただければお答えします。


第2回はこちら

potala123.hatenablog.com

 [大戦犯]Arduinoを破壊してしまった...

タイトルの通りである。Arduino Uno R3をぶっ壊しました。

 

経緯

今回、新たにAmazonで購入したLEDマトリクスの動作テストを行うことに。

 

ライブラリのサンプルスケッチを動かしながら、動作をなんとなく理解し始めたころ、悲劇は起こった

 

「上手く動作しているし、回路を拡張してみるか」と調子に乗った結果、あろうことか通電したまま回路をいじってしまった。 

 

 

しかも最悪なことに、しょっぱなからGND線をぶっこ抜くという失態。

 

 

LEDが徐々に力なく消灯していく。あれ?と思いArduinoを触ってみると、今までにないレベルの発熱...

 

 

電源を抜き差しして再度実行するも反応なし。スケッチの再書き込みを試みたが、そもそもCOM3ポートが逝っていた。

 

 

Arduino Uno R3 享年1歳2か月、大往生である

 

 

原因

破壊に至った原因だが、これは明らかに「通電させた状態で回路をいじった」もっと言えば、一部の線をGNDから抜いてしまったことが原因だろう。

 

おそらく、回路の一部がGNDと接続されなくなったことで、Arduinoの端子間にとんでもない電位差が生じた、あるいは大電流が流れたことで、あっさり逝ってしまったのだと思う。

 

 

対応

その後、再度通電させ、スケッチの書き込みなどを試みたが、COM3ポートが完全に破壊され、PC側からArduinoが認識されなくなっていた。

 

 

仕方なくArduinoにお別れを告げ、後任を再度購入することにした。

 

 

それがこちら。

 

 

 

お気づきの方もいるかもしれないが、この度、ついに念願の純正品Arduinoを購入した。価格は3000円弱。互換品の倍くらいするが、造りはかなりしっかりしてそう。

 

 

個人的にうれしかったのは、背面が透明なプラスチックカバーで覆われているという点。互換品だとこの部分がむき出しであることが多く、この部分に金属などを当てた状態で通電させるとショートする危険性があった。

 

 

 

ともかく、今後はつまらない原因でぶっ壊さないよう取り扱いに十分注意したい。

 

 

 

まとめ

回路をいじるときは電源抜け!

 

 

今日はここまで。

 

 

[Arduino入門]スイッチを1回押すごとにLEDの点灯・消灯が切り替わる回路の作り方を解説します!

今回は、スイッチを1回押すごとにLEDの点灯・消灯が切り替わる回路の作り方を紹介します。

この記事は前回の続きになります。前回の記事はこちらから↓
potala123.hatenablog.com



配線図とスケッチの全文を公開しているのでよかったら最後までご覧ください。

スイッチを押すたびにON、OFFが切り替わる機能を実装したい!

ここまでのおさらいをすると、タクトスイッチは"押している間だけON"となるスイッチでした。しかし、我々の身の回りにある一般的なスイッチ、たとえば部屋の電気をつけるためのスイッチなどは、"一度押すとON,もう一度押すとOFF"というように押すたびにONとOFFが切り替わるようになっています。

タクトスイッチも、"一度押すとON,もう一度押すとOFF"となったら便利ですよね。


そこでここからは、"タクトスイッチを押すたびにON、OFFが切り替わる"機能を実装していきたいと思います。

どのようなスケッチを書けばいいか構想を立ててみる

タクトスイッチは"押している間だけON"ですが、今回実装したいのは"押すたびにON,OFFが切り替わる"機能です。
この機能を実装するためにはどうすればよいでしょうか。


例えば、「ボタンが押されたことを検知するたびに、LEDへの出力のHIGH,LOWを切り替える」というように考えてみると、今回必要となる機能は、「ボタンが検出されたことを検知する」という機能と、「LEDへの出力のHIGH,LOWを切り替える」という機能の2つということになります。

今回使用する配線図とスケッチ

今回使用する回路です。

今回使用する回路の図

今回使用するスケッチ(プログラム)です。コピペすればすぐに実行できます。

int switch_status = 1;//スイッチの状態。最初はLOWが入力されている
int LED_status = 0;//LEDの状態。最初は消灯している

void setup() {
pinMode(8,INPUT_PULLUP);//8PINを受信用に設定、プルアップ抵抗付き
pinMode(13,OUTPUT);//13PInを出力用に設定
}

void loop() {
 if (digitalRead(8) != switch_status && digitalRead(8) == 0){//スイッチの状態が変わった,かつスイッチが押されている状態
  if (LED_status == 0){
    digitalWrite(13,HIGH);
    LED_status = 1;
  }else if (LED_status == 1){
    digitalWrite(13,LOW);
    LED_status = 0;
  }
}
switch_status = digitalRead(8);//8ピンの状態を変数に保存
delay(100);
}


この部分では、switch_statusという変数と、LED_statusという変数をそれぞれ定義しています。頭についている"int"は”整数型”、すなわち整数を入れるための変数であるということを意味しています。

今回はスイッチのON,OFFを識別するための変数をswitch_status、回路内のLEDが点灯しているかどうかを示す変数をLED_statusとします。

最初はスイッチが押されておらず、この状態ではHIGH(=1)の信号が入力されるので、switch_statusの初期値は1とします。また、LEDは最初は点灯していないので、LED_status の初期値は0とします。

最初スイッチが押されていない状態からスタートするなら、switch_statusの初期値はLOW(=0)ではないのか、と疑問に思われる方もいるかもしれませんが、この点については後ほど解説します。




それでは次に、setup関数の部分を見てみましょう

setup関数

void setup() {
pinMode(8,INPUT_PULLUP);//8PINを受信用に設定、プルアップ抵抗付き
pinMode(13,OUTPUT);//13PInを出力用に設定
}

setup関数内では、8ピンと13ピンの設定を行っています。

pinMode(8,INPUT_PULLUP) の部分では、8ピンをINPUT(入力用)に設定しています。なお今回は、INPUTではなくINPUT_PULLUPとすることで、プルアップ抵抗機能を用いています。

プルアップ抵抗機能は、Arduinoとスイッチを接続する際に重宝する機能です。ここではプルアップ抵抗に関する解説は行いませんが、私が参考にしたページを紹介します。

burariweb.info


pinMode(13,OUTPUT); の部分では、13ピンをOUTPUT(出力用)に設定しています。そのままですね。


それではいよいよメインとなるloop関数の説明に入ります。

loop関数


loop関数内は記述が多いうえに動作も複雑なので、何か所かに分割して解説していきます。

まずは最初のif文から。

if (digitalRead(8) != switch_status && digitalRead(8) == 0){

急に難易度が跳ね上がったように見えますが、よく見ると簡単なのでご心配なさらず。

まずdigitalRead(8) != switch_statusの部分。

ここではdigitalRead(8)、すなわち8ピンの入力の状態(すなわちスイッチが押されているかどうか)と変数”switch_status”の状態を比較しています。



通常のイコールではなく"!="で結ばれているので、スイッチの状態と変数”switch_status”の状態が異なれば真ということになります。



なお、この後解説しますが、変数”switch_status”には、直前のボタンの状態(押されているかいないか)を記録してあります。



つまり「スイッチの状態と変数”switch_status”の状態が異なる」とは、「直前までスイッチが押されていなかったが、今は押されている」
または「直前までスイッチが押されていたが、今は押されていない」と言いかえることができます。


回りくどい言い方になりましたが、要するに「スイッチのON,OFFが切り替わったかどうか」を表しています。





次にdigitalRead(8) == 0の部分について。この部分では、8ピンの入力がゼロ、すなわちスイッチが押されている状態を真としています。



以上2つの条件が&&、すなわち「かつ」でつながれているため、if (digitalRead(8) != switch_status && digitalRead(8) == 0)の部分を日本語で表現すれば、



「スイッチのON,OFFが切り替わった」かつ「スイッチが今まさに押されている状態」 


と表せます。またまた回りくどい表現ですが、これを簡単な言葉に言いかえると



「スイッチを押した瞬間」ということです。



注意したいのは、「スイッチから指を離した瞬間」はif文の条件を満たさないということです。なぜなら「スイッチから指を離した瞬間」は「スイッチが今まさに押されている状態」という条件を満たさないからです。


以上をまとめると、if (digitalRead(8) != switch_status && digitalRead(8) == 0)の部分は「スイッチが押された場合」という条件を意味しているということです。


それでは、次の部分について解説します。

if (LED_status == 0){
    digitalWrite(13,HIGH);
    LED_status = 1;
}else if (LED_status == 1){
    digitalWrite(13,LOW);
    LED_status = 0;

まず1行目について。if (LED_status == 0) は、変数"LED_status"の値がゼロ、すなわち”LEDが消灯しているとき”を意味しています。
この時、 digitalWrite(13,HIGH);で13ピンからの出力をHIGHにすることで13ピンに接続されたLEDを点灯させます。その後、LEDの店頭状態を表す変数” LED_status”の値を1にしておきます。

一方で、else if (LED_status == 1)、すなわちLEDが点灯している場合は、digitalWrite(13,LOW);とすることで13ピンからLEDへの出力をゼロにし、変数"LED_status" の値をゼロに変更します。



そして最後の部分について。

switch_status = digitalRead(8);//8ピンの状態を変数に保存
delay(100);

switch_status = digitalRead(8)の行では、8ピンの様子(スイッチが押されているか否か)を変数"switch_status"に記憶しています。

ここで記憶されたスイッチの状態は、 if (digitalRead(8) != switch_status && digitalRead(8) == 0)の部分でスイッチが押されたかどうかの判定に用いられます。

例えば、”一つ前のloopではスイッチは押されていなかった(switch_status = 1)が、今は押されている(digitalRead(8) = 0)”みたいな感じです。(この回路ではプルアップ抵抗を用いているので、スイッチが押されたときが0,押されていないときが1であることに注意。)


そして最後の行では、delay(100);とすることで100ミリ秒、すなわち0.1秒の間プログラムを一時停止させています。



なぜわざわざ一時停止を挟まなければいけないのか、と疑問に思う方もいるかもしれませんが、ここはこういうものだと覚えてください。



気になった方はdelay(100)の部分を消去してから実行してみるといいでしょう。たまにではありますが、ボタンを押した時の反応がおかしくなるはずです。



解説は以上になります。押すたびにON,OFFが切り替わる仕組みは様々な場面で活用できるはずです。ぜひマスターしていただければと思います。