まごころせいじつ堂

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

Arduino

カイゼン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互換機 Uncompatinoの組み立て失敗

 愉快な製作例が満載 作って遊べる Arduino互換機鈴木哲哉著)を買ってきた。作例で使うArduino互換のUncompatino基板が付いている。部品は別に入手しなければならないが、秋月電子で1000円で売っていた。
『作って遊べるArduino互換機』パーツセット
【書籍】作って遊べるArduino互換機

2013uncompatino1
 
 さて、難関はFT232RLのハンダ付け。これだけ2.54mmピッチではない。本の通りにやってみる。ハンダの吸い取りは吸い取り線にフラックスを塗ってやってみた。
2013uncompatino2

 他の部品も取り付けた後、PC側に必要なソフト類を用意。
BitBang版avrdude(avrdude-setjtag04e.zip) (すzのAVR研究)
avrdude-GUI(avrdude-GUI-1.0.5.zip) (ゆきの研究室)
libusb-win32

 Uncompatinoのプラグを全ショートにしてUSBで接続。avrdude-GUIでFUSEを読み込んでみるが以下のエラーが発生。


 
avrdude.exe: BitBang OK
avrdude.exe: pin assign miso 3 sck 5 mosi 6 reset 7
avrdude.exe: drain OK

ft245r:  bitclk 76800 -> ft baud 38400
ft245r:  bitclk 76800 -> ft baud 38400
avrdude.exe: ft245r_program_enable: failed
avrdude.exe: initialization failed, rc=-1
             Double check connections and try again, or use -F to override
             this check.


avrdude.exe done.  Thank you.

 -Fオプションを付けてやってみると:
avrdude.exe: BitBang OK
avrdude.exe: pin assign miso 3 sck 5 mosi 6 reset 7
avrdude.exe: drain OK

ft245r:  bitclk 76800 -> ft baud 38400
ft245r:  bitclk 76800 -> ft baud 38400
avrdude.exe: ft245r_program_enable: failed
avrdude.exe: initialization failed, rc=-1
avrdude.exe: AVR device initialized and ready to accept instructions
avrdude.exe: Device signature = 0x000000
avrdude.exe: Yikes!  Invalid device signature.
avrdude.exe: Expected signature for ATMEGA328P is 1E 95 0F

avrdude.exe done.  Thank you.
 USBからFT232RLへの通信は上手く行ってるみたいだが、FT232RLとATmega328pの通信がうまく行っていない。これはもうハンダ付け不良。
2013uncompatino3
 
 目視してもわからない。ショートチェックはやったが基板とFT232RLの足がうまくついているかはわからないので、半田ごてでなぞってみる。
 そうやってからUSB接続したらLEDが薄明るく点灯。読み書き操作で点滅。これで上手く行った。 Arduino用のブートローダを書き込んで、BlinkのサンプルスケッチでLチカやって動作確認。
 これでArduinoが一枚増えた。また、AVRの書き込み器としても使えそう。
 老眼つらい。

 
作って遊べるArduino互換機作って遊べるArduino互換機
鈴木 哲哉

ソシム 2013-08-21
売り上げランキング : 119653

Amazonで詳しく見る
by G-Tools

LaunchPad用のArduinoライクな開発環境Energia

 昨年(2012年)頃まで450円とキャンペーン価格だったTIのMSP430ボードLaunchPadとCortex-M4FボードのStellaris LM4F120 LaunchPad。これら用のArduinoライクな開発環境、Energiaを試してみた。

 現在はキャンペーン価格は終了している。共立エレショップで購入できる。
MSP430 LaunchPad(ローンチパッド)
LM4F120 Stellaris LaunchPad(ステラリス ローンチパッド)
MSP430 LaunchPadは私が買った頃はMSP430G2231搭載でMSP430G2211が付属だったけど、グレードアップしている。
Get started with the LaunchPad Evaluation Platform from Texas Instruments
TIから直接購入することもできる。
MSP430 LaunchPad バリュー・ライン開発キット
Stellaris® LM4F120 LaunchPad Evaluation Kit

追記:
宮崎 仁のマイコン基礎の基礎: 第12回 安価で手軽なMSP430™開発キットLaunchPadを使ってみよう

 さて、EnergiaだけどMacOSX10.8で試した。
Energia

 Energiaのサイト、Downloadからenergia-0101E0009-macosx.dmg - Mac OS X: Binary release version 0101E0009 (12/06/2012) をダウンロードする。CDCドライバが入っているのでこれを先にインストール。インストール後は再起動が必要。次にEnergia本体をインストール。インストール手順の説明ではパッケージに署名がないためこれを無視する手順が書かれてある。私はすでにそういう設定にしてあったので何も警告は出なかった。MacOSX10.8でインターネット上に公開されているソフトをインストール可能にする手順と多分同じ。

 Energiaを起動するとArduino IDEに似た赤い画面が出てくる。あとはArduinoを使ったことがあればだいたい同じかんじ。
 [ツール]→[マイコンボード]で対応するボードを選択する。USB経由でLaunchPadを接続し、[ツール]→[シリアルポート]で接続先を選択する。/dev/tty.usbmodem????や/dev/tty.uart-????といったポートが追加されているはず。

 サンプルのblinkをいじってボタンを押している間、赤と緑が交互に点灯するスケッチを書いてみた。
