2020年8月16日日曜日

DigisparkでキーボードのLEDの状態を取得してみる

 久しぶりにDigisparkを引っ張り出してきたのでUSBキーボードエミュレーションして遊んでいたらキーボードのLED状態を取得できるような機能をライブラリに追加していた人がいたので試してみた。

キーボードのLEDステータスというのはCapsLockとNumLockとScroll LockのLEDの状態のこと。DigikeyboardだとそもそもPCからの情報取得は行わないようになっていたのでAdafruitのTrinket USBを使う方法しかなかった。

これが使えると何が便利なのかというとパソコンからDigisparkへのInputとして使えたり。
例えば、ScrollLockキーを押すとScrollLockのLEDが点灯するのでそれをDigikeyboardから読み込んでなにか動作をさせることが可能…
という具合。

まぁ普通にNumLock LED付きNumLock専用ボタンとかも作れちゃうわけだけど…

Digikeyboard with LEDs 作者のページには動画も上がっているので参考に。

というわけで早速試してみた。まずはGithubの作者のページから
DigiKeyboard.h
usbconfig.h
hidkeys.h
この3つのファイルをダウンロードしてくる。

そしたらエクスプローラで
%appdata%\..\Local\Arduino15\packages\digistump\hardware\avr\1.6.7\libraries\DigisparkKeyboard\
を開いて上書き。
これで準備は完了。

ちなみにこれをやるとDigiKeyboard.getLEDs()を使っていなかったとしてもフラッシュメモリの使用量が200バイトぐらい増えるので注意。

Digisparkの起動直後はうまく判別できなかったのでsetupにDigiKeyboard.delay(300)をいれて対策した。どうしてもLEDがついてないのに電源入った直後は起動していることになっている?これでもたま不安定…

とりあえず実用例がだいぶ前に作ったミツトヨのデジマチック出力をUSBキーボードとして入力してくれるデバイスぐらいしか思いつかなかったのでこいつを改造してみた。
スクロールロックキーを押すとミツトヨのノギスとかの測定データをUSBキーボードとして入力してくれる。これ、自分が持ってる海外製ノギスにもそのうち対応したい…

デジマチック出力の詳細は前回の記事を参考にしてもらうとして、これにSCROLL LOCKのLED状態を判別する部分を追加しただけ。フットスイッチでSCROLL LOCKを設定すればフットスイッチでも値を入力できる!かも?
追加したのはSCROLL LOCKのLEDがついたのを確認したら測定ボタンを押されたときの動作をした後、もう一回SCROLL LOCKをキーストロークしてSCROLL LOCKのLEDを解除するというだけ。(SCROLL LOCKを自動で解除しないと無限ループになってしまうし…)
まぁこういった使い方もできるということで…
// Use modified version of DigiKeyboard library
// https://github.com/Danjovic/DigistumpArduino/tree/master/digistump-avr/libraries/DigisparkKeyboard
#include "DigiKeyboard.h"

#define REQ 1
#define DAT 0
#define CLK 2
#define BTN 5//reset pin

void setup() {
  pinMode(REQ, OUTPUT);
  pinMode(DAT, INPUT_PULLUP);
  pinMode(CLK, INPUT_PULLUP);
  pinMode(BTN, INPUT_PULLUP);
  digitalWrite(REQ,LOW);
  DigiKeyboard.delay(300);
  if (DigiKeyboard.getLEDs() & SCROLL_LOCK){
    DigiKeyboard.sendKeyStroke(0);
    DigiKeyboard.sendKeyStroke(KEY_SCR_LOCK);
  }
 }

