前回は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 |
---|
この角度を0度とすると... |
実行結果2 |
---|
45度 |
実行結果3 |
---|
90度 |
実行結果4 |
---|
最後にLED消します |
半田付け無しでもサーボが回せて楽しいです。