IoT何をいまさら(105) MicroNavRingセンサをArduinoに接続してみる

Joseph Halfmoon

別シリーズでリング型の「タッチパッド」センサを入手。圧力の変化を抵抗の変化に変換するタイプの素子です。薄いドーナツ型形状なので、指でぐるぐる回したりする操作を検出するのに向いてそうです。しかし別シリーズでは手動で動作確認したのみ。マイコンで動かしてみないと。そーゆー時にお楽なのが伝統のArduinoであります。

Ring Sensor、今回実験の回路

今回はArduinoシリーズでも定番中の定番、Arduino Unoを使用であります。なんといってもArduino環境はお楽、気が楽です。

センサを駆動するためのデジタル3端子と結果のアナログ入力1端子が必要であるので、以下のようにいたしました。左端はArduinoの端子名です。

    • A0、センサからのアナログ入力
    • D2、センサのD1端子に接続、内部抵抗を駆動
    • D3、センサのD2端子に接続、内部抵抗を駆動
    • D4、センサのD3端子に接続、内部抵抗を駆動

接続はこんな感じ。簡単。NavRingArduinoDUT

Ring Sensor駆動用の「スケッチ」

Arduino環境ではソースを「スケッチ」と呼びますな。以下に今回実験使用の全文を掲げます。これまたベタな書き方。今回は円形を3分割したリージョン位置の検出のみ。リージョン内の位置推定もできる筈なのですがまた今度。

// Tested on Arduino Uno.
#include <Arduino.h>

#define D1  (2)
#define D2  (3)
#define D3  (4)
#define TH  (100)

int v1, v2, v3;
int zone=0;

void scanRingSensor() {
  digitalWrite(D1, LOW);
  delay(5);
  v1 = analogRead(A0);
  digitalWrite(D1, HIGH);
  delay(5);
  digitalWrite(D2, LOW);
  delay(5);
  v2 = analogRead(A0);
  digitalWrite(D2, HIGH);
  delay(5);
  digitalWrite(D3, LOW);
  delay(5);
  v3 = analogRead(A0);
  digitalWrite(D3, HIGH);
}

void initRingSensor() {
  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);
  pinMode(D3, OUTPUT);
  digitalWrite(D1, HIGH);
  digitalWrite(D2, HIGH);
  digitalWrite(D3, HIGH);
}

void printReadRing() {
  Serial.print("v1=");
  Serial.print(v1);
  Serial.print(" v2=");
  Serial.print(v2);
  Serial.print(" v3=");
  Serial.println(v3);
}

void printZone() {
  if (v1<=v2) {
    if ((v3 - v1) > TH) zone = 1;
    if ((v1 - v3) > TH) zone = 3;
  } else {
    if ((v3 - v2) > TH) zone = 2;
    if ((v2 - v3) > TH) zone = 3;
  }
  Serial.println(zone);
}

void initLED() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
}

void blinkLED() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);
  delay(1000);
}

void setup() {
  Serial.begin(9600);
  while(!Serial) {};
  Serial.println("Test RingSensor.");
  initLED();
  initRingSensor();
}

void loop() {
  scanRingSensor();
  printZone();
  printReadRing();
  blinkLED();
}

なお、今回は、Arduinoご本家のArduinoIDEを使わず、VScode上でソース編集し、VScodeのPlatformIOプラグインを使ってビルド、アップロード、シリアルモニタをやってます。たまたま別件でVScodeを開いていたため。なおPlatformIO使用なのでソース拡張子は .cpp となってます。VScodePIO

Ring Sensor駆動上の問題点ひとつ

このRing Sensorのメーカである米Interlink社の製品ページが以下に

Ring Sensor

Integration Guideがダウンロードでき、それを読めば駆動方法とかリージョンの識別方法が分かります。しかし、素のままやって一つ問題に気づきました。

1回の測定で3つのアナログデータ(Arduino Unoの場合ADCは10ビットなので0から1023という整数値が読み取れます。デフォルトでは電源電圧が1023、グランド電圧が0の筈、だいたいね。)しかし、まったくセンサに触れていなくても、時々下の方のビットは揺らぐのでありますな。偶然誤差?こんな感じ。sensorRaw

これを真っ正直に解釈してしまうと、リージョンを飛び回っているかのごとき結果が得られて落ち着きません。

ここはスレッショルド値を決め、それを上回る変動がなければ無視

することにいたしました。これにより識別結果は非常に安定し、アチコチ飛び回るようなことはなくなりました。けれども

今回設定したスレッショルド(TH)100はデカすぎ

な感じがいたします。位置だけでなく圧力にも対応したアナログ値が得られるので、TH=100とするとかなり鈍感です。そこそこ強く押さないと反応しません。

また今回は毎回の「押し」とその結果を確かめるために2秒に1回のレートでした測定していません。実際にはもっと早い速度で測定し続けないとUI的なレスポンスは得られないでしょう。ま、要調整ってことかね。

実験結果

以下 v1= などとある行は、1回の測定で3点得られるアナログ値の生データ(10ビット整数)です。その数値からリング型センサ上の「リージョン」を識別したものがその直上行にある数字です。こちらは1、2、3のリージョン番号です。押し方が弱かったりして閾値THに達しない場合は、前回のリージョンをそのまま維持します。こんな感じ。Result

まあ、リージョンの識別は出来た。次は、右回りに回している、左回り、何回転?といったところの認識ですかね。

IoT何をいまさら(104) ESP-EYE、ESP-IDFでSimple HTTPD へ戻る

IoT何をいまさら(106) SAR型ADCの原理回路をArduinoで制御してみる へ進む