Files
AutoClicker3000/AutoClicker3000.ino
2020-03-18 23:23:11 -07:00

277 lines
5.3 KiB
C++

#include <Wire.h>
#include <Adafruit_RGBLCDShield.h>
#include <utility/Adafruit_MCP23017.h>
#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();
}