So-net無料ブログ作成

Arduino EEPROMの初期値 [Arduino]

サインスマートのLeonardo互換ボードでEEPROMを使ってみようと思ったのですが、そもそも初期値はどーなってるの? というわけで、メモリダンプしてみました。

以下、EEPROMメモリダンプスケッチ。

※初出時、最終アドレスが0x1ffとなっていたため、0x3ffに修正しました。(2016/1/16)

[ dumpEEPROM.ino ]
/*
 *  Arduino EEPROM Dump
 *  Written by Toshiyuki UENO MMXVI
 */
#include  <EEPROM.h>

void dumpEEPROM(unsigned int start_adrs, unsigned int end_adrs){
  unsigned int i, a;
  char s[4];

  if(start_adrs >= 1024 || end_adrs >= 1024 || start_adrs > end_adrs){
    return; // error
  }
  a = int(start_adrs / 16);
  Serial.print("      +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F");
  for(i = a; i <= end_adrs; i++){
    if((i % 16) == 0){
      sprintf(s, "\n%04X:", i);
      Serial.print(s);
    }
    if(i >= start_adrs){
      sprintf(s, " %02X", EEPROM.read(i));
      Serial.print(s);
    } else {
      Serial.print("   ");
    }
  }
  Serial.println("");
}

void setup() {
  Serial.begin(9600);
  while(!Serial);       // シリアルポートオープン待ち
  dumpEEPROM(0, 1023);
}

void loop() {
}

実行結果は次のとおり。

      +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F
0000: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0010: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0020: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0030: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0040: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0050: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0060: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0070: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0080: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0090: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00A0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00B0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00C0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00D0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00E0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00F0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0100: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0110: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0120: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0130: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0140: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0150: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0160: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0170: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0180: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0190: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
01A0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
01B0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
01C0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
01D0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
01E0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
01F0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0200: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0210: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0220: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0230: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0240: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0250: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0260: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0270: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0280: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0290: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
02A0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
02B0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
02C0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
02D0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
02E0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
02F0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0300: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0310: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0320: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0330: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0340: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0350: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0360: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0370: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0380: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0390: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
03A0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
03B0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
03C0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
03D0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
03E0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
03F0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF

すべて0xffでした。EEPROM使用前にゼロクリアしたほうがよさげですな。


Arduinoをはじめようキット

Arduinoをはじめようキット

  • 出版社/メーカー: スイッチサイエンス
  • メディア: おもちゃ&ホビー



Arduinoをはじめよう 第3版 (Make:PROJECTS)

Arduinoをはじめよう 第3版 (Make:PROJECTS)

  • 作者: Massimo Banzi
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2015/11/28
  • メディア: 単行本(ソフトカバー)



Arduino Leonardoで\記号を打つ [Arduino]

Arduino LeonardoでUSBキーボードエミュレーションを行う場合、IDE付属のKeyboardライブラリを使うと記号が化けたり、「\」「|」「半角/全角キー」などの打てない文字・キーがあったりします。

Keyboardライブラリは101キーボードをエミュレートするため、106/109キーボードにしかない文字やキーを打てず、キーバインドの異なる記号は化けてしまうのです。

そこで、Keyboard.h/Keyboard.cppを改変し、日本語106/109キーボード対応版を作成してみました。(Arduino IDE 1.6.7で動作確認済)

ユーザーフォルダ\Documents\Arduino\libraries\Keyboard_jp フォルダを作成して、そのフォルダ内に下のKeyboard_jp.h、Keyboard_jp.cppを保存すると利用できます。


以下の関数の使用方法は、IDE付属Keyboardライブラリと同じです。「Arduinoリファレンス・キーボードライブラリ」を参照してください。また、Keyboar_jpで使用できる修飾キーは、Keyboard_jp.hを参照してください。

vold begin(void)
void end(void)
size_t write(uint8_t k)
size_t press(uint8_t k)
size_t release(uint8_t k)
void releaseAll(void)


Keyboard_jpで追加された関数は以下の3つです。動作はKeyboard.write、Keyboard.press、Keyboard.releaseと同じですが、引数が(キーコードではなく)UsageIndexであることに注意してください。UsageIndexの詳細は、「Keyboard Scan Code Specification」(Microsoft Word形式)を参照してください。

