#include <Adafruit_ILI9341.h> // Hardware-specific library #include <SdFat.h> // SD card & FAT filesystem library #include <Adafruit_ImageReader.h> // Image-reading functions #include <stdint.h> #include <TouchScreen.h> #include <Keyboard.h> #include <Keypad.h> //picture loader #define USE_SD_CARD #define SD_CS 4 // SD card select pin #define TFT_CS 5 // TFT select pin #define TFT_DC 6 // TFT display/command pin SdFat SD; // SD card filesystem Adafruit_ImageReader reader(SD); // Image-reader object, pass in SD filesys Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC); Adafruit_Image img; // An image loaded into RAM //Touch screen inputs #define YP A0 #define XM A3 #define YM A2 #define XP A1 #define TS_MINX 178 #define TS_MAXX 866 #define TS_MINY 137 #define TS_MAXY 880 TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300); //X and Y coordinates of the 20 Buttons -> k = German = "klein" = small (Button) int kx1 = 180, ky1 = 10; //Each touch button is 60x60 pixel int kx2 = 180, ky2 = 70; int kx3 = 180, ky3 = 130; int kx4 = 180, ky4 = 190; int kx5 = 180, ky5 = 250; int kx6 = 120, ky6 = 10; int kx7 = 120, ky7 = 70; int kx8 = 120, ky8 = 130; int kx9 = 120, ky9 = 190; int kx10 = 120, ky10 = 250; int kx11 = 60, ky11 = 10; int kx12 = 60, ky12 = 70; int kx13 = 60, ky13 = 130; int kx14 = 60, ky14 = 190; int kx15 = 60, ky15 = 250; int kx16 = 1, ky16 = 10; int kx17 = 1, ky17 = 70; int kx18 = 1, ky18 = 130; int kx19 = 1, ky19 = 190; int kx20 = 1, ky20 = 250; bool discord = true; //shows if Discord is muted or not bool mic = true; //shows if my mic is muted or not (in Discord). Not used atm bool streammic = true; //shows if my mic is muted or not (in OBS) int gui = 1; //GUI 1=main menu, 2=Stream, 3=Affinity, 4=Twitch, 5=VM Potato Macros, //Tastenfeld const byte ROWS = 4; // 4 rows x 5 columns = 20 buttons const byte COLS = 5; char keys[ROWS][COLS] = { {'1', '2', '3', '4', '5'}, {'6', '7', '8', '9', 'A'}, {'B', 'C', 'D', 'E', 'F'}, {'G', 'H', 'I', 'J', 'K'} }; byte rowPins[ROWS] = { 25, 27, 23, 29}; // I messed up the wiring. That's why the numbers are mixed up byte colPins[COLS] = { 39, 37, 35, 33, 31}; Keypad tastatur = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); void setup(void) { ImageReturnCode stat; // Status from image-reading functions Keyboard.begin(); Serial.begin(9600); tft.begin(); // Initialize screen if (!SD.begin(SD_CS, SD_SCK_MHZ(25))) { Serial.println(F("SD begin() failed")); for (;;); // Fatal error, do not continue } Serial.println(F("OK!")); tft.fillScreen(0xA3CA); //Fills Background -> Shows me that something is happening - Colors in "RGB 565" (16 Bit) stat = reader.drawBMP("/guimain.bmp", tft, 0, 0); //Loads the main menu picture reader.printStatus(stat); delay(1000); // 1 sec pause } void loop() { TSPoint p = ts.getPoint(); p.x = map(p.x, TS_MINX, TS_MAXX, 0, 240); p.y = map(p.y, TS_MINY, TS_MAXY, 0, 320); char key = tastatur.getKey(); Serial.println(key); if (gui == 1) { //main menu if (key) { //switch menus through button Serial.println(key); switch (key) { case 'C': //to the stream menu gui = 2; reader.drawBMP("/strgui.bmp", tft, 0, 0); if ( streammic == true) { reader.drawBMP("/kanmic.bmp", tft, kx7 , ky7); } else { reader.drawBMP("/kausmic.bmp", tft, kx7 , ky7); } if ( discord == true) { reader.drawBMP("/kandisc.bmp", tft, kx8 , ky8); } else { reader.drawBMP("/kausdisc.bmp", tft, kx8 , ky8); } key = 'Y'; delay(500); break; case 'D': //to the Affinity menu gui = 3; reader.drawBMP("/affgui.bmp", tft, 0, 0); p.x = 0; p.y = 0; key = 'Y'; delay(500); break; case 'E': //to the Twitch/Emote menu gui = 4; reader.drawBMP("/guiemot.bmp", tft, 0, 0); p.x = 0; p.y = 0; key = 'Y'; delay(500); break; case 'H': //to the VoiceMeter Potato menu gui = 5; reader.drawBMP("/guivmp.bmp", tft, 0, 0); p.x = 0; p.y = 0; key = 'Y'; delay(500); break; } } if (p.z > ts.pressureThreshhold) { //switch menus through the touch screen Serial.print("X = "); Serial.print(p.x); Serial.print("\tY = "); Serial.print(p.y); Serial.print("\tPressure = "); Serial.println(p.z); if (p.x > kx12 & p.x < kx12+66 & p.y > ky12 & p.y < ky12+66){//Touch to stream menu gui = 2; reader.drawBMP("/strgui.bmp", tft, 0, 0); if ( streammic == true) { reader.drawBMP("/kanmic.bmp", tft, kx7 , ky7); } else { reader.drawBMP("/kausmic.bmp", tft, kx7 , ky7); } if ( discord == true) { reader.drawBMP("/kandisc.bmp", tft, kx8 , ky8); } else { reader.drawBMP("/kausdisc.bmp", tft, kx8 , ky8); } key = 'Y'; delay(500); } if (p.x > kx13 & p.x < kx13+66 & p.y > ky13 & p.y < ky13+66){//Touch to Affinity menu gui = 3; reader.drawBMP("/affgui.bmp", tft, 0, 0); p.x = 0; p.y = 0; key = 'Y'; delay(500); } if (p.x > kx14 & p.x < kx14+66 & p.y > ky14 & p.y < ky14+66){//Touch to Twitch/emote menu gui = 4; reader.drawBMP("/guiemot.bmp", tft, 0, 0); p.x = 0; p.y = 0; key = 'Y'; delay(500); } if (p.x > kx17 & p.x < kx17+66 & p.y > ky17 & p.y < ky17+66){ gui = 5; reader.drawBMP("/guivmp.bmp", tft, 0, 0); p.x = 0; p.y = 0; key = 'Y'; delay(500); } } } //End main menu //Start stream menu if (gui == 2) { if (key) { Serial.println(key); switch (key) { case '1': Keyboard.press(KEY_RIGHT_SHIFT); Keyboard.press(KEY_RIGHT_ALT); Keyboard.press(KEY_F13); delay(100); break; case '2': Keyboard.press(KEY_RIGHT_SHIFT); Keyboard.press(KEY_RIGHT_ALT); Keyboard.press(KEY_F14); delay(100); break; case '3': Keyboard.press(KEY_RIGHT_SHIFT); Keyboard.press(KEY_RIGHT_ALT); Keyboard.press(KEY_F15); reader.drawBMP("/kausmic.bmp", tft, kx7 , ky7); reader.drawBMP("/kausdisc.bmp", tft, kx8 , ky8); discord = false; streammic = false; delay(100); break; case '4': Keyboard.press(KEY_RIGHT_SHIFT); Keyboard.press(KEY_RIGHT_ALT); Keyboard.press(KEY_F16); delay(100); break; case '5': Keyboard.press(KEY_RIGHT_SHIFT); Keyboard.press(KEY_RIGHT_ALT); Keyboard.press(KEY_F17); delay(100); break; case '6': Keyboard.press(KEY_RIGHT_SHIFT); Keyboard.press(KEY_RIGHT_ALT); Keyboard.press(KEY_F18); delay(100); break; case '7': Keyboard.press(KEY_RIGHT_SHIFT); Keyboard.press(KEY_RIGHT_ALT); Keyboard.press(KEY_F19); if ( streammic == true) { reader.drawBMP("/kausmic.bmp", tft, kx7 , ky7); streammic = false; } else { reader.drawBMP("/kanmic.bmp", tft, kx7 , ky7); streammic = true; } delay(100); break; case '8': Keyboard.press(KEY_RIGHT_SHIFT); Keyboard.press(KEY_RIGHT_ALT); Keyboard.press(KEY_F20); if ( discord == true) { reader.drawBMP("/kausdisc.bmp", tft, kx8 , ky8); discord = false; } else { reader.drawBMP("/kandisc.bmp", tft, kx8 , ky8); discord = true; } delay(100); break; case '9': Keyboard.press(KEY_RIGHT_SHIFT); Keyboard.press(KEY_RIGHT_ALT); Keyboard.press(KEY_F21); delay(100); break; case 'A': Keyboard.press(KEY_RIGHT_SHIFT); Keyboard.press(KEY_RIGHT_ALT); Keyboard.press(KEY_F22); delay(100); break; case 'B': Keyboard.press(KEY_RIGHT_SHIFT); Keyboard.press(KEY_RIGHT_ALT); Keyboard.press(KEY_F23); delay(100); break; case 'C': Keyboard.press(KEY_RIGHT_SHIFT); Keyboard.press(KEY_RIGHT_ALT); Keyboard.press(KEY_F24); reader.drawBMP("/kausmic.bmp", tft, kx7 , ky7); streammic = false; delay(100); break; case 'D': Keyboard.press(KEY_RIGHT_SHIFT); Keyboard.press(KEY_RIGHT_ALT); Keyboard.press(','); delay(100); break; case 'E': Keyboard.press(KEY_RIGHT_SHIFT); Keyboard.press(KEY_RIGHT_ALT); Keyboard.press('.'); delay(100); break; case 'F': Keyboard.press(KEY_RIGHT_SHIFT); Keyboard.press(KEY_RIGHT_ALT); Keyboard.press(KEY_UP_ARROW); delay(100); break; case 'G': Keyboard.press(KEY_RIGHT_SHIFT); Keyboard.press(KEY_RIGHT_ALT); Keyboard.press(KEY_RIGHT_ARROW); reader.drawBMP("/rpldn.bmp", tft, kx16 , ky16); delay(100); reader.drawBMP("/rplber.bmp", tft, kx16 , ky16); delay(100); break; case 'H': Keyboard.press(KEY_RIGHT_SHIFT); Keyboard.press(KEY_RIGHT_ALT); Keyboard.press(KEY_LEFT_ARROW); delay(100); break; case 'I': Keyboard.press(KEY_RIGHT_SHIFT); Keyboard.press(KEY_RIGHT_ALT); Keyboard.press(KEY_DOWN_ARROW); delay(100); break; case 'J': Keyboard.press(KEY_RIGHT_SHIFT); Keyboard.press(KEY_RIGHT_ALT); Keyboard.press(']'); delay(100); break; case 'K': Keyboard.press(KEY_RIGHT_SHIFT); Keyboard.press(KEY_RIGHT_ALT); Keyboard.press('/'); delay(100); break; } } if (p.z > ts.pressureThreshhold) { Serial.print("X = "); Serial.print(p.x); Serial.print("\tY = "); Serial.print(p.y); Serial.print("\tPressure = "); Serial.println(p.z); if (p.x > 1 & p.x < 240 & p.y > 1 & p.y < 160) { // Back to the main menu (left half of the screen) gui = 1; reader.drawBMP("/guimain.bmp", tft, 0, 0); p.x = 0; p.y = 0; delay(100); } if (p.x > 120 & p.x < 240 & p.y > 160 & p.y < 320) { // To the VM Potato menu (top right of the screen) gui = 5; reader.drawBMP("/guivmp.bmp", tft, 0, 0); p.x = 0; p.y = 0; key = 'Y'; delay(100); } } } //End stream menu //Start Affinity if (gui == 3) { if (key) { Serial.println(key); switch (key) { case '1': Keyboard.press(KEY_LEFT_CTRL); Keyboard.press(KEY_LEFT_ALT); Keyboard.press(KEY_LEFT_SHIFT); Keyboard.press('N'); delay(100); break; case '2': Keyboard.press(KEY_LEFT_CTRL); Keyboard.press(KEY_F13); delay(100); break; case '3': Keyboard.press(KEY_LEFT_CTRL); Keyboard.press(KEY_F14); delay(100); break; case '4': Keyboard.press(KEY_LEFT_CTRL); Keyboard.press(KEY_F15); delay(100); break; case '5': Keyboard.press(KEY_LEFT_CTRL); Keyboard.press(KEY_F16); delay(100); break; case '6': Keyboard.press(KEY_LEFT_CTRL); Keyboard.press(KEY_F17); delay(100); break; case '7': Keyboard.press(KEY_LEFT_CTRL); Keyboard.press(KEY_F18); delay(100); break; case '8': Keyboard.press(KEY_LEFT_CTRL); Keyboard.press(KEY_F19); delay(100); break; case '9': Keyboard.press(KEY_LEFT_CTRL); Keyboard.press(KEY_F20); delay(100); break; case 'A': Keyboard.press(KEY_LEFT_CTRL); Keyboard.press(KEY_F21); delay(100); break; case 'B': Keyboard.press(KEY_LEFT_CTRL); Keyboard.press(KEY_F22); delay(100); break; case 'C': Keyboard.press(KEY_LEFT_CTRL); Keyboard.press(KEY_F23); delay(100); break; case 'D': Keyboard.press(KEY_LEFT_CTRL); Keyboard.press(KEY_F24); delay(100); break; case 'E': Keyboard.press(KEY_LEFT_ALT); Keyboard.press(KEY_F13); delay(100); break; case 'F': Keyboard.press(KEY_LEFT_ALT); Keyboard.press(KEY_F14); delay(100); break; case 'G': Keyboard.press(KEY_LEFT_ALT); Keyboard.press(KEY_F15); delay(100); break; case 'H': Keyboard.press(KEY_LEFT_ALT); Keyboard.press(KEY_F16); delay(100); break; case 'I': Keyboard.press(KEY_LEFT_CTRL); Keyboard.press(KEY_LEFT_ALT); Keyboard.press(KEY_RIGHT_SHIFT); Keyboard.press('S'); // Keyboard.press(KEY_F17); delay(100); break; case 'J': Keyboard.press(KEY_LEFT_ALT); Keyboard.press(KEY_F18); delay(100); break; case 'K': Keyboard.press(KEY_LEFT_ALT); Keyboard.press(KEY_F19); delay(100); break; } } if (p.z > ts.pressureThreshhold) { Serial.print("X = "); Serial.print(p.x); Serial.print("\tY = "); Serial.print(p.y); Serial.print("\tPressure = "); Serial.println(p.z); if (p.x > 1 & p.x < 240 & p.y > 1 & p.y < 160) { // Back to the main menu (left half of the screen) gui = 1; reader.drawBMP("/guimain.bmp", tft, 0, 0); p.x = 0; p.y = 0; delay(100); } if (p.x > 120 & p.x < 240 & p.y > 160 & p.y < 320) { // To the VM Potato menu (top right of the screen) gui = 5; reader.drawBMP("/guivmp.bmp", tft, 0, 0); p.x = 0; p.y = 0; key = 'Y'; delay(100); } } } //End Affinity menu //Start Twitch/emotes menu if (gui == 4) { if (key) { Serial.println(key); switch (key) { case '1': Keyboard.print("cocoac1HI cocoac1HI cocoac1HI cocoac1HI"); Keyboard.press(KEY_RETURN); delay(500); break; case '2': Keyboard.print("cocoac1Crzing cocoac1Crzing cocoac1Crzing cocoac1Crzing"); //since my PC uses the German keyboard layout and the Arduino uses the English one Y=Z and Z=Y etc. Keyboard.press(KEY_RETURN); delay(500); break; case '3': Keyboard.print("cocoac1Lurk cocoac1Lurk cocoac1Lurk cocoac1Lurk"); Keyboard.press(KEY_RETURN); delay(500); break; case '4': Keyboard.print("cocoac1Love cocoac1Love cocoac1Love cocoac1Love"); Keyboard.press(KEY_RETURN); delay(500); break; case '5': Keyboard.print("cocoac1Zeaz cocoac1Zeaz cocoac1Zeaz cocoac1Zeaz"); Keyboard.press(KEY_RETURN); delay(500); break; case '6': Keyboard.print("cocoac1Wow cocoac1Wow cocoac1Wow cocoac1Wow"); Keyboard.press(KEY_RETURN); delay(500); break; case '7': Keyboard.print("cocoac1Love PridePenguin cocoac1Love cocoac1Wow "); delay(100); Keyboard.print("HzpeLove cocoac1Wow cocoac1Love "); delay(100); Keyboard.print("PridePenguin cocoac1Love"); Keyboard.press(KEY_RETURN); delay(500); break; case '8': Keyboard.print("2020Celebrate cocoac1Zeaz cocoac1Love cocoac1Zeaz "); delay(100); Keyboard.print("cocoac1Love cocoac1Zeaz "); delay(100); Keyboard.print("cocoac1Love cocoac1Zeaz 2020Celebrate"); Keyboard.press(KEY_RETURN); delay(500); break; case '9': Keyboard.print("PrideFlower PrideUwu PrideFlower PrideUwu "); delay(500); break; case 'A': Keyboard.print("LUL PrideLaugh LUL PrideLaugh "); delay(500); break; case 'B': Keyboard.print("!sticker "); delay(500); break; case 'C': Keyboard.print("!discord "); delay(500); break; case 'D': Keyboard.print("!zoutube "); delay(500); break; case 'E': Keyboard.print("!instagram "); delay(500); break; case 'F': Keyboard.print("!sonicscrewups"); delay(500); break; case 'G': Keyboard.print("!liebe "); delay(500); break; case 'H': Keyboard.print("!game "); delay(500); break; case 'I': Keyboard.print("!paul "); delay(500); break; case 'J': Keyboard.print("!uptime "); delay(500); break; case 'K': Keyboard.print("!bsg "); delay(500); break; } } if (p.z > ts.pressureThreshhold) { Serial.print("X = "); Serial.print(p.x); Serial.print("\tY = "); Serial.print(p.y); Serial.print("\tPressure = "); Serial.println(p.z); if (p.x > 1 & p.x < 240 & p.y > 1 & p.y < 160) { // Back to the main menu (left half of the screen) gui = 1; reader.drawBMP("/guimain.bmp", tft, 0, 0); p.x = 0; p.y = 0; delay(100); } if (p.x > 120 & p.x < 240 & p.y > 160 & p.y < 320) { // To the VM Potato menu (top right of the screen) gui = 5; reader.drawBMP("/guivmp.bmp", tft, 0, 0); p.x = 0; p.y = 0; key = 'Y'; delay(100); } } } if (gui == 5) { //VM Potato Macros if (key) { Serial.println(key); switch (key) { case '1': delay(100); break; case '2': Keyboard.press(KEY_LEFT_ALT); Keyboard.press(KEY_HOME); delay(100); break; case '3': Keyboard.press(KEY_LEFT_ALT); Keyboard.press('0'); delay(100); break; case '4': Keyboard.press(KEY_LEFT_ALT); Keyboard.press('1'); delay(100); break; case '5': Keyboard.press(KEY_LEFT_ALT); Keyboard.press('2'); delay(100); break; case '6': gui = 4; reader.drawBMP("/guiemot.bmp", tft, 0, 0); p.x = 0; p.y = 0; key = 'Y'; delay(100); break; case '7': Keyboard.press(KEY_LEFT_ALT); Keyboard.press(KEY_END); delay(100); break; case '8': Keyboard.press(KEY_LEFT_ALT); Keyboard.press('3'); delay(100); break; case '9': Keyboard.press(KEY_LEFT_ALT); Keyboard.press('4'); delay(100); break; case 'A': Keyboard.press(KEY_LEFT_ALT); Keyboard.press('5'); delay(100); break; case 'B': gui = 3; reader.drawBMP("/affgui.bmp", tft, 0, 0); p.x = 0; p.y = 0; key = 'Y'; delay(100); break; case 'C': Keyboard.press(KEY_LEFT_ALT); Keyboard.press(KEY_PAGE_UP); delay(100); break; case 'D': Keyboard.press(KEY_LEFT_ALT); Keyboard.press('6'); delay(100); break; case 'E': Keyboard.press(KEY_LEFT_ALT); Keyboard.press('7'); delay(100); break; case 'F': Keyboard.press(KEY_LEFT_ALT); Keyboard.press('8'); delay(100); break; case 'G': gui = 2; reader.drawBMP("/strgui.bmp", tft, 0, 0); if ( streammic == true) { reader.drawBMP("/kanmic.bmp", tft, kx7 , ky7); } else { reader.drawBMP("/kausmic.bmp", tft, kx7 , ky7); } if ( discord == true) { reader.drawBMP("/kandisc.bmp", tft, kx8 , ky8); } else { reader.drawBMP("/kausdisc.bmp", tft, kx8 , ky8); } key = 'Y'; delay(100); break; case 'H': Keyboard.press(KEY_LEFT_ALT); Keyboard.press(KEY_PAGE_DOWN); delay(100); break; case 'I': Keyboard.press(KEY_LEFT_ALT); Keyboard.press('9'); delay(100); break; case 'J': Keyboard.press(KEY_LEFT_ALT); Keyboard.press('L'); delay(100); break; case 'K': Keyboard.press(KEY_LEFT_ALT); Keyboard.press('K'); delay(100); break; } } if (p.z > ts.pressureThreshhold) { Serial.print("X = "); Serial.print(p.x); Serial.print("\tY = "); Serial.print(p.y); Serial.print("\tPressure = "); Serial.println(p.z); if (p.x > 1 & p.x < 240 & p.y > 1 & p.y < 160) { // Zurück ins Hauptmenü gui = 1; reader.drawBMP("/guimain.bmp", tft, 0, 0); p.x = 0; p.y = 0; delay(100); } } } //End VoiceMeter Potato menu delay(50); Keyboard.releaseAll(); }