勝手な電子工作・・

勝手なオリジナル電子工作に関する記事を書きます

Zoom会議用かんたん操作ボタンをArduinoで作る(まとめ)

Zoom会議の操作を楽ちんにするボタンを、今回はBeetleで作りました。前回の記事(Zoom会議用・・・その3)の最後に少し書いておきましたが、BeetleとはArduino Leonardo互換(というよりサブセット)の小さな基板です。今回作ったのは写真の右側のもので、これで3個目(しつこいですね^^;)。

f:id:a-tomi:20200517144240j:plain

前の記事に付け足そうかとも思いましたが、この「勝手な電子工作」の記事がちょうど50作目になるようなので、別建てにして書くことにしました。

BeetleはPCのUSB端子に直接差し込める小さな基板で、下の写真のようなATmega32U4のブレークアウトボードです。Arduino-IDEではLeonardoとしてプログラミングをすることができます。

f:id:a-tomi:20200517145615j:plain

今eBayをちらりとみると、数年前より少し値上がりしたようですが、1個500円程度です。日本のアマゾンでみると6倍ほどの価格のものが見られます、たまたまかもしれませんが。

f:id:a-tomi:20200517150015j:plain

最近は新型コロナの影響による輸送の混乱のためか、若干の送料がかかる品が増えました。しかし複数買えば価格も安い(たとえば2PCSとつけて検索すれば出る)ので、後のために少し補給をしておきたくなり、つい注文してしまいました。

このUSB基板をどんなケースに収めるかですが、FRISKのケースは大きすぎて、USB端子に刺してつかうには幅・厚さともいまひとつです。オリジナルの簡単な方法は、配線してホットメルトをつけ、透明ビニールシートを巻きつけるというやり方です。勝手な知恵ですが、こうすると最終的にしっかりと丈夫にできます。あたりまえですが余計なケースは要りません。こういうのにぴったり。

巻くだけといっても、必要な時にマイコンボードがそのまま取り出せるように作ります。なので直接巻くのではなく、小さなストライプ基板をかませてその基盤側にだけホットメルトをつけます。

汚い手書きですみませんが次の案のように。こうするとケーブル接続も丈夫にできます。

f:id:a-tomi:20200517151139j:plain

Beetleのピンは、連続するD11、D10、D9、A0(D18)を使うことにします。そして右にあるグランドピンからひっぱってきて、隣のストライプをグラウンドにします。

まず、ストライプ基板をカットしておきます。

f:id:a-tomi:20200517152506j:plain

そして背中合わせの形にして、スズメッキ線で取り付けます。

f:id:a-tomi:20200517152646j:plain

こうしておけば、万一あとでBeetleを取り外す場合でも、5か所のはんだを吸い取るだけでOKなので。

そしてホットメルト(ホットボンドともいいますかね)をつけるのですが、ケーブル固定用に次の熱軟化樹脂を粘土として併用すると、私のような不器用者でもうまくできます。これは120℃ぐらいにセットしたヒートガンを使うと早く加工できます。

f:id:a-tomi:20200517152956j:plain

配線は、シールド被覆のあるUSBケーブルなら、中に4線+グラウンド線がしっかり収まっていますので適当ですしノイズを拾いません。はんだ付けしたら、ストライプ基板の銅箔面側だけにホットメルトを少し塗り、それを起点に透明ビニールシートを2回ほど巻きつけ、最後はホットメルトで同じ面へ止めます。そして冷めたら不要箇所をニッパーで切りとれば出来上がりです。ほら、こんな感じ。

f:id:a-tomi:20200517153220j:plain

横から見るとこんなかっこう。

f:id:a-tomi:20200517153812j:plain

貼り付け面側のみかけは少しきたないですが次。

f:id:a-tomi:20200517153856j:plain

ケーブル取り付け部も頑丈にできあがります。そしてケーブルの片側をスイッチに配線します。

作ったArduinoスケッチは次です。

/* **************************************************
       "Zoom" short-cut buttons with Beetle
          V00: Initial version           May 10, 2020
       Funcion: Provides four short-cut-buttons
          Button 1 for Mute all members (on/off)
          Button 2 for View gallery (on/off=speaker) 
          Button 3 for Tool-bar (on/off)
          Button 4 for Full-screen (on/off)
       Remarks: Apply Leonardo to build w/Arduino IDE
      (c) Akira Tominaga, All rights reserved.
 ****************************************************
*/
#include "Keyboard.h"   // for Leonardo(ATmega32U4) only
#define B1 11           // Button 1 for Mute-all
#define B2 10           // Button 2 for View-gallery
#define B3 9            // Button 3 for Toolbar
#define B4 18  //=A0    // Button 4 for Full-screen 
// Chattering time depends on the Buttons used
#define Cht 30          // chattering time
#define lCht 200        // longer chtrg to ignore
#define typOn 10        // type-on time (mS)
byte  Fk=KEY_F1;        // save area for cur Func key 

void setup() { // Setup **************************
  Keyboard.begin();
  // define Buttons and pull them up
  pinMode(B1, INPUT_PULLUP);
  pinMode(B2, INPUT_PULLUP);
  pinMode(B3, INPUT_PULLUP);
  pinMode(B4, INPUT_PULLUP);
}

void loop() {  // Arduino loop ******************
  if (digitalRead(B1) == LOW) { // B1: Mute all members
    delay(Cht);        // avoid chattering
    while (digitalRead(B1) == LOW) {} // wait for btn-off
    Keyboard.press(KEY_LEFT_ALT); // push Alter key
    Keyboard.print("m"); // and type m
    delay(typOn);
    Keyboard.releaseAll(); 
    delay(lCht);       // avoid longer chattering
  }

  if (digitalRead(B2) == LOW) { // B2:View gallery or Spkr
    delay(Cht);        // avoid chattering
    while (digitalRead(B2) == LOW) {} // wait button-off
    if (Fk == KEY_F2) { // checck cur func key
      Fk=KEY_F1;       // set F1 if currently F2 used
     } else {
      Fk=KEY_F2;       // set F2 if currently F1 used
     }
    Keyboard.press(KEY_LEFT_ALT); // push Alter key
    Keyboard.press(Fk); // and push Function key 1 or 2
    delay(typOn); 
    Keyboard.releaseAll(); // release all keys
    delay(lCht);       // avoid longer chattering
  }

  if (digitalRead(B3) == LOW) { // B3: Toolbar
    delay(Cht);        // avoid chattering
    while (digitalRead(B3) == LOW) {} // wait button-off
    Keyboard.press(KEY_LEFT_ALT); // push Alter key
    delay(10);
    Keyboard.releaseAll(); // release all keys
    delay(lCht);       // avoid longer chattering
  }

  if (digitalRead(B4) == LOW) { // B4: Full screen
    delay(Cht);        // avoid chattering
    while (digitalRead(B4) == LOW) {} // wait button-off
    Keyboard.press(KEY_LEFT_ALT); // push Alter key
    Keyboard.print("f");  // and type f
    delay(typOn);
    Keyboard.releaseAll(); // release all keys
    delay(lCht);       // avoid longer chattering
  }
}
// End of program *******************************

 これをArduino-IDEで本体に直接書き込めば全てできあがります。何も問題なく動作をしています。しめしめ、持ち運びも簡単。

f:id:a-tomi:20200517154632j:plain

もしもち運び用としてまた作るときは、スイッチをもっと軽くしたい(しつこい?)。

 

今回はチャタリングが相当長くても大丈夫なコーディングにしたのですが、それには次のわけがあります。以下余計な話ではありますが、たまには失敗するのです^^;

スイッチを思い切り軽くしようと思い、実はまず次のキーパッドでトライしました。

f:id:a-tomi:20200517154608j:plain

このキーパッドは裏の剥離紙をはがすと、貼り付け面がこうなっています。

f:id:a-tomi:20200517155100j:plain

このパッドのリードフィルムは長すぎて邪魔です。120度ていど折りまげても接続には問題ないことを確認し、もう少しだけ折って蛇腹の形にたたみこんで、小ボックスにとりつけてみました。

f:id:a-tomi:20200517155347j:plain

なかなか小さくて薄くスマートです。箱は秋月で扱っている小さなものです。裏から見ると次。

f:id:a-tomi:20200517155413j:plain

これを試してみたところ、スイッチのノイズが大。そこでチャタリング許容時間を伸ばしたら一見問題なさそうでした。

ところがです。1つのキーが効かないのです。調べたら、なんとリードフィルム内で断線してます。いくら現代のキーパッドでも、こんな折りたたみ方をしたらやっぱりだめですねえ。実は折りたたむのも、ヒートガンを少し使ったりして結構大変でした。それではあたりまえでしょうね。

というわけで、長いチャタリングに耐えるプログラムテストの役割は果たしたのでした^^;

 

話を戻して、肝心のZoom会議はというと、会議中に複数のキーからなるショートカットが使える人はよほど器用な方だと思います。たった4キーであっても、よく使うオンオフ操作ボタンがあると、操作全体がとても楽です。とくにホストの場合はめっちゃ楽。

 

さて、このシリーズ記事*の最初に挑戦したUNOは、そのうちにFlipで元のUNOに戻すことにするかもしれません。後で作った2つの装置を暫らく使い続けるわけなので。

ということで、今回のシリーズのまとめはこのへんで終わりたいと思います。

最後までご覧頂き有難うございました。

 

*このシリーズ記事のバックナンバーは次です(インデックスが整ってなくてすみません)。 

Zoom用かんたん操作ボタンをArduino-UNOで作る(その1) - 勝手な電子工作・

Zoom用かんたん操作ボタンをArduino-UNOで作る(その2)やったね! - 勝手な電子工作・・

Zoom会議用かんたん操作ボタンをArduinoで作る(≒その3) - 勝手な電子工作・・

 

© 2020 Akira Tominaga, All rights reserved.

 

 

Zoom会議用かんたん操作ボタンをArduinoで作る(≒その3)

注文したArduino Pro Microが届きましたので、今度はそれで製作。この「かんたん操作ボタン」を使うと、家族のリモート団らんでの画面操作も楽ちんになります、あたりまえか^^;

f:id:a-tomi:20200510101000j:plain

到着したPro Microはコンパチ機。海外なら4ドル前後ですが日本では千円近くというところでしょうか。小サイズで組込みにも適していますね。これなら今後も少しは使う可能性が高いので今回6つを調達しました。

f:id:a-tomi:20200510101606j:plain

ごていねいに箱(コンパチ箱!?)もついてますよ。

f:id:a-tomi:20200510101726j:plain

下の方に書くプログラムで、まずブレッドボードによるテスト。ヘダーピンなど取りつけずにICクリップワイヤーで接続します。ヘダーピンをつけるとあとで組込む際には邪魔になるわけなので。

テスト接続のためのスルーホール用ワイヤーもありますが、基板の縁に近い穴の場合は、むしろICクリップのほうがしっかり接続できます。次のように。

f:id:a-tomi:20200510102119j:plain

接続先は前回のブレッドボードです。

f:id:a-tomi:20200510102101j:plain

Arduino Leonardo系ですから、Keyboard Libraryを使うと簡単です。ArduinoのモデルとしてはArduino Microを指定し、次のようにプログラムを作りました。(プログラムを更新しておきましたー2020年5月12日 もちろん前のままでも大丈夫です。)

/* ***************************************************
       "Zoom" short-cut buttons with Arduino-Micro
          V00: Initial version             May 9, 2020
          V01,02: Ignore long chattering  May 10, 2020
       Funcion: Provide four short-cut-buttons
        Button 1 for Mute all memabers (on/off)
        Button 2 for View gallery (on/off=speaker)
        Button 3 for Tool-bar (on/off)
        Button 4 for Full-screen (on/off)
      (c) Akira Tominaga, All rights reserved.
 *****************************************************
*/
#include "Keyboard.h"  // for ATmega32U4 only
#define B1 7           // Button 1 for Mute-all
#define B2 8           // Button 2 for View-gallery
#define B3 14          // Button 3 for Toolbar
#define B4 15          // Button 4 for Full-screen 
// Chattering time depends on the Buttons used
#define Cht 30         // chattering time
#define lCht 200       // longer chtrg to ignore *V02
#define typOn 10       // type-on time (mS)
byte  Fk = KEY_F1;     // save area for cur Func key

void setup() { // Setup **************************
  Keyboard.begin();
  // define Buttons and pull them up
  pinMode(B1, INPUT_PULLUP);
  pinMode(B2, INPUT_PULLUP);
  pinMode(B3, INPUT_PULLUP);
  pinMode(B4, INPUT_PULLUP);
}