https://gist.github.com/houmei/6262174

// LaunchPad(MSP430G2231),StellarisLaunchPad(LM4F120)
//
void setup() {
  // initialize the digital pin as an output.
  // Pin 14 has an LED connected on most Arduino boards:
  pinMode(RED_LED, OUTPUT);
  pinMode(GREEN_LED, OUTPUT);
  pinMode(PUSH2, INPUT);
}

  int tg=0;
  int a,b;
void loop() {
  if (tg==0) {
     digitalWrite(RED_LED, HIGH);
     digitalWrite(GREEN_LED, LOW);
  } else {
     digitalWrite(RED_LED, LOW);
     digitalWrite(GREEN_LED, HIGH);
  }    

  a=digitalRead(PUSH2);
  delay(50);
  b=digitalRead(PUSH2);
  if (a==0&&b==0) {
    tg=!tg;
  }
  delay(100);
}


2013launchpad430
Stellaris LaunchPad
2013launchpadStellaris

 
追記:LaunchPad v1.4、MSP430G2553に差し替えてもOKだった。基板上はTxD、RxDのショートプラグを外す。Energia IDEはLaunchPad G2553を選択。

2013MSP430G2553 

S9705 照度ー周波数変換フォトICを使った照度計

 秋月電子で売っている照度ー周波数変換フォトIC S9705 を使った照度計を作った。

照度・周波数変換フォトIC 550nm S9705(2個入)

資料:S9705 (浜松フォトニクス)

作例:■簡易照度計V2(S9705) (電子工作etc) こちらによると、100lx=50KHzなので周波数を測定したあと÷500をするだけでよいとのこと。
 では、手持ちのArduinoでやるには周波数カウンタがあればよいわけだ。探したらライブラリがありました。
Arduinoで遊ぼう - 周波数カウンタ(なんでも作っちゃう、かも。)
Arduino Frequency Counter Library(Lab III)

 これはATMega328内蔵のカウンタを使ってArduino Pin5に入るパルスを一定時間カウントするもの。ゲートタイムを1秒に設定すればそのままカウント数が周波数になる。S9705の出力はデューティ50%で最大周波数は10Klxで1000KHz、とあるので充分。

2013photoIC
 Arduino IDE1.0.5で確認した。先程のArduino Frequency Counter Libraryからライブラリをダウンロードし、ライブラリをインストールする。MacOSXだとArduinoのアイコンを右クリックして「アプリケーションの内容を表示」をクリック、Contents→Resources→Java→Libraries以下にフォルダごとコピー。

 最初はまったのはArduino Leonardoで動作しなかったこと。ライブラリ中、defined (__AVR_ATmega328P__) という箇所があるので__AVR_ATmega32U4__と追加したらエラー発生。AVRのレジスタに関するシンボルが見つからないみたい。32U4もハードウェアとしてはカウンタを持っているはずなのでここをちゃんと定義してやれば使えそうだが、Arduino Unoに変えて楽することに。
 と思ったらヨソで使用中なので現在手持ちにArduino Unoがない。で、鳥人間のHarpy nanoがあったなあと引っ張り出してきて使用。マイコンボードはArduino Pro or Pro Mini (3.3V, 8MHz) w/ ATmega 328を選択する。S9705を3.3Vで使用することになるが問題ない。
2013photoIC3

スケッチは以下:サンプルを少し改変した程度。
#include <FreqCounter.h>

void setup() {
  Serial.begin(9600);                    // connect to the serial port
  Serial.println("Frequency Counter");
}

long int frq;
void loop() {
  FreqCounter::f_comp = 8;             // Set compensation to 12
  FreqCounter::start(1000);            // Start counting with gatetime of 1000ms
  while (FreqCounter::f_ready == 0);  // wait until counter ready
  frq = FreqCounter::f_freq;            // read result
 Serial.print(frq);                // 
 Serial.print(" ");                // 
 Serial.println(frq/500);                // S9705 100Lux=50KHz
  delay(80);
}
 これでシリアルコンソールに周波数と照度を垂れ流す。一応、同じく秋月電子で買った照度計で大きくずれてないか確認した。

2013s9705

メモ:マイコン関係のリンク色々

 ブラウザのタブ整理。主にtwitter経由で知ったものをあとで読むつもりで貯めていたものです。

ArduinoをAVRライタとして使う
Arduino ISPを使う 
FT232Rモジュール利用 AVR TPIライター

Arduinoのライブラリを作るときの参考:
Arduinoの各種ライブラリ  
自作ライブラリの作り方 
 
開発環境:
embedXcode
MPIDE: One IDE to rull them all. (For Arduino and its varients anyway) 
Emuduino Emu(lator) + (Ar)duino Arduinoエミュレータ
ブラウザでArduinoプログラミング 
ino使うとCUIでArduinoをビルドできて便利

