/**************************************************************************
https://grok.com/share/bGVnYWN5_606fe78d-439e-484c-b71a-41b17f2d3894
https://grok.com/share/bGVnYWN5_29159ac2-7dbd-481c-9d6a-2e33a0160839
https://grok.com/share/bGVnYWN5_1ab675dc-2f2a-4bb8-bced-cd9b7e89ef90
**************************************************************************/
/*
Wireless Bucket Level Project
ESP32-S2 Mini + 1.69" ST7789V3 (240x280) TFT
Optimized Hardware SPI + Your Custom Pins
*/
//define debug
//#define ST7789
#define F // fahrenheit temperature
#include <Adafruit_NeoPixel.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Arduino_JSON.h>
#include <OneButton.h>
#ifdef ST7789
#include <Adafruit_ST7789.h>
#else
#include <Adafruit_ILI9341.h>
#endif
#include <SPI.h>
#include "page.h"
// Preprocessor fix for JavaScript in raw literal
#define function
// ====================== YOUR CUSTOM PIN DEFINITIONS ======================
#define TFT_CS 5//
#define TFT_RST 4//
#define TFT_DC 2//
#define TFT_CLK 7// // SCLK
#define TFT_MOSI 11// // MOSI
#define TFT_MISO 9// // MISO (not always needed for display)
#define TFT_LED 6// // Backlight
#define SDA_pin 33//
#define SCL_pin 35//
#define batteryVoltagePin 1//
#define PIXEL_PIN 16
#define onboard_LED_pin 15 // ESP32-S2 Mini onboard LED =15
// Buttons
#define upButtonPin 18
#define downButtonPin 17
#define enterButtonPin 21 // if needed later
// ====================== CONSTANTS ======================
#define batteryVoltageHigh 4.2
#define batteryVoltageNom 3.7
#define batteryVoltageLow 3.2
#define NUMPIXELS 1
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* compileDateTime = __DATE__ " " __TIME__;
const float G = 9.80665;
// ====================== OBJECTS ======================
// Hardware SPI TFT
#ifdef ST7789
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
#else
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
#endif
Adafruit_MPU6050 mpu;
Adafruit_NeoPixel pixels(NUMPIXELS, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
OneButton button1(upButtonPin, true);
OneButton button2(downButtonPin, true);
//OneButton button3(enterButtonPin, true); // if needed later
AsyncWebServer server(80);
AsyncEventSource events("/events");
JSONVar readings;
sensors_event_t a, g, temp;
struct GyroData {
float pitch = 0;
float roll = 0;
float yaw = 0;
float prev_pitch = 0;
float prev_roll = 0;
float prev_yaw = 0;
}; // <-- Don't forget this semicolon!
// 2. Create an instance of the struct
GyroData gyroData;
// ====================== VARIABLES ======================
unsigned long lastTime = 0, lastTimeTemperature = 0, lastTimeAcc = 0, lastTimeVoltage = 0;
unsigned long gyroDelay = 20, temperatureDelay = 1000, accelerometerDelay = 200, voltageDelay = 2000;
float gyroX = 0, gyroY = 0, gyroZ = 0;
float prevGyroX = 0, prevGyroY = 0, prevGyroZ = 0;
float accX, accY, accZ;
float temperature = 0;
float batteryVoltage = 0;
float prevbatteryVoltage = 0;
unsigned long previousTime = 0;
// ====================== SETUP ======================
void setup() {
#ifdef debug
Serial.begin(115200);
Serial.println("ESP32-S2 Mini + ST7789 TFT Ready");
#endif
analogReadResolution(13);
// Pin configuration
pinMode(TFT_LED, OUTPUT);
digitalWrite(TFT_LED, HIGH);
pinMode(upButtonPin, INPUT_PULLUP);
pinMode(downButtonPin, INPUT_PULLUP);
setup_buttons();
// Initialize TFT with Hardware SPI
setup_display();
boot_display();
pixels.begin();
pixels.clear();
pixels.show();
initWiFi();
initMPU();
previousTime = millis();
// Web Server
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send_P(200, "text/html", index_html);
});
server.on("/reset", HTTP_GET, [](AsyncWebServerRequest * request) {
prevGyroX += gyroX; prevGyroY += gyroY; prevGyroZ += gyroZ;
gyroX = gyroY = gyroZ = 0;
request->send(200, "text/plain", "OK");
});
server.on("/resetX", HTTP_GET, [](AsyncWebServerRequest * request) {
prevGyroX += gyroX;
gyroX = 0;
request->send(200, "text/plain", "OK");
});
server.on("/resetY", HTTP_GET, [](AsyncWebServerRequest * request) {
prevGyroY += gyroY;
gyroY = 0;
request->send(200, "text/plain", "OK");
});
server.on("/resetZ", HTTP_GET, [](AsyncWebServerRequest * request) {
prevGyroZ += gyroZ;
gyroZ = 0;
request->send(200, "text/plain", "OK");
});
events.onConnect([](AsyncEventSourceClient * client) {
client->send("hello!", NULL, millis(), 10000);
});
server.addHandler(&events);
server.begin();
#ifdef debug
Serial.println("System Ready - Hardware SPI @ 40MHz");
#endif
main_display_static();
}
// ====================== MAIN LOOP ======================
void loop() {
button1.tick();
button2.tick();
if ((millis() - lastTime) > gyroDelay) {
events.send(getGyroReadings().c_str(), "gyro_readings", millis());
lastTime = millis();
}
if ((millis() - lastTimeAcc) > accelerometerDelay) {
events.send(getAccReadings().c_str(), "accelerometer_readings", millis());
lastTimeAcc = millis();
}
if ((millis() - lastTimeTemperature) > temperatureDelay) {
events.send(getTemperature().c_str(), "temperature_reading", millis());
lastTimeTemperature = millis();
}
if ((millis() - lastTimeVoltage) > voltageDelay) {
events.send(getVoltage().c_str(), "voltage_reading", millis());
lastTimeVoltage = millis();
}
if (gyroData.pitch != gyroData.prev_pitch ||
gyroData.roll != gyroData.prev_roll ||
gyroData.yaw != gyroData.prev_yaw) {
main_display();
gyroData.prev_pitch = gyroData.pitch;
gyroData.prev_roll = gyroData.roll;
gyroData.prev_yaw = gyroData.yaw;
}
}
// ====================== FUNCTIONS ======================
void initMPU() {
Wire.begin(SDA_pin, SCL_pin);
if (!mpu.begin()) {
#ifdef debug
Serial.println("MPU6050 Failed!");
#endif
while (1) delay(100);
}
#ifdef debug
Serial.println("MPU6050 OK");
#endif
mpu.setGyroRange(MPU6050_RANGE_250_DEG);
mpu.setFilterBandwidth(MPU6050_BAND_44_HZ);
}
//--------------------------------------------------------
void initWiFi() {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
#ifdef debug
Serial.print(".");
#endif
}
#ifdef debug
Serial.println("\nWiFi Connected - IP: " + WiFi.localIP().toString());
#endif
}
//--------------------------------------------------------
String getGyroReadings() {
mpu.getEvent(&a, &g, &temp);
unsigned long currentTime = millis();
float dt = (currentTime - previousTime) / 1000.0;
previousTime = currentTime;
gyroX += (g.gyro.x * 180.0 / PI) * dt;
gyroY += (g.gyro.y * 180.0 / PI) * dt;
gyroZ += (g.gyro.z * 180.0 / PI) * dt;
gyroData.pitch = gyroX;
gyroData.roll = gyroY;
gyroData.yaw = gyroZ;
readings["pitch"] = String(gyroX, 1);
readings["roll"] = String(gyroY, 1);
readings["yaw"] = String(gyroZ, 1);
return JSON.stringify(readings);
}
//--------------------------------------------------------
String getAccReadings() {
mpu.getEvent(&a, &g, &temp);
readings["accX"] = String(a.acceleration.x, 2);
readings["accY"] = String(a.acceleration.y, 2);
readings["accZ"] = String(a.acceleration.z, 2);
return JSON.stringify(readings);
}
//--------------------------------------------------------
String getTemperature() {
mpu.getEvent(&a, &g, &temp);
#ifdef F
float temp_f = (temp.temperature * 9.0 / 5.0) + 32.0;
return String(temp_f, 1);
#else
return String(temp.temperature, 1);
#endif
}
//--------------------------------------------------------
String getVoltage() {
//int raw = analogReadMilliVolts(batteryVoltagePin);
int raw = analogRead(batteryVoltagePin);
#ifdef debug
Serial.print("analog:\t"); Serial.println(raw);
#endif
batteryVoltage = mapf(raw, 0, 8191, 0.0, 5.0);
return String(batteryVoltage, 2);
}
//--------------------------------------------------------
float mapf(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
Loading
wemos-s2-mini
wemos-s2-mini
240x320 2.8" LCD-TFT
Rounded Corner
ST7789v3 240x280 1.69" LCD-TFT