void loop() {  // Arduino loop ******************
  if (digitalRead(B1) == LOW) { // B1: Mute all members
    delay(Cht);        // ignore chattering
    while (digitalRead(B1) == LOW) {} // wait for btn-off
    Keyboard.press(KEY_LEFT_ALT); // push Alter key
    Keyboard.print("m"); // and type m
    delay(typOn);
    Keyboard.releaseAll();
    delay(lCht);       // avoid longer chattering   *V02
  }

  if (digitalRead(B2) == LOW) { // B2:View gallery or Spkr
    delay(Cht);        // avoid chattering
    while (digitalRead(B2) == LOW) {} // wait button-off
    if (Fk == KEY_F2) { // checck cur func key
      Fk = KEY_F1;     // set F1 if currently F2 used
    } else {
      Fk = KEY_F2;     // set F2 if currently F1 used
    }
    Keyboard.press(KEY_LEFT_ALT); // push Alter key
    Keyboard.press(Fk); // and push Function key 1 or 2
    delay(typOn);
    Keyboard.releaseAll(); // release all keys
    delay(lCht);       // avoid longer chattering   *V02
  }

  if (digitalRead(B3) == LOW) { // B3: Toolbar
    delay(Cht);        // avoid chattering
    while (digitalRead(B3) == LOW) {} // wait button-off
    Keyboard.press(KEY_LEFT_ALT); // push Alter key
    delay(typOn);
    Keyboard.releaseAll(); // release all keys
    delay(lCht);       // avoid longer chattering   *V02
  }

  if (digitalRead(B4) == LOW) { // B4: Full screen
    delay(Cht);        // avoid chattering
    while (digitalRead(B4) == LOW) {} // wait button-off
    Keyboard.press(KEY_LEFT_ALT); // push Alter key
    Keyboard.print("f");  // and type f
    delay(typOn);
    Keyboard.releaseAll(); // release all keys
    delay(lCht);       // avoid longer chattering   *V02
  }
}
// End of program *******************************

どんなスイッチを使っても問題ないように、処理に続いて思い切り長い100mSのDelayを追加してあります。操作性には全く問題ありませんし、これでスイッチの質をいっさい気にしなくて大丈夫でしょう。

そしてスイッチ用の箱を加工し、前から目をつけていたスイッチを使い、そのケース中にマイコンも収容しました。よって使用時はこれとPCをUSBケーブルでつなぐだけ。

f:id:a-tomi:20200510103454j:plain

キートップは紙に印刷して収容しました。

意味はこれまでどおりです。

f:id:a-tomi:20200510103616j:plain

以上です・・・。これでは工作好きの方には物足りないでしょう。「どこが工作なの?」というぐらい簡単。よって、このプラスチックケースの加工のことを少し書いておくことにします。

 

そもそもこの特定のキーはとりつけるネジ間隔が80mmもあるし、昔のキーなので高さがやけに高く、なかなか適当なケースはありません。厚さ(深さ)30mm以上ないとどうにもなりません。3Dプリンターで作ればよいのでしょうがそこまではちょっと・・。それなら取付を汎用ケースの外側にするか、と考えつきました。そして手持ちを探したら適当なケースがありました。

f:id:a-tomi:20200510104226j:plain

50x90x26mmで昔の「タカチGC50」を少し厚くしたような感じ。(ちなみに今のタカチGC50は30x90で深さは時代を反映してずっと浅いです、念のため。)これは台湾製ですが精度も高くよくできています。台北に出張の折にたまに時間があると勝手に光華商場を見物して楽しんでいました。そこで購入したものと思います。表示された台湾ドルはその頃の日本円換算で100円ほどか。

シュリンクラップに包まれラベルに連絡先まで書いてあります!好感がもてますね。

f:id:a-tomi:20200510105242j:plain

どう加工するかと言えば、お決まりの穴をあけてつなぐやり方。とはいえ今回は部品で見えなくなる穴なので、精度や直線などを気にせずに気楽にできますね。表面の他の部分に傷さえつけなければ良いわけなので、表面はマスキングテープで保護しておいて作業します。

f:id:a-tomi:20200510110030j:plain


穴をつないだところ。荒っぽいですが仕上げ不要、これで十分。

f:id:a-tomi:20200510110146j:plain

そしてスイッチを取付。

f:id:a-tomi:20200510110231j:plain

この中にPro Microをどう取り付けるかが悩ましいところ。ピン数か所をスズメッキ線で半田づけした基板をケースの底にねじ付けすることにしました。

まずは蛇の目基板を加工。

f:id:a-tomi:20200510110416j:plain

Pro Microの複数のピンをスズメッキ線で基板へ配線(固定を兼ねます)してから、その基盤を2mmφネジ4つでケースの底に取り付けることにしました。取付後は下の写真です。

その際、マイクロUSB-B型端子がきれいに外へ出るよう、その穴をまず先に加工してから、基板の最終的な取り付け位置を決めてネジ穴をあけて取り付けます。そしてスイッチ側から、基盤表面に出しておいたスズメッキ線の端へと配線します。

こうしておけばしっかり取り付けでき、もし後で不要になったらPro Microは簡単に取り出せます。

ところでですが、ATmega32U4の弱プルアップされたインピーダンスは20kΩ程度はあるので、環境の余計な電界ノイズを拾うことがないよう、はい線は一応束ねておきます。

 

f:id:a-tomi:20200510110601j:plain

表面が黒なので見えにくいですが、USB端子は次のような感じで穴の真ん中にうまく出ています。

f:id:a-tomi:20200510110804j:plain

後はPCとこのUSBをUSBケーブルで接続し、Arduino-IDEを使って先ほどのスケッチを書きこめば、あっという間に出来上がりです。最後にケースの付属ネジ4本を締めます。たぶんもう開けることはないでしょう。

ついでに書いておくべきことを思い出しました。スケッチの作成で注意する点としては、Arduino-Leonardo系に共通のことなのですが、テスト段階でやたらとキーボードへの信号を出しっぱなしにしないことです。もしそうやるとシリアル接続がそれに占拠されてスケッチの書き込みができなくなりますから。スイッチなど何かのトリガーでしかキーボード信号を出さないようにするということですね。

もし仮にそれに気づかず失敗をしたら、ATmega32U4を復活するにはリセット(!Reset端子をグランドに接続するとリセットです)を何度かかけながら、運よく書き込めるタイミングでの書き込みを何度かトライするしかなくなると思います。

 

さて、これで「かんたん操作ボタン」記事は終わり、、かと言えばそうでもありません。

手持ちArduinoの在庫を確かめていたら、"Beetle"を見つけてしまいました。かつてKBハッカー用とか称されて盛んに使われていたもの。マイコンは同じATmega32U4です。

f:id:a-tomi:20200510112258j:plain

これの手持ちは残り2個だけですが、今回の用途にはこんなに気の利いた基板もないものです!組み込む必要すらなく、単にキーからこれへ配線をしてそのままPCのUSBに突っ込むだけですから!考えることは、たぶんこのBeetleのケースをどうするかだけです^^。

そのうちにやってみたいと思います。うまく出来たらここに書き足すか、別記事として書こうかと・・。

 

©2020 Akira Tominaga, All rights reserved.

 

 

Zoom用かんたん操作ボタンをArduino-UNOで作る(その2)やったね!

とりあえず簡単な4ボタンを使ってプログラムをめでたく完成しました。ごく短いスケッチでできます。この装置をZoom会議本番で使ってみたら、操作ががぜん楽になりました。プログラムを含めて詳しくご紹介したいと思います。f:id:a-tomi:20200504214817j:plain

このサブジェクトの最初の記事(その1)の翌日に、プログラム(Arduinoスケッチ)を作り、テストしたら一発で動き快適!調整したのはチャタリング時間の定数設定だけ。最初のテストに作ったボタンは、次のようなブレッドボード上のタクトスイッチです。

f:id:a-tomi:20200504221720j:plain

このボタン装置ならちょっとした時間でできますね。

f:id:a-tomi:20200504221747j:plain

次は、なぜか作業時のマスクをしたままですが^^; 最初のテストをやってます。このテストへの参加者は白クマだけですが^^

f:id:a-tomi:20200505105434j:plain

検討の結果、ショートカットキーの1番目をMute All(ホスト以外)に変更しました。多数が参加するZoom会議本番では、メンバーの中の誰かのスピーカー音がマイクに戻る場合にエコーやハウリングを起こすことがあります。そういう場合、ホスト役としては各参加者のマイクをミュートにして確認しながら、邪魔なノイズを除去します。その際は1つのキーでホスト以外を全てミュートにできると楽ですね。1番目のボタンをそれに変更することにしました。

f:id:a-tomi:20200504220227j:plain

回路は単純で、各スイッチを押せばグランドに接続するようにつくります。他に部品は要りません。接続は次の本番プログラムを見ていただいたく方が早いかと思います(勝手ながら2020年5月13日プログラムを更新しました:ボタン名Bxにウォーニングが出る場合があるためBtnxにし、また、チャタリングの特に長いスイッチにも対応しました)。

//* **************************************************
       "Zoom" short-cut buttons with Arduino-UNO
          V00: Initial version for test   May 1, 2020
          V01: Updated Button assignment  May 2, 2020
          V02  For very long chatterings  May 10,2020
       Funcion: Provide four short-cut-buttons
        Button 1 for Mute all memabers (on/off) *V01
        Button 2 for View gallery (on/off=speaker) 
        Button 3 for Tool-bar (on/off)
        Button 4 for Full-screen (on/off)
      (c) Akira Tominaga, All rights reserved.
 ****************************************************
*/
#define B1 9            // Button 1 for Mute-all *V01
#define B2 10           // Button 2 for View-gallery
#define B3 11           // Button 3 for Toolbar
#define B4 12           // Button 4 for Full-screen
// Chattering time depends on the Buttons used
#define Cht 30          // chattering max time (mS)
#define lCht 200        // time to bypass longer chtrg

