見出し画像

clusterのMetaGadgetで外部出力のメモ

clusterのMetaGadgetで外部にデータを送れるようになったので
実際にやってみた時のメモです。何かの参考になればどうぞ。

元のGitHubに始め方があります。(少しだけ補足)

動作環境

Raspberry Pi 4B 4GB
Raspbian buster

Pythonは3.8以上

私の場合、ライブラリをインストールしようとするとエラーがでました。

pi@raspberrypi:~ $ pip install metagadget RPi.GPIO
Defaulting to user installation because normal site-packages is not writeable
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
ERROR: Ignored the following versions that require a different python version: 0.0.3 Requires-Python >=3.8; 0.0.4 Requires-Python >=3.8
ERROR: Could not find a version that satisfies the requirement metagadget (from versions: none)
ERROR: No matching distribution found for metagadget

Pythonが3.8以上でないといけないようです。(3.7.3でした)
次のサイトを参考に3.8にするとインストールできました。
(OSがRaspbian busterと古かったので、新しくしてもよいと思います)

ngrokの登録と取得

「ngrok」を使用しますので、アカウント登録します。
登録後に、「Auth Token」と「Domain」が必要になります。

「Auth Token」は左のメニューの「Your Authtoken」になります。
「Copy」でコピーして、どこかに貼り付けておきます。

「Domain」は左のメニューの「Domains」から「Create Domain」で作成されます。「Domain」の部分をコピーして、どこかに貼り付けておきます。

動作確認(ON・OFF)

あとは、公式の内容通りです。。

数値の送信と頻度

数値を送ることも可能ですので、サーボモータを動かしてみました。
RaspberryPI側のコードはこちら。

from gpiozero import AngularServo
from gpiozero.pins.pigpio import PiGPIOFactory
from time import sleep
from metagadget import MetaGadget

SERVO_PIN = 12

MIN_DEGREE = -90
MAX_DEGREE = 90

def main():
    factory = PiGPIOFactory()

    servo = AngularServo(SERVO_PIN, min_angle=MIN_DEGREE, max_angle=MAX_DEGREE, 
                         min_pulse_width=0.5/1000, max_pulse_width=2.4/1000, frame_width=1/50,
                         pin_factory=factory)

    app = MetaGadget()
    @app.receive
    def hundle(data):
        angle_input = (int(data) / 180) * 180 - 90
        if -85 < angle_input < 85:
            servo.angle = angle_input
            sleep(0.1)
            print(data, angle_input)

    app.run()
    
if __name__ == "__main__":
    main()

数値の送信のサンプルはこちら。

モータ動作の参考はこちらのサイトです。

アイテムのスクリプトはこちら。
アイテムの角度を読み込んで送ってます。
ただ、送る頻度に制限があるり、間隔が小さいとエラーが出ます。
このため、タイマーを入れてます。

let prevTensDigit = null;

$.onStart(() => {
  $.state.waitingTime = 0;
});

$.onUpdate(deltaTime => {
  let position = $.getPosition();
  let angle = Math.atan2(position.z, position.x);
  let angleInDegrees = Math.abs(Math.round(angle * (180 / Math.PI)));
  $.setStateCompat("this", "angleInDegrees", angleInDegrees);

  let currentTensDigit = angleInDegrees;
  let waitingTime = $.state.waitingTime + deltaTime;
  if (waitingTime >= 0.5) {
    waitingTime = 0;
    if (currentTensDigit !== prevTensDigit) {
        angleInDegrees_out = angleInDegrees;
        prevTensDigit = currentTensDigit;
        $.log(angleInDegrees_out);
        $.callExternal(angleInDegrees_out, "test");
    }
  }
  $.state.waitingTime = waitingTime;
});

更新頻度はこちらを参考にしてます。

動作確認(数値)

スムーズではないですがなんとか動いてます。。

頻繁に送るのには向いていないので
一定時間空いて送るようなものを作った方がよさそうです。。

いいなと思ったら応援しよう!