Arduinoで.hexファイルを出力する方法について
Issue 493: .hex export option 

I2C関連:
ArduinoでI2C通信をやる際のメモ
I2C block for ArduinoIO simulink package
ストロベリー・リナックスの低電圧I2C液晶をArduinoで使う
I2C液晶のArduinoライブラリ


その他:
V-USB Virtual USB port for AVR

Arduino + イーサネットシールド + LCDでFacebookページの「いいね数カウンター」をつくる
デザイナーがやる、はじめての電子工作(1):暗くなったらArduinoから自動的につぶやくおやすみメッセージ
参考)部屋の明るさをツイッターでつぶやいてみよう!

WIZ820ioをつかってみました

sparkfun OpenLog

AVRとZ80でCP/Mの改良 

Free Online Design Tools from Aspen Labs and Digi-Key Give Engineers an Edge in Online Printed Circuit Board Design 

メモ PIC/PIC32MX/ビデオ出力

ビデオ出力の原理。D/Aコンバータ
Wayne and Layne

Arduinoでの作例
Arduino Uno output to VGA monitor


【紹介】PIC32MXマイコンでカラーコンポジット出力を試す&ビデオゲームもできる!

PIC32MX,HC08,MSP430用BASIC
CPUStick and StickOS

PICのクラスタ
PIC cluster

Arduino Online Compiler
Arduino Online Compiler


ArduinoライクなPIC32MX開発環境
Pinguino X4 IDE 簡単インストール

PIC32MXについて(概要)

AVR VGA Generation

PIC32MX USB

Arduinoで4×4キーマトリックス

キーマトリックスのスキャンをやってみた。Arduinoのシールドにタクトスイッチを16個取り付け、4×4で扱う。
2013keyscan0

D9,D10,D11,D12は出力で、どれか1つをLOWにする。これをD5,D6,D7,D8で読み取り、キーが押されている位置を判定する。
2013keyscan

D9,D10,D11,D12の出力には2.2KΩの抵抗を入れている。これは複数のキーを押した時に出力のLOW-HIGHが直接繋がってしまうのを避けるため。
Arduinoのリファレンスによると、INPUTに指定したピンにHIGHを出力するとプルアップが有効になり、LOWで無効になるとあるので、この抵抗はいらなかったかも。 

スケッチはこちら。押したキーの番号を0〜15で返す。-1は何も押されていない。シリアルに出力する。
https://gist.github.com/houmei/4735235


int KO[4]={5,6,7,8};
int KI[4]={9,10,11,12};

void setup() {
  pinMode(KI[0],INPUT_PULLUP);
  pinMode(KI[1],INPUT_PULLUP);
  pinMode(KI[2],INPUT_PULLUP);
  pinMode(KI[3],INPUT_PULLUP);
  pinMode(KO[0],OUTPUT);
  pinMode(KO[1],OUTPUT);
  pinMode(KO[2],OUTPUT);
  pinMode(KO[3],OUTPUT);
  Serial.begin(9600);
  keyscan_init();
}

void loop() {
  int a;
  a=keyscan();
  if (a>=0) Serial.println(a);
}


void keyscan_init() {
  digitalWrite(KO[0],HIGH);
  digitalWrite(KO[1],HIGH);
  digitalWrite(KO[2],HIGH);
  digitalWrite(KO[3],HIGH);
}

int keyscan() { // pressed 0-15 , not pressed -1
  int i,j;
  int n=-1;
  for(i=0;i<4;i++) {
    for(j=0;j<4;j++) {
       if (i==j) {
          digitalWrite(KO[j],LOW);
       } else {
         digitalWrite(KO[j],HIGH);
       }
    }
    for(j=0;j<4;j++) {
      if (n<0 && digitalRead(KI[j])==LOW) {
        n=i+j*4;
      }
      delay(1); // wait for 1ms
    }
  }
  keyscan_init();
  return n;
}


Adafruit 1.8インチTFTシールド

スイッチサイエンスで扱っているAdafruit 1.8インチTFTシールドをとりあえず使ってみた。

Adafruit 1.8インチTFTシールド
(スイッチサイエンス)

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

 ST7735R 128×160ドット 18bit色のディスプレイ、おおよそ33mm×40mmの大きさで、ウォークマンW用の液晶保護シートがぴったり貼れる。microSDカードスロット付き。上下左右と押しこむ操作のスティック付き。あと、バックライトを制御できそうなことが書いてあった(何もしないとON)。
 使用ピンはSPI接続でpin13,11,10,8。microSDカードを使う場合は加えて12と4。スティックはアナログ出力でA4。このシールドは3.3V/5V対応なのでGR-SAKURAに使えるかもしれん。

#define sclk  13  
#define mosi  11
#define sd_cs  4
#define lcd_cs 10
#define dc     8
#define rst    0  


 ライブラリはAdafruit-ST7735-LibraryとAdafruit-GFX-Libraryが必要。Adafruit-GFX-Libraryは同社のOLEDでも使われている。

