#include #include #include #include "Keyboard.h" #include "Mouse.h" // The shield uses the I2C SCL and SDA pins. On classic Arduinos // this is Analog 4 and 5 so you can't use those for analogRead() anymore // However, you can connect other I2C sensors to the I2C bus and share // the I2C bus. Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield(); // These #defines make it easy to set the backlight color #define RED 0x1 #define YELLOW 0x3 #define GREEN 0x2 #define TEAL 0x6 #define BLUE 0x4 #define VIOLET 0x5 #define WHITE 0x7 unsigned long lcdTimeout = 1500; unsigned long lcdLastSet = 0; unsigned long debounceDelay = 50; typedef struct { unsigned long lastDebounceTime = 0; bool state = false; bool lastState = false; } DebounceButton; DebounceButton up, down, left, right, select; typedef enum { MODE_LEFT_CLICK, MODE_WALKING, MODE_COUNT } Mode; Mode currMode = MODE_LEFT_CLICK; char *modeNames[] = { "Click mode ", "Keyboard mode " }; int modeColors[] = { WHITE, YELLOW }; extern void clickActivate(); extern void clickSlower(); extern void clickFaster(); extern void walkForward(); extern void walkBackward(); extern void holdShift(); void (*upButtonFuncs[])() = { NULL, walkForward }; void (*downButtonFuncs[])() = { clickActivate, walkBackward }; void (*leftButtonFuncs[])() = { clickSlower, holdShift }; void (*rightButtonFuncs[])() = { clickFaster, NULL }; extern void cancelClicking(); extern void cancelWalking(); void (*cancelModeFuncs[])() = { cancelClicking, cancelWalking }; bool doClicking = false; unsigned long lastClickTime = 0; int clickColor = 0; bool doWalking = false; void setup() { Serial.begin(9600); // set columns and rows: lcd.begin(16, 2); Mouse.begin(); Keyboard.begin(); lcd.print("AutoClicker 3000"); lcd.setCursor(0, 1); lcd.print("For Jasper"); lcd.setBacklight(VIOLET); lcdLastSet = millis(); } void debounce(DebounceButton &b, bool reading) { if ((millis() - b.lastDebounceTime) > debounceDelay) { b.lastState = b.state; b.state = reading; b.lastDebounceTime = millis(); } } bool triggered(DebounceButton &b) { return b.state and !b.lastState; } int clickDelay = 100; // millis int delayChange = 10; // millis void loop() { uint8_t buttons = lcd.readButtons(); debounce(up, buttons & BUTTON_UP); debounce(down, buttons & BUTTON_DOWN); debounce(left, buttons & BUTTON_LEFT); debounce(right, buttons & BUTTON_RIGHT); debounce(select, buttons & BUTTON_SELECT); if (buttons) { if (triggered(up)) { if (upButtonFuncs[currMode] != NULL) { upButtonFuncs[currMode](); } } if (triggered(down)) { if (downButtonFuncs[currMode] != NULL) { downButtonFuncs[currMode](); } } if (triggered(left)) { if (leftButtonFuncs[currMode] != NULL) { leftButtonFuncs[currMode](); } } if (triggered(right)) { if (rightButtonFuncs[currMode] != NULL) { rightButtonFuncs[currMode](); } } if (triggered(select)) { if (cancelModeFuncs[currMode] != NULL) { cancelModeFuncs[currMode](); } changeMode(); } } // TODO make into mode-specific action func if (doClicking) { unsigned long time = millis(); if ((unsigned long)(time - lastClickTime) >= clickDelay) { if (clickColor == RED) { clickColor = WHITE; } else { clickColor = RED; } lcd.setBacklight(clickColor); Mouse.click(MOUSE_LEFT); lastClickTime = time; } } // clear second lcd line after a while if (lcdLastSet > 0 && millis() > lcdLastSet + lcdTimeout) { lcd.setCursor(0, 0); lcd.print(modeNames[currMode]); lcd.setCursor(0, 1); lcd.print(" "); lcdLastSet = 0; } } void changeMode() { currMode = (currMode + 1) % MODE_COUNT; lcd.setCursor(0, 0); lcd.print(modeNames[currMode]); lcd.setBacklight(modeColors[currMode]); } void flashLCD(char* msg) { lcd.setCursor(0, 1); lcd.print(msg); lcdLastSet = millis(); } void updateLCD(char* msg) { lcd.setCursor(0, 1); lcd.print(msg); lcdLastSet = 0; } void clearLCD() { lcd.setCursor(0, 1); lcd.print(" "); lcdLastSet = 0; } // mode functions void clickActivate() { doClicking = !doClicking; lcd.setBacklight(WHITE); if (doClicking) { flashLCD("Start clicking "); } else { flashLCD("Stop clicking "); } } void clickSlower() { if (clickDelay < 1000) { clickDelay += delayChange; } flashLCD("Slower "); } void clickFaster() { if (clickDelay > 50) { clickDelay -= delayChange; } flashLCD("Faster "); } void cancelClicking() { doClicking = false; } // // walking mode // void walkForward() { if (!doWalking) { walk('w', "Forward "); } else { cancelWalking(); clearLCD(); } } void walkBackward() { if (!doWalking) { walk('s', "Backward "); } else { cancelWalking(); clearLCD(); } } void holdShift() { if (!doWalking) { walk(KEY_LEFT_SHIFT, "Shift "); } else { cancelWalking(); clearLCD(); } } void walk(char key, char* msg) { cancelWalking(); Keyboard.press(key); doWalking = true; updateLCD(msg); } void cancelWalking() { doWalking = false; Keyboard.releaseAll(); }