Newer
Older
// ======================= Acknowledgments =================================
// - The shake detection functionality seen in the ShakeDetection() helper
// function is adapted from the example code in the MPU6050 library
// (shake.ino) by maarten-pennings
// * https://github.com/maarten-pennings/MPU6050
//
// - TODO -- more
#include <Wire.h>
#include <mpu6050.h>
#include <PushButton.h>
#include <BleCombo.h>
#include <nvs_flash.h>
#define LED_BUILTIN 2
const int SW_pin = 16;
const int X_pin = 34;
const int Y_pin = 36;
const int vib_pin = 25;
PushButton SW_button(SW_pin);
MPU6050 mpu6050;
// ======================= Function Declarations =================================
// Monitors the MPU6050 sensor for shakes.
// If a shake is detected, it triggers visual feedback by blinking the internal LED
// and sends a short vibration to simulate impact, as if the axe controller is hitting something.
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Parameters:
// mpu6050: An instance of the MPU6050 class representing the sensor.
void ShakeDetection(MPU6050 mpu6050);
// Detects joystick movements and button presses.
// Prints the direction and whether the button was pressed or not to the serial monitor.
void JoystickDetection();
// Erases all connected devices from the controller
void resetBLE();
void setup() {
Serial.begin(9600);
Wire.begin();
resetBLE();
Keyboard.begin();
int error = mpu6050.begin();
pinMode(LED_BUILTIN, OUTPUT);
pinMode(vib_pin, OUTPUT);
pinMode(SW_pin, INPUT_PULLUP);
SW_button.setActiveLogic(LOW);
digitalWrite(LED_BUILTIN, LOW);
}
void loop() {
SW_button.update();
if (Keyboard.isConnected()) {
ShakeDetection(mpu6050);
JoystickDetection();
}
}
void ShakeDetection(MPU6050 mpu6050) {
MPU6050_t data = mpu6050.get();
if (data.accel.error == 0) {
float magnitude = sqrt(data.accel.x * data.accel.x + data.accel.y * data.accel.y + data.accel.z * data.accel.z);
if (magnitude > 2.45 * MPU6050_GRAVITY_EARTH) {
digitalWrite(LED_BUILTIN, HIGH);
Serial.println("Shaken");
digitalWrite(vib_pin, HIGH);
delay(300);
digitalWrite(vib_pin, LOW);
} else {
digitalWrite(vib_pin, LOW);
digitalWrite(LED_BUILTIN, LOW);
}
}
}
void JoystickDetection() {
if (SW_button.isClicked()) {
//Serial.println("Pressed!");
Keyboard.write('P');
delay(400);
}
if (analogRead(X_pin) > 3800) {
//Serial.println("up!");
Keyboard.write('W');
delay(400);
}
if (analogRead(X_pin) < 300) {
//Serial.println("down!");
Keyboard.write('S');
delay(400);
}
if (analogRead(Y_pin) > 3800) {
//Serial.println("right!");
Keyboard.write('D');
delay(400);
}
if (analogRead(Y_pin) < 300) {
//Serial.println("left!");
Keyboard.write('A');
delay(400);
}
}
void resetBLE() {
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
nvs_flash_erase();
ret = nvs_flash_init();
}
if (ret != ESP_OK) {
Serial.println("Failed to initialize NVS");
return;
}
// Erase pairing information
ret = nvs_flash_erase();
if (ret != ESP_OK) {
Serial.println("Failed to erase NVS");
} else {
Serial.println("NVS erased, all bonding information cleared");
}
}