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();
}
この記事が気に入ったらサポートをしてみませんか?