まごころせいじつ堂

浜町庄金 研究開発  マイコンで遊んでばっかりで

Leonardo

ロータリーエンコーダ実験

 半年くらいまえにちょっとやってうまくいかず放置していたロータリーエンコーダの実験、うまくできたので整理。

環境:MacOSX 10.10 / Arduino IDE 1.0.6 / Seeeduino Lite(Arduino Leonardo互換)

ロータリーエンコーダはA相とB相の状態を見て回転方向を調べる。C端子はGND、AとBは10KΩでプルアップすることになっているが、ピンのプルアップ設定でよい。

2014rot1

コードは以下を参考に少し変えた。A相の変化で割り込みを使ってBの変化を読み方向を決める方式。
Leonardo系はpin2の割り込み番号がUNO系の0と違って1なので注意。

ロータリーエンコーダーを使ってみる(忘れないページ)
arduinoでロータリーエンコーダを使う (創ったり投げたり。)

https://gist.github.com/houmei/6524d5254652c7460a6e

私の環境では大量のテキストを連続してArduino IDEのシリアルモニタに送るとArduino IDEが応答なしになってしまう現象があった。なので、適当にdelay()を入れ、数値も変化した場合のみ送ることにした。
元のソースでは回転方向を'R'、'L'でいったん記録し、続くif文で++または--している。'R'を+1、'L'を-1にして続きでそのまま加算してやれば簡単になると思って改変したら'R'方向(ClockWise)の動きが渋くなってしまった。なんでプラス方向だけスッポ抜けることがあるのか不明だが調査保留とした。

追記:
Arduino IDE1.0.6の最新ファームを純正Arduino Leonardoに書き込んで実験→再現。Arduino UNOでも再現。

 さて以前やったときなぜうまくいかなかったか。ひとつはロータリーエンコーダの理解不足でカチカチと動かした時にA相B相の状態が固定になると思っていた。しかしクリックできる所で止まるとA,BともCとの接続はOFFになる。
 もうひとつはロータリーエンコーダによる端子配列の違い。

 これは上からC,B,Aの順。秋月電子のキットから流用したもの。
2014rot2

 これは上からB,C,Aの順。どこで買ったか忘れた。最近見かけるLED内蔵の透明な軸のタイプもこれ。
2014rot3

 これを間違って配線すると、片方向にしか回らないという現象が発生する。


メモ:arduino MsTimer2の上位FlexiTimer2

 arduinoでタイマ割り込みが必要な時はMsTimer2を使ってきたが、32U4を使っているArduino Leonardo系ではコンパイルできない。が、探したらあった。FlexiTimer2というのを使う。

http://playground.arduino.cc/Main/FlexiTimer2


 Teensyというのが書いてあるが、Teensy2.0は32U4を使ったボード。ということでやってみたら動いた。MsTimer2での書き方がFlexiTimer2でもそのまま使えた。

メモなんで詳細略。すまん。

Arduino Leonardo/Micro互換のPololu A-Star 32U4 Micro

 A-Star 32U4 Microは超小型のArduino Leonardo/Micro互換マイコン。
A-Star 32U4 Micro
(スイッチサイエンス)

A-Star 32U4 Micro(Pololu)

 Arduino Microより小さい。ピンアサインはこちら。
A-Star 32U4 Micro PinAssign

 ピンの一部を出さないことでサイズを小さくしている。Digital13はLEDのみで、Analog2-5はない。32U4だと一部のDigitai端子にアナログ入力が割り当てられるので、使いたければこちらを使用するという考え。
2014pololu

これまでの選択肢としてはこういうのがあった:
Arduino Micro
Pro Micro 5V/16MHz
ダヴィンチ(ストロベリーリナックス)
32U4ブレークアウト
(スイッチサイエンス)

A-Star Programmable Controllersの仲間にはArduino Microと同じサイズのものがあり、動作電圧のバリエーションがある。

以下はA-STAR 32U4 MicroのUSB情報。

Pololu A-Star 32U4:
  製品 ID:0x2300
  製造元 ID:0x1ffb
  バージョン: 1.00
  速度:最高 12 Mb/秒
  製造元:Pololu Corporation
  場所 ID:0xfd120000 / 4
  利用可能な電流(mA):500
  必要な電流(mA):500
 


Arduinoで任意のUSBコードを送る 解決編

 Arduino Leonardo/MicroはUSBキーボードとして使えるが、Usageコードが101より大きいものは無視されるという問題があった。
