ラズパイで、距離計測をしてみました。
使ったのは、超音波距離センサー HC-SR04です。
その昔、学校にいたころに触ったこともあったので気軽に買ったのですが、
Node.js なのか、Raspberry Pi なのか何が理由かうまくいかなくて、
悩みながらの作成になってしまいました。
それでは、ハードウェアの接続からです。
目次
ハードウェア
以下の写真のように接続します。
と言ったってやっぱりわかりにくい・・・。
文字に起こすと以下の様になります。
ラズパイ側 : HC-SR04側
物理ピン 2番(+5v) => vcc ピン
物理ピン12番(GPIO18番) => Echoピン
物理ピン24番(GPIO14番) => Trigピン
物理ピン39番(GND) => Gnd ピン
お次はコードです。
コード
とりあえず、どこかでディレクトリを作ってそのフォルダに移動、
npm init
を実行
今回マイクロ秒単位で、時間を取得したいので
npm i microseconds
を実行し、パッケージを取得します。
uss.js として以下を保存します。(ultrasonic sensor なので)
uss.js1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| const fs = require("fs"); const path = require("path"); const microsec = require("microseconds");
let trpinnum = 23; let ecpinnum = 18;
let pathstr = "/sys/class/gpio/"; let gpio23 = path.join(pathstr, "gpio" + trpinnum); let gpio18 = path.join(pathstr, "gpio" + ecpinnum);
let echostate = 0;
fs.writeFileSync(path.join(pathstr, "export"), trpinnum); fs.writeFileSync(path.join(gpio23, "direction"), "out"); fs.writeFileSync(path.join(pathstr, "export"), ecpinnum); fs.writeFileSync(path.join(gpio18, "direction"), "in");
let microsleep = (time) => { let starttime = microsec.now(); while (true) { if (microsec.since(starttime) > time) { break; } } };
let getdata3 = (trigpin, echopin) => { let starttime = 0; let startexetime = -1; let time = 0;
fs.writeFileSync(path.join(trigpin, "value"), 0); microsleep(10); fs.writeFileSync(path.join(trigpin, "value"), 1); microsleep(10); fs.writeFileSync(path.join(trigpin, "value"), 0);
startexetime = microsec.now(); while (fs.readFileSync(path.join(echopin, "value"), "utf8") == 0) { if (microsec.since(startexetime) > 50000) return -1; } starttime = microsec.now(); while (fs.readFileSync(path.join(echopin, "value"), "utf8") == 1) { if (microsec.since(startexetime) > 50000) return -2; } time = microsec.since(starttime);
let kyori = time * 0.017175; return kyori; };
let loop = setInterval(async () => { console.log("///////////////////////////"); let buf = getdata3(gpio23, gpio18); console.log(":" + buf); }, 500);
process.on("SIGINT", () => { clearInterval(loop); fs.writeFileSync(path.join(pathstr, "unexport"), trpinnum); fs.writeFileSync(path.join(pathstr, "unexport"), ecpinnum); console.log("PROCESS EXIT"); process.exit(1); });
|
実行は、sudo node uss.js
です。
終了するときはCtrl+C
を入力します。
実行すると以下のように表示されます。
///////////////////////////
:10.702154643917083
///////////////////////////
:14.519985409641265
///////////////////////////
:14.277577486896515
///////////////////////////
:21.380127002620696
///////////////////////////
:14.053941813468933
///////////////////////////
:15.71150110015869
///////////////////////////
:14.367024890041352
^CPROCESS EXIT
測定ができました。
しかし!
HC-SR04 の分解能は 0.3cm と記載があるんですが、
実際は+-3cm 程度の誤差が出てしまったんですが、これが直せない・・・。
調べた範囲では Raspberry Pi の raspbian がリアルタイム OS ではないから、
計測処理中に OS で割り込みが入っている?という結論でした。
(そういうリアルタイム向けの処理のために RTLinax ってものもあるようです。)
とはいえ、ドアの開け閉め検知や目の前の障害物の存在判定ぐらいなら問題なさそうです。
参考にしてくれる人がいれば何よりです。
ではでは。