size_t writeRaw(uint8_t k)
size_t pressRaw(uint8_t k)
size_t releaseRaw(uint8_t k)


[ Keyboard_jp.h ]
/*
  Keyboard_jp.h

  Copyright (c) 2015, Arduino LLC
  Original code (pre-library): Copyright (c) 2011, Peter Barrett
  Modified for Japanese 106/109 Keyboard by Toshiyuki UENO MMXVI

  This library is free software; you can redistribute it y it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#ifndef KEYBOARD_h
#define KEYBOARD_h

#include "HID.h"

#if !defined(_USING_HID)

#warning "Using legacy HID core (non pluggable)"

#else

//================================================================================
//================================================================================
//  Keyboard

#define KEY_RETURN        0x80  // 0x28
#define KEY_ESC           0x81  // 0x29
#define KEY_BACKSPACE     0x82  // 0x2a
#define KEY_TAB           0x83  // 0x2b

#define KEY_KANJI         0x8d  // 0x35 Hankaku/Zenkaku | Kanji

#define KEY_CAPS_LOCK     0x91  // 0x39
#define KEY_F1            0x92  // 0x3a
#define KEY_F2            0x93  // 0x3b
#define KEY_F3            0x94  // 0x3c
#define KEY_F4            0x95  // 0x3d
#define KEY_F5            0x96  // 0x3e
#define KEY_F6            0x97  // 0x3f
#define KEY_F7            0x98  // 0x40
#define KEY_F8            0x99  // 0x41
#define KEY_F9            0x9a  // 0x42
#define KEY_F10           0x9b  // 0x43
#define KEY_F11           0x9c  // 0x44
#define KEY_F12           0x9d  // 0x45
#define KEY_PRINT_SCREEN  0x9e  // 0x46
#define KEY_SCROLL_LOCK   0x9f  // 0x47
#define KEY_PAUSE         0xa0  // 0x48
#define KEY_INSERT        0xa1  // 0x49
#define KEY_HOME          0xa2  // 0x4a
#define KEY_PAGE_UP       0xa3  // 0x4b
#define KEY_DELETE        0xa4  // 0x4c
#define KEY_END           0xa5  // 0x4d
#define KEY_PAGE_DOWN     0xa6  // 0x4e
#define KEY_RIGHT_ARROW   0xa7  // 0x4f
#define KEY_LEFT_ARROW    0xa8  // 0x50
#define KEY_DOWN_ARROW    0xa9  // 0x51
#define KEY_UP_ARROW      0xaa  // 0x52

#define KEY_KANA          0xe0  // 0x88 Katakana/Hiragana
#define KEY_HENKAN        0xe2  // 0x8a
#define KEY_MUHENKAN      0xe3  // 0x8b

#define KEY_LEFT_CTRL     0xf8  // 0xe0
#define KEY_LEFT_SHIFT    0xf9  // 0xe1
#define KEY_LEFT_ALT      0xfa  // 0xe2
#define KEY_LEFT_GUI      0xfb  // 0xe3
#define KEY_RIGHT_CTRL    0xfc  // 0xe4
#define KEY_RIGHT_SHIFT   0xfd  // 0xe5
#define KEY_RIGHT_ALT     0xfe  // 0xe6
#define KEY_RIGHT_GUI     0xff  // 0xe7

//  Low level key report: up to 6 keys and shift, ctrl etc at once
typedef struct
{
  uint8_t modifiers;
  uint8_t reserved;
  uint8_t keys[6];
} KeyReport;

class Keyboard_ : public Print
{
private:
  KeyReport _keyReport;
  void sendReport(KeyReport* keys);
public:
  Keyboard_(void);
  void begin(void);
  void end(void);
  size_t write(uint8_t k);
  size_t press(uint8_t k);
  size_t release(uint8_t k);
  void releaseAll(void);
  size_t writeRaw(uint8_t k);
  size_t pressRaw(uint8_t k);
  size_t releaseRaw(uint8_t k);
};
extern Keyboard_ Keyboard;

#endif
#endif


[ Keyboard_jp.cpp ]
/*
  Keyboard_jp.cpp

  Copyright (c) 2015, Arduino LLC
  Original code (pre-library): Copyright (c) 2011, Peter Barrett
  Modified for Japanese 106/109 Keyboard by Toshiyuki UENO MMXVI
  
  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "Keyboard_jp.h"

#if defined(_USING_HID)

//================================================================================
//================================================================================
//  Keyboard

static const uint8_t _hidReportDescriptor[] PROGMEM = {

  //  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, 0xfe,                    //   LOGICAL_MAXIMUM (101)  *** modified 0x65 to 0xfe
    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
    
  0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))
    0x29, 0xfe,                    //   USAGE_MAXIMUM (Keyboard Application)  *** modified 0x65 to 0xfe
    0x81, 0x00,                    //   INPUT (Data,Ary,Abs)
    0xc0,                          // END_COLLECTION
};

Keyboard_::Keyboard_(void) 
{
  static HIDSubDescriptor node(_hidReportDescriptor, sizeof(_hidReportDescriptor));
  HID().AppendDescriptor(&node);
}

void Keyboard_::begin(void)
{
}

void Keyboard_::end(void)
{
}

void Keyboard_::sendReport(KeyReport* keys)
{
  HID().SendReport(2,keys,sizeof(KeyReport));
}

extern
const uint16_t _asciimap[128] PROGMEM;

#define SHIFT 0x8000

const uint16_t _asciimap[128] =
{
  0x00,        // NUL
  0x00,        // SOH
  0x00,        // STX
  0x00,        // ETX
  0x00,        // EOT
  0x00,        // ENQ
  0x00,        // ACK
  0x00,        // BEL
  0x2a,        // BS   Backspace
  0x2b,        // TAB  Tab
  0x28,        // LF   Enter
  0x00,        // VT
  0x00,        // FF
  0x00,        // CR
  0x00,        // SO
  0x00,        // SI
  0x00,        // DEL
  0x00,        // DC1
  0x00,        // DC2
  0x00,        // DC3
  0x00,        // DC4
  0x00,        // NAK
  0x00,        // SYN
  0x00,        // ETB
  0x00,        // CAN
  0x00,        // EM
  0x00,        // SUB
  0x00,        // ESC
  0x00,        // FS
  0x00,        // GS
  0x00,        // RS
  0x00,        // US
 
  0x2c,        // " "
  0x1e|SHIFT,  // !
  0x1f|SHIFT,  // "
  0x20|SHIFT,  // #
  0x21|SHIFT,  // $
  0x22|SHIFT,  // %
  0x23|SHIFT,  // &
  0x24|SHIFT,  // '
  0x25|SHIFT,  // (
  0x26|SHIFT,  // )
  0x34|SHIFT,  // *
  0x33|SHIFT,  // +
  0x36,        // ,
  0x2d,        // -
  0x37,        // .
  0x38,        // /
  0x27,        // 0
  0x1e,        // 1
  0x1f,        // 2
  0x20,        // 3
  0x21,        // 4
  0x22,        // 5
  0x23,        // 6
  0x24,        // 7
  0x25,        // 8
  0x26,        // 9
  0x34,        // :
  0x33,        // ;
  0x36|SHIFT,  // <
  0x2d|SHIFT,  // =
  0x37|SHIFT,  // >
  0x38|SHIFT,  // ?
  0x2f,        // @
  0x04|SHIFT,  // A
  0x05|SHIFT,  // B
  0x06|SHIFT,  // C
  0x07|SHIFT,  // D
  0x08|SHIFT,  // E
  0x09|SHIFT,  // F
  0x0a|SHIFT,  // G
  0x0b|SHIFT,  // H
  0x0c|SHIFT,  // I
  0x0d|SHIFT,  // J
  0x0e|SHIFT,  // K
  0x0f|SHIFT,  // L
  0x10|SHIFT,  // M
  0x11|SHIFT,  // N
  0x12|SHIFT,  // O
  0x13|SHIFT,  // P
  0x14|SHIFT,  // Q
  0x15|SHIFT,  // R
  0x16|SHIFT,  // S
  0x17|SHIFT,  // T
  0x18|SHIFT,  // U
  0x19|SHIFT,  // V
  0x1a|SHIFT,  // W
  0x1b|SHIFT,  // X
  0x1c|SHIFT,  // Y
  0x1d|SHIFT,  // Z
  0x30,        // [
  0x89,        // Yen(Backslash)
  0x31,        // ]
  0x2e,        // ^
  0x87|SHIFT,  // _
  0x2f|SHIFT,  // @
  0x04,        // a
  0x05,        // b
  0x06,        // c
  0x07,        // d
  0x08,        // e
  0x09,        // f
  0x0a,        // g
  0x0b,        // h
  0x0c,        // i
  0x0d,        // j
  0x0e,        // k
  0x0f,        // l
  0x10,        // m
  0x11,        // n
  0x12,        // o
  0x13,        // p
  0x14,        // q
  0x15,        // r
  0x16,        // s
  0x17,        // t
  0x18,        // u
  0x19,        // v
  0x1a,        // w
  0x1b,        // x
  0x1c,        // y
  0x1d,        // z
  0x30|SHIFT,  // {
  0x89|SHIFT,  // |
  0x31|SHIFT,  // }
  0x2e|SHIFT,  // ~
  0            // DEL
};


uint8_t USBPutChar(uint8_t c);

// press() adds the specified key (printing, non-printing, or modifier)
// to the persistent key report and sends the report.  Because of the way 
// USB HID works, the host acts like the key remains pressed until we 
// call release(), releaseAll(), or otherwise clear the report and resend.
size_t Keyboard_::press(uint8_t k) 
{
  uint8_t i;
  uint16_t c;

  if (k >= 0xf8) {          // it's a modifier key
    _keyReport.modifiers |= (1 << (k-0xf8));
    k = 0;
  } else if (k >= 0x80){    // it's a non-printing key and KANJI key
    k -= 0x58;
  } else {                  // it's a printing key
    c = pgm_read_word(_asciimap + k);
    k = uint8_t(c) & 0xff;
    if (!c) {
      setWriteError();
      return 0;
    }
    if (c & SHIFT) {
      _keyReport.modifiers |= 0x02;
    }
  }

  // Add k to the key report only if it's not already present
  // and if there is an empty slot.
  if (_keyReport.keys[0] != k && _keyReport.keys[1] != k && 
    _keyReport.keys[2] != k && _keyReport.keys[3] != k &&
    _keyReport.keys[4] != k && _keyReport.keys[5] != k) {
    
    for (i=0; i<6; i++) {
      if (_keyReport.keys[i] == 0x00) {
        _keyReport.keys[i] = k;
        break;
      }
    }
    if (i == 6) {
      setWriteError();
      return 0;
    }  
  }
  sendReport(&_keyReport);
  return 1;
}

// release() takes the specified key out of the persistent key report and
// sends the report.  This tells the OS the key is no longer pressed and that
// it shouldn't be repeated any more.
size_t Keyboard_::release(uint8_t k) 
{
  uint8_t i;
  uint16_t c;

  if (k >= 0xf8) {          // it's a modifier key
    _keyReport.modifiers &= ~(1<<(k-0xf8));
    k = 0;
  } else if (k >= 0x80) {   // it's a non-printing key and KANJI key
    k -= 0x58;
  } else {                  // it's printing key
    c = pgm_read_word(_asciimap + k);
    k = uint8_t(c) & 0xff;
    if (!k) {
      return 0;
    }
    if (c & SHIFT) {
      _keyReport.modifiers &= ~(0x02);
    }
  }

  // Test the key report to see if k is present.  Clear it if it exists.
  // Check all positions in case the key is present more than once (which it shouldn't be)
  for (i=0; i<6; i++) {
    if (0 != k && _keyReport.keys[i] == k) {
      _keyReport.keys[i] = 0x00;
    }
  }

  sendReport(&_keyReport);
  return 1;
}

void Keyboard_::releaseAll(void)
{
  _keyReport.keys[0] = 0;
  _keyReport.keys[1] = 0;
  _keyReport.keys[2] = 0;
  _keyReport.keys[3] = 0;
  _keyReport.keys[4] = 0;
  _keyReport.keys[5] = 0;
  _keyReport.modifiers = 0;
  sendReport(&_keyReport);
}

size_t Keyboard_::write(uint8_t c)
{  
  uint8_t p = press(c);  // Keydown
  release(c);            // Keyup
  return p;              // just return the result of press() since release() almost always returns 1
}

size_t Keyboard_::pressRaw(uint8_t k) {
  uint8_t  i;
  
  if(!k){
    return 0;
  }

  // Add k to the key report only if it's not already present
  // and if there is an empty slot.
  if (_keyReport.keys[0] != k && _keyReport.keys[1] != k && 
    _keyReport.keys[2] != k && _keyReport.keys[3] != k &&
    _keyReport.keys[4] != k && _keyReport.keys[5] != k) {
    
    for (i=0; i<6; i++) {
      if (_keyReport.keys[i] == 0x00) {
        _keyReport.keys[i] = k;
        break;
      }
    }
    if (i == 6) {
      // setWriteError();
      return 0;
    }  
  }
  sendReport(&_keyReport);
  return 1;
}

size_t Keyboard_::releaseRaw(uint8_t k) {
  uint8_t i;
  if (!k) {
    return 0;
  }

  // Test the key report to see if k is present.  Clear it if it exists.
  // Check all positions in case the key is present more than once (which it shouldn't be)
  for (i=0; i<6; i++) {
    if (0 != k && _keyReport.keys[i] == k) {
      _keyReport.keys[i] = 0x00;
    }
  }

  sendReport(&_keyReport);
  return 1;
}

size_t Keyboard_::writeRaw(uint8_t c)
{  
  uint8_t p = pressRaw(c);  // Keydown
  releaseRaw(c);            // Keyup
  return p;                 // just return the result of press() since release() almost always returns 1
}

Keyboard_ Keyboard;

#endif

以下は、サンプルスケッチ(Keyboar_jp使用例)です。Digital Pin 2-GND間、Digital Pin 4-GND間に接続したタクトスイッチを押下すると、円記号を含む文字列を出力します。Pin 2ボタン押下時はKeyboard.write、Keyboard.printを使用して出力、Pin4ボタン押下時はKeyboard.writeRawを使用して出力しています。

[ Keyboard_jp_test ]
/*
 * Keyboard_jp サンプルスケッチ
 * Written by Toshiyuki UENO
 */

