見出し画像

P004 Bluetooth Keyboard Skecth

DSair2用に開発をしたWiFi DCC Throttle P-004(写真中央)の、ハードウェアはESP32C3(M5StampC3)、キーパッド、ロータリエンコーダスイッチ、OLEDディスプレイを組み合わせたものになっています。

ESP32はWiFiの他にBleutooth通信機能をもっています。このBleutooth通信機能を使って、シリアル通信リモコン、Keyboard、Mouse等のアプリケーションを適用することが可能です。

今回はBleutooth Keyboardのスケッチを書いてみました。

このスケッチで何かが出来るわけでは無いのですが、キーパッドとエンコーダスイッチで色々なことができることに気付いて頂けますと嬉しいです。

今、僕はadobe  lightroomのコントローラーを開発しています。うまく作れましたら、こちらのスケッチを公開したいと思います。

//
// Bluetooth Keyboard for HMX P-004
//
// BleKeyboard.hは
// https://github.com/T-vK/ESP32-BLE-Keyboard
// の非公式バージョンのESP32-BLE-Keyboard.0.3.3を使用します。
//
 #include  <Adafruit_SSD1306.h> #include  <RotaryEncoder.h> #include  <Adafruit_NeoPixel.h> #include  <Keypad.h> #include  "BleKeyboard.h"
 #define  SW_VERSION 1.00
 #define  SCREEN_WIDTH 128 // OLED display width, in pixels #define  SCREEN_HEIGHT 32 // OLED display height, in pixels #define  OLED_RESET    -1 // Reset pin # (or -1 if sharing Arduino reset pin) #define  SCREEN_ADDRESS 0x3C //< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
 #define  LED_PIN 2 #define  Enc_1A_PIN 19 #define  Enc_1B_PIN 4 #define  SW_1_PIN 20

const byte ROWS = 3; // To avoid the problem of M5Stamp, ROWS and COLS are changed.
const byte COLS = 4; //

char keys[ROWS][COLS] = {
  {'1', '4', '7', '*'},
  {'2', '5', '8', '0'},
  {'3', '6', '9', '#'},
};

byte rowPins[ROWS] = {1, 10, 7};
byte colPins[COLS] = {6, 5, 18, 21};

// OLED Display //
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// BleKeyboard //
BleKeyboard bleKeyboard("BT KB"); //デバイスの名前を指定できます

// Initialize keyboard layout //
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

// create a pixel strand with 1 pixel on PIN_NEOPIXEL
Adafruit_NeoPixel pixels(1, LED_PIN);

// Encoder //
RotaryEncoder* encoder1 = nullptr;
IRAM_ATTR void checkPosition() {
  encoder1->tick();
}

void setup() {

  delay(100);
  pixels.setPixelColor(0, pixels.Color(255, 0, 0));
  pixels.setBrightness(8);
  pixels.show();
  delay(100);

  // OLED Display //
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    delay(100);
    pixels.setPixelColor(0, pixels.Color(255, 0, 0));
    pixels.show();
    pixels.setBrightness(255);
    for (;;); // Don't proceed, loop forever
  }
  delay(100);
  pixels.setPixelColor(0, pixels.Color(32, 32, 32));
  pixels.show();
  delay(100);

  // Encoder //  必ずOLEDより後に入れる。
  encoder1 = new RotaryEncoder(Enc_1A_PIN, Enc_1B_PIN, RotaryEncoder::LatchMode::TWO03);
  attachInterrupt(digitalPinToInterrupt(Enc_1A_PIN), checkPosition, CHANGE);
  attachInterrupt(digitalPinToInterrupt(Enc_1B_PIN), checkPosition, CHANGE);

  char TextVal[50];
  snprintf(TextVal, 50, "BT KB     ver%4.2f" , SW_VERSION );
  Draw_Text2(TextVal);
  delay(100);
  bleKeyboard.begin();

  // Switch //
  pinMode( SW_1_PIN, INPUT_PULLUP );
  pixels.setPixelColor(0, pixels.Color(0, 64, 0));
  pixels.show();

}

void loop() {

  // 変数定義 //
  static unsigned long Update_time = millis();
  static unsigned long Elapsed_time = millis();

  if (bleKeyboard.isConnected()) {   //接続されているとき
    if (readEncoder(true) == false ) {
      if (readKeypad(true) == false ) {
        readSW();
      }
    }
    delay(10);
  } else {
    delay(3000);
    if (bleKeyboard.isConnected() == false) {
      ESP.restart();
    }
  }
}

//---------------------------------------------------------------------
// readEncoder()
//---------------------------------------------------------------------
bool readEncoder(bool bt_excute) {

  static int Ex_pos1 = 0;

  // 状態取得 //
  encoder1->tick(); // just call tick() to check the state.
  int newPos1 = encoder1->getPosition();

  // ダイアル //
  if (Ex_pos1 != newPos1) {
    delay(50);
    encoder1->tick(); // just call tick() to check the state.
    newPos1 = encoder1->getPosition();
    if (bt_excute) {
      if (Ex_pos1 != newPos1) {
        char TextVal[50];
        snprintf(TextVal, 50, "%d" , newPos1 - Ex_pos1 );
         bleKeyboard.print(TextVal);
        snprintf(TextVal, 50, "Encoder=%d" , newPos1 - Ex_pos1 );
        Draw_Text2(TextVal);
        Ex_pos1 = newPos1 ;
        return true;
      } else {
        return false;
      }
    }
  }
}

//---------------------------------------------------------------------
// readKeypad()
//---------------------------------------------------------------------
bool readKeypad(bool bt_excute) {

  char key = keypad.getKey();
  char TextVal[50];

  if (key != NO_KEY)
  {
    bleKeyboard.print(key); // PCによっては*や#が他のキーとして認識される場合があります。
    snprintf(TextVal, 50, "Key = %c" , key );
    Draw_Text2(TextVal);
    return true;
  } else {
    return false;
  }
}

//---------------------------------------------------------------------
// readSW()
//---------------------------------------------------------------------
void readSW()
{
  static int Ex_SW1 = 0;
  int SW1 = digitalRead(SW_1_PIN);

  // SW //
  if (SW1 != Ex_SW1) {
    if (SW1 == 0) {
      char TextVal[50];
      bleKeyboard.print("On");
      snprintf(TextVal, 50, "%s" , "SW = ON" );
      Draw_Text2(TextVal);
    }
    Ex_SW1 = SW1;
  } else {
    // Nothing
  }
}

//---------------------------------------------------------------------
// Draw_Text()
//---------------------------------------------------------------------
void Draw_Text1(char info[]) {
  display.setTextSize(1);
  display.clearDisplay() ;
  display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
  display.setCursor(0, 0);
  display.print(info);
  display.display();
}
void Draw_Text2(char info[]) {
  display.setTextSize(2);
  display.clearDisplay() ;
  display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
  display.setCursor(0, 0);
  display.print(info);
  display.display();
}
void Draw_Text2_WB(char info[]) {
  display.setTextSize(2);
  display.clearDisplay() ;
  display.fillRect(  0,  0, SCREEN_WIDTH, SCREEN_HEIGHT, WHITE ) ;
  display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
  display.setCursor(1, 0);
  display.print(info);
  display.display();
}


この記事が気に入ったらサポートをしてみませんか?