void loop() {
  DigiKeyboard.update();
  static boolean scrStatus = false;
  if (DigiKeyboard.getLEDs() & SCROLL_LOCK){
    scrStatus = true;
  }
  if(digitalRead(BTN) == LOW || scrStatus == true){
    byte mydata[14];
    digitalWrite(REQ, HIGH);
    for(uint8_t i = 0; i < 13; i++ ) {
      uint8_t k = 0;
      for (uint8_t j = 0; j < 4; j++) {
        while( digitalRead(CLK) == LOW) {
          DigiKeyboard.update();
        }
        while( digitalRead(CLK) == HIGH) {
          DigiKeyboard.update();
        }
        bitWrite(k, j, (digitalRead(DAT) & 0x1));
      }
      mydata[i] = k;
    }
    digitalWrite(REQ,LOW);
  
    uint8_t sign = mydata[4];
    uint8_t decimal = mydata[11];
    //uint8_t units = mydata[12];

    char buf[7];
    for(int lp = 0; lp < 6; lp++){
      buf[lp] = mydata[lp+5] + '0';
    }
    buf[6] = 0;
    float num = (atol(buf));
    switch (decimal){
      case 2:
        num = num / 100;
        break;
      case 3:
        num = num / 1000;
        break;
      case 4:
        num = num / 10000;
        break;
      case 5:
        num = num / 100000;
        break;
    }
    if(mydata[1] == 0xF && mydata[2] == 0xF && mydata[3] == 0xF){
      DigiKeyboard.sendKeyStroke(0);
      if(sign == 8){
        DigiKeyboard.print("-");
      }
      DigiKeyboard.print(num, decimal);
      DigiKeyboard.sendKeyStroke(KEY_ENTER);
      DigiKeyboard.delay(60);
      while(digitalRead(BTN) == LOW){
        DigiKeyboard.update();
      }
    }
    if(scrStatus == true){
      scrStatus = false;
      DigiKeyboard.sendKeyStroke(0);
      DigiKeyboard.sendKeyStroke(KEY_SCR_LOCK);
      DigiKeyboard.delay(300);
    }
  }
}

2020年8月15日土曜日

Digisparkを久しぶりにいじってみた。

 確かAliexpressだったと思うんだけど安かったときにAttiny85を取るために買った抜け殻が見つかったので復活させてみた。そんでもって自分用のメモ。

DigisparkはDigistampから出ていたAttiny85搭載のUSB直結できるタイプのマイコンボードで、Arduinoで手軽に開発できるし、HIDデバイスにもなれるし、お安いので数年前にちょっと流行っていたような気が。

自分もクローンを購入してUSBボリュームノブとか作っていた気がする…

とりあえず使用済みAttiny85もあったのでとりあえずこれで復活させてみようかなと。

まずはBootloaderの書き込み。
DigisparkのBootloaderはmicronucleusなのでgithubよりhexをダウンロードしてくる。
今回はattiny85なのでt85_default.hexを使用した。

書き込み機はHIDaspxを使用した。
DigisparkでP5(リセットPin)もIOとして使いたい場合はヒューズビットを0xE1(low)0x5D(high)とする。まぁ本家もリセットPinが使える設定なので今回も本家と同じようにしておいた。
リセットPinをIOとして使えるようにすると高電圧プログラマーじゃないと書き込めなくなるので、Bootloaderをアップデートしたりするときはヒューズリセッターを使うと良いかも。
なので書き込む順番も注意である。まずはHexを書き込んでからヒューズビット書き込まないとつみます。

うまく書き込めたら実装するだけ。

これで復活である。ブートローダーもv2.04なので本家より容量使える?
そんでもってリセットピンも使えるのでUSB接続使ったとしても4つのPinをIOとして使える。(クローンだとよくリセットPinがIOとして使えなかったり)

Arduino IDE側は環境設定の追加のボードマネージャのURLに以下を追加。
http://digistump.com/package_digistump_index.json

そしてボードマネージャからDigisparkを追加するだけ。
USBドライバは
%USERPROFILE%\AppData\Local\Arduino15\packages\digistump\tools\micronucleus
の中に入っているのでinstall.exeからインストールしておく。

Digisparkはシリアルポートとして認識させるのは不安定なので、シリアルモニタの代わりに、libusbを使用したDigiUSBを使うことが推奨されている。
なのでデバッグとかで通信したい場合はDigisparkExampleProgramsに含まれるmonitor.exeを使用すると良い。

2020年8月3日月曜日

安価な完全ワイヤレスイヤホンHaylou GT1 Plus