#include  "Keyboard_jp.h"

// define Button Pin Number
// Button[0] = 2, Button[1] = 4
const int BUTTON[] = { 2, 4 };

void setup() {
  int i;
  for( i = 0; i <= 1; i++ ){
    pinMode(BUTTON[i], INPUT_PULLUP);
  }
  Keyboard.begin();
  delay(1000);  // wait for initialization
}

void loop() {
  int i;
  for( i = 0; i <= 1; i++ ){
    if( !digitalRead(BUTTON[i]) ){
      if( i == 0 ){                       // if press button[0]                 
        Keyboard.write('a');
        Keyboard.write('A');
        Keyboard.write('_');
        Keyboard.write('\\');
        Keyboard.write(KEY_RETURN);
        delay(100);
        Keyboard.print("aA_\\");
        Keyboard.write(KEY_RETURN);
      } else if( i == 1 ){                // if press button[1]
        Keyboard.writeRaw(0x04);   // 'a'
        Keyboard.pressRaw(0xe1);   // press LeftShift
        Keyboard.writeRaw(0x04);   // 'A'
        Keyboard.writeRaw(0x87);   // '_'
        Keyboard.releaseRaw(0xe1); // release LeftShift
        Keyboard.writeRaw(0x89);   // '\'
        Keyboard.writeRaw(0x28);   // Return(ENTER)
      }
      delay(100);                         // button debounce
      while( !digitalRead(BUTTON[i]) ){}; // wait button release
      delay(100);                         // button debounce
    }
  }
}

【謝辞】
Keyboard_jpライブラリの作成にあたり、「まごころ誠実堂~Arduinoで任意のUSBコードを送る 解決編」を参考にさせていただきました。



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

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

  • 出版社/メーカー: Arduino
  • メディア: 付属品



サインスマート(SainSmart) レオナルド 互換 Leonardo R3 ケーブル付 ブラック

サインスマート(SainSmart) レオナルド 互換 Leonardo R3 ケーブル付 ブラック

  • 出版社/メーカー: サインスマート(SainSmart)
  • メディア: おもちゃ&ホビー