PS/2キーボード変換器の製作(18) USBキーボードの無視されるキーについて
対策箇所はわかっていたが、当時はバイナリにパッチするという手段しか思いつかず強引にやっていた。
PS/2キーボード変換器の製作(19) HEXファイルにパッチを当てる
 この後、Arduino IDEのフォルダ内にあるソースをいじると反映されることを知った。Arduino IDEは毎回ソースから全部ビルドしてたのか!コアな部分はコンパイル済と勝手に思っていた。
Turning an Arduino Leonardo into a joystick.(Imarginary Industries)
 この記事ではUSBAPI.h、HID.cppを修正することによりジョイスティックのUSB-HIDを追加している。ということはArduino IDEにあるHID.cppのHID Report Descripterを修正することで日本語キーボードの機種で¥マークなどを入力できるようになるはずだ。
MacOSXだと修正対象のソースはContents/Resources/Java/hardware/arduino/cores/arduino/以下にある。
https://gist.github.com/houmei/2ad9f7a713f46149e72f

HID.cppを差し替え、ライブラリを組み込む。このライブラリはHID.cpp/USBAPI.hと一体化もできると思うが以前作ったのをそのまま流用しているのでこうなっている。

2014shot1
 これはDavinciにArduino Microのファームウェアを書き込んだもの。pin4にスイッチを付けてフリスクの大きめのケースに入れてみた。たったこれだけ。日本語キーボードがついてるものがWindowsXPの古いノートPCしかなかったのでそれに接続して¥マークが入力できることを確認した。

https://gist.github.com/houmei/0ac6873618caa02f22b4

 USBキーボードのUsageコードについては以下からどうぞ。注意点としてUSキーボードのレイアウトが基準。
USB HID to PS/2 Scan Code Translation Table

 ああ、これで数年悩んでた問題が解決だ。変なバイナリパッチ作った時点で誰も突っ込んでくれないのね。


 ついでにPrint ScreenのUsageコード(0x46)を設定して最近話題のエビデンス画面スクリーンショット用ボタンにしてみた。これでハードコピー取り放題よ。
2014shot2

 

Adafruit 1.8" TFT Shield用ゲタ

 Adafruitの1.8" TFT Shield、SPI関係の信号線をICSP端子からではなくArduino UNOのD13、D11から取っているのでそのままではArduino LeonardoやDueで動かない。そこで端子を変換するゲタを作った。

2014tftshield1


(1)Arduinoのバニラシールドは、ICSP端子の部分が使えるものを選ぶ。秋月電子扱いのものは該当部分に穴がない。
(2)ピンヘッダのうち、D13(SCLK)、D11(MOSI)、D10(CS)はピンを曲げて下のシールドに刺さらないようにする。
(3)バニラシールド上のD13をICSP端子のSCLK、D11をMOSIに接続。D10はD9にハンダ付け。
※D10はD9とICSP端子の横にジャンパで接続が切り替えられるようにしているが、これは86DuinoのハードウェアCSに繋ごうと思ったため。
※手抜きでメッキ線の空中配線しています。


2014tftshield2


 このようにArduino DueでハードウェアによるSPIで動作。Arduino DueはSPI.setClockDivider()の指定が数値で、SPI.setClockDivider(2);とすると動作クロック÷2=42MHzとなる。しかし、Adafruit 1.8" Shieldのレベルコンバータの仕様で10MHzが上限とあった。動作クロックは観測していない。

Arduino Due Hardware SPI (The 21st Century Digital Home)

 なお、Arduino Leonardo、86Duinoでの動作も確認できた。
2014tft86duino



Arduino用バニラシールド基板ver.2(黒)Arduino用バニラシールド基板ver.2(黒)

スイッチサイエンス
売り上げランキング : 204199

Amazonで詳しく見る
by G-Tools
Arduino用バニラシールド基板ver.2(赤)Arduino用バニラシールド基板ver.2(赤)

スイッチサイエンス
売り上げランキング : 298693

Amazonで詳しく見る
by G-Tools
Arduino用バニラシールド基板ver.2(緑)Arduino用バニラシールド基板ver.2(緑)

スイッチサイエンス
売り上げランキング : 349393

Amazonで詳しく見る
by G-Tools
Arduino用バニラシールド基板ver.2(青)Arduino用バニラシールド基板ver.2(青)

スイッチサイエンス
売り上げランキング : 125733

Amazonで詳しく見る
by G-Tools
Arduino用バニラシールド基板ver.2(白)Arduino用バニラシールド基板ver.2(白)

スイッチサイエンス
売り上げランキング : 134964

Amazonで詳しく見る
by G-Tools

Adafruit 1.8" TFT ShieldをLeonardoで使う(SoftSPI)

※サンプルスケッチをしばらく実行しているとハングします※
→解決 microSDカードのせい http://blog.livedoor.jp/hardyboy/archives/7270159.html

 TFTシールドの続き。Arduino UNOではそのまま動くがLeonardoでは動かない。シールドの端子がハードウェアSPIに決め打ちになっているせい。これをソフトウェアSPIでやった。

