Подставка с кнопками для 3Dconnexion SpaceMouse Wireless

nc750s

✩✩✩✩✩✩✩
7 Июн 2023
1
3
Всем добрый день,

решил поделиться своим небольшим проэктом. Пользуюсь уже полгода и очень доволен :) Буду рад если кому-то понравится или может кто-то захочет развить проэкт.

Продукт: подставка с кнопками для 3Dconnexion SpaceMouse Wireless

Функционал: позволяет запрограммировать девять кнопок и для комфорта использовать в программе 3D моделирования, например Fusion 360. Ну и руке удобнее )) . На дисплее можо вывести раскладку кнопок. Включить или выключить подсветку кнопок.

Детали:
Adafruit ItsyBitsy 32u4 - 5V 16MHz (можно Arduino с чипом ATmega32u4, но тогда проверить распиновку!)
9x 12мм кнопок с подсветкой без фиксации
2x 12мм кнопоки с подсветкой с фиксацией
дисплей 1.3 inch OLED Module SPI 128X64
2x M4 18мм
1x M3 12мм

Интерфейс и настройка: Все настройки производятся в коде. Подлючается к компютеру по USB.

Пара фотографий:
connection diagram.png
mouse1.jpeg
mouse2.jpeg
1672248541245.jpg


Скачать детали можно здесь: https://www.thingiverse.com/thing:5751236

Код для Adafruit / Arduino:
Код для Adafruit / Arduino::
// Define Buttons
#define BTN_PIN_5 5    // Display mode
#define BTN_PIN_7 7    // Ctrl
#define BTN_PIN_8 8    // Shift
#define BTN_PIN_9 9    // LED on/off
#define BTN_PIN_11 11  // Alt
#define BTN_PIN_12 12  // TAB
#define BTN_PIN_13 13  // F6
#define BTN_PIN_18 18  // Del
#define BTN_PIN_19 19  // ESC
#define BTN_PIN_20 20  // P
#define BTN_PIN_21 21  // S

// Define Display
#define OLED_MOSI     16
#define OLED_CLK      15
#define OLED_DC       4
#define OLED_CS       10
#define OLED_RST      6

// Define LED Power PINs
#define LED_POWER_1   22
#define LED_POWER_2   23
#define LED_POWER_3   1

// Includes for Buttons
#include <VirtualButton.h>
#include <Keyboard.h>
#include <Keyboard_de_DE.h>

// Includes for Display
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>

// Create the OLED display
Adafruit_SH1106G display = Adafruit_SH1106G(128, 64, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RST, OLED_CS);

// Create Buttons
VButton btn5;
VButton btn7;
VButton btn8;
VButton btn9;
VButton btn11;
VButton btn12;
VButton btn13;
VButton btn18;
VButton btn19;
VButton btn20;
VButton btn21;

// Buttons labels
const char btn5Name[] = "Display mode";
const char btn7Name[] = "Ctrl";
const char btn8Name[] = "Shift";
const char btn9Name[] = "LED on/off";
const char btn11Name[] = "Alt";
const char btn12Name[] = "TAB";
const char btn13Name[] = "F6";
const char btn18Name[] = "Del";
const char btn19Name[] = "ESC";
const char btn20Name[] = "P";
const char btn21Name[] = "S";

// Logo 'W', 128x64px
const unsigned char epd_bitmap_logo_w [] PROGMEM = {
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x3f, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xe1, 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xfe, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xfc, 0x07, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xf0, 0x1f, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x70, 0x3f, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x70, 0xff, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x71, 0xff, 0xf1, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x77, 0xff, 0xe0, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xe1, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xc1, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xc1, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xdc, 0x3f, 0xff, 0x81, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0x9c, 0x3f, 0xff, 0x81, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0x1c, 0x3f, 0xff, 0x01, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xfe, 0x0c, 0x1f, 0xff, 0x01, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xf8, 0x1e, 0x1f, 0xfe, 0x01, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xf8, 0x3e, 0x1f, 0xfe, 0x03, 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xf0, 0x7e, 0x1f, 0xfc, 0x43, 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xe0, 0xfe, 0x1f, 0xfc, 0xe3, 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xc1, 0xfe, 0x1f, 0xf8, 0xe3, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0x83, 0xfe, 0x1f, 0xf9, 0xe3, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0x07, 0xfe, 0x1f, 0xf1, 0xc3, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0x1f, 0xf3, 0xc3, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0x1f, 0xe3, 0xc3, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0x1f, 0xe7, 0xc3, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x0f, 0xc7, 0xc3, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x0f, 0xcf, 0xc3, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x9f, 0xc3, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x9f, 0xc3, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x3f, 0xc3, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x3f, 0xc3, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0e, 0x7f, 0xc3, 0xff, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0e, 0x7f, 0xe3, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0c, 0xff, 0xe1, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0xff, 0xe1, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xe1, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xe0, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xe0, 0x61, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};

bool display_mode = true;
bool LED_On_Off = false;

