MFT2018で、一番にご来場いただいたお客様が、昨年からの信州MAKERSをご贔屓にしていただいているマルチサイクリスト様でした。その方から、マウスポインタとして6軸力覚センサ利用できないかとアイデアをいただきました。また、別のお客様から口にマウスピースのようくわえて、あごの噛む力をセンシングしてマウスポインタにならないかというアイデアをいただきました。
御両者様には、アイデアを検討するとお約束しましたので
さっそく、様子見の試作をしました。
大手電機メーカーS社のソフトウェア技術者のK様からArduino LeonardoのHID機能を使うと簡単にマウスが作れるとのアドバイスをいただいてその通り、3日で力覚マウスが試作できました。
●2軸力覚マウス仕様
マウスはXY座標で動くので、2軸でいいだろうと考えました、
更に、BlueToothマウスを直付けして、クリックはBlueTooth経由にしてArduinoからはXY座標をPCへ出力する仕様にしました。
マウス底面にホームセンターで売っていた板付きナットM6を
エポキシ接着剤で接着しました。
5分乾燥で、クロスビームにマウスを載せてダブルナットで締め付けます。
結構しっかり接合できましたので、力は十分伝わります。
●力覚マウスプログラム
HX711の出力をMouse.Move(X,Y,0)するだけで相対移動してくれます。しかし、XYに与える値のゲインなどの調整が難しいです。
手とマウス形状によってモーメントの加え方が違うのでリニアにMxMyがでてこないです。センサはリニアでも人間の手の曲げ方はリニアにならないので、これを調整するのは大変だと思いました。
————–HiLetgo Leonardo Pro Microで動作したPGM
#include <Mouse.h>
#include “HX711.h”
;
int Fx;
int Fy;
int Fx_1;
int Fy_1;
HX711 scale;
HX711 scale2;
//Variables
double gainx=0.6;
double gainy=0.3;
int Fxr;
int Fyr;
void setup() {
Serial.begin(38400);
// initialize mouse control:
Mouse.begin();
//HX711 initialize Sub
Hx711_setup();
}
void loop() {
Fx_1=Fx;
Fy_1=Fy;
Fx=int(scale.get_units());
Fy=int(scale2.get_units());
Fxr=abs(Fx)-abs(Fx_1);
Fyr=abs(Fy)-abs(Fy_1);
Serial.print(Fx);
Serial.print(“,”);
Serial.print(Fy);
Serial.print(“,”);
Serial.print(Fxr);
Serial.print(“,”);
Serial.println(Fyr);
if (abs(Fx)>3 || abs(Fy)>3) {
Mouse.move(Fx*gainx, Fy*gainy, 0);
}
}
void Hx711_setup(){
Serial.println(“Initializing the scale”);
// parameter “gain” is ommited; the default value 128 is used by the library
// HX711.DOUT – pin #A1
// HX711.PD_SCK – pin #A0
scale.begin(A1, A0);
scale2.begin(A3,A2);
Serial.println(“Before setting up the scale:”);
Serial.print(“read: \t\t”);
Serial.println(scale.read()); // print a raw reading from the ADC
Serial.println(scale2.read()); // print a raw reading from the ADC
Serial.print(“read average: \t\t”);
Serial.println(scale.read_average(20)); // print the average of 20 readings from the ADC
Serial.print(“read average2: \t\t”);
Serial.println(scale2.read_average(20)); // print the average of 20 readings from the ADC
Serial.print(“get value: \t\t”);
Serial.println(scale.get_value(5)); // print the average of 5 readings from the ADC minus the tare weight (not set yet)
Serial.print(“get value: \t\t”);
Serial.println(scale2.get_value(5)); // print the average of 5 readings from the ADC minus the tare weight (not set yet)
Serial.print(“get units: \t\t”);
Serial.println(scale.get_units(5), 1); // print the average of 5 readings from the ADC minus tare weight (not set) divided
Serial.print(“get units2: \t\t”);
Serial.println(scale2.get_units(5), 1); // print the average of 5 readings from the ADC minus tare weight (not set) divided
// by the SCALE parameter (not set yet)
scale.set_scale(2280.f); // this value is obtained by calibrating the scale with known weights; see the README for details
scale.tare(); // reset the scale to 0
scale2.set_scale(2280.f); // this value is obtained by calibrating the scale with known weights; see the README for details
scale2.tare(); // reset the scale to 0
Serial.println(“After setting up the scale:”);
Serial.print(“read: \t\t”);
Serial.println(scale.read()); // print a raw reading from the ADC
Serial.print(“read2: \t\t”);
Serial.println(scale2.read()); // print a raw reading from the ADC
Serial.print(“read average: \t\t”);
Serial.println(scale.read_average(20)); // print the average of 20 readings from the ADC
Serial.print(“read average2: \t\t”);
Serial.println(scale2.read_average(20)); // print the average of 20 readings from the ADC
Serial.print(“get value: \t\t”);
Serial.println(scale.get_value(5)); // print the average of 5 readings from the ADC minus the tare weight, set with tare()
Serial.print(“get value2: \t\t”);
Serial.println(scale2.get_value(5)); // print the average of 5 readings from the ADC minus the tare weight, set with tare()
Serial.print(“get units: \t\t”);
Serial.println(scale.get_units(5), 1); // print the average of 5 readings from the ADC minus tare weight, divided
// by the SCALE parameter set with set_scale
Serial.print(“get units2: \t\t”);
Serial.println(scale2.get_units(5), 1); // print the average of 5 readings from the ADC minus tare weight, divided
// by the SCALE parameter set with set_scale
Serial.println(“Readings:”);
}
————————————————————————–
●適当に調整して動画を撮りました。
●課題抽出
①左右のMxは、手からモーメントを入力しにくい
=>手の自然な動きにない動作を強いるみたいで非常にやりにくいです、MzもしくはFx分力センサに交換したほうがよさそうです。
②上記原因もあるかもしれませんがまだまだ、光学マウスのようななめらかな動きと調整ができません
=>ソフトウェアで力覚入力の処理を考えないといけない感じです。
③マウスそっくりの用途より、力覚センサが生かせる用途のほうがいいのではないか
メリット1:動きなしでMOVEができる
=>ジョイスティックでも代替えできる用途はだめ
メリット2:多分力にして、ボタンダイアルではできないたくさんの機能を入力できる
デメリット1:コスト高い
デメリット2:サイズ大きい
デメリット3:操作性がなれが必要
●以後
お盆以降パワーメーターの開発を進めていくので、ここまでで3カ月くらいお蔵入りとなります。もし、いじってみて、いけそうか見てみたい方は、お貸しします。
ich48397@wd5.so-net.ne.jpまでご連絡ください。
ハードセットを貸与いたします。
先着順ですので、申し込み順に期間を決めてお貸しします。