Adafruit 1.8" 18-bit Color TFT Shield w/microSD and Joystick

シールドでの端子は以下の様になっている。
#define sclk 13
#define mosi 11
#define cs   10
#define dc   8
#define rst  0
#define sd_cs 4
ジョイスティックはアナログポートA3。


さて、以下のように書くとエラーになってしまう。TFT.hとTFT.cppはAdafruit_ST7735.hを呼び出しているが、ソフトウェアSPIを呼び出す5引数の部分の記述がないから。
TFT screen = TFT(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
以下に差し替え用のTFT.hとTFT.cpp、画面に線を引くサンプルを作った。

https://gist.github.com/houmei/1ec877f60f20c9d45a6e

 ソフトによるSPIは遅そうなので描画時間を測定した。線1本を引く時間はこのような差があった。

 Arduino UNO / ハードウェアSPI 8.65ms
Arduino Leonardo / ソフトウェアSPI 39.5ms 

2014SPIline 

追記:サンプルのスケッチ、Leonardo用はSerialコンソールを開いてないと先に進みません
ー以下解決ー
追記2:Arduino IDE1.5.6-r2にてMEGA2560互換機(Sinesmart)、Arduino DueはソフトSPIにて動作。
ただし両方共しばらく経つとハングする。(Leonardoも)

 ハングするとこうなる。Arduino Leonardoで4分46秒後に発生。
 Arduino UNO / ハードウェアによるSPIでも約1分で発生し、再起動するような挙動。TFTライブラリ?
2014softTFThang
 

Leonardo互換のSeeeduino LiteとGrove OLEDテスト


 Seeeduino Lite (スイッチサイエンス) 1995円。同社扱いのArduino Leonardo 2835円とくらべて安い。
黄色いコネクタと白いGrove用コネクタは自分でハンダ付けする。
特徴として、3.3V/5V切り替え、I2CとシリアルのGroveコネクタ、半ピンずらしたコネクタ取り付けのパターンあり。

 MacOSX 10.9.1 + Arduino IDE 1.0.5で動作確認。

 Seeeduino Lite Wiki
2014leo



 このままだとちょっとつまらないのでGroveを使ってみる。Groveは4ピンコネクタを使用するセンサ類を接続するSeeedStudio独自の規格。最初、右側のシリアル端子にシリアル用LCDを接続して試してみたが、Seeeduino Liteでは1,2番ピンに接続されている。これはATMega32U4のハードウェアシリアル端子なので、ライブラリに付属しているexamplesでは動かないようだ。
 そこで左側のI2C接続端子に128x64 OLEDを接続してみた。

GROVE System

Grove - OLED Display 0.96"

2014leo2 

 これは簡単、ライブラリをインストールしてArduino IDEを再起動、サンプルスケッチを呼び出してみただけ。
 

Arduino Leonardo用 USB-HIDの書き換えメモ、その他

 この記事、Arduino Leonardoでどうやって標準ではないUSB-HIDジョイスティックを入力可能にしているのかと思っていたら:
ゲームコントローラー cubic9.com

Turning an Arduino Leonardo into a joystick.

USBAPI.hとHID.cppを差し替えるだけだったのか! バイナリにパッチ当ててたよ……


以下、今月のメモ
HID-class USB Serial communication for AVRs using V-USB

Arduinoで物足りなくなっちゃった方へ。Cypress CY8CKIT-042 PSoC 4 PIONEER KIT
DA4121 PSoC 4 PIONEER KIT 共立エレショップ
Fubarino SD Development Board MICROCHIP PIC32MXのボード

mbed LPC1114FN28で8桁7セグLEDモジュールを制御してみた きょうのかんぱぱ
AVR用ISP変換ケーブルふたたび ikkei blog
Raspberry Piクイックスタートアップガイド (日本語) 
日本語音声認識  cubic9.com
ATmega32U2でArduinoモドキを作る  kosaka lab
Freescale,ノイズ耐性などに優れた5V電源仕様のARM Cortex-M0+マイコンを発売  5V系ARM
FRDM-KE02Z: Kinetis EシリーズFreedom開発プラットフォーム 
Cyclone V GX Starter Kit $179。DE0の次はこれか?
VFDとは
3V-5V switchable I2C Real Time Clock Shield
Marcelo Barros / This repository is a program ArduinoShieldSPI
ASOOVU USB

たぶん最後のカイゼン LEDのチラつきをなくしキー入力を確実に

 以下の続き。

 カイゼンCookieClicker用自動マウスクリック(TimerOne割り込みによるキー読み取り)  

Arduino Leonardoでマウスクリック/クッキーを自動的に焼く装置(マウスクリック99回/秒、設定変更可能)

 残り、気になっている点は7セグメントLEDのチラつきと、クリック送出開始・送出終了のキー反応が敏感すぎること。一回確実に押しっぱなしにしてON、離してから次に押しっぱなしにしてOFFのような動作にしたい。

 LEDのチラつきは表示を消してから書いているためで、値が変わらなければ表示の更新もしないことで解決。BASICでゲーム作る時は移動先にキャラクタを描いてから元のキャラクタを消さないとちらついてましたね。

 送出開始・終了は、割り込みルーチン内で直前は押していない、現在は押している状態を認識させればよい。押しっぱなしでも記録されるのは1回だけ。これでかなり操作性が良くなった。
 なおディレイ間隔の増減は押しっぱなしで連続的に変化してもらいたいためそのままとした。

  key=digitalRead(CBTN);
  if (key==LOW && Psend==HIGH) Send=1; // Press
  Psend=key;
 
ソースはこちら:
https://gist.github.com/houmei/6627272

現在、4.5GcpsでUncannyClickerのarchivementを得た。
 

カイゼンCookieClicker用自動マウスクリック(TimerOne割り込みによるキー読み取り)

前回作った
Arduino Leonardoでマウスクリック/クッキーを自動的に焼く装置(マウスクリック99回/秒、設定変更可能)
が大変雑だったので、スケッチを作りなおした。

 どのへんが雑だったかというと:
(1)ループ内でキーを読み込んでいるため、ループ回数などが簡単にいじれずキーの反応も悪い。
(2)1000回ループのうち指定した回数を最初の方に1ms間隔でマウスクリックを押し込めたのでどうもよろしくない(ブラウザが固まることがある)

 特に操作感が悪かったのでキー入力を取りこぼさないようタイマ割り込みで読み取り、グローバル変数に結果を置き、メインのループでそれを参照するようにした。また、マウスクリック(1ms)+指定したms何もしないで待つ、という動作を繰り返すようにしてなるべくマウスクリックを一定間隔にあけられるようにした。このため、7セグLEDでの表示は待ち時間のmsに変更。つまり数値が小さいほど時間あたりのクリック数は多い。

ソースはこちら:
https://gist.github.com/houmei/6611030 

 タイマ割り込みについてはTimerOneライブラリを使用する。これはArduino Leonardoにも対応している。動作は簡単に言うとBASICのON TIME GOSUB 行番号。通じた?

 TimeOneライブラリを使用するにはsetup()内で初期化する。

  Timer1.initialize();
  Timer1.attachInterrupt(readkey,30000); // 30ms 

これで30ms間隔でreadkey()関数を呼び出す。

 readkey()関数はプッシュボタンの状態を呼び出す。直前のボタンの状態と比較し、押されていたらグローバル変数Up,Down,Sendを1に設定する。これはボタンのチャタリングを除去するため。Up,Down,Sendはloop()内で読み出したら0にクリアする。

volatile int Send=0;
volatile int Up=0;
volatile int Down=0;

volatile int Psend=0;
volatile int Pup=0;
volatile int Pdown=0;

void readkey() {
  int key;
  key=digitalRead(ABTN);
  if (key==LOW && Pdown==LOW) Down=1;
  Pdown=key;
  key=digitalRead(BBTN);
  if (key==LOW && Pup==LOW) Up=1;
  Pup=key;
  key=digitalRead(CBTN);
  if (key==LOW && Psend==LOW) Send=1;
  Psend=key;
}

 さて、ちょっとはまったのが noInterrupts()と interrupts()。これらは割り込みを抑止/許可するのだが、Mouse.click()以前にnoIntterrupts()状態だとクリックが送出されない。つまり、USBのHIDマウス/キーボードを使うときには割り込みを許可しておかなければならない。
 
 で、だいぶ操作感は改善されましたよ。

2013cookieclick3




現在3.5Gcps (cookies per second)

http://orteil.dashnet.org/cookieclicker/ 



Arduino Leonardo (ソケット・ヘッダ付き)Arduino Leonardo (ソケット・ヘッダ付き)

Arduino
売り上げランキング : 38773

Amazonで詳しく見る
by G-Tools

Arduino Leonardoでマウスクリック/クッキーを自動的に焼く装置(マウスクリック99回/秒、設定変更可能)

 なぜか今日ツイッターの自分のTLで突然流行り始めたクッキークリッカー。最初はクッキーをクリックするだけだったのが……
http://orteil.dashnet.org/cookieclicker/

 常にクリックするのも面倒なので、勝手に連続クリックするのを作ってみた。マウスクリックの代わりはArduino Leonardoを使えば簡単にできそうだ、ということでその辺にある物で作ってみた。

https://gist.github.com/houmei/6572149

2013cookie


 Pin8,9,10にタクトスイッチを接続。もう片方はGNDへ。
 表示はシリアル接続7セグメント4桁LED(赤)を使ったけどクリック動作には直接関係ない。約1秒あたりのクリック数を表示させる。これはArduino Leonardoのハードウェアシリアル機能を使うのでPin2をモジュールのRXに接続する。以前ちょっと試した。
シリアル接続7セグメント4桁LEDとUSB-TTLシリアルコンバータケーブル
 8,9に接続したボタンでクリックする数を増減させる。10に接続したボタンでクリックの開始と停止。これはメインのループ内でポーリングしているだけなので応答が悪い。クリックを送出している時はLeonardo上のLEDを点灯させる。ま、TXランプが点滅するのでわかるんだけど。
 やってみたら1秒あたり100回ぐらい、もっと増やすとブラウザ側が応答できなくなってくる。

 こんな感じでスクリプト言語を使ってるみたいに思いついたものを作りたいんだけど、物理的な部品と使い方のストックが必要なのよねー 
 

Arduino IDE1.0.2 1.0.1との違い調査

Arduino IDE 1.0.2がリリースされた。
Download the Arduino Software

 リリースノートが和訳されている。
2012/11/5 Arduino-1.0.2リリース

 Arduino IDE 1.0.1でいじって気付いたLeonardo周りについて変化がないか確認した。

(1)USB HIDキーボードの送出可能コード範囲
ソースのHID.cppから該当箇所を確認。送出可能なコードの指定部分は0x65(101)で以前と変わらない。

(2)割込み
Arduino Leonardoの外部割り込み番号とピンの割り当てが異なる

これも変わらなかった。
PIN2かPIN3にスイッチを付けてGNDに落とし、割込みがかかるか調べる。

Arduino UNO R3:
INTNUM=0,INTPIN=2でPIN2○ PIN3×
INTNUM=0,INTPIN=3でPIN2○ PIN3△ (保証外動作)
INTNUM=1,INTPIN=2でPIN2× PIN3○ (保証外動作)
INTNUM=1,INTPIN=3でPIN2× PIN3○ 

Arduino Leonardo:
INTNUM=0,INTPIN=2でPIN2× PIN3△
INTNUM=0,INTPIN=3でPIN2× PIN3○
INTNUM=1,INTPIN=2でPIN2○ PIN3×
INTNUM=1,INTPIN=3でPIN2△ PIN3△ (不安定)

今後の実験はArduino IDE 1.0.2に移行する。

PS/2キーボード変換器の製作(19) HEXファイルにパッチを当てる

前回、Arduino LeonardoではUSBキーボードに関するHID Report Descriptorではふつうの日本語キーボード等とは違い、キーの上限を101に制限していることがわかった。これが原因で日本語キーボードの[¥]や[ろ]に対応するコードを送っても無視されていた。
 このHID Report Descriptorの記述はArduino IDE1.0.1のソースにあるHID.cppの中で定義されてある。これはコンパイル済みなのでいじれない。そこでArduino IDEが生成する、マイコンに書き込むイメージファイルである.HEXファイルにパッチを当てることにした。

 Arduino IDE1.0.1でコンパイル時に生成される.hexファイルの所在は以下の方法で知ることが出来る。
Arduino開発環境が使えなくなってハマった件

例えばこのようなディレクトリの中に生成される。(MacOSX)
/var/folders/r5/h8nsfjps4kzdltsm9t4p0qr00000gn/T/build2978712088924621678.tmp/sketch_oct06a.cpp.hex

.hexファイルはひとつしかないので、これをコピーして以下のパッチを当てる。
25行目、
:100180008103950675081500256505071900296581
 ↓
:10018000810395067508150025FE0507190029FE4F

 パッチ当て後はチェックサムも変更しなければならないのでawkで作ったツールで確認した。
[awk]インテルHEXフォーマットのチェッカ

 こうやって作った.hexファイルを書き込む。色々試行錯誤して、結局AVRISPmkIIを使った。
 
$ /Applications/Arduino1.0.1.app/Contents/Resources/Java/hardware/tools/avr/bin/avrdude -C/Applications/Arduino1.0.1.app/Contents/Resources/Java/hardware/tools/avr/etc/avrdude.conf -v -patmega32u4 -cavrispmkII -Pusb -b57600 -e -Uflash:w:ok.hex:i

書き込み用ツールavrdudeはArduinoIDE内のものを、confファイルも同様。ここでは-eでフラッシュメモリを消去してから書き込んでいる。-Uオプションで消去をスキップしたらverifyでエラーが出たため。

以下、ログ
avrdude: Version 5.11, compiled on Sep  2 2011 at 18:52:52
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2009 Joerg Wunsch

         System wide configuration file is "/Applications/Arduino1.0.1.app/Contents/Resources/Java/hardware/tools/avr/etc/avrdude.conf"
         User configuration file is "/Users/takesita/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : usb
         Using Programmer              : avrispmkII
         Overriding Baud Rate          : 57600
avrdude: usbdev_open(): Found AVRISP mkII, serno: 000200081404
         AVR Part                      : ATmega32U4
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PA0
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    10     8    0 no       1024    8      0  9000  9000 0x00 0x00
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0x00 0x00
           lfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           lock           0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : STK500V2
         Description     : Atmel AVR ISP mkII
         Programmer Model: AVRISP mkII
         Hardware Version: 1
         Firmware Version Master : 1.10
         Vtarget         : 5.0 V
         SCK period      : 8.00 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e9587
avrdude: safemode: lfuse reads as FF
avrdude: safemode: hfuse reads as D8
avrdude: safemode: efuse reads as CB
avrdude: erasing chip
avrdude: reading input file "ok.hex"
avrdude: writing flash (6676 bytes):

Writing | ################################################## | 100% 2.75s

avrdude: 6676 bytes of flash written
avrdude: verifying flash memory against ok.hex:
avrdude: load data flash data from input file ok.hex:
avrdude: input file ok.hex contains 6676 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 2.01s

avrdude: verifying ...
avrdude: 6676 bytes of flash verified

avrdude: safemode: lfuse reads as FF
avrdude: safemode: hfuse reads as D8
avrdude: safemode: efuse reads as CB
avrdude: safemode: Fuses OK

avrdude done.  Thank you.


 これで書き込んだLeonardo(Davinci)をPCに接続し、前回のキー入力テストを行うと、ちゃんと¥マークが入力できた。成功!

 なお、Arduino IDEのソース中ではLEDの状態を受信する部分は定義されていないので、USB経由の指示で、接続したPS/2キーボードのLEDを制御することができないようだ。

PS/2キーボード変換器の製作(17) USBキーボードの任意コードの送出

Arduino Leonardo+IDE1.0.1ではKeyboard.press() / release()でUSB HIDキーボードのキーを押したような動作ができるが、引数としてアルファベットはASCIIコードを受け付け、HID Usage IDに変換してから送出しているので送れないキーがある。できれば余計な変換なしでHID Usage IDをそのまま送りたい。
 キーボードのコードを送信している部分 HID.cpp内のKeyboard_::sendReport(KeyReport* keys)はUSBAPI.hではprivateで宣言されている。USBAPI.hをコピーしてここだけpublic宣言にすればダマせるかなとやってみたがそんなのは通用しなかった。ここはコンパイル済で提供されているのでいじると大げさだしそんな実力はない。ということで、sendReport()内で呼び出してるHID_SendReport()は隠されてないのでこれを呼び出すArduinoライブラリを作ってみた。

https://gist.github.com/2ad9f7a713f46149e72f

ほぼHID.cppからのコピペですよ。

PS/2キーボード変換器の製作(16) ArduinoIDE1.0.1

Bootloaderメモ:
ArduinoのブートローダをいじってHIDのみホストに認識させることはできないだろうか?
dfu-programmer

ATmega 32u4 bootloader without ISP connection

USBメモ:
Arduino Leonardoを使ってUSBキーボード相当を実現しようとすると日本語キーボードの一部(¥、_)に対応するコードが送信できない。keyboard.press()を実現している部分をArduinoIDE1.0.1のソースから持ってきてそのままのコードを送れるように書き換えた。
ただしコンパイルが通った程度&汚いのでとりあえず置いとく。今週ちゃんと書きなおす。

https://gist.github.com/3827425

PS/2キーボード変換器の製作(15) US配列→JP配列の問題点

US配列から日本語配列に変換する部分を作成した。
Arduino用のスケッチは以下のとおり。これはUSB HIDキーボードに文字を出力すると共にシリアルポートにデバッグ情報を流す。
https://gist.github.com/3464019
ライブラリ(ps2kybd.h、ps2kybd.cpp)は前回から修正なし。
https://gist.github.com/ab100bfb33a78ddf067d



記号の置き換えは、以下のパターンで行う。
(1)SHIFTを押していない状態でSHIFTを押したような入力……右シフトキーpress、置き換えコード、右シフトキーrelease
(2)SHIFTを押していない状態で記号の置き換え……置き換えコード
(3)SHIFTを押した状態でSHIFTを押したような入力……置き換えコード
(4)SHIFTを押した状態でSHIFTを押さないような入力……左右のシフトキーをrelease、置き換えコード、元のシフトキーをpress

ALTキーを押した状態では、[`~]キーは変換せずにそのまま出力することで[ALT]+[漢字]と同じ操作になる。

 これで記号の置き換え、漢字入力のON/OFFができた。

 残った問題点。
(1)CapsLockの扱い。CapsLockはUSキーではSHIFT併用だが、日本語キーではそのまま。
→Capsフラグはライブラリ側にまかせているが、これをスケッチ側で対処
(2)[¥_]が入力できない →Arduino LeonardoはいったんASCIIコードで受けて内部で変換しUSB HIDコードを送っている。USキーのレイアウトを前提にしているため、日本語配列の[¥_]は対応するものがない。
(3)このアダプタをWindowsXPに接続するたびにデバイスドライバの確認ダイアログが登場する。

(2)、(3)は非常に大きな問題。

(2)はUSB HIDを直接送出する方法を調べなければならない。
(3)はArduinoのブートローダを置き換えなければならない。

うーん、これはけっこう難しいぞ……

スイッチサイエンス32U4ブレークアウトボードとAVRISPmkII

スイッチサイエンスの32U4ブレークアウトボードをArduino Leonardo化した。

SWITCH SCIENCE 32U4ブレークアウトボード

AVR ISPmkIIでArduinoブートローダを書き込むための端子は以下。

SCK (2).B1
MOSI (3).B2
MISO (4).B3
RST (5)
Vcc (6)
GND (21)

ACR ISPmkIIのICSP端子を上から見た図
AVRISPmkIIcon

ブレッドボード上で書き込み用の接続。32U4ブレークアウトボードはひっくり返して載せてる。また、AVR ISPmkIIのICSPコネクタは写真では上を向けているのでVccが左上に見える(赤い線)。
AVRISPmkII-32U4
 
 Arduino IDEから[ツール]→[書込装置]でAVRISPmkIIを選択し、[ツール]→[ブートローダを書き込む]でしばらく待つと青いLEDが点滅するようになる。これでOK。

参考:
AVRC Programming-Programmer

記事タイトルPS/2キーボード変換器の製作(14) US配列でPS/2→USB変換OK

PS/2のスキャンコードをUSB UserIDまで変換できた。次にArduino Leonardoで扱っているコードに変換する。変換方法はほぼ同じで、テーブルを別に用意する。

https://gist.github.com/ab100bfb33a78ddf067d

PrtScr / ScrLock / Break まわりが難航した。ここはスキャンコードが面倒。
USBのコードをKeyboard.press()やKeyboard.release()で操作する時には充分に注意しないとスケッチの修正ができなくなる。Arduino IDEからソースをコンパイルする時にスケッチ画面に文字がタイプされてしまうからだ。

・Windows7(64bit)(英語キーボード配列の設定)に本アダプタと英語キーボードを接続し確認
・WindowsXP(日本語キーボード配列の設定)に本アダプタと日本語キーボードを接続し確認

○(1)PrintScreen / ALT+PrintScreen 正常動作
○(2)ScrLock正常動作(Excelで確認)
○(3)[目](App)キー正常動作
○(4)日本語入力/英数入力切り換え確認OK
○(5)接続したままPC本体電源ONでも動作OK。Windows7のパスワード入力も確認
×(6)[\ろ] キーと[¥]キーを\に対応させたいのだがうまくいかない(日本語キーボード接続時)
→これは無視してもよいか?

Arduino Leonardoのライブラリの制限で、PC側の[無変換][変換][かな]キーに対応するコードを送ることができない。外付けキーボードの[無変換][変換][かな]キーを別のキーに割り当てることは可能。

その他の問題点:
(a)アダプタを接続するたびにデバイスマネージャがデバイスドライバを探す。(WindowsXP)
Windows7ではドライバがインストールできなかったことを通知。でも気持ち悪い。
→できればArduino用のドライバを入れずに動かしたい

(b)キーボードのステータスがわからない。
→PC本体からの指示を受け取る手段がない。PS/2キーボード側に送信するプログラムを書いていない。
※本体接続のキーボードのランプは点灯する。

しばらく英語キーボード配列のPCに接続して使ってみる。並行してUS→JP変換のテーブルを作成。

追記:
(6)は日本語キーボードのみの問題で、キーに対応するコードがArduino Leonardoから送れないため。
(a)はブートローダ差し替えでできそう。32U4はHWB端子を見てブートローダを起動するかどうかを判断するが、Arduinoのブートローダは関連するフューズビットを設定していないらしい。 

PS/2キーボード変換器の製作(13) ハードウェアはできたが……

ハードウェアはできた。Daviciマイコンボードに6Pのmini-DINコネクタを接続、CLKとDATAをプルアップしてケース収納。
2012key01
2012key02
2012key03

 あとはPS/2のスキャンコードをUSB-UIDに変換(済)、Arduino Leonardoのkeyboard.press()に変換、さらに日本語キーボードの配列に変換するだけなのだが、問題点発覚。

以前調査した、Arduino IDE1.0.1でのコード変換部分。
Arduino IDE1.0.1/Leonardで足らないUSBキーを追加する
[HID.cpp]
	uint8_t i;
	if (k >= 136) {			// it's a non-printing key (not a modifier)
		k = k - 136;
	} else if (k >= 128) {	// it's a modifier key
		_keyReport.modifiers |= (1<<(k-128));
		k = 0;
	} else {				// it's a printing key
		k = pgm_read_byte(_asciimap + k);
		if (!k) {
			setWriteError();
			return 0;
		}
		if (k & 0x80) {						// it's a capital letter or other character reached with shift
			_keyReport.modifiers |= 0x02;	// the left shift modifier
			k &= 0x7F;
		}
	}
 上記ソースはkeybord.press()でコードを変換している箇所。与えられた数値が0x00〜0x7fを印字可能なキー、0x80〜0x87をモディファイアキー、0x88〜を表示不能な特殊キーとみなしている。0x00〜0x7fは const uint8_t _asciimap[128] で定義されてあるテーブルで変換される。0x88以上は、その値から0x88を引いた数値がUsageIDとしてUSB経由で送信される。つまり、ファンクションキーF7は #define KEY_F7 0xC8 と定義されているが、実際は0xC8ー0x88=0x40が送信される。
 ここで漏れてしまうキーは、UIDが0x78より大きいもので、日本語キーボード関連で影響がありそうなものは
[ろ](0x87)、[かたかな/ひらがな](0x88)、[¥](0x89)、[変換](0x8a)、[無変換](0x8b)、[かたかな](0x92)、[ひらがな](0x93)、[全角/半角](0x94)。
特に最後の[全角/半角](0x94)は日本語キーボードと認識している場合どうしたものか。USB-HIDをそのまま送出する方法を探すしかないのか。

 ターゲットとなるPCがキーボードを日本語配列と認識している場合、ALT+[`]が[全角/半角]と同等か調査し、もし違っていればUSB-UIDを直接送出する方法を探す。

追記: 
    Keyboard.press(KEY_LEFT_ALT);
    Keyboard.press('`');
    delay(10);
    Keyboard.release('`');
    Keyboard.release(KEY_LEFT_ALT);
 
WindowsXPにてこれで日本語入力が切り替わることを確認。助かった。MacOSXではそのままALT+`扱い。 

Arduino Leonardoの外部割り込み番号とピンの割り当てが異なる

PS/2キーボードのライブラリ改造を行なっていたら、Arduino Leonardoで動作がおかしい。Arduino UNO R3だと期待通りに動作する。どちらもマイコンからはピンが直接出ているので何が違うのか調べていたら、外部割り込みの番号とピン番号のアサインが違うことがわかった。

参考:Arduinoリファレンス attachinterrupt()

 再現環境を作った。(Arduino IDE 1.0.1、MacOSX)
 201207leonardo

以下のスケッチを使う。
// 20120703 Arduino IDE1.0.1
// Arduino UNO R3   INT_NUM=0,PIN=2 / INT_NUM=1,PIN=3
// Arduino Leonardo INT_NUM=0,PIN=3 / INT_NUM=1,PIN=2 (wrong)


#define INT_NUM 1
#define INT_PIN 3

int led = 13;
volatile int state = LOW;

void setup()
{
  pinMode(led, OUTPUT);
  pinMode(INT_PIN, INPUT_PULLUP);
  attachInterrupt(INT_NUM, blink, CHANGE);
}

void loop()
{
  digitalWrite(led, state);
}

void blink()
{
  state = !state;
}
 ピン2またはピン3に押ボタンを接続して、設定通りだとボタンを押せばLEDが反転する(チャタリングはとりあえず無視して)。
 Arduino UNO R3の場合は割り込み番号0、ピン2/割り込み番号1、ピン3の組み合わせで動作。
 Arduino Leonardoの場合は割り込み番号1、ピン2/割り込み番号0、ピン3の組み合わせで動作する。

この様に食い違っている。

記事検索
プロフィール

hardyboy

カテゴリ別アーカイブ
月別アーカイブ
QRコード
QRコード
  • ライブドアブログ