https://github.com/adafruit/Adafruit-ST7735-Library

https://github.com/adafruit/Adafruit-GFX-Library

 これらをgithubのzipでダウンロードするボタンを押して、Arduino IDEのライブラリに展開すればいいんだけどそのままのフォルダ名だと半角英数字以外使えんといったエラーメッセージが出るので、-masterは削除しハイフン(-)はアンダースコア(_)に変えた。

 以下、ArduinoIDE1.0.3、MacOSX、Arduino UNO R3で確認。
2013tft1

 サンプルでついてくるshieldtestを開いて実行。スティックを動かすと画面に向きを表示。押しこむとmicroSDカードにあるparrot.bmpを開いて表示するらしいのだが、手元にないので適当に用意する。サンプルのparott.bmpを適当にリネームし、用意した128x160サイズのBMP画像のファイル名に合わせる(実際には128x171サイズ)。この時ファイル名は8+3文字の制限があるみたい。シリアルには以下の様に出力され、画像が液晶画面に表示される。

Button read analog = 3.34
Button read analog = 3.34
Button read analog = 0.59
Button read analog = 0.59
Button read analog = 3.34
Button read analog = 3.34
Button read analog = 3.34
Button read analog = 1.05
Initializing SD card...
Loading image 'sakura.bmp'
File size: 65718
Image Offset: 54
Header size: 40
Bit Depth: 24
Image size: 128x171
Loaded in 1111 ms

2013tft2


こんな感じです。

lcd.write(0)でerror: call of overloaded 'write(int)' is ambiguousと言われる

キャラクタ液晶を扱うライブラリLiquidCrystalには、ユーザ定義文字を設定するcreateChar(num,data)という関数がある。これを試したらなぜかエラーになった。

createChar(num,data) Arduino日本語リファレンス
createChar() (原文)

Arduino1.0.3で以下のメッセージ。(MacOSX) Windowsでも同様

sketch_jan04b.ino: In function 'void setup()':
sketch_jan04b:18: error: call of overloaded 'write(int)' is ambiguous
/Applications/Arduino1.0.3.app/Contents/Resources/Java/libraries/LiquidCrystal/LiquidCrystal.h:82: note: candidates are: virtual size_t LiquidCrystal::write(uint8_t)
/Applications/Arduino1.0.3.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Print.h:49: note:                 size_t Print::write(const char*)

??サンプルがそのまま動かないのナンデ? 0x00に書き換えても同様。

調べたら定数0を指定した時だけの問題。lcdに限らない。
call of overloaded 'write(int) is ambigous?

lcd.write(0); を lcd.write((byte)0);にして解決。1〜の定数を指定した時はエラーが発生しない。
もちろん、変数で指定した場合は問題ない。
サンプルのコピペでちょっとハマッてしまった。
 2013smile

ArduinoIDE1.0.3 USB-HID特に変わらず

やっと今日Arduino1.0.3のソースがダウンロードできたので、USB0-HIDのキーボード部分をチェックした。

// Keyboard
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)	// 47
    0x09, 0x06,                    // USAGE (Keyboard)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x85, 0x02,                    //   REPORT_ID (2)
    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
   
	0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)
    0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    
	0x95, 0x08,                    //   REPORT_COUNT (8)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x95, 0x01,                    //   REPORT_COUNT (1)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x81, 0x03,                    //   INPUT (Cnst,Var,Abs)
    
	0x95, 0x06,                    //   REPORT_COUNT (6)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x65,                    //   LOGICAL_MAXIMUM (101)
    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
    
	0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))
    0x29, 0x65,                    //   USAGE_MAXIMUM (Keyboard Application)
    0x81, 0x00,                    //   INPUT (Data,Ary,Abs)
    0xc0,                          // END_COLLECTION

そんなわけで LOGICAL_MAXIMUM(101) 、USAGE_MAXIMUM(101) →0x65 で変わらず。
なんで毎回制限してんだろ?日本語キーボードなど国際化無視?
 

A/Dコンバータの勘違い(植木算)とLM35DZを使った場合の誤差

植木算 -Wikipedia

 Arduino(ATmega328や32U4)のADCはAREFで与えられた基準電圧を0〜1023の値で取得できる。何も考えずに分解能10bit、1024で割っていたが本当は1024-1だった。
※追記:なんか考えてたら分解能による限界のような気もしてきましたがいちおうこのままで出しておきます
 
やばい。とある装置は今日持っていったばっかりで手元にないので検算してみる。ツッコミ大歓迎。

※追記 2021.9.5
23.7 ADC Conversion
Result "0x000 represents analog ground, and 0x3FF represents the selected reference voltage minus one"
10年誤解してた。÷1024でいいんだ。ォァー


AREFが1.1V(INTERNAL)、3.3V(EXTERNAL)、5V(EXTERNAL)の場合の1ステップあたりの電圧を計算した。有効数字は6桁で計算。

