HV Pulse Power Design
GND and low-voltage LV_GNDTable
| Net | ESP32 pin |
|---|---|
| I2C_SDA | GPIO21 |
| I2C_SCL | GPIO22 |
| ADC1_ALERT_N | GPIO32 |
| ADC2_ALERT_N | GPIO33 |
| ADC3_ALERT_N | GPIO4 |
| HW_FAULT_N | GPIO27 |
| CHARGER_ENABLE_CMD | GPIO16 |
| INVERTER_ENABLE_CMD | GPIO17 |
| CHARGER_ILIM_CMD | GPIO23 |
| BIDIR_ENABLE | GPIO5 |
| BIDIR_DIRECTION | GPIO19 |
| BIDIR_CURRENT_CMD | GPIO13 |
| BIDIR_FAULT_N | GPIO14 |
| CHARGER_FAULT_N | GPIO2 |
| BIDIR_SC_V_TELEM | GPIO34, input only |
| BIDIR_BAT_V_TELEM | GPIO35, input only |
| CHARGER_V_TELEM | SENSOR_VP / GPIO36 |
| CHARGER_I_TELEM | SENSOR_VN / GPIO39 |
| ESP_BOOT_GPIO0 | GPIO0 |
| UART RX/TX | RXD0/TXD0 |
Ini
[env:esp32dev] platform = espressif32 board = esp32dev framework = arduino monitor_speed = 115200 build_flags = -DCORE_DEBUG_LEVEL=3
Cpp
#include <Arduino.h> #include <Wire.h> static constexpr int PIN_HW_FAULT_N = 27; static constexpr int PIN_CHARGER_CMD = 16; static constexpr int PIN_INVERTER_CMD = 17; static constexpr int PIN_CHARGER_ILIM = 23; static constexpr int PIN_BIDIR_ENABLE = 5; static constexpr int PIN_BIDIR_DIR = 19; static constexpr int PIN_BIDIR_CURRENT = 13; static constexpr int PIN_BIDIR_FAULT_N = 14; static constexpr int PIN_CHARGER_FAULT_N = 2; static constexpr int PIN_ADC1_ALERT_N = 32; static constexpr int PIN_ADC2_ALERT_N = 33; static constexpr int PIN_ADC3_ALERT_N = 4; static constexpr int PIN_SC_TELEM = 34; static constexpr int PIN_BAT_TELEM = 35; static constexpr int PIN_CHARGER_V = 36; static constexpr int PIN_CHARGER_I = 39; static constexpr uint8_t ADS_ADDR[3] = {0x48, 0x49, 0x4A}; bool writeADS(uint8_t addr, uint8_t reg, uint16_t value) { Wire.beginTransmission(addr); Wire.write(reg); Wire.write(value >> 8); Wire.write(value & 0xFF); return Wire.endTransmission() == 0; } bool readADS(uint8_t addr, uint8_t reg, int16_t &value) { Wire.beginTransmission(addr); Wire.write(reg); if (Wire.endTransmission(false) != 0) return false; if (Wire.requestFrom((int)addr, 2) != 2) return false; value = (int16_t)((Wire.read() << 8) | Wire.read()); return true; } bool readADSChannel(uint8_t addr, uint8_t channel, int16_t &raw) { uint16_t mux = 0x4000u + ((uint16_t)channel << 12); uint16_t config = 0x8000u | mux | 0x0200u | 0x0100u | 0x0080u | 0x0003u; if (!writeADS(addr, 0x01, config)) return false; delay(10); return readADS(addr, 0x00, raw); } void forceSafeState() { digitalWrite(PIN_CHARGER_CMD, LOW); digitalWrite(PIN_INVERTER_CMD, LOW); digitalWrite(PIN_BIDIR_ENABLE, LOW); digitalWrite(PIN_BIDIR_CURRENT, LOW); digitalWrite(PIN_CHARGER_ILIM, LOW); } void setup() { Serial.begin(115200); Wire.begin(21, 22); pinMode(PIN_HW_FAULT_N, INPUT_PULLUP); pinMode(PIN_BIDIR_FAULT_N, INPUT_PULLUP); pinMode(PIN_CHARGER_FAULT_N, INPUT_PULLUP); pinMode(PIN_ADC1_ALERT_N, INPUT_PULLUP); pinMode(PIN_ADC2_ALERT_N, INPUT_PULLUP); pinMode(PIN_ADC3_ALERT_N, INPUT_PULLUP); pinMode(PIN_CHARGER_CMD, OUTPUT); pinMode(PIN_INVERTER_CMD, OUTPUT); pinMode(PIN_CHARGER_ILIM, OUTPUT); pinMode(PIN_BIDIR_ENABLE, OUTPUT); pinMode(PIN_BIDIR_DIR, OUTPUT); pinMode(PIN_BIDIR_CURRENT, OUTPUT); forceSafeState(); analogReadResolution(12); Serial.println("Hybrid power supervisor starting in SAFE/OFF state"); } void loop() { const bool hwHealthy = digitalRead(PIN_HW_FAULT_N) == HIGH; const bool chargerHealthy = digitalRead(PIN_CHARGER_FAULT_N) == HIGH; const bool bidirHealthy = digitalRead(PIN_BIDIR_FAULT_N) == HIGH; if (!hwHealthy || !chargerHealthy || !bidirHealthy) forceSafeState(); for (uint8_t adc = 0; adc < 3; ++adc) { for (uint8_t channel = 0; channel < 4; ++channel) { int16_t raw = 0; if (readADSChannel(ADS_ADDR[adc], channel, raw)) { Serial.printf("ADS%u CH%u=%d ", adc + 1, channel, raw); } else { Serial.printf("ADS%u CH%u=ERR ", adc + 1, channel); } } } Serial.printf("SC=%d BAT=%d CHG_V=%d CHG_I=%d HW=%d\n", analogRead(PIN_SC_TELEM), analogRead(PIN_BAT_TELEM), analogRead(PIN_CHARGER_V), analogRead(PIN_CHARGER_I), hwHealthy); delay(1000); }
Bash
pio run pio run -t upload pio device monitor
Platform
Pin Mapping
platformio.ini
src/main.cpp
Build and Flash