Arduino Pro Micro + ADNS-5050によるトラックボールのコントロール

大分時間が空いてしまいまして、すみません。本業が忙しかったもので。
 
さて、今回は、Arduino Pro Micro  +  Arduino IDEを使用した場合のADNS-5050の使い方について簡単に触れてみたい。つまり、QMK Firmware でなく、Arduino のライブラリを使ってADNS-5050というマウスセンサをPro Microでコントロールして、USBマウスを作る方法だ。
 
Pro MicroとADNS-5050の物理的な接続はSPIという規格のインタフェースを用いて行う。(例えば、https://www.analog.com/jp/analog-dialogue/articles/introduction-to-spi-interface.html  )ちょっと難しそうだけれど、幸い、 https://github.com/okhiroyuki/ADNS5050 とのライブラリを見つけた。これを使わせていただくと、そんなに難しくはなかった。
また、Arduinoのライブラリには、USBマウスのためのMouse.hなどというものがあるので、単にUSBトラックボールを作るだけなら、比較的簡単にできることが分かった。また、多少苦労したものの、Fusion 360 + 3Dプリンタでボールカップを作成し、Mouse.hを使ってマウスカーソルを動かすことができた。

さて、具体的なやり方を見ていこう。
まず、ハードウェア。ビットトレードワンの通販ページからデータシート https://btoshop.jp/wp-content/uploads/sites/3/2019/04/ADNS-5050.pdf を入手する。Fig. 8 にサンプルの回路図があるので、それに従って、Pro Micro と ADNS-5050を接続する。基本的に、ADNS-5050にLEDとコンデンサを繋ぎ、Pro MicroとSCLK, SDIO, NCSを接続すればOK。回路としてはそんな難しくはない。(実装は面倒かとは思う。ADNS-5050はピン間が2mmなので、ユニバーサル基板にはうまく収まらない。私は、100円ショップで買ったマウスを分解してプリント基板を加工して流用した。)
ソフトウェアは、
 
1. https://github.com/okhiroyuki/ADNS5050 のCode -> Download ZIP から、ライブラリをダウンロード。
2. Arduino IDE のスケッチ->ライブラリをインクルード->.ZIP形式のライブラリをインストール、でライブラリをインストール。
3. サンプルプログラムは以下のとおり。10番ピンがローだとUSB HIDとして動き、ロー以外ならI2Cで動作する。I2CのピンアサインはSDIO: 4, SCLK: 5, NCS: 6とした。

/* ADNS-5050 Controller

 for USB HID and QMK Firmware (I2C)
 Default I2C Address: 0x10(7bit) 0x20(8bit, QMK Firmware)
*/

#include <Wire.h>
#include <Mouse.h>

// ADNS-5050 ライブラリのインクルードが必要です。
// https://github.com/okhiroyuki/ADNS5050
#include <adns5050.h>

#define USB_HID_MODE_PIN 10 // LOW: USB_HID is active. Not LOW: i2c is available.
#define I2C_SLAVE_2_ADDRESS 0x10 // (7 bit version of I2C addresses)
#define LED_PIN  13

// The register map of ADNS5050
#define MOTION          0x02  //R   0x00
#define DELTA_X         0x03  //R   any
#define DELTA_Y         0x04  //R   any

// Mouse sensor object
ADNS5050 mouse(4, 5, 6); // (SDIO, SCLK, NCS)

unsigned long last_time; 
char mouse_dx = 0;
char mouse_dy = 0;

// I2C応答イベント
void receiveEvent(int s) {
  char c;

  while (Wire.available()) 
  {
    c = Wire.read(); // 1バイト(文字)読み出し
    if (c == 'a') digitalWrite(13, HIGH); // LED on
    if (c == 'z') digitalWrite(13, LOW);  // LED off
#ifdef DEBUG
    Serial.println(c, HEX);
#endif
  }
}

// I2C要求イベント
void requestEvent() {
  if (digitalRead(USB_HID_MODE_PIN) == HIGH) { // HIGH: I2C is active. USB HID is inactive.
#ifndef DEBUG
    Wire.write(-mouse_dx);
    Wire.write(-mouse_dy);
    Wire.write(0); // ハードウェアスイッチ用のデータフィールド(予約。現在未使用。)
    Wire.write(0); // タッチスイッチ用のデータフィールド(予約。現在未使用。)
    #endif
#ifdef DEBUG
    Serial.print(mouse_dx);
    Serial.print(", ");
    Serial.print(mouse_dy);
    Serial.print("; ");
#endif
    mouse_dx = mouse_dy = 0;
  }
}

void setup() {
  // シリアル通信のセットアップ
  Serial.begin(9600);

  // I2Cのセットアップ
  Wire.begin(I2C_SLAVE_2_ADDRESS);
  Wire.onReceive(receiveEvent);
  Wire.onRequest(requestEvent);
  pinMode(USB_HID_MODE_PIN, INPUT_PULLUP);

  // マウスセンサのセットアップ
  mouse.begin();
  delay(100);
  mouse.sync();
  if (digitalRead(USB_HID_MODE_PIN) == LOW) {
    Mouse.begin();
  }
  last_time = millis();
}

void loop() {
  unsigned long curr_time = 0;
  unsigned long interval = 10;
  byte prev_button_state, prev_touch_button_state;

  curr_time = millis();

  // read the mouse sensor.
  if ((abs(curr_time - last_time) > interval) && (mouse.read(MOTION) != 0) ) {
    mouse_dx = mouse_dx + (char)mouse.read(DELTA_X);
    mouse_dy = mouse_dy + (char)mouse.read(DELTA_Y);
    last_time = curr_time;
  }

  if (digitalRead(USB_HID_MODE_PIN) == LOW) { // USB HID is active
    Mouse.move(mouse_dx, mouse_dy);
    mouse_dx = mouse_dy = 0;
  }
}

これで、マウスとしては動作すると思う。I2CについてはQMK Firmware側の対応もちょっと面倒なので、次回にでも。

小変更

(最近、本業が忙しくて更新が滞っています。すみません。)

本当は、ADNS-5050の使い方や、I2Cを使って、Nyquistにさらにもう一つProMicroを追加する方法を書きたいのだが、真面目に書こうとするとそれなりに準備が必要で、まだまだ書けていない状況。次の更新は12月後半になりそう。すみません。

 

 とか言い訳していてもつまらないので、ちょっとだけ見た目を変えたので紹介したい。

f:id:EdoBall:20201201231228j:plain

EdoBall KB-I(改)

Amazonをみていたら、導電性ゴムシートというものが有ったので購入し、以前の導電性テープと交換してみた。導電性テープに比べればギラつきが抑えられていて、多少は見た目もマシになったか?(私は機能を重視していて、見た目はあまり気にしていないのだが。)抵抗値は、導電性テープに比べればかなり高いが、それでもタッチセンサ用では問題になるレベルではない。

ついでに、今まで、不用意に押したくないキーは、3Dプリントした自作の背の低い小さなキーキャップを使っていたが、それを手持ちのDSAのものに変えてみた。どうも、キーの高さが違うとタイピングのリズムが狂うようで、ミスタイプが逆に増えてしまったためだ。私がOrthogonal配列に慣れたせいもあるかと思うが、交換前よりタイピングミスは減ったように思う。タイピングミスといえば、Orthogonal配列に慣れたとはいえ、5行のうち最上段(数字の行)は、通常のキーボードから1文字分ぐらい右にオフセットしているので、どうもタイプミスが多い。(2をタイプしようとして1をタイプしてしまうなど。)やはりこの辺は試してみないと分からないことも多い。

キーの機能別に、手持ちのキーキャップから色を変えてみたのだが、少々うるさい印象。どうしたものかと思案中である。

トラックボールのセンサ

トラックボール部は今回の製作の中でも、大きなチャレンジだった。キーボード部は、最初からNyquistを改造して使うことを決めていた。キットだから作例も多く、あまり問題になることはない。しかし、トラックボールの自作となると、ネットを見てもあまり作例は多くない。何より、わたし自身が以前、一度製作に挫折している。
最初は市販のトラックボールのボールカップとセンサをそのまま流用して試作してみたのだが、これでは、トラックボール部とキーボード部を連動して制御できない。一体化する意味が半減してしまう。となると、ボールカップ3Dプリンタで自作し、市販の光学マウスセンサをNyquistにつなげるか?そう思っていはいたものの、何しろ素人。マイコンを使ってセンサICを制御したことなどなく、自分にできるかどうかも分からない。
いろいろ思案していたところ、Bit Trade One でAvago / ADNS-5050という光学マウスセンサを販売しているのを目にした。
今や、マウスが数百円で買えることを考えると、センサだけで880円はあまり安くはないが、何しろデータシートはあるし、いろんな面で信頼できる。
しばらく悩んだが、やる気を出すために(埋没費用効果?)買ってしまうことにした。

ハードウェアのコンセプトについて

私の個人的な話になるのだが、今から20年以上前、Panasonic Let’s note AL-N2 というノートパソコンを愛用していた。
このパソコンは、キーボードの手前に光学式トラックボールを搭載していて、キーボードからあまり手を離すことなく、トラックボールの操作をすることができた。また、ボールの球径こそ、19mmと小さいものの、当時としては珍しい、ボールにドットパターンが見えない光学式トラックボールで、かつ、当時の他のPCのトラックパッドとは比較にならないほどの、リニアでスムーズなマウスカーソル操作が可能であった。
個人的にこの、キーボード手前のトラックボールというのが、とても気に入っていたので、いつか自分でもそんな入力デバイスが欲しいと思っていた。これが、目的の一つ。
 
もう一つ、過去に気に入っていたものがある。Microsoft Trackball Optical という、やはり20年ほど前のトラックボールである。
このトラックボール、親指操作型トラックボールとしては、ボール径や筐体がやや大きく、筐体にやや右下がりでゆったり右手を置くと、手指の負担が少なくトラックボール操作ができた。
 
この両者の特徴を、何とか一つのデバイスとしてまとめることはできないか?というのが、今回の入力デバイスの初期コンセプトだった。
 
 そしてその後、いろいろ試行錯誤を繰り返してできたのが現在の形ということになる。
キーボードの左右に傾斜をつけ、高くなった中央にトラックボールを設け、トラックボールのボタンはキーボードと兼用する。手首の負担を考えて、あえて、ホームポジションから指をずらして、パームレストに手を置いてトラックボールを操作する。トラックボールモードとキーボードモードを意識せずに切り替えるためにパームレスト部にタッチセンサを設ける。これらは、試作や思考実験を繰り返しながら詰めていった仕様だ。

f:id:EdoBall:20201103124525j:plain

ボロボロで汚れたLet's note AL-N2。今も捨てられずにいる。

はじめまして

はじめまして

ちょっとした入力デバイス、キーボード付きトラックボールを自作したので紹介したいと思う。
 
実は、10年以上前、私はトラックボールを作ろうとして挫折したことがある。私は、電子工作もプログラミングも素人で、当時は私のスキルでは実用的なものは作れなかった。しかし、時は流れ、Makerムーブメントの拡大、キーボード自作ブーム、3Dプリンタの普及……。素人がモノを作るにあたり、いろいろな面でハードルは下がってきた。おかけで、時間はかかったものの、今回は挫折せずにキーボード付きトラックボールを完成することができた。
 

EdoBall KB-I

EdoBall KB-I
見ての通り、トラックボールとキーボードが一体化したデバイスである。
これからしばらく、これがどんなデバイスか、これをどうやって作ったかを紹介していきたいと思う。
若い方の作品に比べれば、どうにも拙いモノではあるが、お付き合いいただきたい。
 
まずは、今回作成したデバイスの概要を説明しよう。
 

EdoBall KB-I の特徴

  • 親指操作型34mmトラックボールと5x14直交型(orthogonal)左右分離型キーボードを統合したもの。
  • 基本キー配列はUS。日本語キーボードとして認識された場合も、US配列となるモード有り。
  • トラックボールのキーは、キーボードのキーと共用。パームレスト部のタッチスイッチで、トラックボールモードとキーボードモードを切り替え。
  • トラックボールによるスクロール機能。
  • Emacsライクなカーソル移動キー配列をサポート。
 

その他の仕様

 

ハードウェアの概要

  • ベースとなるキーボードはKeebioのNyquistのキット。これに、左右一列ずつ加え、通常のUS配列があまり無理なく収まるようにした。(他の(特にノートPCの)キーボードと併用しても、違和感を少なくするため。)右側のキーボードには球径34mmのトラックボールを統合した。筐体は3Dプリンタで作成した。
  • キーボード部のファームウェアはQMK FirmwareNyquistのものを多少修正して使用。別に、トラックボールセンサとタッチスイッチのために、Arduino Pro Micro互換機を使用(こちらは、QMKではなく、通常のArduinoライブラリを使用)。キーボード部のPro MicroとはI2Cで接続した。
ファームウェアの詳細等については、今後書いていきたいと思う。