
ESP32-C3 その5 簡易データーグローブソフトウェア部門(曲げセンサー)
簡易データグローブとは
精度はそんなに高くなく、指の曲がりは曲げ伸ばし、指同士の間隔は測れず、ただただ安価を目指します。
の続き
動作自体はそれなりになってきたのでSlimeVRと悪魔合体してみる。
ESP32C3側のプログラム
・ADCの設定を色々と変えてみる。
・指関係のソースはfingersにまとめう。
ADCのサンプリング回数・・・余り増やすとバグる
#define AVE_SAMPLES 10
校正済みのインプットを使う
pinMode(FINGER_LITTLE, ANALOG);
減衰率の変更・・・0dbなので減衰なし
analogSetAttenuation(ADC_0db);
SlimeVRTrackerから設定を拝借
osc_host = ServerConnection::serverAddress();
fingers/fingers.cpp
#include "fingers.h"
u_long last_time;
#define AVE_SAMPLES 10
int osc_send_port = 9002;
IPAddress osc_host;
float lit, rng, mid, idx, tmb;
void Fingers::setup() {
pinMode(FINGER_LITTLE, ANALOG);
pinMode(FINGER_RING, ANALOG);
pinMode(FINGER_MIDDLE, ANALOG);
pinMode(FINGER_INDEX, ANALOG);
pinMode(FINGER_THUMB, ANALOG);
// ADCの減衰器の設定
analogSetAttenuation(ADC_0db);
last_time = micros();
}
void Fingers::update() {
if(!ServerConnection::isConnected()) {
return;
}
// 1000ns * 50 = 50ms
if((micros() - last_time) < 1000 * 50) {
return;
}
last_time = micros();
lit = rng = mid = idx = tmb = 0;
osc_host = ServerConnection::serverAddress();
for(int l; l < AVE_SAMPLES; l++) {
lit += Fingers::read(FINGER_LITTLE);
rng += Fingers::read(FINGER_RING);
mid += Fingers::read(FINGER_MIDDLE);
idx += Fingers::read(FINGER_INDEX);
tmb += Fingers::read(FINGER_THUMB);
}
lit = lit / AVE_SAMPLES;
rng = rng / AVE_SAMPLES;
mid = mid / AVE_SAMPLES;
idx = idx / AVE_SAMPLES;
tmb = tmb / AVE_SAMPLES;
// return;
#ifdef LEFT_HAND
OscWiFi.send(osc_host.toString(), osc_send_port, "/Left/Hand/Little", (float)lit);
OscWiFi.send(osc_host.toString(), osc_send_port, "/Left/Hand/Ring", (float)rng);
OscWiFi.send(osc_host.toString(), osc_send_port, "/Left/Hand/Middle", (float)mid);
OscWiFi.send(osc_host.toString(), osc_send_port, "/Left/Hand/Index", (float)idx);
OscWiFi.send(osc_host.toString(), osc_send_port, "/Left/Hand/Thumb", (float)tmb);
#endif
#ifdef RIGHT_HAND
OscWiFi.send(osc_host.toString(), osc_send_port, "/Right/Hand/Little", (float)lit);
OscWiFi.send(osc_host.toString(), osc_send_port, "/Right/Hand/Ring", (float)rng);
OscWiFi.send(osc_host.toString(), osc_send_port, "/Right/Hand/Middle", (float)mid);
OscWiFi.send(osc_host.toString(), osc_send_port, "/Right/Hand/Index", (float)idx);
OscWiFi.send(osc_host.toString(), osc_send_port, "/Right/Hand/Thumb", (float)tmb);
#endif
}
uint16_t Fingers::read(uint8_t f) {
uint16_t ret;
ret = analogReadMilliVolts(f);
return ret;
}
fingers/fingers.h
#ifndef MENTAIGLOBE_FINGERS_H_
#define MENTAIGLOBE_FINGERS_H_
#include <Arduino.h>
#include <ArduinoOSCWiFi.h>
#include "network/udpclient.h"
// 手の切り替え
// 両方定義した場合は、
// 左手に装着した状態を想定し、
// そのデータをOSCで両手に送る
#define LEFT_HAND
#define RIGHT_HAND
#ifdef LEFT_HAND
#define FINGER_LITTLE 0
#define FINGER_RING 1
#define FINGER_MIDDLE 2
#define FINGER_INDEX 3
#define FINGER_THUMB 4
#elif RIGHT_HAND
#define FINGER_LITTLE 0
#define FINGER_RING 1
#define FINGER_MIDDLE 2
#define FINGER_INDEX 3
#define FINGER_THUMB 4
#endif
namespace Fingers {
void setup();
void update();
uint16_t read(uint8_t);
}
#endif // MENTAIGLOBE_FINGERS_H_
main.cpp
includeの最後に
#include "fingers/fingers.h"
void setup() {} の最後に
Fingers::setup();
void loop() {} の ledManager.update(); の後に
Fingers::update();
SlimeVRTrackerを少し改造する
hostを取得するために serverAddress(); を追加する。
===> network/udpclient.h
namespace ServerConnection {
void connect();
void update(Sensor * const sensor, Sensor * const sensor2);
void resetConnection();
bool isConnected();
IPAddress serverAddress();
}
===> network/udpclient.cpp
IPAddress ServerConnection::serverAddress()
{
return host;
}
所感
オープンソースのものになーんとなく機能を追加するにはこんな感じかなと、もうすこしスマートなやり方はあるとは思う。
ソフトウェアは一通り完成として曲げセンサーを以下にして固定するかを考えよう。