1.1V ÷ 1024 = 1.07422mV (誤り) ×1000すると1.07422V
1.1V ÷ 1023 = 1.07527mV (正しい) ×1000すると1.07527V
※1023が示す電圧の範囲は、1.07527V〜1.10000V

1.1Vで 1.05mVの差

3.3V ÷ 1024 = 3.22266mV (誤り) ×1000すると3.22266V
3.3V ÷ 1023 = 3.22581mV (正しい) ×1000すると3.22581V
※1023が示す電圧の範囲は、3.22581V〜3.30000V

3.3Vで 3.15mVの差

5.0V ÷ 1024 = 4.88281mV (誤り) ×1000すると4.88281V
5.0V ÷ 1023 = 5.00489mV (正しい) ×1000すると4.88759V
※1023が示す電圧の範囲は、4.88759V〜5.00000V

5.0Vで 4.78mVの差

今回はAREFで3.3Vを使用、LM35DZは1℃あたり10mV。
10〜50℃あたりで使用することを考えると、100mVから500mVを観測することになる。
値が大きいほど誤差は大きくなるので、500mVで考える。

誤ったプログラム 500mV ÷ 3.22266mV = 155.15.. 表示値は156 (切り上げだから)
正しいプログラム 500mV ÷ 3.22851mV = 154.87.. 表示値は155になるはず

 156(誤った値) × 3.22581mV(正しい1ステップあたりの電圧) = 503.226mV
その差 3.226mV → 間違ったプログラムでは50℃付近で約0.3℃高く表示される。

で、いま使ってるセンサLM35DZの誤差は25℃付近で±1.5℃、Typ±0.6℃。グレードが低いのは承知の上で使っているので±2℃程度は気にしない。

ということで室温の範囲内なら問題ないでしょう。

LM35DZを複数繋いだ温度ロガーと誤差

温度センサLM35DZを複数個繋いだロガーやっとできた。

これまでの記事:
LM35DZを複数つないだ時の問題 お詫びとハードでの解決
温度センサLM35DZを複数Arduinoに繋いだ時のトラブル
LM35DZによる温度測定とanalogReference()

マイコン風雲録さんのanalogReadEx()関数で解決しました。ありがとうございました。
Arduino:温度センサー Processing + Firmata LM61BIZとLM35DZとDS18B20のメモ[マイコン風雲録]

Arduino UNOのA0〜A5ポートにLM35DZを接続。信号線は10KΩでGNDに。

 ログ時刻はRTCをつないで頑張るつもりだったが、Arduino UNOではI2Cの端子がアナログポートとかぶるのであきらめた。Arduino Microだとアナログポートはたくさんあるし次はこれ使おう。
で、肝心のタイムスタンプはTeraTermに任せた。ログを取るときに□タイムスタンプのチェックボックス入れるか、teraterm.ini内のLogTimestamp=onにする。
参考:
TeraTermログの行毎に自動的にタイムスタンプを付与する

※追記:@maris_HYさんにSPI接続のRTC教えてもらいました。
DS3234搭載のリアルタイムクロック・モジュール

以下を追加・修正した。
・Setup()内で5秒の待ち。シリアルモニタ(TeraTerm等)を立ち上げる時間を待つため
・別のセンサを付けることを考慮して、A0〜A5ポートの入れ替えを最初のほうで定義した。
・温度測定の結果は先頭に連番を付けるようにした
・Arduinoが生きているかどうか分かるようLEDを点滅させる処理を追加
・LM35DZセンサの誤差を補正できるようにした(Adj[]で定義)

さて、これで安定して測定できるようになったが、温度センサを一箇所にまとめても数℃の誤差が出る。これはセンサについてまわるので素子のばらつきと思われる(安いグレードだし)が、ADCの基準電圧が内部リファレンス1.1Vと外部リファレンス3.3Vではどう違うだろうか。

ADCの基準電圧1.1Vと3.3Vについて200回測定し、平均を求めた。
$ gawk -f 20121130.awk lm35dz1v1.txt
AVG1= 188.02
AVG2= 190.65
AVG3= 193.33
AVG4= 191.77
AVG5= 192.27
AVG6= 194.555

1.1V÷1024で分解能は1.07mV
6.54ステップのゆらぎ 約7.00mV

$ gawk -f 20121130.awk lm35dz3v3.txt
AVG1= 60.2977
AVG2= 61.1395
AVG3= 61.4512
AVG4= 61.214
AVG5= 60.9488
AVG6= 61.8791

3.3V÷1024で分解能は3.22mV
1.58ステップのゆらぎ 約5.10mV

 ということで、ATmega328の内部1.1Vよりも外部の定電圧レギュレータによる3.3Vの方がより正確。外部5Vも使えるが、USBから給電して使う場合はそちらに影響されるので3.3V参照のほうがよさそう。
 または、基準1.1Vの方がセンサの誤差に対してより敏感なのかも。ちょっとこの辺はLM35DZの良いグレードの品で比較しないといけないんだろうけど資本切れです。


プログラムはこちら。
※analogReference()の箇所がINTERNALになってますが3.3V参照ではEXTERNALでした。ただしINTERNAL設定でもAREFにかかっている電圧が優先になるようです。

