1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ハード その他Advent Calendar 2022

Day 20

embotをブラウザから操作したい

Last updated at Posted at 2022-12-19

前回はLチカだけでしたが今回はサーボとブザーも操作してみます。
サーボはサーボの字が上に向くように置いて上から見たとき0度に対して反時計回りに180度まで回転できるようです。
またブザーは半音単位で、52を基準のドとして20ぐらいから100ぐらいまでは音程が取れるようです。自動で音を止めたりはしてくれないので止める場合は 0 を指定します。

下記のように index.html と index.js を作成し
index.html を Edge に読み込みます。
※不要なコードも混ざっています。
「開始する」をクリックするとブラウザがペア設定ダイアログを出しますので
embot を選択してペアリングします。
少し待つとブザーが鳴りLEDがつきサーボが回りLEDが消えブザーが止まります。

index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>embot 操作したい</title>
</head>
<body>
<button onclick="_start()">開始する</button>
<script src="index.js"></script>
</body>
</html>
index.js
const _uuid = (s) => {
    return `f7fc${s}-7a0b-4b89-a675-a79137223e2c`;
};
class Em { // 非公式
    constructor() {
        this.bpm = 60;
        this._led = { on: 1, off: 2 };
        this._speed1 = 1;
        this._speed2 = 1;
    }
    async _write(char, val) {
        const buf = new Uint8Array(1);
        buf[0] = Number.parseInt(val);
        await char.writeValueWithoutResponse(buf.buffer);
    }
    async _initialize() {
        const blue = window.navigator.bluetooth;
        try {
            const opt = {
                optionalServices: [ _uuid('e510') ],
                filters: [{ namePrefix: 'EMBOT_' }]
            };
            const device = await blue.requestDevice(opt);
            const server = await device.gatt.connect();
            const service = await server.getPrimaryService(_uuid('e510'));
            this._led1 = await service.getCharacteristic(_uuid('e515'));
            this._led2 = await service.getCharacteristic(_uuid('e516'));
            this._servo1 = await service.getCharacteristic(_uuid('e511'));
            this._servo2 = await service.getCharacteristic(_uuid('e512'));
            this._buzzer = await service.getCharacteristic(_uuid('e521'));
            this._other = await service.getCharacteristic(_uuid('e525'));
        } catch(e) {
            console.error(`_initialize catch`, e.message);
        }
    }
    sleep(sec) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve();
            }, sec * 1000);
        });
    }
    getDefaultRobotId() { return 'default'; }
    async connectEmbot(id) {}
    logout(arg) { console.warn(eval(arg)); }
    showError(s) { alert(s); }
    rest(sec) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                this.write(this._buzzer, 0);
                resolve();
            }, sec * 1000);
        });
    }
    async buzzerTimer(beat) { return 60 * beat / this.bpm; }
    async restInOctave(beat) { return 60 * beat / this.bpm; }
    async sendToEmbot(id, info) {
        switch(info.type) {
        case 'led':
            await this._write(info.id === 1 ? this._led1 : this._led2,
                this._led[info.value]);
            break;
        case 'servo':
            await this._write(info.id === 1 ? this._servo1 : this._servo2,
                info.value);
            break;
        case 'rotatingServo':
            if (info.id === 1) {
                this._speed1 = info.value;
            } else {
                this._speed2 = info.value;
            }
            break;
        case 'buzzer': // '61' ラ1
            await this._write(this._buzzer, info.value);
            break;
        case 'octave': // 高い方は100ぐらい 52はド1 28ド-1
            await this._write(this._buzzer, info.value);
            break;
        }
    }
    end() {}

    async action_1() {
        try {
            let blockInfo = '';
            let robotId = this.getDefaultRobotId();
            await this.connectEmbot(robotId);
            blockInfo = { type: 'led', id: 2, value: 'on' };
            await this.sendToEmbot(robotId, blockInfo);
            blockInfo = { type: 'octave', value: '52' };
            await this.sendToEmbot(robotId, blockInfo);
            blockInfo = { type: 'servo', id: 1, value: '0' };
            await this.sendToEmbot(robotId, blockInfo);
            await this.sleep(2);
            blockInfo = { type: 'servo', id: 1, value: '45' };
            await this.sendToEmbot(robotId, blockInfo);
            await this.sleep(2);
            blockInfo = { type: 'servo', id: 1, value: '90' };
            await this.sendToEmbot(robotId, blockInfo);
            await this.sleep(2);
            blockInfo = { type: 'octave', value: '0' };
            await this.sendToEmbot(robotId, blockInfo);
            blockInfo = { type: 'led', value: 'off' };
            await this.sendToEmbot(robotId, blockInfo);
        } catch (error) {
            throw error;
        }
    }

}
const em = new Em();
const _start = async () => {
    try {
        await em._initialize();
        await em.action_1();
    } catch(e) {
        em.showError(e.message);
    }
};
実行結果1
00度.png
この角度を0度とすると...
実行結果2
45度.png
45度
実行結果3
90度.png
90度
実行結果4
90度off.png
最後にLED消します

半田付け無しでもサーボが回せて楽しいです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?