友人が安い完全ワイヤレスイヤホンがほしいと言っていたので探していたらHaylou GT1 Plusというのが良さそうだったので代わりにAliexpressから購入してみた。

HaylouのGT1とGT1 Proはアマゾンでも売っているんだけどGT1 Plusが売っていないので…
外見はどれも見分けがつかないぐらいなんだけど、GT1 Plusは搭載ICがQualcomm QCC3020なのでApt-Xが使えるのと、低消費電力なので駆動時間が長い。
PCで使うらしいのでApt-X対応のほうが低遅延だし。AACにも対応しているのでiPhoneなどでも問題なし。
それでいて2200円という超破格…

商品紹介ページにノイズキャンセリングって書いてあったけど、どうやらアクティブノイズキャンセリング(周囲の雑音を聞こえなくするやつ)ではなくて、CVCノイズキャンセリングといって通話時にマイクから入る雑音を除去して通話相手が聞きやすくするためのノイズキャンセリングらしい。

ケースをフル充電でイヤホン本体が3回ぐらいフル充電できるらしい。一回の充電で4,5時間使えるっぽい。充電時間はケースが2時間、イヤホン本体が1.5時間らしい。

付属品はサイズ違いのイヤーピースとUSBケーブルのみ。
ケース充電には5V 500mA以上の充電器があるといいかも。

イヤホン本体はケースに入れると自動で電源オフ&充電開始で、ケースから外すと電源が入る感じ。
イヤホン本体にはタッチボタンがついていて、シングルタップで再生/一時停止、ダブルタップで通話を受ける/切る、1秒長押しで電話無視、トリプルタップでSiriなどの音声アシスタンスを起動できる。
音楽再生中は左をダブルタップで曲戻し、右ダブルタップで曲送りになるらしい。
長押しで電源をオフにすることも可能。

ちなみに片耳ずつのヘッドセットとしても使用可能らしい。
片耳だけ使うときは充電ケースから同時に取り出して、使わない方を戻してからペアリングすればいいらしい。
まぁこの機能のせいでペアリングおかしくなったりする場合があるらしいけど…

ペアリングおかしくなったとき(モノラルでしか使えなくなったとき)の対処法
ペアリングしてるデバイスから設定を削除。
充電ケースから同時にイヤホンを取り出す。(電源が入る)
左右どちらもボタンを5秒間ぐらいタッチして電源を切る。
左右どちらもボタンを15秒ぐらいタッチしてペアリングモードに入れる(押してる間は白点滅→赤白一瞬点滅で完了)
左右どちらもボタンを押して同時に電源を入れる。
これで左右でペアリングされて、スマホなどのデバイスからはRをペアリングできるような状態になっているはず。RをペアリングするとRはLとつながっているのでステレオモードとして使える。

HaylouのGT1シリーズの外見は全部そっくりなんだけど、Apt-X使いたい場合はGT1 Plusだけっぽいので注意かな。
音質はドンシャリ気味だけど無音時にホワイトノイズとか聞こえないらしいので自分も購入しようかな…値段を考えると良さそう。

2020年8月2日日曜日

USB2CANをPCAN-USB化してみた

USB2CANモジュールをPCAN-USB化して、Windows上のPythonで使えるようにしてみた。
USB2CANをWindowsで使う場合はmicrobusが使えるので特に機能的には問題がなかったんだけど、Pythonでpython-canモジュールを使ってCAN-BUSを使おうとするとUSB2CANのgsusbだとうまく動かなかったので…(No backend availableとか出てfilterとかインストールしてみたけどデバイスが切断されたりして使えなかった…)

USB2CANに現在入ってるファームウェアはSWDとかで吸い出せそうになかったので、だめだったらもとに戻せるようにマイコンをSTM32F042C6Tに交換してみた。ついでに16Mhzのクリスタルと負荷コンデンサとして4.7pFも実装した。(C3、C5)あとI2C接続のEEPROMは外した。外部クロックに変更したのは今回使用させてもらったPCAN-USB化ファームウェアはCANtact用だったため、仕様をCANtactに合わせた感じ。(I2Cのプルアップ抵抗も外してよかったかも)

