Esp32 Capacitor discharge and charge — ESP32 simulation

An interactive ESP32 circuit simulation you can run free in your browser on Velxio, by vinittechpro.

Components

Sketch code

#include <Wire.h>
#include <math.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define ADC_PIN 34
#define SWITCH_PIN 27

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

Adafruit_SSD1306 display(
  SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1
);

// -------- RC COMPONENT VALUES --------
const float R1 = 30000.0f;
const float R2 = 30000.0f;
const float C  = 220e-6f;
const float VCC = 3.3f;

// -------- RC MATHEMATICS --------
const float REQ = (R1 * R2) / (R1 + R2);
const float TAU = REQ * C;
const float VFINAL = VCC * R2 / (R1 + R2);

// -------- GRAPH SETTINGS --------
const int GRAPH_SIZE = 112;
const int GRAPH_TOP = 26;
const int GRAPH_BOTTOM = 60;
const float GRAPH_MAX = 1.8f;

// 200 milliseconds between samples
const unsigned long SAMPLE_MS = 200;

int measuredGraph[GRAPH_SIZE];
int theoryGraph[GRAPH_SIZE];

unsigned long lastSample = 0;
unsigned long phaseStart = 0;
unsigned long switchChangeTime = 0;

int stableSwitch = LOW;
int candidateSwitch = LOW;

float voltage = 0.0f;
float theoryVoltage = 0.0f;
float initialVoltage = 0.0f;

// -------- READ REAL VOLTAGE --------
float readCapVoltage() {
  float total = 0;

  for (int i = 0; i < 8; i++) {
    total += analogReadMilliVolts(ADC_PIN);
    delay(1);
  }

  return total / 8000.0f;
}

// -------- CALCULATE EXPONENTIAL CURVE --------
float calculateTheory(float t) {

  // Target depends on switch position
  float target = (stableSwitch == HIGH)
                   ? VFINAL
                   : 0.0f;

  // General RC exponential equation
  return target +
         (initialVoltage - target) *
         expf(-t / TAU);
}

// -------- CONVERT VOLTAGE TO PIXEL --------
int voltageToY(float v) {
  float fraction = constrain(
    v / GRAPH_MAX, 0.0f, 1.0f
  );

  return GRAPH_BOTTOM -
         roundf(fraction *
         (GRAPH_BOTTOM - GRAPH_TOP));
}

// -------- SWITCH CHANGE --------
void beginNewPhase(int position) {
  stableSwitch = position;

  // Use the actual voltage at switch change
  initialVoltage = readCapVoltage();

  phaseStart = millis();

  // IMPORTANT:
  // Do not clear the graph here!
}

// -------- OLED DISPLAY --------
void drawDisplay() {
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(1);

  display.setCursor(0, 0);
  if (stableSwitch == HIGH) {
    display.print("CHARGING");
  } else {
    display.print("DISCHARGING");
  }

  display.setCursor(0, 12);
  display.print("M:");
  display.print(voltage, 2);
  display.print(" T:");
  display.print(theoryVoltage, 2);

  // Axes
  display.drawLine(
    13, GRAPH_TOP,
    13, 62,
    SSD1306_WHITE
  );

  display.drawLine(
    13, 62,
    127, 62,
    SSD1306_WHITE
  );

  // Measured curve: solid line
  for (int i = 1; i < GRAPH_SIZE; i++) {
    if (measuredGraph[i] < 0 ||
        measuredGraph[i - 1] < 0) {
      continue;
    }

    display.drawLine(
      15 + i - 1, measuredGraph[i - 1],
      15 + i, measuredGraph[i],
      SSD1306_WHITE
    );
  }

  // Mathematical curve: dotte