https://gist.github.com/4176111


20121201terrmal

一晩測ってExcelに持っていった。おおよそ期待通り。上がったりしている箇所はストーブを使った時間。

Arduino MicroとLED付き押ボタンスイッチ

秋月電子のLED付き押ボタンスイッチが以前から気になっていた。今回入手してこれまた最近発売されたArduino Microと組み合わせてブレッドボード上で組み立ててみた。

LED付き押しボタンスイッチ(白・正方形・赤色LED)ST12-401FCG (秋月電子)

Arduino Micro 5V 16MHz (ATmega32u4 - ピンヘッダ付き) (スイッチサイエンス)
まだスイッチサイエンスが扱う前だったのでAdafruitから買った。Arduino Leonardoの時みたいに品薄になるんじゃないかなあと思ってたらそんなことはなかった。



 Arduino MicroはATmega32U4を使ったブレッドボード上で使える小さなArduinoで、Arduino Leonardo相当の機能。Arduino IDE 1.0.2から使える。([ツール]→[マイコンボード]で指定) 通電するとmicroUSBコネクタ下にある青LEDが光る。

2012micro1

 Arduino IDE 1.0.2では、Leonardoでtone()を使った時の問題が修正されたらしいので圧電ブザーも繋いでみた。これで電子ゲームっぽくなる。
 Arduino Microのピンアウトはこちらを参照。
Arduino Micro

 電源はArduino MicroのUSB経由でもらっている。
タクトスイッチ部分はA0,A1,A2,A3を使用。analog入力で読んでいる。A0〜A3はINPUT_PULLUPでプルアップ指定し、スイッチはONでGNDに接続。
LED部分はタクトスイッチとは独立して制御できる。12(PWM),11(PWM),10(PWM),9(PWM)で明るさを変化させている。アノード(+)側を端子に接続し、カソード(-)は330Ωの抵抗を通してGNDへ。
圧電ブザーは4(PWM)へ、隣のSCL,SDA端子をまたいでGNDに接続。
 2012micro2

 LED付き押ボタンスイッチは普通のブレッドボードに5個まで並べて挿せるようだ。LEDの(+)、(-)端子は細くて接触不良を起こしやすいので、挿す前に少し広げておく。
 ブレッドボード2枚で作れた。
2012micro3

確認用のソースは以下。動作開始時にブザーが鳴り、LEDが点滅する。ボタンを押すとその場所のLEDが消え、ブザーが鳴る。

☆toneのサンプルスケッチではpatches.hをincludeしているのだが、単体のソースで動くようにコピペして貼り付けました。

気になる点:いちばん左端のLED (A0ポート)が消灯する割合が高いような。
あと、以下の行間違い(というより当初の意図どおりではなかった)。点滅の具合が変わります。
int t=random(0,16)*16;
アナログポートA0〜はデジタルポートとしても使えるはずなのだが、上手くいかなかったのでアナログ入力で誤魔化しています(100以下でボタンが押されていると判定)。私の勘違いで上手く使えなかったのかもしれないし、なんかあるのかもしれない。

// LED tactswitch+Arduino Micro
// 20121124 K.Takesita
//

// copy from pitches.h
/*************************************************
 * Public Constants
 *************************************************/

#define NOTE_B0  31
#define NOTE_C1  33
#define NOTE_CS1 35
#define NOTE_D1  37
#define NOTE_DS1 39
#define NOTE_E1  41
#define NOTE_F1  44
#define NOTE_FS1 46
#define NOTE_G1  49
#define NOTE_GS1 52
#define NOTE_A1  55
#define NOTE_AS1 58
#define NOTE_B1  62
#define NOTE_C2  65
#define NOTE_CS2 69
#define NOTE_D2  73
#define NOTE_DS2 78
#define NOTE_E2  82
#define NOTE_F2  87
#define NOTE_FS2 93
#define NOTE_G2  98
#define NOTE_GS2 104
#define NOTE_A2  110
#define NOTE_AS2 117
#define NOTE_B2  123
#define NOTE_C3  131
#define NOTE_CS3 139
#define NOTE_D3  147
#define NOTE_DS3 156
#define NOTE_E3  165
#define NOTE_F3  175
#define NOTE_FS3 185
#define NOTE_G3  196
#define NOTE_GS3 208
#define NOTE_A3  220
#define NOTE_AS3 233
#define NOTE_B3  247
#define NOTE_C4  262
#define NOTE_CS4 277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4 370
#define NOTE_G4  392
#define NOTE_GS4 415
#define NOTE_A4  440
#define NOTE_AS4 466
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_CS5 554
#define NOTE_D5  587
#define NOTE_DS5 622
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_FS5 740
#define NOTE_G5  784
#define NOTE_GS5 831
#define NOTE_A5  880
#define NOTE_AS5 932
#define NOTE_B5  988
#define NOTE_C6  1047
#define NOTE_CS6 1109
#define NOTE_D6  1175
#define NOTE_DS6 1245
#define NOTE_E6  1319
#define NOTE_F6  1397
#define NOTE_FS6 1480
#define NOTE_G6  1568
#define NOTE_GS6 1661
#define NOTE_A6  1760
#define NOTE_AS6 1865
#define NOTE_B6  1976
#define NOTE_C7  2093
#define NOTE_CS7 2217
#define NOTE_D7  2349
#define NOTE_DS7 2489
#define NOTE_E7  2637
#define NOTE_F7  2794
#define NOTE_FS7 2960
#define NOTE_G7  3136
#define NOTE_GS7 3322
#define NOTE_A7  3520
#define NOTE_AS7 3729
#define NOTE_B7  3951
#define NOTE_C8  4186
#define NOTE_CS8 4435
#define NOTE_D8  4699
#define NOTE_DS8 4978


