Guest User

Code

a guest
Jul 14th, 2025
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.78 KB | None | 0 0
  1. // ================================================================ //
  2. // DEFINITIVE GUIDE: FINAL MASTER CODE FOR YOUR 4x3 BUILD //
  3. // ================================================================ //
  4.  
  5. // --- LIBRARIES ---
  6. #include <Wire.h>
  7. #include <Adafruit_GFX.h>
  8. #include <Adafruit_SSD1306.h>
  9. #include <Adafruit_NeoPixel.h>
  10. #include <HID-Project.h>
  11. #include <Encoder.h>
  12. #include <Keypad.h>
  13.  
  14. // --- HARDWARE CONFIGURATION ---
  15. #define SCREEN_WIDTH 128
  16. #define SCREEN_HEIGHT 64
  17. #define OLED_RESET -1
  18. Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
  19.  
  20. #define LED_PIN 1 // Using the RX pin
  21. #define LED_COUNT 12
  22. Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
  23.  
  24. #define VOL_ENCODER_A A0
  25. #define VOL_ENCODER_B A1
  26. #define VOL_ENCODER_SW A2
  27. #define PAGE_ENCODER_A 15
  28. #define PAGE_ENCODER_B 16
  29. #define PAGE_ENCODER_SW 14
  30. const int hotkeyPin = A3;
  31. Encoder volumeEncoder(VOL_ENCODER_A, VOL_ENCODER_B);
  32. Encoder pageEncoder(PAGE_ENCODER_A, PAGE_ENCODER_B);
  33. long lastVolumePos = -999, lastPagePos = -999;
  34.  
  35.  
  36. // 8================================================================ //
  37. // KEY MATRIX SETUP -- PERSONALIZE THIS WITH YOUR MAP //
  38. // ================================================================ //
  39. const byte PHYSICAL_ROWS = 4;
  40. const byte PHYSICAL_COLS = 3;
  41.  
  42. // <<< CRITICAL STEP: EDIT THIS MAP! >>>
  43. // Replace the numbers below with the map you wrote down from the diagnostic test.
  44. // Remember that 'A' is 10 and 'B' is 11.
  45. char keys[PHYSICAL_ROWS][PHYSICAL_COLS] = {
  46. {0, 1, 2}, // Replace with your measured top row
  47. {3, 4, 5}, // Replace with your measured second row
  48. {6, 7, 8}, // Replace with your measured third row
  49. {9, 10, 11} // Replace with your measured bottom row
  50. };
  51.  
  52. byte physicalRowPins[PHYSICAL_ROWS] = {10, 9, 8, 7};
  53. byte physicalColPins[PHYSICAL_COLS] = {6, 5, 4};
  54. Keypad customKeypad = Keypad(makeKeymap(keys), physicalColPins, physicalRowPins, PHYSICAL_COLS, PHYSICAL_ROWS);
  55.  
  56. // ================================================================ //
  57. // PRIMARY CUSTOMIZATION SECTION //
  58. // ================================================================ //
  59. int ledBrightness = 70;
  60. int effectInterval = 20;
  61. uint32_t colors[] = { strip.Color(255, 0, 0), strip.Color(0, 0, 255), strip.Color(255, 100, 0) };
  62. #define NUM_PAGES 3
  63. const char* PAGE_TITLES[NUM_PAGES] = { "Work", "Gaming", "Media" };
  64. const char* MACRO_NAMES[NUM_PAGES][12] = {
  65. {"Copy","Paste","Cut", "Undo","Save","Del", "Up","Sig","Left", "Down","Right","Deafen"},
  66. {"P2Talk","Jump","Reload", "Melee","Use","Map", "Inv.","Crouch","Ping", "Sprint","Gadget","Heal"},
  67. {"Play","Next","Prev", "Vol+","Vol-","Mute", "Scn 1","Scn 2","Stream", "Record","Replay","Clip"}
  68. };
  69. int currentPage = 2;
  70. #define NUM_MODES 4
  71. int currentMode = 0;
  72. bool ledsOn = true;
  73. int currentColorIndex = 0;
  74. const int numColors = sizeof(colors) / sizeof(uint32_t);
  75. unsigned long lastEffectUpdate = 0;
  76.  
  77. // ================================================================
  78. // CORE PROGRAM LOGIC
  79. // ================================================================
  80. void setup() {
  81. pinMode(hotkeyPin, INPUT_PULLUP); pinMode(VOL_ENCODER_SW, INPUT_PULLUP); pinMode(PAGE_ENCODER_SW, INPUT_PULLUP);
  82. if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { for(;;); }
  83. strip.begin(); strip.setBrightness(ledBrightness); strip.show();
  84. Consumer.begin(); Keyboard.begin();
  85. updateOLED();
  86. }
  87. void loop() {
  88. handleButtons(); handleEncoderButtons(); handleEncoders(); updateLighting();
  89. }
  90. void handleButtons() {
  91. if (customKeypad.getKeys()) {
  92. bool hotkeyState = (digitalRead(hotkeyPin) == LOW);
  93. for (int i=0; i<LIST_MAX; i++) {
  94. if (customKeypad.key[i].stateChanged && customKeypad.key[i].kstate == PRESSED) {
  95. if (hotkeyState) { handleHotkeyAction(customKeypad.key[i].kcode); }
  96. else { executeMacro(currentPage, customKeypad.key[i].kcode); }
  97. }
  98. }
  99. }
  100. }
  101. void handleEncoders() {
  102. long vPos=volumeEncoder.read(); long pPos=pageEncoder.read();
  103. if (vPos!=lastVolumePos) { if (vPos>lastVolumePos) Consumer.write(MEDIA_VOLUME_UP); else Consumer.write(MEDIA_VOLUME_DOWN); lastVolumePos=vPos; }
  104. if (pPos!=lastPagePos) { int dir=(pPos>lastPagePos)?1:-1; currentPage=(currentPage+dir+NUM_PAGES)%NUM_PAGES; updateOLED(); lastPagePos=pPos; }
  105. }
  106. void handleHotkeyAction(int buttonIndex) {
  107. switch (buttonIndex) {
  108. case 0: ledsOn = !ledsOn; break;
  109. case 1: currentMode = (currentMode + 1) % NUM_MODES; break;
  110. case 2: if (currentMode == 0) { currentColorIndex = (currentColorIndex + 1) % numColors; } break;
  111. case 3: ledBrightness += 50; if (ledBrightness > 255) ledBrightness = 20; strip.setBrightness(ledBrightness); break;
  112. }
  113. if (buttonIndex != 3) { staticColor(); }
  114. }
  115. void updateOLED() {
  116. display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE);
  117. display.setCursor(0, 4);
  118. display.print("Page "); display.print(currentPage + 1); display.print("/");
  119. display.print(NUM_PAGES); display.print(": "); display.print(PAGE_TITLES[currentPage]);
  120. const int gridStartY = 16;
  121. int boxWidth = SCREEN_WIDTH / 3; int boxHeight = (SCREEN_HEIGHT - gridStartY) / 4;
  122. for (int row = 0; row < 4; row++) {
  123. for (int col = 0; col < 3; col++) {
  124. int buttonIndex = row * 3 + col; int16_t x1,y1; uint16_t w,h;
  125. display.getTextBounds(MACRO_NAMES[currentPage][buttonIndex],0,0,&x1,&y1,&w,&h);
  126. display.setCursor((col*boxWidth)+((boxWidth-w)/2), gridStartY+(row*boxHeight)+((boxHeight-h)/2));
  127. display.print(MACRO_NAMES[currentPage][buttonIndex]);
  128. }
  129. }
  130. display.display();
  131. }
  132. void updateLighting() {
  133. if (!ledsOn) { strip.fill(0); strip.show(); return; }
  134. if (millis()-lastEffectUpdate > effectInterval) {
  135. lastEffectUpdate=millis();
  136. switch (currentMode) {
  137. case 0: staticColor(); break; case 1: rainbowCycle(); break;
  138. case 2: colorWipe(colors[currentColorIndex], 50); break;
  139. case 3: theaterChase(colors[currentColorIndex], 50); break;
  140. }
  141. }
  142. }
  143. void staticColor() { strip.fill(colors[currentColorIndex]); strip.show(); }
  144. void rainbowCycle() { static uint16_t h=0; strip.rainbow(h,1,255,100,true); h+=256; strip.show(); }
  145. 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); }
  146. 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++; }
  147.  
  148. // ================================================================ //
  149. // MACRO CUSTOMIZATION SECTION //
  150. // ================================================================ //
  151. void handleEncoderButtons() {
  152. if (digitalRead(VOL_ENCODER_SW) == LOW) {
  153. Consumer.write(MEDIA_VOLUME_MUTE);
  154. delay(200);
  155. }
  156. if (digitalRead(PAGE_ENCODER_SW) == LOW) {
  157. Keyboard.write(KEY_RETURN);
  158. delay(200);
  159. }
  160. }
  161. void executeMacro(int page, int buttonIndex) {
  162. display.clearDisplay(); display.setCursor(10, 24); display.setTextSize(2);
  163. display.print(MACRO_NAMES[page][buttonIndex]); display.display(); delay(300); updateOLED();
  164. switch (page) {
  165. case 0: // --- PAGE 1: WORK ---
  166. switch (buttonIndex) {
  167. case 0: Keyboard.press(KEY_LEFT_CTRL); Keyboard.press('c'); delay(50); Keyboard.releaseAll(); break;
  168. case 1: Keyboard.press(KEY_LEFT_CTRL); Keyboard.press('v'); delay(50); Keyboard.releaseAll(); break;
  169. //...
  170. }
  171. break;
  172. case 1: /* PAGE 2 ACTIONS */ break;
  173. case 2: /* PAGE 3 ACTIONS */ break;
  174. }
  175. }
Advertisement
Add Comment
Please, Sign In to add comment