void setup() {
  Serial.begin(9600);
  delay(300);

  // Display
  display.begin(0, true);
  delay(1000);
  display.display();

  display.setRotation(2);
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SH110X_WHITE);
  display.setCursor(0, 0);

  display.print(btn20Name); display.print("        "); display.print(btn19Name); display.print("     "); display.print(btn18Name);
  display.println();
  display.println();
  display.println();
  display.print("  "); display.print(btn8Name); display.print("        "); display.println(btn21Name);
  display.println();
  display.print(" "); display.print(btn7Name); display.print("             "); display.println(btn13Name);
  display.println();
  display.print(btn11Name); display.print("         "); display.println(btn12Name);
  display.display();

  // German keyboard layout
  Keyboard.begin(KeyboardLayout_de_DE);

  pinMode(BTN_PIN_5, INPUT_PULLUP);
  pinMode(BTN_PIN_7, INPUT_PULLUP);
  pinMode(BTN_PIN_8, INPUT_PULLUP);
  pinMode(BTN_PIN_9, INPUT_PULLUP);
  pinMode(BTN_PIN_11, INPUT_PULLUP);
  pinMode(BTN_PIN_12, INPUT_PULLUP);
  pinMode(BTN_PIN_13, INPUT_PULLUP);
  pinMode(BTN_PIN_18, INPUT_PULLUP);
  pinMode(BTN_PIN_19, INPUT_PULLUP);
  pinMode(BTN_PIN_20, INPUT_PULLUP);
  pinMode(BTN_PIN_21, INPUT_PULLUP);

  pinMode(LED_POWER_1, OUTPUT); digitalWrite(LED_POWER_1, HIGH);
  pinMode(LED_POWER_2, OUTPUT); digitalWrite(LED_POWER_2, HIGH);
  pinMode(LED_POWER_3, OUTPUT); digitalWrite(LED_POWER_3, HIGH);
}

void loop() {
  btn5.poll(!digitalRead(BTN_PIN_5));
  btn7.poll(!digitalRead(BTN_PIN_7));
  btn8.poll(!digitalRead(BTN_PIN_8));
  btn9.poll(!digitalRead(BTN_PIN_9));
  btn11.poll(!digitalRead(BTN_PIN_11));
  btn12.poll(!digitalRead(BTN_PIN_12));
  btn13.poll(!digitalRead(BTN_PIN_13));
  btn18.poll(!digitalRead(BTN_PIN_18));
  btn19.poll(!digitalRead(BTN_PIN_19));
  btn20.poll(!digitalRead(BTN_PIN_20));
  btn21.poll(!digitalRead(BTN_PIN_21));

  // PIN5 - Display mode
  if (btn5.click()) {
    display_mode = !display_mode;
    if (display_mode) {
      display.clearDisplay();
      display.setCursor(0, 0);

      display.print(btn20Name); display.print("        "); display.print(btn19Name); display.print("     "); display.print(btn18Name);
      display.println();
      display.println();
      display.println();
      display.print("  "); display.print(btn8Name); display.print("        "); display.println(btn21Name);
      display.println();
      display.print(" "); display.print(btn7Name); display.print("             "); display.println(btn13Name);
      display.println();
      display.print(btn11Name); display.print("         "); display.println(btn12Name);

      display.display();
    } else {
      display.clearDisplay();
      display.drawBitmap(0, 0,  epd_bitmap_logo_w, 128, 64, 1);
      display.display();
    }
  }

  // PIN9 - LED on/off
  if (btn9.click()) {
    if (LED_On_Off) {
      digitalWrite(LED_POWER_1, HIGH);
      delay(300);
      digitalWrite(LED_POWER_2, HIGH);
      delay(300);
      digitalWrite(LED_POWER_3, HIGH);
    }
    else {
      digitalWrite(LED_POWER_1, LOW);
      digitalWrite(LED_POWER_2, LOW);
      digitalWrite(LED_POWER_3, LOW);
    }
    LED_On_Off = !LED_On_Off;
  }

  // PIN 7 - Ctrl
  if (btn7.press()) {
    Keyboard.press(KEY_LEFT_CTRL);
  }
  if (btn7.release()) {
    Keyboard.release(KEY_LEFT_CTRL);
  }

  // PIN 8 - Shift
  if (btn8.press()) {
    Keyboard.press(KEY_LEFT_SHIFT);
  }
  if (btn8.release()) {
    Keyboard.release(KEY_LEFT_SHIFT);
  }

  // PIN 11 - Alt
  if (btn11.press()) {
    Keyboard.press(KEY_LEFT_ALT);
  }
  if (btn11.release()) {
    Keyboard.release(KEY_LEFT_ALT);
  }

  // PIN 12 - TAB
  if (btn12.press()) {
    Keyboard.write(KEY_TAB);
  }

  // PIN 13 - F6
  if (btn13.press()) {
    Keyboard.write(KEY_F6);
  }

  // PIN 18 - Delete
  if (btn18.press()) {
    Keyboard.write(KEY_DELETE);
  }

  // PIN 19 - ESC
  if (btn19.press()) {
    Keyboard.write(KEY_ESC);
  }

  // PIN 20 - P
  if (btn20.press()) {
    Keyboard.write('p');
  }

  // PIN 21 - S
  if (btn21.press()) {
    Keyboard.write('s');
  }
}


Всем успехов!
 
Изменено: