#if ARDUINO_USB_MODE
#warning This sketch should be used when USB is in OTG mode
void setup() {}
void loop() {}
#else
#include "USB.h"
#include "USBHIDMouse.h"
USBHIDMouse Mouse;
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "frames.h"
#define SCREEN_I2C_ADDR 0x3C
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RST_PIN -1
#define BUTTON_PIN 15
int animationId = 0;
int counter = 0;
int buttonState = 0;
int lastButtonState = LOW;
unsigned long previousMillis = 0;
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RST_PIN);
#define FRAME_DELAY (10)
#define PAUSE_DURATION (10000)
#define FRAME_WIDTH (128)
#define FRAME_HEIGHT (64)
const unsigned char * *animation[] {
blink,
sad,
heart,
dino
};
/*
animationData[][0] is the animation type and it can be:
0 = forward gif, 1 = looped gif, 2 = looped gif with pause
animationData[][1] is the number of frames for the animation
*/
const int animationData[][2] { //
{2, 4},
{2, 9},
{2, 11},
{0, 38}
};
void setup() {
Serial.begin(115200);
pinMode(BUTTON_PIN, INPUT);
oled.begin(SSD1306_SWITCHCAPVCC, SCREEN_I2C_ADDR);
oled.clearDisplay();
oled.setTextSize(2);
oled.setTextColor(WHITE);
oled.setCursor(0, 10);
String text = "Hello :)";
oledDisplayCenter(text);
mouseSetup();
}
void loop() {
buttonState = digitalRead(BUTTON_PIN);
unsigned long currentMillis = millis();
if (buttonState != lastButtonState) {
if (buttonState == HIGH) {
animationId = (animationId + 1) % (sizeof(animation) / sizeof(animation[0]));
String text = "GIF " + String(animationId + 1);
oledDisplayCenter(text);
delay(500);
}
}
lastButtonState = buttonState;
updateFrame(currentMillis);
delay(FRAME_DELAY);
mouseMove(50000, currentMillis);
}
void mouseSetup() {
Mouse.begin();
USB.begin();
for (int x = 0; x < 5; x++) {
mouseMove(500, 500);
};
}
void mouseMove(int delayMs, unsigned long currentMillis) {
if (currentMillis - previousMillis >= delayMs) {
Mouse.move(10, 0, 0);
delay(20);
Mouse.move(20, 0, 0);
delay(10);
Mouse.move(-10, 0, 0);
delay(20);
Mouse.move(-20, 0, 0);
}
}
void updateFrame(unsigned long currentMillis) {
int frameCount = animationData[animationId][1];
int frame = counter > frameCount ? frameCount * 2 - counter : counter;
int frameDelay = animationData[animationId][0] == 2 && frame == 0 ? PAUSE_DURATION : 0;
if (currentMillis - previousMillis >= frameDelay) {
previousMillis = currentMillis;
oled.clearDisplay();
oled.drawBitmap(0, 0, animation[animationId][frame], FRAME_WIDTH, FRAME_HEIGHT, 1);
oled.display();
updateCounter(frameCount);
}
}
void updateCounter(int frameCount) {
if (animationData[animationId][0] == 0) {
counter = (counter + 1) % frameCount;
} else {
counter = (counter + 1) % (frameCount * 2);
};
}
void oledDisplayCenter(String text) {
int16_t x1;
int16_t y1;
uint16_t width;
uint16_t height;
oled.getTextBounds(text, 0, 0, &x1, &y1, &width, &height);
// display on horizontal and vertical center
oled.clearDisplay();
oled.setCursor((SCREEN_WIDTH - width) / 2, (SCREEN_HEIGHT - height) / 2);
oled.println(text);
oled.display();
}
#endif