const int SW0 = A0; //A0
const int SW1 = A1; //A1
const int SW2 = A2; //A2
const int SW3 = A3; //A3

const int LED0 = 12;
const int LED1 = 11;
const int LED2 = 10;
const int LED3 = 9;

int button[4] = { SW0,SW1,SW2,SW3 };
int light[4] = { LED0,LED1,LED2,LED3 };
int bright[4] = { 128,128,128,128 } ;
void setup() {
  pinMode(SW0,INPUT_PULLUP);
  pinMode(SW1,INPUT_PULLUP);
  pinMode(SW2,INPUT_PULLUP);
  pinMode(SW3,INPUT_PULLUP);
  
  pinMode(LED0,OUTPUT);
  pinMode(LED1,OUTPUT);
  pinMode(LED2,OUTPUT);
  pinMode(LED3,OUTPUT);
  
  tone(4,NOTE_C4,100);
}
void loop(){

  for(int i=0; i<4; i++) {
    if (analogRead(button[i])<100) {
      tone(4,NOTE_A4,10);
      analogWrite(light[i],0);
    } else {
      int t=random(0,16*16);
      analogWrite(light[i],t);
    }
  }

  delay(100);
}


シリアル接続7セグメント4桁LEDとUSB-TTLシリアルコンバータケーブル

 Sparkfunの7-Segment Serial Displayというのを使ってみた。最近改版されたらしい。

7-Segment Serial Display - Blue(Sparkfun)
※Sparkfunの写真は上下逆。

スイッチサイエンスから購入できる。
シリアル接続7セグメント4桁LED(青) (スイッチサイエンス)

シリアル、I2C、SPIでマイコンと接続、0〜Fの表示だけでなく任意のセグメントも表示可能で輝度も調整できるらしい。ATmega328で制御していて、Arduinoブートローダもあるので単独でも動作できるようだ。
2012led1
2012led2

 が、いきなりマイコンに接続して使うのもなんなのでUSB-TTLシリアルコンバータケーブルというのでPCから直接いじってみた。ストロベリーリナックスからUSBケーブルの様なシリアル変換器が出ている。5V品と3.3V品がある。

USB-TTLシリアルコンバータ(5V) (ストロベリーリナックス)
FTDI USB TTL Serial Cables (FTDIchip)

2012led4

黒 ー GND
茶 ← *CTS
赤 → Vcc電源出力 Max75mA
橙 → TXD
黄 ← RXD
緑 → *RTS

MacOSXだと/dev/tty.usbserial-なんとか という風に見える。

 では7セグLEDの実験。端子の取り付けはちょっと悩んだが、上にある10個はLEDの見える側にメス、右側のI2Cと電源はブレッドボードに載せられるようオスのピンヘッダを半田付け。I2Cと電源は左側にも配置してある。
 2012led3
 USB-TTLシリアルコンバータケーブルからの電力供給は弱そうで保護もないので、5V電源は別に取っている。ここではUSBミニコネクタ経由で5Vを給電。
7セグLEDの+、ー端子に電源接続、上の10個ある端子の右端にUSB-TTLシリアルコンバータの4番ピン(橙)、USB-TTLシリアルコンバータの1番ピン(黒)をGNDに接続。これだけ。
電源を接続しただけでは何も表示されない。Arduino IDEのシリアルモニタ経由で
cdef
と入力すると写真の様に表示される。
2012led5

キー入力順に左から右に出力され、4文字目を表示した次は1文字目の位置から出力される。cdefと入力した時とCDEFと入力した時は表示されるフォント(と言っていいのか)が若干異なる。

 ということでえらい簡単に動作確認できた。

メモ:秋月電子で買えるRTC(RealTimeClock)

データロガーを作ろうとしてるけど、タイムスタンプも欲しいよねということで調べた。秋月電子ではDIP基板に載せてモジュール化したものが2種類ある。

リアルタイムクロック(RTC)モジュール RTC-8564NB 
RTC-4543SA使用32kHz出力シリアルRTC基板モジュール RTC-4543SA

大きな違いは、RTC-8564NBがI2C、RTC-4543SAは独自シリアルI/Fでマイコンと通信する点。

