Project Started
3D Model
3D Model
3D Model
3D Model
3D Model
Waiting for input
~KILL..ino file, compile, and upload at 115200 baud.U5:CELL is connected to the BAT net. The firmware reports GAUGE ERROR when the MAX17048 does not return valid data. Correct this connection before ordering the next PCB revision.Table
| Function | ESP32-S3 GPIO |
|---|---|
| USB D- / D+ | GPIO19 / GPIO20 (native USB) |
| I2C SDA / SCL | GPIO8 / GPIO9 |
| SPI MOSI / MISO / SCLK | GPIO11 / GPIO13 / GPIO12 |
| microSD CS | GPIO10 |
| LCD CS / DC / RESET | GPIO14 / GPIO15 / GPIO16 |
| LCD backlight PWM | GPIO17 |
| Touch INT / RESET | GPIO18 / GPIO21 |
| Soft-power KILL | GPIO4 |
| Soft-power interrupt | GPIO5 |
| Fuel-gauge ALERT | GPIO6 |
| Regulator power-good | GPIO7 |
| Zero displayed sensor values button | GPIO1 (active-low, internal pull-up) |
| BOOT | GPIO0 |
platformio.ini:Ini
[env:esp32-s3] platform = espressif32 board = esp32-s3-devkitc-1 framework = arduino monitor_speed = 115200 build_flags = -D ARDUINO_USB_MODE=1 -D ARDUINO_USB_CDC_ON_BOOT=1
Cpp
#include <Arduino.h> #include <Wire.h> #include <SPI.h> static constexpr int PIN_I2C_SDA = 8; static constexpr int PIN_I2C_SCL = 9; static constexpr int PIN_SPI_MOSI = 11; static constexpr int PIN_SPI_MISO = 13; static constexpr int PIN_SPI_SCLK = 12; static constexpr int PIN_SD_CS = 10; static constexpr int PIN_LCD_CS = 14; static constexpr int PIN_LCD_DC = 15; static constexpr int PIN_LCD_RST = 16; static constexpr int PIN_LCD_BL = 17; static constexpr int PIN_TP_INT = 18; static constexpr int PIN_TP_RST = 21; static constexpr int PIN_PWR_KILL = 4; static constexpr int PIN_PWR_INT = 5; static constexpr int PIN_FUEL_ALERT = 6; static constexpr int PIN_PWR_GOOD = 7; static constexpr int PIN_ZERO_VALUES = 1; static constexpr uint8_t MAX17048_ADDR = 0x36; static constexpr uint8_t FT6336_ADDR = 0x38; static constexpr uint32_t IDLE_TIMEOUT_MS = 5UL * 60UL * 1000UL; SPIClass displaySPI(FSPI); volatile bool powerButtonEvent = false; volatile bool touchEvent = false; uint32_t lastActivityMs = 0; float displayedSensorValue1 = 0.0f; float displayedSensorValue2 = 0.0f; void resetDisplayedSensorValues() { displayedSensorValue1 = 0.0f; displayedSensorValue2 = 0.0f; // Redraw the value fields here after integrating the graphics library. Serial.println("Displayed sensor values reset to zero"); } void IRAM_ATTR onPowerButton() { powerButtonEvent = true; } void IRAM_ATTR onTouch() { touchEvent = true; } void lcdCommand(uint8_t cmd) { digitalWrite(PIN_LCD_DC, LOW); digitalWrite(PIN_LCD_CS, LOW); displaySPI.transfer(cmd); digitalWrite(PIN_LCD_CS, HIGH); } void lcdData(uint8_t data) { digitalWrite(PIN_LCD_DC, HIGH); digitalWrite(PIN_LCD_CS, LOW); displaySPI.transfer(data); digitalWrite(PIN_LCD_CS, HIGH); } void initDisplay() { pinMode(PIN_LCD_CS, OUTPUT); pinMode(PIN_LCD_DC, OUTPUT); pinMode(PIN_LCD_RST, OUTPUT); pinMode(PIN_SD_CS, OUTPUT); digitalWrite(PIN_LCD_CS, HIGH); digitalWrite(PIN_SD_CS, HIGH); digitalWrite(PIN_LCD_RST, LOW); delay(20); digitalWrite(PIN_LCD_RST, HIGH); delay(120); lcdCommand(0x01); // Software reset delay(150); lcdCommand(0x11); // Sleep out delay(120); lcdCommand(0x3A); // Pixel format lcdData(0x55); // RGB565 lcdCommand(0x36); // Memory access control lcdData(0x48); lcdCommand(0x29); // Display on } void initBacklight() { ledcAttach(PIN_LCD_BL, 20000, 8); ledcWrite(PIN_LCD_BL, 180); } void initTouch() { pinMode(PIN_TP_RST, OUTPUT); pinMode(PIN_TP_INT, INPUT_PULLUP); digitalWrite(PIN_TP_RST, LOW); delay(10); digitalWrite(PIN_TP_RST, HIGH); delay(100); attachInterrupt(PIN_TP_INT, onTouch, FALLING); } bool i2cRead(uint8_t address, uint8_t reg, uint8_t *data, size_t length) { Wire.beginTransmission(address); Wire.write(reg); if (Wire.endTransmission(false) != 0) return false; return Wire.requestFrom(address, length) == length && ([&]() { for (size_t i = 0; i < length; ++i) data[i] = Wire.read(); return true; })(); } float readBatteryPercent() { uint8_t raw[2]; if (!i2cRead(MAX17048_ADDR, 0x04, raw, 2)) return NAN; return raw[0] + raw[1] / 256.0f; } float readBatteryVoltage() { uint8_t raw[2]; if (!i2cRead(MAX17048_ADDR, 0x02, raw, 2)) return NAN; uint16_t value = (uint16_t(raw[0]) << 8) | raw[1]; return (value >> 4) * 0.00125f; } bool readTouch(uint16_t &x, uint16_t &y) { uint8_t count; if (!i2cRead(FT6336_ADDR, 0x02, &count, 1) || (count & 0x0F) == 0) return false; uint8_t p[4]; if (!i2cRead(FT6336_ADDR, 0x03, p, 4)) return false; x = ((p[0] & 0x0F) << 8) | p[1]; y = ((p[2] & 0x0F) << 8) | p[3]; return true; } [[noreturn]] void shutdownSystem() { ledcWrite(PIN_LCD_BL, 0); delay(20); // LTC2955 KILL is held high in normal operation. Pulling it low releases EN. digitalWrite(PIN_PWR_KILL, LOW); while (true) delay(1000); // Power should disappear here. } void setup() { pinMode(PIN_PWR_KILL, OUTPUT); digitalWrite(PIN_PWR_KILL, HIGH); // Must occur within LTC2955 startup blanking interval. pinMode(PIN_PWR_INT, INPUT_PULLUP); pinMode(PIN_FUEL_ALERT, INPUT_PULLUP); pinMode(PIN_PWR_GOOD, INPUT); pinMode(PIN_ZERO_VALUES, INPUT_PULLUP); attachInterrupt(PIN_PWR_INT, onPowerButton, FALLING); Serial.begin(115200); // Native USB CDC with PlatformIO build flags above. Wire.begin(PIN_I2C_SDA, PIN_I2C_SCL, 400000); displaySPI.begin(PIN_SPI_SCLK, PIN_SPI_MISO, PIN_SPI_MOSI, PIN_LCD_CS); initBacklight(); initDisplay(); initTouch(); lastActivityMs = millis(); Serial.println("ESP32-S3 touch controller started"); } void loop() { static bool previousZeroButton = HIGH; static uint32_t zeroButtonChangedMs = 0; bool zeroButton = digitalRead(PIN_ZERO_VALUES); if (zeroButton != previousZeroButton && millis() - zeroButtonChangedMs >= 30) { zeroButtonChangedMs = millis(); previousZeroButton = zeroButton; if (zeroButton == LOW) { resetDisplayedSensorValues(); lastActivityMs = millis(); } } if (powerButtonEvent) { powerButtonEvent = false; lastActivityMs = millis(); Serial.println("Power button event"); } if (touchEvent) { touchEvent = false; uint16_t x, y; if (readTouch(x, y)) { lastActivityMs = millis(); Serial.printf("Touch: %u,%u\n", x, y); } } static uint32_t lastBatteryRead = 0; if (millis() - lastBatteryRead >= 5000) { lastBatteryRead = millis(); Serial.printf("Battery: %.2f V, %.1f %%\n", readBatteryVoltage(), readBatteryPercent()); } if (millis() - lastActivityMs >= IDLE_TIMEOUT_MS) shutdownSystem(); delay(10); }
0x36 and FT6336 at 0x38 when the display is attached.Complete Arduino Application
Required Arduino Setup
Critical Battery-Gauge Hardware Correction
Hardware GPIO Map
PlatformIO Configuration
Starter Firmware
Bring-Up Sequence
Known Integration Item