Æthel Drive Hardware Design
Table
| Function | ESP32 GPIO | Net | Notes |
|---|---|---|---|
| I2C SDA | 21 | I2C_SDA | MPU6050 + SSD1306, 4.7 kΩ pull-up to 3V3 |
| I2C SCL | 22 | I2C_SCL | MPU6050 + SSD1306, 4.7 kΩ pull-up to 3V3 |
| L298N ENA PWM | 25 | MOTOR_PWM_ENA | LEDC PWM-capable |
| L298N IN1 | 26 | MOTOR_IN1 | Direction |
| L298N IN2 | 27 | MOTOR_IN2 | Direction |
| MPU6050 INT | 16 | MPU6050_INT | Optional interrupt |
| Current ADC | 34 | ADC_MOTOR_CURRENT | ADC1 input-only |
| Voltage ADC | 35 | ADC_MOTOR_VOLTAGE | ADC1 input-only |
Ini
[env:esp32dev] platform = espressif32 board = esp32dev framework = arduino monitor_speed = 115200 lib_deps = adafruit/Adafruit MPU6050@^2.2.6 adafruit/Adafruit SSD1306@^2.5.13 adafruit/Adafruit GFX Library@^1.11.11
Cpp
#include <Arduino.h> #include <Wire.h> #include <WiFi.h> #include <Adafruit_MPU6050.h> #include <Adafruit_Sensor.h> #include <Adafruit_SSD1306.h> #define I2C_SDA_PIN 21 #define I2C_SCL_PIN 22 #define MOTOR_PWM_ENA_PIN 25 #define MOTOR_IN1_PIN 26 #define MOTOR_IN2_PIN 27 #define MPU6050_INT_PIN 16 #define ADC_MOTOR_CURRENT_PIN 34 #define ADC_MOTOR_VOLTAGE_PIN 35 #define PWM_CHANNEL 0 #define PWM_FREQ_HZ 20000 #define PWM_RES_BITS 10 #define OLED_WIDTH 128 #define OLED_HEIGHT 64 Adafruit_MPU6050 mpu; Adafruit_SSD1306 display(OLED_WIDTH, OLED_HEIGHT, &Wire, -1); static unsigned long lastSampleMs = 0; float readMotorVoltageV() { uint16_t raw = analogRead(ADC_MOTOR_VOLTAGE_PIN); float adcV = raw * 3.3f / 4095.0f; return adcV * 4.0f; // 30k/10k divider: ADC = VIN * 0.25 } float readMotorCurrentA() { uint16_t raw = analogRead(ADC_MOTOR_CURRENT_PIN); float adcV = raw * 3.3f / 4095.0f; float acsV = adcV * 1.5f; // 10k/20k divider: ADC = ACS * 2/3 return (acsV - 2.5f) / 0.185f; // ACS712-05B typ sensitivity } void setMotor(int duty0to1023, bool forward) { duty0to1023 = constrain(duty0to1023, 0, 1023); digitalWrite(MOTOR_IN1_PIN, forward ? HIGH : LOW); digitalWrite(MOTOR_IN2_PIN, forward ? LOW : HIGH); ledcWrite(PWM_CHANNEL, duty0to1023); } void setup() { Serial.begin(115200); Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN); pinMode(MOTOR_IN1_PIN, OUTPUT); pinMode(MOTOR_IN2_PIN, OUTPUT); pinMode(MPU6050_INT_PIN, INPUT); ledcSetup(PWM_CHANNEL, PWM_FREQ_HZ, PWM_RES_BITS); ledcAttachPin(MOTOR_PWM_ENA_PIN, PWM_CHANNEL); setMotor(0, true); analogReadResolution(12); analogSetPinAttenuation(ADC_MOTOR_CURRENT_PIN, ADC_11db); analogSetPinAttenuation(ADC_MOTOR_VOLTAGE_PIN, ADC_11db); if (!mpu.begin(0x68, &Wire)) Serial.println("MPU6050 not found"); if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) Serial.println("SSD1306 not found"); display.clearDisplay(); display.setTextColor(SSD1306_WHITE); display.setTextSize(1); display.setCursor(0, 0); display.println("Aethel Drive"); display.display(); } void loop() { if (millis() - lastSampleMs >= 500) { lastSampleMs = millis(); sensors_event_t a, g, temp; mpu.getEvent(&a, &g, &temp); float vmotor = readMotorVoltageV(); float imotor = readMotorCurrentA(); Serial.printf("V=%.2f V I=%.2f A ax=%.2f ay=%.2f az=%.2f\n", vmotor, imotor, a.acceleration.x, a.acceleration.y, a.acceleration.z); display.clearDisplay(); display.setCursor(0, 0); display.printf("Aethel Drive\nV: %.2f V\nI: %.2f A\nAx: %.2f\n", vmotor, imotor, a.acceleration.x); display.display(); } }
pio runpio run -t uploadpio device monitorPin Mapping
platformio.ini
src/main.cpp
Build & Flash