byte KbD[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; // HID report
// KbD[0]=Modifier for USB HID Keyboard-code
#define rGUI B10000000  // right Windows key
#define rALT B01000000  // right Alt key
#define rSFT B00100000  // right Shift key
#define rCTL B00010000  // right Ctl key
#define lGUI B00001000  // left Windows key
#define lALT B00000100  // left Alt key
#define lSFT B00000010  // left Shift key
#define lCTL B00000001  // left Ctl key
// KbD[1] should always be 0x00
// KbD[2] to KbD[7] include key-codes (max 6 keys)
// Alphabet code = ASCIIcode-0x5D (ex.a:0x61 -> 0x04)
#define Csub 0x5D       // Character value to subtract
//   Special key codes
#define ScF1 0x3A       // USB KB code for F1 key (Speaker)
#define ScF2 0X3B       // USB KB code for F2 key (Gallery)
byte  Fk=ScF1;          // save area for cur Func key 

void setup() { // Setup **************************
  Serial.begin(9600);
  // define Buttons and pull them up
  pinMode(B1, INPUT_PULLUP);
  pinMode(B2, INPUT_PULLUP);
  pinMode(B3, INPUT_PULLUP);
  pinMode(B4, INPUT_PULLUP);
}

void loop() {  // Arduino loop ******************
  if (digitalRead(B1) == LOW) { // B1: Mute all members
    delay(Cht);         // avoid chattering
    while (digitalRead(B1) == LOW) {} // wait button-off
    // Serial.println("B1=Mute all"); // for test only
    KbD[2] = 'm' - Csub; // set character m
    KbD[0] = lALT;      // set ALT key
    KbWrite();          // send HID-Make and Brake
  }

  if (digitalRead(B2) == LOW) { // B2: View gallery
    delay(Cht);         // avoid chattering
    while (digitalRead(B2) == LOW) {} // wait button-off
    // Serial.println("B2=View"); // for test only
    if (Fk == ScF2) {   // select function key
      Fk = ScF1;        // set F1 if currently F2
    } else {
      Fk = ScF2;        // set F2 if currently F1
    }
    KbD[2] = Fk;        // set the Func-key
    KbD[0] = lALT;      // set left ALT key
    KbWrite();          // send HID-Make and Brake
  }

  if (digitalRead(B3) == LOW) { // B3: Toolbar
    delay(Cht);         // avoid chattering
    while (digitalRead(B3) == LOW) {} // wait button-off
    // Serial.println("B3=Tool"); // for test only
    KbD[0] = lALT;      // set left ALT key
    KbWrite();          // send HID-Make and Brake
  }

  if (digitalRead(B4) == LOW) { // B4: Full screen
    delay(Cht);         // avoid chattering
    while (digitalRead(B4) == LOW) {} // wait button-off
    // Serial.println("B4=Scrn"); // for test only
    KbD[2] = 'f' - Csub; // Set keyboard f char
    KbD[0] = lALT;      // set left ALT key
    KbWrite();          // send HID-Make and Brake
  }
}

/********************************
 * *** User defined functions ***
 * *****************************/
// *** KbWrite()  send HID-Make and HID-Brake
void KbWrite(void)
{
  Serial.write(KbD, 8); // HID-Make
  KbD[2] = 0x00;        // clear character
  KbD[0] = 0x00;        // clear modifier
  Serial.write(KbD, 8); // HID-Break
  delay(lCht);        // to ignore longer chtrg *V02
}

ボタンが押されたのを確認する処理は簡単そうですが、実は十分な注意が必要です。

単にLOWになったかどうかをチェックするだけでなく、数ミリ~数十ミリ秒のチャタリング(接点オン時のノイズ)回避用delay時間をとった後で、HIGHになる(ボタンを離す)まで待つ必要があります。ボタンに対する処理の量が少ない(つまりごく短時間に処理が終わる)場合には特に大事なことです。チャタリングの長いスイッチもあるので、念のために各処理の後に余分な時間を入れます。これは操作性には影響しません。

こうしないとチャタリングによって複数回押されたことになり、連続して複数回の同じ処理をしてしまうことにもなります。どれだけの時間を待つかはスイッチの品質にもよりますが、いかに高品質でも物理的なスイッチであればチャタリングは避けられません。回路上でローパスフィルタを入れれば多少は軽減できますが、現代ではそうはせずにソフトウェアで回避するのがいちばん妥当ですね。

人の手によるボタン操作の後処理なので、プログラム側で30mS待っても影響はありません。同じコーディングをされるようにお勧め。スイッチに合わせてこの時間を調節することもできますが、処理の後(この例ではユーザー定義関数の最後)に200mSをいれましたので、調整しなくともどれでも大丈夫ですし、操作性にも影響しません。

 

テスト段階で使うタクトスイッチは2ピンのものがお勧めです。ブレッドボードで使う場合、2本足のタクトスイッチなら取り付けも操作も安定していますから。普通のタクトスイッチは4ピンのものが殆どですが、基板用なので脚を延ばしても短すぎブレッドボードには不向きです。次の写真で奥のものが不適切な4ピン、手前の2つが適当な2ピンのタクトスイッチです。

f:id:a-tomi:20200504222001j:plain

 

2回の会議本番では、以上の4つのボタン装置があれば必要十分と感じました。ご自分の操作しやすさに合わせてお好みのものにするとか、ボタンを増やしたりされても使いやすいかもしれません。

Zoomが現在(2020年5月5日)提供しているショートカットキーは次のものです。

f:id:a-tomi:20200504222450j:plain

 

さて、とくに問題もみつからないので、ボタンのセットを作ることにします。

こんなに助かる装置なので、そのうちにArduino Microを調達してスイッチと併せて小さく作りたいと考えました。なので、前の記事(その1)で説明した本命の押釦はそれ用にとっておくことにしました。

そして翌日の会議に間に合うように急いで、一番早く製作できるボタンを使いました(その代り品質は個体差も多くてロクなものではありません、チャタリング回避時間を思い切り延ばしたわけです^^;)。これなら、例えばタカチのプラスチックケースにとりつけるならすぐに加工できますし。なお、消費税が5%の頃に入手した感じ^^

f:id:a-tomi:20200504222820j:plain

次のように完成しました。

f:id:a-tomi:20200504222848j:plain

左からMute all, View gallery, Tool, Full screen。4つなら頭文字だけ表示すればよいかな。

小さい箱なので配線にひと手間かかりますが、そこには生活の知恵を。スイッチに直接ケーブルを配線をするのではなく、ごく小さな基板をかませます。ここまではスズメッキ線などで配線します。こうすると速くて確実・丈夫にできます。中身は少しみっともないですが次。

f:id:a-tomi:20200504223159j:plain

使っているシールドケーブルは使わないUSBケーブルを流用したものです。中に4線がシールドされているのでノイズを拾わず、なにより柔らかい。そして百均のケーブルでも確実であり、こういう用途にはぴったりですね。内部には赤、緑、白、黒、そしてシールドがあります。シールド線にははんだ付け前に1mmφ熱収縮チューブ等をかぶせます。

Arduino UNOも別のケースに収めます。Arduinoとの配線は、ケースに収容して固定しない限り、操作中に抜けたり、長く使うとArduino側ヘダーピン(メス)が傷んでだんだん緩くなってしまいます。よって面倒でもケースに収めるわけです。

もしArduino Microでつくる場合なら、ボタンと併せて1つの筐体にしてしまいますが、今回はUNOなのでやむを得ないですね。こちらには秋月で売っている小さなポリカーボネートケースを使いました。割れないので工作がとても速くできます。余計なソケットなどは省くのが今回は得策ですね。

f:id:a-tomi:20200504223537j:plain

ところで、後で考えてみればこのUNOのケースにボタンをとりつけてもよかったのか・・?。手元に必要なスペースが増えるのは感心しませんので、これでいいか。

f:id:a-tomi:20200504223731j:plain

ヘダーピンのところにはL型オス1列ヘダーピンを使用。使うのはグランド、デジタルピン12、11、10、9です。ピン13はUNO基板のLEDを後で使うかもしれないので、スキップし、そのピンはL型ヘダーピンから抜いておきます。

f:id:a-tomi:20200504223931j:plain

1本ずつではなく連結したピンを使うと、全体が動きにくくなりArduino UNO側のメスピンが傷みにくくなります。

Arduino UNO専用のケースが、かつてAmazon等で百数十円で売られていましたので、その時に沢山入手してあります。そちらは体裁がよいのですが、日頃使う装置にこれを使うとピンの固定にひと工夫がいりますので、今回は敬遠。

f:id:a-tomi:20200504224212j:plain

 

以上について真似をされる方は事前に前の記事(その1)を読んでくださいね。Arsuino-UNOのUSB接続をKeyboardにしたりArduinoに戻したりする方法をそちらに書いてありますので。

a-tomi.hatenablog.com

 

また、キーボードの文字コードについての情報が必要かと思いますのでここに書きます。OADGで出されているHID(ヒューマンインターフェイスバイス)のプロトコルに従うものですが、次のコードをご覧になればわかりやすいかと思います。

日本語キーボードでもZoomのショートカットキーは幸い同じようですが、その他のキーの違いを知る必要のある場合は、”日本語  USB-HIDキーボード  コード”などでググっていただくとキー配列の設定がいくつか見つかりますのでそちらをご参照ください。

/**
MightyPork/usb_hid_keys.h
*
 * USB HID Keyboard scan codes as per USB spec 1.11
 * plus some additional codes
 * 
 * Created by MightyPork, 2016
 * Public domain
 * 
 * Adapted from:
 * https://source.android.com/devices/input/keyboard-devices.html
 */

#ifndef USB_HID_KEYS
#define USB_HID_KEYS

/**
 * Modifier masks - used for the first byte in the HID report.
 * NOTE: The second byte in the report is reserved, 0x00
 */
#define KEY_MOD_LCTRL  0x01
#define KEY_MOD_LSHIFT 0x02
#define KEY_MOD_LALT   0x04
#define KEY_MOD_LMETA  0x08
#define KEY_MOD_RCTRL  0x10
#define KEY_MOD_RSHIFT 0x20
#define KEY_MOD_RALT   0x40
#define KEY_MOD_RMETA  0x80

/**
 * Scan codes - last N slots in the HID report (usually 6).
 * 0x00 if no key pressed.
 * 
 * If more than N keys are pressed, the HID reports 
 * KEY_ERR_OVF in all slots to indicate this condition.
 */

#define KEY_NONE 0x00 // No key pressed
#define KEY_ERR_OVF 0x01 //  Keyboard Error Roll Over - used for all slots if too many keys are pressed ("Phantom key")
// 0x02 //  Keyboard POST Fail
// 0x03 //  Keyboard Error Undefined
#define KEY_A 0x04 // Keyboard a and A
#define KEY_B 0x05 // Keyboard b and B
#define KEY_C 0x06 // Keyboard c and C
#define KEY_D 0x07 // Keyboard d and D
#define KEY_E 0x08 // Keyboard e and E
#define KEY_F 0x09 // Keyboard f and F
#define KEY_G 0x0a // Keyboard g and G
#define KEY_H 0x0b // Keyboard h and H
#define KEY_I 0x0c // Keyboard i and I
#define KEY_J 0x0d // Keyboard j and J
#define KEY_K 0x0e // Keyboard k and K
#define KEY_L 0x0f // Keyboard l and L
#define KEY_M 0x10 // Keyboard m and M
#define KEY_N 0x11 // Keyboard n and N
#define KEY_O 0x12 // Keyboard o and O
#define KEY_P 0x13 // Keyboard p and P
#define KEY_Q 0x14 // Keyboard q and Q
#define KEY_R 0x15 // Keyboard r and R
#define KEY_S 0x16 // Keyboard s and S
#define KEY_T 0x17 // Keyboard t and T
#define KEY_U 0x18 // Keyboard u and U
#define KEY_V 0x19 // Keyboard v and V
#define KEY_W 0x1a // Keyboard w and W
#define KEY_X 0x1b // Keyboard x and X
#define KEY_Y 0x1c // Keyboard y and Y
#define KEY_Z 0x1d // Keyboard z and Z

#define KEY_1 0x1e // Keyboard 1 and !
#define KEY_2 0x1f // Keyboard 2 and @
#define KEY_3 0x20 // Keyboard 3 and #
#define KEY_4 0x21 // Keyboard 4 and $
#define KEY_5 0x22 // Keyboard 5 and %
#define KEY_6 0x23 // Keyboard 6 and ^
#define KEY_7 0x24 // Keyboard 7 and &
#define KEY_8 0x25 // Keyboard 8 and *
#define KEY_9 0x26 // Keyboard 9 and (
#define KEY_0 0x27 // Keyboard 0 and )

#define KEY_ENTER 0x28 // Keyboard Return (ENTER)
#define KEY_ESC 0x29 // Keyboard ESCAPE
#define KEY_BACKSPACE 0x2a // Keyboard DELETE (Backspace)
#define KEY_TAB 0x2b // Keyboard Tab
#define KEY_SPACE 0x2c // Keyboard Spacebar
#define KEY_MINUS 0x2d // Keyboard - and _
#define KEY_EQUAL 0x2e // Keyboard = and +
#define KEY_LEFTBRACE 0x2f // Keyboard [ and {
#define KEY_RIGHTBRACE 0x30 // Keyboard ] and }
#define KEY_BACKSLASH 0x31 // Keyboard \ and |
#define KEY_HASHTILDE 0x32 // Keyboard Non-US # and ~
#define KEY_SEMICOLON 0x33 // Keyboard ; and :
#define KEY_APOSTROPHE 0x34 // Keyboard ' and "
#define KEY_GRAVE 0x35 // Keyboard ` and ~
#define KEY_COMMA 0x36 // Keyboard , and <
#define KEY_DOT 0x37 // Keyboard . and >
#define KEY_SLASH 0x38 // Keyboard / and ?
#define KEY_CAPSLOCK 0x39 // Keyboard Caps Lock

#define KEY_F1 0x3a // Keyboard F1
#define KEY_F2 0x3b // Keyboard F2
#define KEY_F3 0x3c // Keyboard F3
#define KEY_F4 0x3d // Keyboard F4
#define KEY_F5 0x3e // Keyboard F5
#define KEY_F6 0x3f // Keyboard F6
#define KEY_F7 0x40 // Keyboard F7
#define KEY_F8 0x41 // Keyboard F8
#define KEY_F9 0x42 // Keyboard F9
#define KEY_F10 0x43 // Keyboard F10
#define KEY_F11 0x44 // Keyboard F11
#define KEY_F12 0x45 // Keyboard F12

#define KEY_SYSRQ 0x46 // Keyboard Print Screen
#define KEY_SCROLLLOCK 0x47 // Keyboard Scroll Lock
#define KEY_PAUSE 0x48 // Keyboard Pause
#define KEY_INSERT 0x49 // Keyboard Insert
#define KEY_HOME 0x4a // Keyboard Home
#define KEY_PAGEUP 0x4b // Keyboard Page Up
#define KEY_DELETE 0x4c // Keyboard Delete Forward
#define KEY_END 0x4d // Keyboard End
#define KEY_PAGEDOWN 0x4e // Keyboard Page Down
#define KEY_RIGHT 0x4f // Keyboard Right Arrow
#define KEY_LEFT 0x50 // Keyboard Left Arrow
#define KEY_DOWN 0x51 // Keyboard Down Arrow
#define KEY_UP 0x52 // Keyboard Up Arrow

#define KEY_NUMLOCK 0x53 // Keyboard Num Lock and Clear
#define KEY_KPSLASH 0x54 // Keypad /
#define KEY_KPASTERISK 0x55 // Keypad *
#define KEY_KPMINUS 0x56 // Keypad -
#define KEY_KPPLUS 0x57 // Keypad +
#define KEY_KPENTER 0x58 // Keypad ENTER
#define KEY_KP1 0x59 // Keypad 1 and End
#define KEY_KP2 0x5a // Keypad 2 and Down Arrow
#define KEY_KP3 0x5b // Keypad 3 and PageDn
#define KEY_KP4 0x5c // Keypad 4 and Left Arrow
#define KEY_KP5 0x5d // Keypad 5
#define KEY_KP6 0x5e // Keypad 6 and Right Arrow
#define KEY_KP7 0x5f // Keypad 7 and Home
#define KEY_KP8 0x60 // Keypad 8 and Up Arrow
#define KEY_KP9 0x61 // Keypad 9 and Page Up
#define KEY_KP0 0x62 // Keypad 0 and Insert
#define KEY_KPDOT 0x63 // Keypad . and Delete

#define KEY_102ND 0x64 // Keyboard Non-US \ and |
#define KEY_COMPOSE 0x65 // Keyboard Application
#define KEY_POWER 0x66 // Keyboard Power
#define KEY_KPEQUAL 0x67 // Keypad =

#define KEY_F13 0x68 // Keyboard F13
#define KEY_F14 0x69 // Keyboard F14
#define KEY_F15 0x6a // Keyboard F15
#define KEY_F16 0x6b // Keyboard F16
#define KEY_F17 0x6c // Keyboard F17
#define KEY_F18 0x6d // Keyboard F18
#define KEY_F19 0x6e // Keyboard F19
#define KEY_F20 0x6f // Keyboard F20
#define KEY_F21 0x70 // Keyboard F21
#define KEY_F22 0x71 // Keyboard F22
#define KEY_F23 0x72 // Keyboard F23
#define KEY_F24 0x73 // Keyboard F24

#define KEY_OPEN 0x74 // Keyboard Execute
#define KEY_HELP 0x75 // Keyboard Help
#define KEY_PROPS 0x76 // Keyboard Menu
#define KEY_FRONT 0x77 // Keyboard Select
#define KEY_STOP 0x78 // Keyboard Stop
#define KEY_AGAIN 0x79 // Keyboard Again
#define KEY_UNDO 0x7a // Keyboard Undo
#define KEY_CUT 0x7b // Keyboard Cut
#define KEY_COPY 0x7c // Keyboard Copy
#define KEY_PASTE 0x7d // Keyboard Paste
#define KEY_FIND 0x7e // Keyboard Find
#define KEY_MUTE 0x7f // Keyboard Mute
#define KEY_VOLUMEUP 0x80 // Keyboard Volume Up
#define KEY_VOLUMEDOWN 0x81 // Keyboard Volume Down
// 0x82  Keyboard Locking Caps Lock
// 0x83  Keyboard Locking Num Lock
// 0x84  Keyboard Locking Scroll Lock
#define KEY_KPCOMMA 0x85 // Keypad Comma
// 0x86  Keypad Equal Sign
#define KEY_RO 0x87 // Keyboard International1
#define KEY_KATAKANAHIRAGANA 0x88 // Keyboard International2
#define KEY_YEN 0x89 // Keyboard International3
#define KEY_HENKAN 0x8a // Keyboard International4
#define KEY_MUHENKAN 0x8b // Keyboard International5
#define KEY_KPJPCOMMA 0x8c // Keyboard International6
// 0x8d  Keyboard International7
// 0x8e  Keyboard International8
// 0x8f  Keyboard International9
#define KEY_HANGEUL 0x90 // Keyboard LANG1
#define KEY_HANJA 0x91 // Keyboard LANG2
#define KEY_KATAKANA 0x92 // Keyboard LANG3
#define KEY_HIRAGANA 0x93 // Keyboard LANG4
#define KEY_ZENKAKUHANKAKU 0x94 // Keyboard LANG5
// 0x95  Keyboard LANG6
// 0x96  Keyboard LANG7
// 0x97  Keyboard LANG8
// 0x98  Keyboard LANG9
// 0x99  Keyboard Alternate Erase
// 0x9a  Keyboard SysReq/Attention
// 0x9b  Keyboard Cancel
// 0x9c  Keyboard Clear
// 0x9d  Keyboard Prior
// 0x9e  Keyboard Return
// 0x9f  Keyboard Separator
// 0xa0  Keyboard Out
// 0xa1  Keyboard Oper
// 0xa2  Keyboard Clear/Again
// 0xa3  Keyboard CrSel/Props
// 0xa4  Keyboard ExSel

// 0xb0  Keypad 00
// 0xb1  Keypad 000
// 0xb2  Thousands Separator
// 0xb3  Decimal Separator
// 0xb4  Currency Unit
// 0xb5  Currency Sub-unit
#define KEY_KPLEFTPAREN 0xb6 // Keypad (
#define KEY_KPRIGHTPAREN 0xb7 // Keypad )
// 0xb8  Keypad {
// 0xb9  Keypad }
// 0xba  Keypad Tab
// 0xbb  Keypad Backspace
// 0xbc  Keypad A
// 0xbd  Keypad B
// 0xbe  Keypad C
// 0xbf  Keypad D
// 0xc0  Keypad E
// 0xc1  Keypad F
// 0xc2  Keypad XOR
// 0xc3  Keypad ^
// 0xc4  Keypad %
// 0xc5  Keypad <
// 0xc6  Keypad >
// 0xc7  Keypad &
// 0xc8  Keypad &&
// 0xc9  Keypad |
// 0xca  Keypad ||
// 0xcb  Keypad :
// 0xcc  Keypad #
// 0xcd  Keypad Space
// 0xce  Keypad @
// 0xcf  Keypad !
// 0xd0  Keypad Memory Store
// 0xd1  Keypad Memory Recall
// 0xd2  Keypad Memory Clear
// 0xd3  Keypad Memory Add
// 0xd4  Keypad Memory Subtract
// 0xd5  Keypad Memory Multiply
// 0xd6  Keypad Memory Divide
// 0xd7  Keypad +/-
// 0xd8  Keypad Clear
// 0xd9  Keypad Clear Entry
// 0xda  Keypad Binary
// 0xdb  Keypad Octal
// 0xdc  Keypad Decimal
// 0xdd  Keypad Hexadecimal

#define KEY_LEFTCTRL 0xe0 // Keyboard Left Control
#define KEY_LEFTSHIFT 0xe1 // Keyboard Left Shift
#define KEY_LEFTALT 0xe2 // Keyboard Left Alt
#define KEY_LEFTMETA 0xe3 // Keyboard Left GUI
#define KEY_RIGHTCTRL 0xe4 // Keyboard Right Control
#define KEY_RIGHTSHIFT 0xe5 // Keyboard Right Shift
#define KEY_RIGHTALT 0xe6 // Keyboard Right Alt
#define KEY_RIGHTMETA 0xe7 // Keyboard Right GUI

#define KEY_MEDIA_PLAYPAUSE 0xe8
#define KEY_MEDIA_STOPCD 0xe9
#define KEY_MEDIA_PREVIOUSSONG 0xea
#define KEY_MEDIA_NEXTSONG 0xeb
#define KEY_MEDIA_EJECTCD 0xec
#define KEY_MEDIA_VOLUMEUP 0xed
#define KEY_MEDIA_VOLUMEDOWN 0xee
#define KEY_MEDIA_MUTE 0xef
#define KEY_MEDIA_WWW 0xf0
#define KEY_MEDIA_BACK 0xf1
#define KEY_MEDIA_FORWARD 0xf2
#define KEY_MEDIA_STOP 0xf3
#define KEY_MEDIA_FIND 0xf4
#define KEY_MEDIA_SCROLLUP 0xf5
#define KEY_MEDIA_SCROLLDOWN 0xf6
#define KEY_MEDIA_EDIT 0xf7
#define KEY_MEDIA_SLEEP 0xf8
#define KEY_MEDIA_COFFEE 0xf9
#define KEY_MEDIA_REFRESH 0xfa
#define KEY_MEDIA_CALC 0xfb

#endif // USB_HID_KEYS

 

また、FLIPツール(その1をご参照)を使ってUNOが正しくUSBキーボードになったのかを確認するためには、デバイスマネジャーを立ち上げておいて表示をみると良いと前回書きました。ついでですが、Windowsでさらに詳しく確認したい場合についてここでご紹介したいと思います。

マイクロソフトが提供している無料開発ツールのUSB ViewerあるいはUSB Tree Viewerのどちらかを導入して、それを使われると良いと思います。USB Tree Viewerの方が詳しい情報が得られます(が、USB Viewerの方が導入は単純です)。各名称でググっていただくとマイクロソフトの説明ページが出てきますので、必要な方は自己責任にてご導入ください。

次はUSB Tree viewer V3.3.8(現時点で最新)での表示例です。

f:id:a-tomi:20200505115159j:plain

上図は私の場合ですが、他のキーボードを常時2個(テンキーレスとテンキーをわけているためです)接続していますので、USB-HIDキーボードが3個になって少し紛らわしいかもしれませんね。 

この例ではPort7を選び表示される詳細は次です。


    =========================== USB Port7 ===========================

Connection Status        : 0x01 (Device is connected)
Port Chain               : 1-7
Properties               : 0x01
 IsUserConnectable       : yes
 PortIsDebugCapable      : no
 PortHasMultiCompanions  : no
 PortConnectorIsTypeC    : no
ConnectionIndex          : 7

      ======================== USB Device ========================

        +++++++++++++++++ Device Information ++++++++++++++++++
Device Description       : USB 入力デバイス
Device Path              : \\?\usb#vid_03eb&pid_2042#5&16caae6d&0&7#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
Device ID                : USB\VID_03EB&PID_2042\5&16CAAE6D&0&7
Hardware IDs             : USB\VID_03EB&PID_2042&REV_0000 USB\VID_03EB&PID_2042
Driver KeyName           : {745a17a0-74d3-11d0-b6fe-00a0c90f57da}\0032 (GUID_DEVCLASS_HIDCLASS)
Driver                   : \SystemRoot\System32\drivers\hidusb.sys (Version: 10.0.18362.175  Date: 2019-08-29)
Driver Inf               : C:\WINDOWS\inf\input.inf
Legacy BusType           : PNPBus
Class                    : HIDClass
Class GUID               : {745a17a0-74d3-11d0-b6fe-00a0c90f57da} (GUID_DEVCLASS_HIDCLASS)
Interface GUID           : {a5dcbf10-6530-11d2-901f-00c04fb951ed} (GUID_DEVINTERFACE_USB_DEVICE)
Service                  : HidUsb
Enumerator               : USB
Location Info            : Port_#0007.Hub_#0001
Location IDs             : PCIROOT(0)#PCI(1400)#USBROOT(0)#USB(7), ACPI(_SB_)#ACPI(PCI0)#ACPI(XHC_)#ACPI(RHUB)#ACPI(HS07)
Container ID             : {6a392c6f-8a75-11ea-9c58-b8aeedafcdef}
Manufacturer Info        : (標準システム デバイス)
Capabilities             : 0x84 (Removable, SurpriseRemovalOK)
Status                   : 0x0180400A (DN_DRIVER_LOADED, DN_STARTED, DN_REMOVABLE, DN_NT_ENUMERATOR, DN_NT_DRIVER)
Problem Code             : 0
HcDisableSelectiveSuspend: 0
EnableSelectiveSuspend   : 0
SelectiveSuspendEnabled  : 0
EnhancedPowerMgmtEnabled : 1
IdleInWorkingState       : 0
WakeFromSleepState       : 0
Power State              : D0 (supported: D0, D3, wake from D0)
 Child Device 1          : HID キーボード デバイス
  DevicePath             : \\?\hid#vid_03eb&pid_2042#6&39102546&0&0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}
  KernelName             : \Device\00000125
  Device ID              : HID\VID_03EB&PID_2042\6&39102546&0&0000
  Class                  : Keyboard

        ---------------- Connection Information ---------------
Connection Index         : 0x07 (7)
Connection Status        : 0x01 (DeviceConnected)
Current Config Value     : 0x01
Device Address           : 0x08 (8)
Is Hub                   : 0x00 (no)
Device Bus Speed         : 0x01 (Full-Speed)
Number Of Open Pipes     : 0x01 (1 pipe to data endpoints)
Pipe[0]                  : EndpointID=1  Direction=IN   ScheduleOffset=0  Type=Interrupt
Data (HexDump)           : 07 00 00 00 12 01 10 01 00 00 00 08 EB 03 42 20   ..............B 
                           00 00 01 02 00 01 01 01 00 08 00 01 00 00 00 01   ................
                           00 00 00 07 05 81 03 08 00 0A 00 00 00 00         ..............

        --------------- Connection Information V2 -------------
Connection Index         : 0x07 (7)
Length                   : 0x10 (16 bytes)
SupportedUsbProtocols    : 0x03
 Usb110                  : 1 (yes)
 Usb200                  : 1 (yes)
 Usb300                  : 0 (no)
 ReservedMBZ             : 0x00
Flags                    : 0x00
 DevIsOpAtSsOrHigher     : 0 (Is not operating at SuperSpeed or higher)
 DevIsSsCapOrHigher      : 0 (Is not SuperSpeed capable or higher)
 DevIsOpAtSsPlusOrHigher : 0 (Is not operating at SuperSpeedPlus or higher)
 DevIsSsPlusCapOrHigher  : 0 (Is not SuperSpeedPlus capable or higher)
 ReservedMBZ             : 0x00
Data (HexDump)           : 07 00 00 00 10 00 00 00 03 00 00 00 00 00 00 00   ................

    ---------------------- Device Descriptor ----------------------
bLength                  : 0x12 (18 bytes)
bDescriptorType          : 0x01 (Device Descriptor)
bcdUSB                   : 0x110 (USB Version 1.10)
bDeviceClass             : 0x00 (defined by the interface descriptors)
bDeviceSubClass          : 0x00
bDeviceProtocol          : 0x00
bMaxPacketSize0          : 0x08 (8 bytes)
idVendor                 : 0x03EB (Atmel Corporation)
idProduct                : 0x2042
bcdDevice                : 0x0000
iManufacturer            : 0x01 (String Descriptor 1)
 Language 0x0409         : "Arduino"
iProduct                 : 0x02 (String Descriptor 2)
 Language 0x0409         : "Keyboard"
iSerialNumber            : 0x00 (No String Descriptor)
bNumConfigurations       : 0x01 (1 Configuration)
Data (HexDump)           : 12 01 10 01 00 00 00 08 EB 03 42 20 00 00 01 02   ..........B ....
                           00 01                                             ..

    ------------------ Configuration Descriptor -------------------
bLength                  : 0x09 (9 bytes)
bDescriptorType          : 0x02 (Configuration Descriptor)
wTotalLength             : 0x0022 (34 bytes)
bNumInterfaces           : 0x01 (1 Interface)
bConfigurationValue      : 0x01 (Configuration 1)
iConfiguration           : 0x00 (No String Descriptor)
bmAttributes             : 0xC0
 D7: Reserved, set 1     : 0x01
 D6: Self Powered        : 0x01 (yes)
 D5: Remote Wakeup       : 0x00 (no)
 D4..0: Reserved, set 0  : 0x00
MaxPower                 : 0x32 (100 mA)
Data (HexDump)           : 09 02 22 00 01 01 00 C0 32 09 04 00 00 01 03 01   ..".....2.......
                           01 00 09 21 11 01 00 01 22 40 00 07 05 81 03 08   ...!...."@......
                           00 0A                                             ..

        ---------------- Interface Descriptor -----------------
bLength                  : 0x09 (9 bytes)
bDescriptorType          : 0x04 (Interface Descriptor)
bInterfaceNumber         : 0x00
bAlternateSetting        : 0x00
bNumEndpoints            : 0x01 (1 Endpoint)
bInterfaceClass          : 0x03 (HID - Human Interface Device)
bInterfaceSubClass       : 0x01 (Boot Interface)
bInterfaceProtocol       : 0x01 (Keyboard)
iInterface               : 0x00 (No String Descriptor)
Data (HexDump)           : 09 04 00 00 01 03 01 01 00                        .........

        ------------------- HID Descriptor --------------------
bLength                  : 0x09 (9 bytes)
bDescriptorType          : 0x21 (HID Descriptor)
bcdHID                   : 0x0111 (HID Version 1.11)
bCountryCode             : 0x00 (00 = not localized)
bNumDescriptors          : 0x01
Data (HexDump)           : 09 21 11 01 00 01 22 40 00                        .!...."@.
Descriptor 1:
bDescriptorType          : 0x22 (Class=Report)
wDescriptorLength        : 0x0040 (64 bytes)
Error reading descriptor : ERROR_INVALID_PARAMETER

        ----------------- Endpoint Descriptor -----------------
bLength                  : 0x07 (7 bytes)
bDescriptorType          : 0x05 (Endpoint Descriptor)
bEndpointAddress         : 0x81 (Direction=IN EndpointID=1)
bmAttributes             : 0x03 (TransferType=Interrupt)
wMaxPacketSize           : 0x0008 (8 bytes)
bInterval                : 0x0A (10 ms)
Data (HexDump)           : 07 05 81 03 08 00 0A                              .......

      -------------------- String Descriptors -------------------
             ------ String Descriptor 0 ------
bLength                  : 0x04 (4 bytes)
bDescriptorType          : 0x03 (String Descriptor)
Language ID[0]           : 0x0409 (English - United States)
Data (HexDump)           : 04 03 09 04                                       ....
             ------ String Descriptor 1 ------
bLength                  : 0x10 (16 bytes)
bDescriptorType          : 0x03 (String Descriptor)
Language 0x0409          : "Arduino"
Data (HexDump)           : 10 03 41 00 72 00 64 00 75 00 69 00 6E 00 6F 00   ..A.r.d.u.i.n.o.
             ------ String Descriptor 2 ------
bLength                  : 0x12 (18 bytes)
bDescriptorType          : 0x03 (String Descriptor)
Language 0x0409          : "Keyboard"
Data (HexDump)           : 12 03 4B 00 65 00 79 00 62 00 6F 00 61 00 72 00   ..K.e.y.b.o.a.r.
                           64 00                                             d.

参考情報がだらだら長引いてしまいました。

 

Zoomは転送データ量が他のネット会議ツールよりも少なく安定しています。Wifi経由でないスマホからの出席者にとってもよいことですね。私は一昨年から遠隔会議に使ってきましたが、最近は乱入防止のために待機室を使うなど簡単な対策もそろってきましたし、この便利なツールにはとても感謝しています。

ネット会議の需要はまだまだ当分続くことでしょうし、広がる一方でしょう。なのでこの簡単操作ボタンの出番は半永久的?次は全体が一番小さいのを作っておこうかと考え始め、今になって結局Arduino Micro系の基板を注文しておきました。あれっ^^; 

小さいのをそちらで作った際には、またここの記事でご報告するつもりです。ただ、記事はなにせ勝手なマイペースですから、途中で他の記事になったりして・・

 

©2020 Akira Tominaga, All rights reserved.

Zoom用かんたん操作ボタンをArduino-UNOで作る(その1)

お籠り生活の続く中です。Zoomで会議をしている方はとても多いでしょうね。クロマキーなどを自作したりして、、。私もそうですが。Zoomには便利なショートカットキーが色々ありますがなかなか使えません。ホスト側の操作を少しでも楽にしたいと考え、簡単な操作ボタンをArduinoで作ってみることにします。

f:id:a-tomi:20200430220126j:plain

操作しやすそうなボタンを手持ち部品から探すと次のものです。

f:id:a-tomi:20200430220320j:plain

 

f:id:a-tomi:20200430220916j:plain


ずいぶん昔の部品なのですが、キートップが入れられ、精度が高くボタン操作は超スムーズな逸品です。裏にTKCというマークがきざまれているので、メーカーは東海通信工業で、1990年頃の製品と思われます。当時の日本製の品質はあらためて凄いと思います。もちろん、操作しやすいボタンなら何をつかってもOKです。

手持ちには8キ―と4キーのものがありますが、8キーを使うと操作が却って煩雑になりそう。この際は次のショートカットキーを選んで、単純に4キーに収めることにします。もちろんキーはいつでも取り換えられますが。

f:id:a-tomi:20200505144612j:plain
さて、これをArduinoで簡単に作りたいと思います。Arduino LeonardoやMicroなどは本体にUSB通信を含むATmega32U4なので、Keyboardライブラリを使えば直接USBキーが作れます。しかし、現時点では手持ちがUnoやMega256、ESPなどばかり。そういう方は多いことでしょう。今さら購入もなんですので、この際は試しにUnoで作ることに。

f:id:a-tomi:20200430221811j:plain

Arduino UnoはUSB接続部分に周辺マイコンとしてATMEGA16U2を使っています。そのファームウェアを書き換えることでUnoをUSBキーボード・コントローラーに変えてしまいます。上の写真では左上のほうにある小さなICがATMEGA16U2です。

f:id:a-tomi:20200430222534j:plain

純正のArduino Unoなら問題ないですが、コンパチモデルでもOK。ただしUSB接続マイコンが上記のものでないとだめ(CH340Gなどだとどうにもなりません)。また、次に書きますように、本体のATMEGA328PがSMDでなくDIP型の方が使いやすいです。

ファームウェアを書き換えると、このマイコンはUSBキーボードに化けてしまいます。それをArduino UNOとしてプログラミングする時には、再びATMEGA16U2のファームウェアを元のファームウェアに戻す必要があります。そうするとテスト中何度もファームウェアを入れ替えなくてはならなくなりますので、それを避けるために次の工夫をします。まず無圧ソケットで次のような部品を2つ作り、別のUNOでプログラミングされた本体のATMEGA328Pをこれと入れ替えながら調整するようにします。

f:id:a-tomi:20200430223258j:plain

28ピン無圧ソケットに普通の28ピンソケットを履かせて、さらにその下に丸ピンソケットを履かせます。丸ピンソケットは14ピンのを2つ差し込む方が簡単にできます。

これでATMEGA328Pに下駄をはかせてUNOに差し込んでおくわけです。こうすれば他のUNOでプログラミングしたものと簡単に取り替えられますから。

f:id:a-tomi:20200430223623j:plain

こうして細工をした2つのUNO(または互換機)を用意します。

f:id:a-tomi:20200430223728j:plain

紛らわしいのでKeyboardに化けさせる側に何かで印をつけておくといいですね。ここでは黄色のシールを貼ることにします。

USBインターフェイスであるATMEGA16U2のファームウェアを書き換えるためには、Atmel社(現在はMicrochip社)のFLIPというツールを使います。これは" atmel flip download"で検索すれば簡単に見つかりますのでWindowsにインストールしておきます。とても簡単なツールです。

ファームウェアGithubArduino-keyboard-0.3.hexをみつけてコピーしておきますが、それを収容するフォルダーにもパスにも日本語や特殊記号がはいらないように作っておきます。そうしないとFLIPがトラブるためです。また、このファームウエアをいれたあとで、必要に応じてArduino Unoのファームウェアに戻すために、次の場所からhexファイルをコピーして、この同じフォルダーに入れておくのが賢いです。

C:\ProgramFiles (x86)\Arduino\hardware\arduino\avr\firmwares\atmegaxxu2\arduino-usbserial\Arduino-usbserial-atmega16u2-Uno-Rev3.hex

ここまでできたら、まずはArduinoのテスト用スケッチを書き込んでおきます。例はこの記事の最後の方につけておきます。

Windows PCにATMEGA16U2を認識させるためには、次のように左上の方にある3対並んだピンの一番左2つをジャンパーピン(黄色)で閉じておきます。もちろんメスーメスのデュポンワイヤーでも構いません。

f:id:a-tomi:20200430225202j:plain

その状態でPCにUSB接続をします。そして数秒後にジャンパーピンを抜くことによってWindowsがATMEGA16U2を認識します。デバイスマネジャー画面を立ち上げていればその状態が観察できます。もしPCにATMEGA16U2ドライバーがないときはそこでインストールしてしてから同じことをやり直します。

そしてFLIPを立ち上げてファームウェアを書き換えるのですが、次のように行います。

f:id:a-tomi:20200430225733j:plain

最初に上の左のようにICの絵をクリックしてデバイスを選択します。次にUSBケーブルの絵をクリックして上の右のようにUSBを選択します。すると次の左のようになります。

f:id:a-tomi:20200430230005j:plain

そしてOpenをクリックすればATMEGA16U2と接続が確立して上の右のようになります。次にFileをクリックして、先ほど準備しておいたファイルkeyboard-0.3.hexを指定します。

f:id:a-tomi:20200430230207j:plain

上図右のように選びます。そしてFLIPの左下にあるRunをクリックすればファームウェアが書き換えられます。

次の図の左下のようにVerifyPASSが表示されればおしまい。FLIPを終了させてUSBをさしなおすことにより、USB-HIDキーボードと認識されます。

f:id:a-tomi:20200430230647j:plain

なお、上図右は、Arduino-UNOに戻すために、ファームウェアを同じ手順で元のArduino-usbserial-atmega16u2-Uno-Rev3.hexに書き直した時の状態です。

テストのためのArduino-Unoのスケッチは次のように簡単に作りました。まだスイッチ部品との接続などは行っておらず、まずはUSBキーボードとして機能することの確認を行うのみです。USB-HID(ヒューマンインターフェイスバイス)キーボードではキーは同時に6つまで押せ、それにシフトやAltなどを加えた状態を識別しますので、送る信号は1バイトの0x00を加えた8バイト、そしてキーを離す信号も同じフォーマットの0x00を8バイト送ります。これを「レポート」と称します。HIDのアーキテクチャに従うため壮大な無駄?をしてますがHIDは遅いので何ら問題ないわけです。

 /* **************************************************
 *     USB-Keyboard for Arduino-UNO                 * 
 *     Test version V00    April 30, 2020           *  
 *     (c) Akira Tominaga, All rights reserved.     *
 ****************************************************     
 */
byte KbD[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
// KbD[0]=Modifier for USB Keyboard -code
#define rGUI B10000000  // right Windows key
#define rALT B01000000  // right Alt key
#define rSFT B00100000  // right Shift key
#define rCTL B00010000  // right Ctl key
#define lGUI B00001000  // left Windows key
#define lALT B00000100  // left Alt key
#define lSFT B00000010  // left Shift key
#define lCTL B00000001  // left Ctl key
// KbD[1] shoule always be 0x00
// KbD[2] to KbD[7] include scan-codes (max 6 codes)
//   Alphabet code = ASCII val-0x5D (from a=0x61 to 0x04)
#define Csub 0x5D       // Character value to subtract
//   Function key code F1=0x3A, F2=0x3B, etc
#define ScF1 0x3A       // USB KB code for F1 key
#define ScF2 0X3B       // USB KB code for F2 key
//   Space key code =0x2c  
#define ScSp 0x2c       // USB KB code for Space key

byte  Chr = 'a'-Csub;   // set initial key = a

void setup() { // Setup **************************
  Serial.begin(9600);
}
  
void loop() {  // Arduino loop ******************
  KbD[2] = Chr;
  KbWrite();
  delay(1); 

  Chr = Chr+0x01;
  KbD[2] = Chr;
  KbD[0] = 0x00+lSFT; // test modifier (Shift)
  KbWrite();
  delay(1); 

  Chr = Chr+0x01;
  KbD[2] = Chr;
  KbWrite();
  delay(1);
  
  KbD[2] = ScSp;  // Space key
  KbWrite();

  Chr = Chr+0x01;     // increase char code
  if(Chr>'z'-Csub){   // if exceeded 'z'
    Chr = 'a'- Csub;  // then re-set to 'a'
  }
  delay(3000); 
}
/********************************
 * *** User defined functions ***
 * *****************************/
// *** KbWrite()  write character as HID KB report
void KbWrite(void)
{
  Serial.write(KbD, 8); // make
  KbD[2] = 0x00;        // clear character
  KbD[0] = 0x00;        // clear modifier
  Serial.write(KbD, 8); // break
}

USB keyboardは 標準USB HID(ヒューマンインターフェイスバイス)として機能しますからドライバーの準備は不要です。差し込めば即USB keyboardとして働きますから、予めメモ帳などを開いておけばそこに文字が書き込まれていきます。上のプログラムではメモ帳に次のように出力されていきます。

f:id:a-tomi:20200430231628j:plain

 ここまでで少し長くなり、4月最後の夜も更けてきました。

少しおまたせすることになってすみませんが、ここまでで、UNOを使うやり方が大体ご理解いただけたかもしれません。文字コードの参照先や、この操作ボタンを使うとZoomホストの操作がどれくらい楽になるかなどを含めて、近日中に同じ題名(その2)を書きたいと思います。

当面はこの装置を試作して次のZoom会議に使うのが優先ですみません^^;

 

©2020 Akira Tominaga, All rights reserved.

 

 

番外編:モノには置き場を!時間は人生だ

パンデミックが長丁場になりそうです。ニュースなど見ていると貴重な時間があっという間に・・。

Zoom会議だけでできないことも多くて落ち着きませんが、この際はやれることに集中するのがいいかと気づきます。趣味の場の整頓などしている人は多いのではないかと想像しますので、今回はその勝手なやり方をご紹介することにします。

f:id:a-tomi:20200331214920j:plain

上の写真は勝手な電子工作コーナー(主にマイコン工房)で、20数年前の仕事が一番忙しい時代にこしらえた趣味の場所で、今でも楽しんでいます。時間のない中でこういうことを短時間でも楽しむには、日頃から整頓をするに限りますね。

この写真は5年くらい前に撮りましたが、今も状態が同じなので流用。狭いですが奥の方には卓上旋盤やミニフライス、テーブルソー、バンドソー、グラインダーやボール盤などもひととおり置いてあります。こういう道具をどうやって揃えてきたかは後で書くとします。大蔵大臣をどう賛同させるかがキー。

写っていませんが左手前には基板を迅速に作る愛用のCNCルーターがあります。ハンダごてなどをときどき取り替えたりしますが、上の写真に最近加わった小道具は温調ヒートガンぐらいかな、SMD用に。

目立つのは周囲に積み上げた電子部品のストックでしょうね。背面のロッカー内も使用頻度の高い部品の置場です。こうするとほぼ立ち歩かずにすぐ出し入れできるので。。こういうものは、もしかすると他人が見るとガラクタの山もしれませんが、本人にとっては宝の山です^^;

忙しい中で時間を大事に使うにはとにかく整頓するに限ります、空間も時間も。それを勝手に考えたわけではなく、偉人ベンジャミン・フランクリンを真似ただけ。ベンジャミンフランクリンは外交官、物理学者、著述家、電気学者、印刷出版業、そして政治家などこなした超多忙な人ですが趣味も楽しみました。勝手な13徳を定義し自分の習慣としたことでも有名。その第3は次です。

f:id:a-tomi:20200331222354j:plain

時間のない中で趣味を楽しむ目的で、部品がすぐ出し入れできるよう箱に収め置場が直ちにわかるようにする習慣が自然につきました。

f:id:a-tomi:20200331222858j:plain

コーナーを作った際、まずは河童橋に行って小さい使い捨て弁当プラ容器を200個購入。大きさは20cm x 10cm x 3~4cmです。この中に小さい部品をチャック付き袋に小分けして入れてます。たとえば次のように。その後、劣化した箱を取り換えたり増やしたりで200個を追加購入しましたが。

f:id:a-tomi:20200331223509j:plain

この例は左はポテンショメーター、右はインダクター。そして棚の中や引き出しに収めます。小さい部品類はこれでいいですが、もう少し大きい部品は中型の箱にし、次のような百均のプラスチック製道具入れ24cm x 14cm x 4cmを100個ほどを使用。

f:id:a-tomi:20200331223925j:plain

この中型箱の例は左は各値のツェナーダイオード、右は可変三端子レギュレータ。部品は小さくとも、抵抗など百個単位をシリーズで揃えるのは、やはりこの箱が使いやすい。次の写真は1/4W抵抗の例。

f:id:a-tomi:20200331224034j:plain

もっと大きな部品は、主に百均の大きめのプラ容器 34cm x 23cm x 5.5m に収めています。重ねられるのでだいたい70箱。その中を弁当容器で仕分けしたりして。

f:id:a-tomi:20200331224517j:plain

はみだすものは例外的な箱にいれ、その置き場所を書いたメモ紙を入れておきます。こうすれば忘れずにすむわけで・・

小分けしないのもありますが、そういう場合は、この大箱が大体ぱんぱんになるまで入れてしまいます^^;

f:id:a-tomi:20200331224840j:plain

上の例では、左はTM1637LEDディスプレイ、右は多ピンコネクターのワイヤー付き。

更に大きな部品、例えばステッパーや金具などは、それに見合うプラケースに入れて物置に収めます。作業しながらすぐ取り出すわけではないので。

さて、そういう箱の置場をどうやって決めているかといえば、大体前の方はツールに近いもの、後ろの方は部品をおくようにしています。例えば測定器類はもちろんですが、ACアダプター各種、無圧ソケット、電池ケースなどはツールに近いので前、ディスクリート部品などは部品そのものですので後方へ。中身を忘れないようにラベルや仮止めテープなどに書きつけて貼っておきます。ごく短時間でやるので綺麗にはできませんが。

 

ここまでで、①しまい方 の概略を書いたのですが、写真を撮りつつ書いていたらあっという間に寝る時間に。。

②道具をどうやって少しずつ揃えてきたか、そして ③やる時間をどうしてきたか についても書こうと思っていましたが、明朝は所用で早いため、残念ですが機会を改めてここに書き足すことにしたいと思います。

なお、②は次の書籍に書きました。③時間の使い方なども書いてありますが。

https://www.amazon.co.jp/dp/4822237400/

③時間の使い方は次の手軽なkindle本にも。

https://www.amazon.co.jp/dp/B079WNNHW8/

 では、中途半端ですみませんが、とりあえずはおやすみなさい。

========== 

ようやく週末がきました。以下に追加を書かせていただきます(2020年4月4日追加):

 まずは番外の記事の更に番外のことですが;新型コロナはますます心配に。感染数は対数にしないと傾向が明確にはわかりません。1昨日までの状態をそうしてみます。旧型BCGが予防に効いているとかの説を確かめたくて比較をしてみると、あまり関係なさそうに見えます(検査量が限られている日本も、これを見ると2週後はたいへんな状態に!!)。自然現象は嘘をつきません。お互いに十分気をつけたいもの。

f:id:a-tomi:20200405121129j:plain

 もう少し国を追加してみました(4月5日):

f:id:a-tomi:20200406204655j:plain

 雑談をいれてしまいましたが、以下は小題の ③時間の使い方  について勝手に書きます。 ②道具の揃え方(要するに大蔵大臣説得法) は一筋縄ではいきませんので番外記事がすごく長くなってしまいそうなのに気づき、とりあえずスキップさせていただきます^^; 

 

時間は場所よりも大切だと思います。ベンジャミンフランクリンはTime is money. と言いましたが、一生を考えれば時間はお金よりも大切と・・。

f:id:a-tomi:20200404202341j:plain

時間を上手に活用した偉人はたくさんいますね。日本では二宮尊徳新井白石などが有名ですし、ピータードラッカーも個人が使った時間の把握と使い方の工夫を力説しました。

気づいている人はたくさんいるでしょうし、いつ気付いても遅くない有益なことです!私はその昔、米国で会社の研修を受け、たまたまラーキン氏のお話などを聴くことができ、目から鱗でした!そのきっかけに今でも感謝、他の人に少しでも伝えるようにしています。人に言われないとなかなか気づかないことですから。

ここから先は勝手なやり方の紹介です。長くなる恐れがありますがご興味があればお付き合いください。面倒が嫌いな方は一番下の方の===の下の絵へスキップを。

==========

To-doリスト(やることを書いたリスト)を使うのは、忙しいビジネスマンにほぼ共通です。今では皆さんがスマホやITを使うのが普通ですが昔は紙のリストでした。"マルチプラン"が出た頃から私はパソコンに切り替え、勝手な形式で入れるようになりました。

f:id:a-tomi:20200404203535j:plain

やる事を入れると番号は自動採番、その活動への割り当て時間はいちいち入力します。数時間の活動の中のほんの1分だけと考えてこの操作をします。「何と面倒なことを!」と思う人が殆どでしょうが、習慣になると面倒とも何とも思わなくなります。

各項目は手掛けた都度、完了%と実績時間(最初はゼロがはいってます)を更新します。残り時間等はもちろん自動計算です。入力する時間は0.1~0.5時間単位のおおまかな記録ですが、こうすると色々気づきます。思っている時間と実際との大差とか^^; 現代では作業時間の測定ツールも色々ありますね。

個人用のTo-doリストは自分のためのものですから、どんな形式でも勝手なわけですが実例は次。下の方の青字はプロジェクトマネジメントのプロ向けの注記で、無視されて結構です。

f:id:a-tomi:20200404204507j:plain

 

済んだ古い項目は順次別シートへと送ります。これとは別の日程表と併せて使います。このTo-doリストを数十年にわたり延々と、実に1万1千項目目に至るまで 継続してきた後、最近試しに使用をやめてみました。そしたら大事な約束をすっぽかしたり、ととんでもない事ばかりおきています^^; 日程表は使っているのですが。

それはさておき、多忙なあるときから趣味の活動もこれに入れてしまうようにしました。そうしないと決してそれに時間を使うことができないからです!休みを取って家族旅行するなどは、ずいぶん前からそうして予定しないと絶対無理^^;

殆どの活動は数時間で終わるものなので、To-doリストだけで良いのですが、仕事でも趣味でも数十時間以上かけるものが時たまあります。そういう活動は、このリストだけでは計画もコントロールも無理です。別途、全体を数時間の単位に割って、別表を作りそれぞれを日程に割り当てます。もし長時間かかる趣味のプロジェクトがあるなら、一日の間にそれにかけられる時間はかなり限られますので、30分単位とか1時間単位程度に割って、別表(この先で説明する表)を作って数十日間に割り当てます。逆に、そうしないと仕事時間を大いにじゃますることになってしまいますから。

割った表はPMではWBS表というのですが、要するに活動の分解。

f:id:a-tomi:20200404205623j:plain

勝手な実例でお話すると、次は3か月かけて著作の原稿を作るプロジェクトです。1週間の中で10数時間だけをそれに割り当て、マイペースで予定期限までに完成するもの。

そのときの仕事の分解は最初のうちはこれ。

f:id:a-tomi:20200404210010j:plain

そして、活動3が終わった時点で4以降を分解し、次のWBS表に割り付けて計画しました。全体で176時間を割り当て、毎週だいたい14時間ずつやることにしました。こうするとマイペースで慌てずに、必ず予定期限までに仕上げることができます。

f:id:a-tomi:20200404210206j:plain

そして各週にやった実績(何時間分の内容ができたのか)と、それに実際にかけた時間を、週末に1度だけ記入します。それ自体は数分ででき負担にはなりませんが、もし計画を変えたところがあればいちいち表を直します。そういう変更は手間がかかりますが、これで得られる「ごりやく」には代えられません。次のようなことを自動的に集計・表示してペースをとるしくみなのです。

まず自動集計がされるのは次の表(EVM表)。

f:id:a-tomi:20200404211123j:plain

自動的に表示されるグラフは主に次の2つ。

1つ目は、今のペースで進めるとその仕事がいつ終わるかを示すグラフ。

f:id:a-tomi:20200404211409j:plain

上で、現時点は11月12日。このペースだと12月29日に終わると出ています。これを見ればペース配分を自分で調節できるわけです。初めに急ぎ過ぎて燃え尽きるとか、締切り間際に慌てるようなことがなくなり、心配もストレスも大幅に減ります。個人の大仕事をやり遂げるには一番便利なグラフといえます。

そして次の自動出力グラフは、このペースなら全部でいったい何時間かけることになるかの見積もり。共同仕事では大事でも、個人の場合はあまり活用しないグラフですが、目標に近づいているのが見えて励みにはなります。

f:id:a-tomi:20200404211650j:plain

やっていることを書きましたが、慣れてないとこれがいいと限りません。個人が好きなようにやればよいのです(プロジェクトマネジメントのプロなら世界共通のやりかたであるWBS+EVMをお勧め)。

数十時間以上の大きな仕事や趣味での大きなプロジェクトは、個人の場合年間でも限られた件数しかないかと思います。そういうもの以外の活動ならWBSなどは必要ありませんね。普通のことはTo-doリストだけで十分。リストアップするより、さっさとやる工夫こそが一番大事ですから^^; 先にやって後で記録することもしばしば。

やる気の維持を含め、もしもご興味があれば個人の進捗計画やコントロールについて、次の電子書籍をご参照ください。https://www.amazon.co.jp/dp/B079WNNHW8/

 

==========

目的が明確なら、手法を使おうが使うまいが、こつこつと進めると人生が充実しますし、その先に良い事が待っています。

f:id:a-tomi:20200404213129j:plain

結構長くなってしまいましたが、電子工作の番外編なのでここまでにしたいと思います。長々とお付き合いいただきましてありがとうございました。

 

©2020 Akira Tominaga, All rights reserved.

一番簡単なジュールシーフ( Joule thief )

このところ会合をネット開催に替えたり予定を延期したりと、新型コロナウィルスで皆さんたいへん、私もたいへん。これを契機に日本もDXが進めば・・。

そうこうしているとブログ記事が滞ってますがそうはいきませんね。あと数時間しかない今月、勝手な電子工作としては、今書けることを何か書いておきます。やりかけの工作や実験を沢山もっている^^; のでね。簡単なのを探すとこれがいいか。下の写真では、ほぼ使い切って0.90Vしかない電池でLEDを明るく点灯しています。

f:id:a-tomi:20200229224415j:plain

種明かしすれば、もちろん熱収縮チューブ内にジュールシーフ(エネルギー泥棒)回路が入っています。

ネットでjoule thief circuitを検索すれば大量にヒットして、次のような様々な回路が出ます。

f:id:a-tomi:20200229225600j:plain

どれもブロッキング発振させて低い電圧を上下に振らせることで、LEDを点灯させる仕組みです。そのためにトランス又はチョークコイルを用います。回路は色々工夫でき、今開けた箱からは過去に勝手に作った種々の実験回路が出てきます。

f:id:a-tomi:20200229225948j:plain

5年ほどまえに、同じ機能が安くて小さい4本足のICに収まっていることに気づき、そこからは回路を考える必要がなくなりました。そのICはYX805でしたが、その後YX8018とか別メーカーのQX5252とか同じ機能の4本足ICに多くの種類があるのに気づきました。どれも中国オリジナルのようで、太陽光電池でソーラーLEDライトを点灯させるためのICです。

f:id:a-tomi:20200229230501j:plain

データシートの例は次のようなリンク先にあります。

http://datasheetcafe.databank.netdna-cdn.com/wp-content/uploads/2018/06/QX5252F.pdf

http://www.datasheet39.com/download.php?id=912097

www.datasheet39.com

私が購入した時は1本あたり5円程度の廉価なICだったと思いますが、これがたいへん便利にできています。

単にジュールシーフ回路とする場合は、太陽光電池をつながず二次電池の代わりに古い電池を入れればよいだけです。

次のような回路となります。毎度手書きで汚くてすみませんが。

f:id:a-tomi:20200229231053j:plain

これだと外付け部品としてインダクタンス1本だけでOKです。データシートにインダクタンス別の消費電流などが記述されています。

ここでは実験をしてみます。たまたま手元にあるインダクタンスは次の種類です。値は実測値。

f:id:a-tomi:20200229231343j:plain

次の実験回路でこれらを入れ替えて、Lx点の波形(つまりLEDにかかっている電圧)をみます。

f:id:a-tomi:20200229231534j:plain

すると次のようになります。

まずは適切そうな88µHです。

f:id:a-tomi:20200229231757j:plain

発振によってVssよりマイナスにもなりますが、上側は2Vも超えており確実に点灯するわけです。

Lを極端に大きく1mH(実測は990µH)にすると、より明るく次のような波形で点灯します。上側の電圧(1.7V程度)でLEDが点灯しているのがわかります。というよりLEDがこのような電位差を作ります。下側は電流を消費しないので平になるわけだと思います。

f:id:a-tomi:20200229232112j:plain

極端に小さなLではどうなるでしょう?

次は僅か0.9µHの場合です。これでも点灯するのですから驚いてしまいますね。

f:id:a-tomi:20200229232739j:plain

デューティ比が小さいですがLEDは問題なく点灯します。大きなLの場合に比べれば暗いですが、かつて百均のソーラーライトを調べた際も、こんな感じの発振でした。

さて、目の前で実験しながら書いてきたら意外に時間がかかりました。このへんで公開をしておきたいと思います。

 

©2020 Akira Tominaga, All rights reserved.

 

 

いちばん簡単なドロボー除け(かな?)

 

f:id:a-tomi:20200131112155j:plain

古いマイコン(PIC12C509)のプログラムメモリーはEPROMですので、紫外線窓付き以外のモデルでは、プログラムを一度書き込んだら特殊な修正以外はできません。ICの上面にある4桁数字は製造年月(YYMM)です。というわけで20年前のこのマイコンはそろそろ捨てるかな?今どきこれが役立つ場面は?

このPIC12C509マイコンの場合、外付けRCでクロックを極端に遅くしさえすれば、電流の消費が小さいのが利点です。クロックを30kHz程度にすればわずか35µA程度しか消耗しないので、アルカリ単三電池が2年以上もちます。今回はこれにまつわるドロボー除け装置について書きます。

f:id:a-tomi:20200131133733j:plain

12C509Aを3Vで30kHzあたりで動かすとこんなもの

プログラム用にフラッシュメモリーを搭載した今のマイコンの場合は、単にクロックを遅くするだけでは電流の消費をそこまで抑えることができません。電池をなるべく長持ちさせたい用途の場合は、別途少し工夫がいります。

だいぶ昔ですが、新築し無防備だった我が家に空き巣が入りました。それに懲りてすぐに色々な防犯対策を施しました。外出時に雨戸を閉める(当たり前か^^;)だけでなく、敷地への侵入者を赤外線センサーで検知して警報を鳴らしたり照明をつけたり、防犯カメラで動くものを自動録画する、留守中の照明の自動操作をする、などあれこれです。そこでは勝手な電子工作が十分楽しめますが^^;  その中で一番簡単で役立つドロボー除け(のおまじない?)を紹介したいと思います。

f:id:a-tomi:20200131113844j:plain

道路からみえない庭側のガラス戸を上図のように破られ、クレセント錠をあけられました。よくあるパターンのようです。そして唾を付けた指で和室側の障子紙に穴をあけて(!)内部の不在を確認のうえで侵入(さすがプロだあ・・)。10分以内の短時間で家じゅうのひきだしや押し入れなど全てを物色、お金と金目の品だけを盗ってお帰りです。その後すぐに次の家を荒らしたそうな。このドロボーは半年後に捕まり、現場に引き回されてきましたが、関東広域どろぼうのプロとのことでした。捕まっても金品は何も戻らずで、以後は絶対入ってほしくないわけです。

防犯カメラは、壊されて侵入されたくはないので一目でわからないように4台設置してあります。自作の記録システムは大容量SDに動画を循環記録、必要な際は1週間遡ってみられます。ところが、記録を万全にすれば予防に役立つということにはなりません!

また、もしルーバー窓が壊されても、そこから中には侵入させないようにメカ(といっても金属棒)を取付てあります。しかし、そもそも侵入したいと思わせない予防装置もあるに越したことはありません

 最初に考えて作ったのは3V省エネで動く、4000シリーズCMOSインバーターを使ったLED点滅機。R1とR2でデューティ比や時間が変えられます。しかし、これだとLEDを一定のパターンでしか点滅できないので、その3年後にこれをマイコンで作り変えました。

f:id:a-tomi:20200203201516j:plain



マイコンだと一定間隔の点滅だけではなく、いかにも何か発見したような点滅が加えられますので、予防効果が一層大きいと思います。実は、見知らぬ人が家を覗き込み、これを見てすぐに立ち去るのが防犯カメラに写っていたことがあり、それでこの装置への自信が湧きました^^; 数年前にもこれを見て慌てて去る不審者が写っていましたのでなおさら。

f:id:a-tomi:20200131134305j:plain

f:id:a-tomi:20200131134901j:plain

当時の基板

これに単三電池2本をつけて、次のように当時のチューインガムケースに収めました。20年も使っていた装置なので傷だらけですが。

f:id:a-tomi:20200131134957j:plain

窓への置き方は次の絵のようにします。

f:id:a-tomi:20200131134810j:plain

これを作った数年後にプログラムを少し改良し、電池が3年以上もつように改善できました。なおEPROM内容が変更できないとはいっても、内部のビットが1であるものを0に変えることだけなら上書きすればできます。それに気づいて、これを利用してプログラム済みのものも定数がうまく更新できました^^。

この単純なドロボー除け装置を見た友人に是非とせがまれて、沢山作ってあげました^^ 相手も同じチューインガムの箱を用意するのがたいへんだったそうです。

f:id:a-tomi:20200131145158j:plain

f:id:a-tomi:20200131135153j:plain

さて、今回は年月が経ち自然に壊れてきたプラスチックのケースを更新したり数台を増設したりする必要がありました。

この際は基板も新たに作ろうと思い、試しに同じプログラム論理をPIC12F1822に入れてみました。ところが、クロックをいかに遅くしても案の定、電流が1桁増えます。フラッシュメモリーのマイコンではクロック速度の調整だけでは電池がとてももちません。

確定申告間近の今(1月末)、忙しい時機なのでやっぱり12C509のままにしようかといったん考えなおしました。しかし増設ぶんについては古いProgram Writerを引っ張り出して使い、RS232接続の為古いノートPCを出して・・と考えていると、やはりこの際新しい型で別の省エネ方法を考えた方がよいかなと考えなおしました。

省エネの方法としてはSleepさせて、それを定期的にWatch-dog-timerで目覚めさせる方法が一番簡単そう。PICにwatch-dog-timerを使ったことはありませんでしたが、モノは試しです。

前と同じ外付けRCで30kHzクロックの最小電流としておき、時間待ち論理の部分をSleep命令に入れかえました。Sleep中の電流を測ってみたら次のとおり、たったの18µA! PIC12F1822の通常ランの電流の1割といったところです。

f:id:a-tomi:20200131141257j:plain

PIC12F1822を30kHzで動かしSleep中の電流

これなら十分にいけますね。例えばですが、5秒中のLED点灯時間(例8mA)を5mSにすれば、無点灯時間の1000分の1の時間なので、平均消費電流はSleep時電流にその影響8µAを加算した26µAに抑えられます。よってこれまでよりもずっと省エネになります!

というわけで次の回路にします(同じですね^^)

f:id:a-tomi:20200131143618j:plain

強いて違いをあげれば、OSC2ピンにクロック信号を出力している点です。クロック周波数が一目でわかるテスト端子となるためとても便利です。

あのチューインガムはもう販売されていないので、箱は次のものを百均で調達。自家製用プリンの入れ物とかで、半透明で密閉でき、風呂場など水がかかる場所でも安心。しかも4つで百円。早速に採用です。

f:id:a-tomi:20200131144100j:plain

これに合わせて基板を作成。今回は基板のほとんどは電池ケースをとりつける面積が占めます。このほうが製作が楽で速いですからね。

f:id:a-tomi:20200131144144j:plain

電池ケースに合わせて穴あけし、ピンをを刺します。

基板の出来上がりは次。

f:id:a-tomi:20200131144324j:plain

ところがです。プラスとマイナスが違っているのに気づき、急きょルーターでパターンをカットして極性を入れ替えました。電池ケースのメーカーにもよるようですが、みっともないですね^^;

f:id:a-tomi:20200131144437j:plain

そして以後のために基板のデザインを修正。秋月でうっている基板用電池ケースに合わせました。なお、固定ネジ穴ははんだ付けの後で、現物に合わせてあけるほうが正確でいいですね。

f:id:a-tomi:20200131144609j:plain

プリン入れのケースに収めれば出来上がり、すきまには適当なスポンジ。とりあえず最初の2個です。プログラムは記事の後ろのほうにつけておきます。また電池が見えないように黒い紙でも入れておくと良い感じですがなくてもよいですね。

f:id:a-tomi:20200131144755j:plain

f:id:a-tomi:20200131144844j:plain

今後は傷んだものからこれに順次取り替えていくことにします。

やっぱりプログラムがいじれるフラッシュメモリーがよいですね。新しい方が値段も安いし圧倒的に高機能ですし。

f:id:a-tomi:20200131145602j:plain

とはいえ前のEPROMマイコンの用途はまだあるかもしれない、、、と考えていて捨てる気にはなりそうもありません。大した場所も取らないし。

以下、その後にPIC12F1822で複数個組み立てたのでその製作について追加で書きます(追加2020年3月15日)。

今回、正しい基板を1回で6枚作って組み立て、上で説明したプリンカップの容器に入れ、昔の古い防犯器すべてをこれに交換しました。LEDは十分明るく点滅するのでプログラム中の点灯時間をだいぶ減らし、さらに省エネとなりました。最新プログラムをはこの記事の最後につけておきます。

次の原稿は基板を6枚並べたもの。

f:id:a-tomi:20200315181744j:plain

これを使ってCNCルーターで生基板を削ります。

f:id:a-tomi:20200315181857j:plain

そしてカットしたのが次の写真です。

f:id:a-tomi:20200315182014j:plain

今回は手動で穴あけしましたが、少ないので全部で10分もかからず完了。

はんだ付けも30分ほどで終わり。テスト済のパターンですから問題ないと思いますが、はんだ付けの点検として念のために電源配線の抵抗値だけをチェックして異常なしを確認。 

f:id:a-tomi:20200315182228j:plain

そしてPIC12F1822を6枚プログラミングして挿入したら基板のできあがり。

次の写真は出来上がりを部品面から。なお電池ケースは、まず端子を基板に挿入してから位置合わせをして穴あけするとぴったりに組み立てできますね。なお、ネジは2mmφのプラスチックねじです(秋月で売られています)。どの基板も一発で問題なく稼働しました。

f:id:a-tomi:20200315182637j:plain

これをプリンカップに収めますが、内部でがたつかないように、隙間テープを適当に貼ります。隙間テープは色々ありますがどれでもいい感じです。今回は右上の発泡ウレタン製のありふれたを適当にカットして使用しました。

f:id:a-tomi:20200315183000j:plain

半日もかからずに6個が完成できました。

f:id:a-tomi:20200315183035j:plain

これで置き換えましたので防水バッチリ。風呂場の窓でも安心です^^。

 

最後にプログラムをつけておきます。20年前に作ったPIC12C509のプログラムをそのまま使い、PIC12F1822で動くように少し変えただけです。論理は同じで、待ち時間を消耗する部分をSleepにおき換えたもの。環境設定やデバッグ機能などは最近のPICデバイスでいつもやっているとおりのコピペです。 

なお、プログラムは最新版に更新をしておきます(2020年3月16日)。


;U2001-Wblinker-12F1822-V03s.asm		   	     As of Mar. 16, 2020
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;										;
; 	Warning Blinker for PIC12F1822  	Initial Version Jan.26, 2020	;
;	        (c)1999-2020 Akira Tominaga, All rights reserved. 		;
;		V02: Shortened LED-on time from 8mS to 6mS. Feb.21, 2020	;
;		V03: Adjusted 1mS (from 5 GOTOs to 3 GOTOs) Mar.16, 2020	;
;		     Changed short WDT from 512mS to 256mS  Mar.16, 2020	;
;										;
;	  Function								;
;		Blink LED with sleep for small energy consumption		;
;		(Upgraded from 12C509(without sleep) to 12F1288(with sleep)	;
;										;
;	  Input/Output for 16F1823						;
;		RA0 LED output (on =H)						;
;		RA4 Osc2 for Clock output (CLKOUTEN_ON)	for test purpose	;
;		RA5 Osc1 for _EXTRC connection					;
;	  Remarks								;
;		1. Clock = EXTRC (as slow as possible)				;
;		   R=100kΩ, C=100pF → f=30kHz	(500 x time of 16MHz clock)	;
;			Hence 1 step ≒ 125μS					;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	page
	list		p=12F1822      ; list directive to define processor
	#include	 ; <p12F1822.inc>specific variables
    __CONFIG _CONFIG1, _FOSC_EXTRC & _WDTE_SWDTEN & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_ON & _IESO_OFF & _FCMEN_OFF
    __CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_19 & _LVP_OFF
;
	page
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 	Macro definitions						;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 	Device dependent Macros	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
DEVset	macro	
	BANKSEL	OSCCON		; Bank=1
	movlw	B'00000000'	; Clock determined by Configuration Word 1
	movwf	OSCCON
;
;	BANKSEL	INTCON		; Interrupt Con (in all banks hence comment)
	clrf	INTCON		; Disable all interrupts
;
; PORTA initialization
	BANKSEL	PORTA		; Bank=0
	clrf	PORTA
	BANKSEL	LATA		; Bank=2
	clrf	LATA
	BANKSEL	ANSELA		; Bank=3
	movlw	B'00000000'	; No use of Analog input
	movwf	ANSELA
	BANKSEL	TRISA		; Bank=1
	movlw	B'11101110'	; RA0 and 4 are output
	movwf	TRISA
;
	BANKSEL	ADCON0		; Bank=1
	clrf	ADCON0		; No use of ADC	
;
	BANKSEL	OPTION_REG	; Bank=1
	bcf	OPTION_REG,7	; Enable weak pull-up
	BANKSEL	WPUA		; Bank=4
	movlw	B'00001000'	; Weak Pull-up for RA3
	movwf	WPUA		;  
;
	BANKSEL WDTCON		; Bank=1
	clrf	WDTCON		; WDT is set by program
;
	clrf	BSR		; Bank=0		
	endm
;	
OUTini	macro			; L for LEDs, and H for Clk, Dio
	nop			; Timing for PORTA
	movlw	B'11001000'	; Set RA0 zero
	movwf	PORTA
	goto	$+1		; Timing for PORTA
	endm
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	I/O macros			;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 	For general purpose	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
OUTon	macro			
	bsf	GPIO,Out
	endm
;
OUToff	macro			
	bcf	GPIO,Out
	endm
;
WDTonL	macro			; Set long WDT
	BANKSEL	WDTCON
	movlw	B'00011001'	; Enable 4 sec WDT
	movwf	WDTCON
	clrf	BSR
	endm
;
WDTonS	macro			; Set short WDT
	BANKSEL	WDTCON
	movlw	B'00010001'	; Enable 256mS WDT
	movwf	WDTCON
	clrf	BSR
	endm
;
WDToff	macro			; Off WDT
	BANKSEL	WDTCON
	bcf	WDTCON,SWDTEN	; Disable SW Watch Dog Timer
	clrf	BSR
	endm
;
LEDon	macro			
	OUTon
	endm
;
LEDoff	macro			
	OUToff
	endm
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Constant time consuming		;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Rm1	macro	Rm1p		;Consume 1 mS x n
	movlw	Rm1p
	call	Rm1r
	endm
;
Rm250	macro	Rm250p		; Consume 250mS x n
	movlw	Rm250p
	call 	Rm250r
	endm
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Debug macros				;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Udebug	macro 	Addr
	movf	Addr,W
	call	Udbgr
	endm
;
Ublink	macro	bno			; Blink LED for specified times
	movlw	bno
	call	Ublinkr
	endm
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 	Files and Equations					;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Files				;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	cblock	H'20'		; available from H'20' to H'6F' (80 bytes)
;
; For application
	Rm1c
	Rm250c
;
; Areas for debugging routine
	DmpA 		; Display byte area 
	Dmp8C 		; Bit counter for loop (Initial Dmp8V =8)
	BlinkC 		; Counter for blinking (set for Debugb or Abendb)
;
; Both for debugging and for application
	Flags		; Flag byte
;
	endc		
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 	Equations			;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 	For logical GPIO port	; ** Change when PORTs changed **
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GPIO	equ	PORTA		; GPIO is for 12C509
Out	equ	0		; Output
LED	equ	0		; LED
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 	Flags Byte		;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LEDsv	equ	0		; LED save bit for debug
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 	For Debug		;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Dmp8V	equ	D'8'		; Debug display bit counter initial value
Debugb	equ	D'8'		; number of blinkings to show Debugging
Abendb	equ	D'30'		; number of blinkings to notify Abend
;
	page
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Initializing						;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	org	0
	goto	Startp		; Go to start entry
	org	4		; This is Interrupt entry
	retfie			; 
;
Startp	DEVset			; Define ports
	OUTini			; L for LED(0), and H for Clk and Dio
	OUTon			; Indicate I am awake
	Rm250	2		;  for a half second
	OUToff			;
	Rm250	D'8'		; Wait for 2 seconds
	clrf	Flags		; Clear Flags byte
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Main program					;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Mainp	equ	$
;
;Step1	Blink LED once and wait 4 seconds
	WDToff			; Off watch-dog-timer
	OUTon			; Blink LED once
	Rm1	6		; for 6mS
	OUToff
	WDTonL			; On watch-dog-timer long
	sleep			; This includes clrwdt
;
;Step2	Blink LED once again and wait 4 seconds
	WDToff			; Off watch-dog-timer
	OUTon			; Blink LED once
	Rm1	6		; for 6mS
	OUToff
	WDTonL			; On watch-dog-timer long
	sleep			; This includes clrwdt
;
;Step3	Blink twice with 0.5 sec sleep and wait 4 seconds
	WDToff			; Off watch-dog-timer
	OUTon			; Blink LED 1st time
	Rm1	6		; for 6mS
	OUToff
	WDTonS			; On watch-dog-timer short
	sleep			; This includes clrwdt
	OUTon			; Blink LED 2ndt time
	Rm1	6		; for 6mS
	OUToff
	WDTonL			; On watch-dog-timer long
	sleep			; This includes clrwdt

	goto	Mainp		; Loop forever
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 	Make about 1 mS x n (Rm1 macro)	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Rm1r	movwf	Rm1c		; 
Rm1l	goto	$+1
	goto	$+1
	goto	$+1
	decfsz	Rm1c,F		; 
	goto	Rm1l		; 
;
	retlw	0		; return (for 12C509)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	250 mS x n	(Rm250 macro)	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Rm250r	movwf	Rm250c 		;
Rm250l	Rm1	D'250'		;
	decfsz	Rm250c,F	;
	goto	Rm250l		;
	retlw	0		; return (for 12C509)
;
	space
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; User debug subroutine		;
;	Show bit 7 to 0 	;
;	of specified area	;
;	by Udebug macro		;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Udbgr	clrf	BSR		; Set Bank=0
	movwf	DmpA		; move data to Dmpa
;
	btfss	PORTA,LED	; Check if LED=on (on=High)
	goto	UdbLoff		;  if LED=off(Low), skip saving process
	bsf	Flags,LEDsv	; Save LEDon status
	LEDoff			; and off LED
	Rm250	D'4'		; wait for 1 sec in case LED has been on
;
UdbLoff	movlw	Dmp8V		; set counter 8
	movwf	Dmp8C		; to Dmp8C
;
Udblp	Ublink	Debugb		; Blink for Debugging = 8 times
	btfsc	DmpA,7		; check top bit 7
	goto	UdbOn		; if on then to UdbOn
	goto	UdbOff		; if off then to UdbOff
;
UdbOn	LEDon
	Rm250	D'20'		;
	goto	Udbeck
;
UdbOff	LEDoff
	Rm250	D'5'		;
;	goto	Udbeck
;
Udbeck	decfsz	Dmp8C,F
	goto	Udbnext
	goto	Udbend
;
Udbnext	rlf	DmpA,F
	goto	Udblp
;
Udbend	Ublink	Debugb		; end blinking and 
	Rm250	D'12'		; blank for 3 seconds to write down
;
	btfss	Flags,LEDsv	; Check if LED was on
	goto	Udbret		;  no, goto return
	LEDon			;  if it was on, then on again
	bcf	Flags,LEDsv	; Clear LED save flag
;
Udbret	return
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Blinking to show debug or abend	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Ublinkr	movwf	BlinkC
Ublinkl	LEDon			; LED on
	Rm1	D'10'		; for 10ms
	LEDoff			; LED off
	Rm1	D'50'		; for 50ms
;
	decfsz	BlinkC,F
	goto	Ublinkl
	return
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	End of program						;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	end

 以上、簡単に書きましたが、もしドロボー除けのご参考にでもなれば幸いです。

 

2022年8月24日追記:

2年半以上にわたり全部そのまま使っていますが、電池を一度も取り替えていません。まだまだ明るく、電池電圧はまだ2.99V以上あります。この分なら3年以上は軽くもちそう。また、どれにも液漏れ等が全く生じていないのは驚き。こういう使い方だとアルカリ電池はダメになりにくいのかもしれませんが、理由はわかりません。とにかくびっくりです。

 

2023年7月19日追記:

驚きです!2019年1月から3年半以上過ぎましたが電池を1度も代えずに、どれも明るく問題なく動いています。相変わらず電池の液漏れ等も生じていません。12本どれもOKということは、こういう時々ピクっと流す使い方ならダメになりにくいのかとますます思えます。百均の電池がよいのか?電池を変えてみたいですがここまで来たなら続けたい。いつ交換が必要になるかな?

 

2024年2月4日追記:

実に4年を過ぎたのに、どれも問題なく稼働中。12個全部です、驚きましたね。こういう使い方だとアルカリ電池が24本はどれも液漏れしないのに驚くばかり。どこまで行けるか試したく、どれも電池を替えずこのままにします。

 

  ©2020 Akira Tominaga, All rights reserved