Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ================================================================ //
- // DEFINITIVE GUIDE: FINAL MASTER CODE FOR YOUR 4x3 BUILD //
- // ================================================================ //
- // --- LIBRARIES ---
- #include <Wire.h>
- #include <Adafruit_GFX.h>
- #include <Adafruit_SSD1306.h>
- #include <Adafruit_NeoPixel.h>
- #include <HID-Project.h>
- #include <Encoder.h>
- #include <Keypad.h>
- // --- HARDWARE CONFIGURATION ---
- #define SCREEN_WIDTH 128
- #define SCREEN_HEIGHT 64
- #define OLED_RESET -1
- Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
- #define LED_PIN 1 // Using the RX pin
- #define LED_COUNT 12
- Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
- #define VOL_ENCODER_A A0
- #define VOL_ENCODER_B A1
- #define VOL_ENCODER_SW A2
- #define PAGE_ENCODER_A 15
- #define PAGE_ENCODER_B 16
- #define PAGE_ENCODER_SW 14
- const int hotkeyPin = A3;
- Encoder volumeEncoder(VOL_ENCODER_A, VOL_ENCODER_B);
- Encoder pageEncoder(PAGE_ENCODER_A, PAGE_ENCODER_B);
- long lastVolumePos = -999, lastPagePos = -999;
- // 8================================================================ //
- // KEY MATRIX SETUP -- PERSONALIZE THIS WITH YOUR MAP //
- // ================================================================ //
- const byte PHYSICAL_ROWS = 4;
- const byte PHYSICAL_COLS = 3;
- // <<< CRITICAL STEP: EDIT THIS MAP! >>>
- // Replace the numbers below with the map you wrote down from the diagnostic test.
- // Remember that 'A' is 10 and 'B' is 11.
- char keys[PHYSICAL_ROWS][PHYSICAL_COLS] = {
- {0, 1, 2}, // Replace with your measured top row
- {3, 4, 5}, // Replace with your measured second row
- {6, 7, 8}, // Replace with your measured third row
- {9, 10, 11} // Replace with your measured bottom row
- };
- byte physicalRowPins[PHYSICAL_ROWS] = {10, 9, 8, 7};
- byte physicalColPins[PHYSICAL_COLS] = {6, 5, 4};
- Keypad customKeypad = Keypad(makeKeymap(keys), physicalColPins, physicalRowPins, PHYSICAL_COLS, PHYSICAL_ROWS);
- // ================================================================ //
- // PRIMARY CUSTOMIZATION SECTION //
- // ================================================================ //
- int ledBrightness = 70;
- int effectInterval = 20;
- uint32_t colors[] = { strip.Color(255, 0, 0), strip.Color(0, 0, 255), strip.Color(255, 100, 0) };
- #define NUM_PAGES 3
- const char* PAGE_TITLES[NUM_PAGES] = { "Work", "Gaming", "Media" };
- const char* MACRO_NAMES[NUM_PAGES][12] = {
- {"Copy","Paste","Cut", "Undo","Save","Del", "Up","Sig","Left", "Down","Right","Deafen"},
- {"P2Talk","Jump","Reload", "Melee","Use","Map", "Inv.","Crouch","Ping", "Sprint","Gadget","Heal"},
- {"Play","Next","Prev", "Vol+","Vol-","Mute", "Scn 1","Scn 2","Stream", "Record","Replay","Clip"}
- };
- int currentPage = 2;
- #define NUM_MODES 4
- int currentMode = 0;
- bool ledsOn = true;
- int currentColorIndex = 0;
- const int numColors = sizeof(colors) / sizeof(uint32_t);
- unsigned long lastEffectUpdate = 0;
- // ================================================================
- // CORE PROGRAM LOGIC
- // ================================================================
- void setup() {
- pinMode(hotkeyPin, INPUT_PULLUP); pinMode(VOL_ENCODER_SW, INPUT_PULLUP); pinMode(PAGE_ENCODER_SW, INPUT_PULLUP);
- if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { for(;;); }
- strip.begin(); strip.setBrightness(ledBrightness); strip.show();
- Consumer.begin(); Keyboard.begin();
- updateOLED();
- }
- void loop() {
- handleButtons(); handleEncoderButtons(); handleEncoders(); updateLighting();
- }
- void handleButtons() {
- if (customKeypad.getKeys()) {
- bool hotkeyState = (digitalRead(hotkeyPin) == LOW);
- for (int i=0; i<LIST_MAX; i++) {
- if (customKeypad.key[i].stateChanged && customKeypad.key[i].kstate == PRESSED) {
- if (hotkeyState) { handleHotkeyAction(customKeypad.key[i].kcode); }
- else { executeMacro(currentPage, customKeypad.key[i].kcode); }
- }
- }
- }
- }
- void handleEncoders() {
- long vPos=volumeEncoder.read(); long pPos=pageEncoder.read();
- if (vPos!=lastVolumePos) { if (vPos>lastVolumePos) Consumer.write(MEDIA_VOLUME_UP); else Consumer.write(MEDIA_VOLUME_DOWN); lastVolumePos=vPos; }
- if (pPos!=lastPagePos) { int dir=(pPos>lastPagePos)?1:-1; currentPage=(currentPage+dir+NUM_PAGES)%NUM_PAGES; updateOLED(); lastPagePos=pPos; }
- }
- void handleHotkeyAction(int buttonIndex) {
- switch (buttonIndex) {
- case 0: ledsOn = !ledsOn; break;
- case 1: currentMode = (currentMode + 1) % NUM_MODES; break;
- case 2: if (currentMode == 0) { currentColorIndex = (currentColorIndex + 1) % numColors; } break;
- case 3: ledBrightness += 50; if (ledBrightness > 255) ledBrightness = 20; strip.setBrightness(ledBrightness); break;
- }
- if (buttonIndex != 3) { staticColor(); }
- }
- void updateOLED() {
- display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE);
- display.setCursor(0, 4);
- display.print("Page "); display.print(currentPage + 1); display.print("/");
- display.print(NUM_PAGES); display.print(": "); display.print(PAGE_TITLES[currentPage]);
- const int gridStartY = 16;
- int boxWidth = SCREEN_WIDTH / 3; int boxHeight = (SCREEN_HEIGHT - gridStartY) / 4;
- for (int row = 0; row < 4; row++) {
- for (int col = 0; col < 3; col++) {
- int buttonIndex = row * 3 + col; int16_t x1,y1; uint16_t w,h;
- display.getTextBounds(MACRO_NAMES[currentPage][buttonIndex],0,0,&x1,&y1,&w,&h);
- display.setCursor((col*boxWidth)+((boxWidth-w)/2), gridStartY+(row*boxHeight)+((boxHeight-h)/2));
- display.print(MACRO_NAMES[currentPage][buttonIndex]);
- }
- }
- display.display();
- }
- void updateLighting() {
- if (!ledsOn) { strip.fill(0); strip.show(); return; }
- if (millis()-lastEffectUpdate > effectInterval) {
- lastEffectUpdate=millis();
- switch (currentMode) {
- case 0: staticColor(); break; case 1: rainbowCycle(); break;
- case 2: colorWipe(colors[currentColorIndex], 50); break;
- case 3: theaterChase(colors[currentColorIndex], 50); break;
- }
- }
- }
- void staticColor() { strip.fill(colors[currentColorIndex]); strip.show(); }
- void rainbowCycle() { static uint16_t h=0; strip.rainbow(h,1,255,100,true); h+=256; strip.show(); }
- void colorWipe(uint32_t c, uint8_t wait) { static int i=0; strip.setPixelColor(i,c); strip.show(); i=(i+1)%strip.numPixels(); if(i==0) strip.fill(0); }
- void theaterChase(uint32_t c, uint8_t wait) { static int j=0,q=0; if(j%wait==0){ for(int i=0;i<strip.numPixels();i=i+3) strip.setPixelColor(i+q,c); strip.show(); for(int i=0;i<strip.numPixels();i=i+3) strip.setPixelColor(i+q,0); q=(q+1)%3; } j++; }
- // ================================================================ //
- // MACRO CUSTOMIZATION SECTION //
- // ================================================================ //
- void handleEncoderButtons() {
- if (digitalRead(VOL_ENCODER_SW) == LOW) {
- Consumer.write(MEDIA_VOLUME_MUTE);
- delay(200);
- }
- if (digitalRead(PAGE_ENCODER_SW) == LOW) {
- Keyboard.write(KEY_RETURN);
- delay(200);
- }
- }
- void executeMacro(int page, int buttonIndex) {
- display.clearDisplay(); display.setCursor(10, 24); display.setTextSize(2);
- display.print(MACRO_NAMES[page][buttonIndex]); display.display(); delay(300); updateOLED();
- switch (page) {
- case 0: // --- PAGE 1: WORK ---
- switch (buttonIndex) {
- case 0: Keyboard.press(KEY_LEFT_CTRL); Keyboard.press('c'); delay(50); Keyboard.releaseAll(); break;
- case 1: Keyboard.press(KEY_LEFT_CTRL); Keyboard.press('v'); delay(50); Keyboard.releaseAll(); break;
- //...
- }
- break;
- case 1: /* PAGE 2 ACTIONS */ break;
- case 2: /* PAGE 3 ACTIONS */ break;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment