SSブログ

中華Arduino Pro Miniのクロックの見分け方 [Arduino]

Arduino Pro Mini互換の中華Pro Miniをまとめて購入してみました。

中華Pro Miniは価格が安く、まとめ買いしてもお財布に優しいのです。Unoよりはるかにコンパクトなので、保管スペースに困ることもありませぬ。

ただし、PCに接続してスケッチを書き込むにはUSB-TTLシリアルコンバータが必要です。Pro Mini単体では、PCと接続できません。

それからもうひとつの弱点は、3.3V/8MHzタイプと5V/16MHzタイプをごちゃまぜにすると、見分けるのが困難になってしまうことww

中華promini1.jpg
↑一方は3.3V/8MHz、もう一方は5V/16MHz。キミは見分けることができるかな? 拙者は見分けられないヨ!


そんなときは、通電すれば一目瞭然。3.3V/8MHzタイプと5V/16MHzタイプとでは、POWER ON LEDの色が異なるのです。

中華promini2.jpg
中華promini3.jpg
↑3.3V/8MHzタイプはPOWER ON LEDが緑色に、5V/16MHzタイプは赤く点灯する。

通電時には周辺回路を外した状態、つまりPro Mini単体に3.3V印加することをおすすめします。5V基板も3.3V印加でLEDが点灯するので判別可能です。

できればごちゃまぜになる前に、見分けがつくようラベルを貼って管理したり、基板裏の周波数/電圧チェックボックスに油性マジックでマーキングしておくのがベストなんですけどね。


EasyWordMall Pro Mini モジュール Atmega328 3.3V 8M Arduino用

EasyWordMall Pro Mini モジュール Atmega328 3.3V 8M Arduino用

  • 出版社/メーカー: Apple Trees E-commerce co., LT
  • メディア: その他

EasyWordMall Pro Mini モジュール Atmega328 5V 16M Arduino用

EasyWordMall Pro Mini モジュール Atmega328 5V 16M Arduino用

  • 出版社/メーカー: Apple Trees E-commerce co., LT
  • メディア: その他




nice!(0)  コメント(0) 
共通テーマ:日記・雑感

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)
  • メディア: おもちゃ&ホビー



この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。