RTC-4543SAはまだ実験してないのでメモ:
■[電子工作][プログラミング]RTC-4543(RTC-4543SA/SB)を使う(後編) (99円のへたれ日記!) 
シリアル出力リアルタイムクロック(RTC-4543SA)を使ってみた (明日から本気だす(´・ω・`))

RTC-8564NBはArduinoで実験してみた。
2012RTC

RTCモジュール上の端子にハンダを盛ってSDA,SCL信号はモジュール内でプルアップする。
スケッチについてはエレキジャックの記事を参照した。
リアルタイムクロックの最近のブログ記事 (エレキジャック・フィジカルコンピューティング)
RTC-8564NBモジュール(1)
RTC-8564NBモジュール(2)

Arduino1.0.2では以下のソースを一部修正。
ardsens090010.txt

Wire.send()はWire.write()に、Wire.receive()はWire.read()に書き換えが必要。
実行するとシリアルに時刻が出力される。そのままでは値がおかしいので
t213000[enter]
d121113[enter]
と入力すれば 2012年11月13日 21時30分00秒と設定される。

ところで、Arduino UNOではSCL,SDA端子がAnalog A5,A4の端子と一緒なので同時には使えない(@maris_HYさんありがとうございました)。
[SCL=A5,SDA=A4]
Arduino LeonardoではAREF端子の上のほうにSDA,SCL端子が増えている。Arduino UNO R3では互換のためにSDA,SCL端子はあるけどA4,A5の端子がそのまま引き出してあるだけ。ということでアナログ6ポートと同時に使うためにはLeonardoが必要。
が、手持ちのバニラシールドはこの増設部分が半分ずれてるのよね。ということでR3対応のものを取り寄せ中。
Arduino用バニラシールド基板ver.2(白) (スイッチサイエンス) 

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に移行する。

LM35DZを複数つないだ時の問題 お詫びとハードでの解決

前回の続き。
温度センサLM35DZを複数Arduinoに繋いだ時のトラブル

こちらの方がADCの動作を考慮した読み捨ての回数を記事にされていた。
Arduino:温度センサー Processing + Firmata LM61BIZとLM35DZとDS18B20のメモ[マイコン風雲録]

ログを分析しようとしててあっと気付いた。
 for(int i=0;i<=NUM_LM35;i++) {
 だめだ……チャネルは6個しかないのに7個目読んでる……

 というわけでADC読み取りの最後が順番によらず跳ね上がるのは私のプログラムが原因でした。未定義のチャネル読んでる。申し訳ありません。

 ところで、チャネル読み込みの初回が順序に関わらず少し上がる現象は間違いなく起こっている。これを改善できるかどうか、以前も参考にした
■AVR(Arduino)にLM35温度センサをつなげた場合に正しくA/D変換出来ないトラブル(2012年2月15日)[SIESTA HOMEPAGE]
を参考に、LM35DZの出力に10KΩをぶら下げた。テスタでちゃんと信号-GND間が10KΩ程度か確認。
2012_10Kohm

 これで一晩ランニング。
比較のため前回とまったく同じヘボいコード(ADC0〜6まで読んでしまうもの)で実施。
この結果、最初に読んだチャネルが跳ね上がるという現象はなくなった。

□前回の生ログ(Arduino Leonardo、3V3リファレンス版) ※間違ったADCの7番目は除去
60702 72 73 74 74 73 74
121405 72 73 74 73 73 74
182107 72 73 73 73 73 73
242809 72 73 74 73 73 73
303512 72 73 73 73 73 73
364215 72 73 73 73 73 73
424918 72 73 73 72 73 73
485620 105 73 73 73 72 73
546323 71 73 73 73 72 73
607026 128 73 73 73 73 73
667727 72 73 73 73 73 74
728430 72 73 73 73 72 73
789133 72 73 73 73 72 73
849836 71 72 73 72 73 73

□今回の生ログ(Arduino Uno R3、1V1リファレンス版)
1759184 135 127 136 122 124 125 
1760387 135 128 136 122 124 124 
1761589 134 128 136 121 125 124 
1762791 135 127 136 122 125 124 
1763994 135 127 136 121 124 124 
1765196 134 127 135 122 125 123 
1766398 134 128 136 121 124 124 
1767602 135 127 136 122 125 124 
1768804 135 128 136 122 124 124 
1770006 134 127 135 122 124 124 
1771209 135 128 136 122 124 124 
1772411 135 128 136 122 125 124 
1773614 134 127 136 122 125 124 
1774816 135 128 136 122 125 124 

 LM35DZ直結の時は最初のADC読み取りで跳ね上がる現象が見られたが、10KΩをぶら下げることによりなくなった。しかし、各センサの値にむらがあるように見える。ADC0とADC2が値が大きい。

・今後の調査方針
(1)温度センサを束ねて同じ条件に
(2)ログをしっかり取ってawkで分析
(3) マイコン風雲録さんのanalogReadEx()で確認
 
 うう、デジタル温度センサに逃げたくなった……

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からのコピペですよ。
記事検索
プロフィール

hardyboy

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