#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();
}