もともとSTM32F072が乗っていたんだけど、PCAN-USB化ファームウェアは16kbあれば行けるっぽいのでSTM32F042でも十分。もともと外部クロックついてないので内蔵クロック使うように変更してファームウェアをビルドすれば外部クロックつけなくても行けるかも。

ちなみにファームウェアの書き込みは書き込み機が必要だと思っていたんだけど、実はこのマイコンはUSB書き込みのBootloarderがもともと入っているっぽいのでそのままUSB接続してdfu-utilで書き込めるらしい。なのでBootモードに入れればUSB経由でファームウェア書き換え放題っぽい。
なお、純正状態だとDFUモードが封じられているっぽいのでDFUモードでファームを書き換えるなら今回みたいにマイコンを新品に交換しないとだめかも。マイコン交換しないならJ-linkとかST-Linkで書き換えられるのかな?(未検証)

PCAN-USB化ファームウェアはgithubにpcan_cantactとして公開されていたファームウェアをビルドして使用させてもらった。ハードウェアをCANtact仕様に改造したのでほぼそのまま使わせてもらった感じ。
Windows環境でビルドするために、MinGW、Cygwin64、GNU Arm Embedded Toolchainを使用した。MinGWはmakeに、Cygwin64はtrに必要だった。
16MHzの外部クロックを追加してUSB2CANをCANtact化したのはいいんだけど、LEDが繋がってるピンが違うので、TXをPB2に、RXをPB10に変更して、LEDが正常に動くように修正してビルドした。USB2CANはLEDが3つついているけどこのfirmwareだと2つしか使えなさそう。全部赤色だったのでTX LEDだけ青に変えておこうかな…

ファームウェアの書き込みはboot用のピンヘッダをピンセットでショートした状態でPCに接続するとDFUモードで起動する。一旦DFUモードでPCに認識されたらピンセットは外してもOK。

DFUモードでUSBに接続するとSTM32 BOOTLOADERとして認識されるけど、ドライバがないのでZadigを使用してlibusbKドライバをインストールする。

ドライバをインストールしたらdfu-utilを使用して書き込みできるようになる。
dfu-utilと先ほどビルドしたファームウェアのbinファイルを同じフォルダに入れてコマンドプロンプトでそのディレクトリまで移動したら
dfu-util -a0 -d 0x0483:0xdf11 -s 0x08000000 -D pcan_cantact_hw.bin
で書き込むことができる。

あとはBoot用のピンヘッダをショートしない状態でUSBケーブルを抜き差ししたらPCAN-USBとして認識されるのでPCAN-USBのドライバをインストールしてPCAN-Viewとかから使えるようになる。
Pythonからpython-canモジュールを使用してアクセスする場合はPCAN-BasicのDLLをpython.exeと同じディレクトリに突っ込むか、環境変数でパスを通しておく必要があるっぽい。ドライバインストーラでPCAN-Basicをインストールしてる場合はそのまま使えそう。

PCAN-USB化してWindowsで使う場合はドライバのインストールが必要になった(USB2CAN純正ファームではドライバインストール不要だった)けどPythonから使う分にはPCAN-BasicのDLL経由で扱えるようになったので結構便利になった。microbusとPCAN-Viewの機能はあまり変わらないような気がしているのでWindows上のPythonでUSB2CANを扱いたい人にはPCAN-USB化はおすすめだけど、microbusで事足りてるならわざわざ書き換える必要はないかもしれない。車載とかいじるならPCAN-OBD-2 Viewerを使えたりするのは便利かも。Windows対応のCANユーティリティーだとPCAN-USB指定だったりすることもあるし。PCAN-USB自体も中古も含めて入手性あんまり良くなさそう…

ちなみにこのファームウェアはcandleLight gsusb系の同じシリーズのマイコンが乗ってるボードなら色んなボードで使えそう。
ということはbootジャンパでDFUモードで起動してgsusbファームウェアを書き込めばもとに戻せるのかもしれない?ラズパイとかのLinux系で使う場合はSocketCANが便利。ラズパイにもともとpeak_usbが入っていたのでgsusb同様ipコマンドだけで使うことができるようになった。