2024年度Web×IoTメイカーズチャレンジPLUS参加録 #1
- 2024年度Web×IoTメイカーズチャレンジPLUS
- GPIOとI2C
- 初めてのLチカ
- リモートからLチカ制御
2024年度Web×IoTメイカーズチャレンジPLUS
「2024年度Web×IoTメイカーズチャレンジPLUS」に参加しました。今回はじめてJavascrptでコードを書いたり、センサー類の制御などを行いました。備忘録も兼ねて、今回学んだことや作成したコードなどをここに記録しておきます。
このメイカーズチャレンジでは、Raspberry Pi Zero2 WとCHIRIMENスターターキットが無料でプレゼントされます!CHIRIMENスターターキットには、ブレッドボードやLED、配線用のワイヤーや抵抗などの各種電子パーツが入っております。
CHIRIMENについてはこちらを参照。
また、こちらに非常に詳しいチュートリアルがあります。私も基本的にこのチュートリアルに沿っていろいろ動かしました。
GPIOとI2C
電子パーツを制御するためには、GPIOとI2Cの2種類の接続・制御方法があります。
GPIO(General-Purpose Input-Output)
- Raspberry Piなどについている金属ピンを通してGPIO対応の電子パーツと電気信号をやり取りする方式で、1つのピンに1つの電子機器が接続される形になります。Raspberry Pi Zero2には合計40本のピンがありますが、このうち17本がGPIOのピンで、それぞれに異なる番号がついています。Javascript上からはこのピン番号を指定して電子パーツと信号の送受信を行います。なおGPIOのピンにはPUとPDの2種類があります。
- PU:プルアップ。デフォルトで"1"(電流が流れる)。"0"の信号を送ると電流をとめられる。
- PD:プルダウン。デフォルトで"0"。"1"の信号を送ると電流が流れる。
I2C(Inter-Integrated Circuit)
- シリアルバス通信を行うための仕組みで、Raspberry Pi Zero2 Wには1本のSDA(Serial Data)と1本のSCL(Serial Clock)のピンが備わっています。I2Cで接続される電子パーツにはあらかじめ7bit長のアドレス(例えば0x48など)が割り当てられており、Javascript上からはこのアドレスを指定して電子パーツと信号の送受信を行います。ピンはSDA, SCLともに1本ずつしかありませんが、ブレッドボード上で並列に接続することで、複数のI2C対応デバイスを制御できます。
Raspberry Pi Zero(Zero2 Wも多分同じ)のピン配列はこちらを参照。
初めてのLチカ
LチカとはLEDをチカチカ点滅させることです(多分)。一番最初にチャレンジしました。
作成したJavascriptは次の通りです。スクリプトは、ほぼチュートリアルのページに書いてあるとおりですけれどもね。RaspberryPiやLED、抵抗などの配線は、チュートリアルのページの第3章を参考にしてください。
led-chikachika.js
// GPIOを使うためのライブラリ読み込み
import {requestGPIOAccess} from "/home/pi/myApp/node_modules/node-web-gpio/dist/index.js";
// 一定時間だけ待機する関数
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
// メイン部分
async function main(){
// GPIOを使うためのコンテナ?
const gpioAccess=await requestGPIOAccess();
// GPIOの26番にアクセスする
var gpioPort=gpioAccess.ports.get(26);
// GPIOの該当ポートを出力型(out)に設定する
await gpioPort.export("out");
// 点滅繰り返し
for(let i=0; i < 10; i++){
// 点灯(1を出力)
await gpioPort.write(1);
await sleep(1000);
// 消灯(0を出力)
await gpioPort.write(0);
await sleep(1000);
}
}
main();
これをnode.jsで実行させます。
なお、スクリプトは~/myApp/の下において実行しないと、何やらパスの関係があるのかエラーになります。なので基本的にmyAppディレクトリの直下に保存しておきます。
% node ~/myApp/led-chikachika.js
リモートからLチカ制御
今度はインターネットを介して、LEDをON/OFFさせます。チュートリアルの「6. IoTを試す」の内容と同じです。
CHIRIMENにはSecure WebSocket(WSS)を使ってリアルタイム通信する機能(ライブラリ)が備わっており、インターネットからWebSocketのリレーサーバを介して、CHIRIMENデバイスを制御することができます。
さらにCHIRIMENの学習用にCHIRIMENのサイトでWebSocketのリレーサーバを提供してくれています。今回はこちらのリレーサーバをお借りして、自分のPC(ブラウザ・Javascript)から先ほどLチカさせたLEDをON/OFFさせてみます。
なおこのリレーサーバはおそらくCHIRIMENの学習用だと思いますので、CHIRIMENの学習以外の目的では使用しな方が良いと思います。多分。
CHIRIMEN側のスクリプトは次の通りです。PC側からメッセージが届くとcontrollLED()関数が実行され、メッセージの内容message.dataに合わせてLEDへ"1"や"0"を送信して点灯・消灯を行います。
led-remote.js
import {requestGPIOAccess} from "/home/pi/myApp/node_modules/node-web-gpio/dist/index.js";
// リレーサーバを利用するためのライブラリを読み込む
import nodeWebSocketLib from "websocket";
import {RelayServer} from "./RelayServer.js";
// グローバル変数
var channel;
var gpioPort;
// メイン部分
async function main(){
const gpioAccess=await requestGPIOAccess();
gpioPort=gpioAccess.ports.get(26);
await gpioPort.export("out");
// リレーサーバ接続のインスタンス作成
// 第一引数:サービス名
// 第二引数:アクセストークン
// 第三引数:? 第四引数:BaseURL?
var relay = RelayServer("chirimentest","chirimenSocket", nodeWebSocketLib, "https://chirimen.org");
// 通信するチャネルを作成(" "内はチャネル名で、PC側と同じものを指定する)
channel = await relay.subscribe("chirimenLEDhogehoge");
// チャネル経由でメッセージを受けたらcontrolLED関数を実行する
channel.onmessage=controlLED;
}
function controlLED(message){
// 送られてきたメッセージ(ONまたはOFF)によって処理を実行する
if(message.data=="ON"){
gpioPort.write(1);
console.log("ON");
// PC側へメッセージを送信する
channel.send("LED ON!");
}else if(message.data=="OFF"){
gpioPort.write(0);
console.log("OFF");
channel.send("LED off!");
}
}
main();
実行して「channelOpened」と出力されれば、Sockサーバにつながったことになります(多分...)。
$ node led-remote.js
object https://chirimen.org
wss://chirimen-web-socket-relay.herokuapp.com/chirimenSocket/chirimenLEDhogehoge null https://chirimen.org
tinyWssModule:channelOpened
PC側のスクリプトは次の通りです。これをPCのブラウザで開けばOKです。ブラウザ上のONボタンを押すとOnLED()関数が呼び出され、channel.send("ON")が実行され、「ON」というメッセージがCHIRIMEN側に送信されます。OFFボタンも同じく「OFF」というメッセージがCHIRIMEN側へ送信されます。
led-remote-pc.html
<script type="module">
/* リレーサーバを利用するためのライブラリを読み込む */
import {RelayServer} from "https://chirimen.org/remote-connection/js/beta/RelayServer.js";
/* グローバル変数 */
var channel;
window.OnLED = OnLED;
window.OffLED = OffLED;
/* CHIRIMEN側から受け取ったメッセージを表示する関数 */
function outmessage(message){
document.getElementById("message").innerText=message.data;
}
/* ONボタンをクリックしたときの処理 */
function OnLED(){
channel.send("ON");
}
/* OFFボタンをクリックしたときの処理 */
function OffLED(){
channel.send("OFF");
}
/* このページが読み込まれたときにchannelの設定を行う */
onload = async function(){
var relay = RelayServer("chirimentest", "chirimenSocket");
channel = await relay.subscribe("chirimenLEDhogehoge");
/* CHIRIMEN側からメッセージがあったらoutmessage関数を呼び出す */
channel.onmessage=outmessage;
}
</script>
<button id="ON" onclick="OnLED()">ON</button>
<button id="OFF" onclick="OffLED()">OFF</button>
<p id="message">____</p>
https://ucchi.info/ 07,Mar 2025
※まだ学んだばかりのことなので、不完全な内容や誤った内容が書いてあるかもしれません。
※このサイトの利用並びに閲覧によって生じたいかなる損害についても当方では責任を負いません。自己責任でお願いいたします。