Community project
Create A Complete Electrical Schematic Esp32 Sma
This project builds a complete sensor and motor control system around an ESP32 microcontroller, powered by a 2-cell 18650 Li-ion battery pack. The system integrates motion detection via ADXL345 accelerometer, temperature monitoring with DS18B20, current sensing through ACS712, obstacle detection with an IR sensor, and dual motor control via L298N H-bridge driver, all displayed on an OLED screen.
The guide provides a complete wiring diagram, full parts list with resistor values, and ready-to-compile firmware that handles I2C communication, motor PWM control, and real-time sensor data display. Follow the assembly outline to safely integrate power distribution, sensor connections, and motor drivers, with inspection checkpoints before first power-up.
Wiring diagram

Gather all the parts
Assemble it in 6 steps
1. Place the power parts first
Put the 2-cell 18650 battery holder, the on/off switch, and the 5 V buck regulator on the car chassis. Connect battery BAT+ to the switch IN, connect switch OUT to the L298N Vs/12V input, and connect battery BAT+ to buck IN+ (motor power and regulator input). Connect battery BAT− to buck IN− and the common GND line (ground). Keep the switch OFF while building.
- Set the buck regulator output to 5.0 V with a meter before plugging it into any module.
- Use thicker wires for the battery, switch, L298N Vs, and motor connections.
- Do not reverse the battery leads — reversed battery power can damage the regulator, driver, and ESP32.
- Do not connect the 7.4 V battery directly to the ESP32 3.3 V or 5 V electronics rail.
2. Make the shared power rails
From the regulator OUT+ terminal, make a labeled +5V rail to the L298N 5V pin, ACS712 VCC, IR sensor VCC, and buzzer positive pin (power). Join regulator OUT− to every GND connection, including the ESP32 GND, L298N GND, sensors, OLED, LEDs, transistor emitter, and battery negative (ground). Use the ESP32 3.3V pin as the labeled +3.3V rail for the ADXL345, DS18B20, OLED, and DS18B20 pull-up resistor (power).
- Treat every GND symbol or wire as one shared electrical point, even when the schematic uses separate ground symbols.
- Keep motor-current wires away from the small sensor wires where possible.
- A missing shared ground can make sensors and motor controls behave unpredictably.
- Make sure the ADXL345 and OLED VCC pins go to 3.3 V, not 5 V — 5 V can damage 3.3 V-only modules.
3. Wire the sensors to the ESP32
Wire ADXL345 SCL to GPIO22 and SDA to GPIO21 (shared data wires); wire INT1 to GPIO19 and INT2 to GPIO18 (signals). Wire OLED SCL to GPIO22 and SDA to GPIO21, with VCC to 3.3V and GND to GND (power and ground). Wire DS18B20 DATA pin 2 to GPIO23 and fit the 4.7 kΩ resistor from that same DATA wire to 3.3V (signal pull-up); DS18B20 pin 1 goes to 3.3V and pin 3 to GND. Wire the protected IR divider output to GPIO25 and the protected ACS712 divider output to GPIO34 (signals).
- On the DS18B20 with its flat face toward you, pin 1 is 3.3 V, the middle pin 2 is DATA, and pin 3 is GND.
- The two I2C data wires are intentionally shared between the ADXL345 and OLED.
- Do not bypass the 12 kΩ and 22 kΩ ACS712 divider — direct 5 V analog output can damage GPIO34.
- Do not bypass the 12 kΩ and 22 kΩ IR divider if your IR module outputs 5 V — it protects GPIO25.
4. Fit the indicators and buzzer driver
Connect GPIO17 to the 220 Ω green LED resistor, then to the green LED anode; connect its cathode to GND (status light). Connect GPIO16 to the 220 Ω red LED resistor, then to the red LED anode; connect its cathode to GND (status light). Connect GPIO5 through the 1 kΩ resistor to the NPN transistor base, connect emitter to GND, collector to buzzer negative, and buzzer positive to +5V (sound control).
- The LED’s longer leg is usually the anode; the shorter leg or flat-sided end is the cathode.
- The transistor face and pin order vary by package, so check its printed pinout before inserting it.
- Each LED must keep its 220 Ω resistor — without it the LED or ESP32 pin can be damaged.
- A transistor wired with collector and emitter swapped may not operate correctly or can overheat.
5. Connect the driver and motors
Connect L298N ENA to GPIO4, IN1 to GPIO2, IN2 to GPIO15, IN3 to GPIO13, IN4 to GPIO12, and ENB to GPIO14 (motor-control signals). Connect L298N OUT1 and OUT2 to the two terminals of TT Motor 1, and OUT3 and OUT4 to the two terminals of TT Motor 2 (motor power). Mount the motors so their wires cannot rub on the wheels.
- If a motor runs backward later, swap only that motor’s two wires at OUT1/OUT2 or OUT3/OUT4.
- Keep the L298N where it can lose heat; it can become warm during motor use.
- GPIO2, GPIO12, and GPIO15 are ESP32 start-up pins; keep the L298N connections in place and avoid adding extra pull-up or pull-down parts to those wires.
- Never unplug or reconnect motor wires while battery power is switched on — a loose wire can short the motor supply.
6. Inspect before powering up
With the switch still OFF, check that every module has GND connected to the same common ground, that no 7.4 V wire reaches a 3.3 V device, and that both voltage-divider resistor pairs are fitted. Then plug the ESP32 into USB for programming and use Schematik’s Deploy button; only switch on the battery after the wiring inspection is complete.
- First power test with the wheels lifted off the table so an unexpected motor movement cannot drive the car away.
- At start-up the supplied firmware deliberately keeps both motors stopped.
- If anything becomes hot, smells unusual, or the regulator output is not 5 V, immediately switch off and disconnect the battery.
- Do not power the car from battery and USB until the common-ground wiring has been checked.
Review all connections
1. Connections between "battery_2s" and "ESP32"
2. Connections between "power_switch" and "ESP32"
3. Connections between "buck_5v" and "ESP32"
4. Connections between "adxl345" and "ESP32"
5. Connections between "acs712" and "ESP32"
6. Connections between "acs_rtop" and "ESP32"
7. Connections between "acs_rbottom" and "ESP32"
8. Connections between "ir_sensor" and "ESP32"
9. Connections between "ir_rtop" and "ESP32"
10. Connections between "ir_rbottom" and "ESP32"
11. Connections between "ds18b20" and "ESP32"
12. Connections between "ds18b20_pullup" and "ESP32"
13. Connections between "oled" and "ESP32"
14. Connections between "green_resistor" and "ESP32"
15. Connections between "green_led" and "ESP32"
16. Connections between "red_resistor" and "ESP32"
17. Connections between "red_led" and "ESP32"
18. Connections between "buzzer" and "ESP32"
19. Connections between "buzzer_transistor" and "ESP32"
20. Connections between "buzzer_base_resistor" and "ESP32"
21. Connections between "l298n" and "ESP32"
Deploy the firmware
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// Forward declarations
void stopMotors();
void configureAdxl345();
void drawStatus(float temperatureC, float currentVoltage, bool obstacle);
constexpr int L298_ENA = 4;
constexpr int L298_IN1 = 2;
constexpr int L298_IN2 = 15;
constexpr int L298_IN3 = 13;
constexpr int L298_IN4 = 12;
constexpr int L298_ENB = 14;
constexpr int BUZZER_PIN = 5;
constexpr int RED_LED_PIN = 16;
constexpr int GREEN_LED_PIN = 17;
constexpr int ADXL_INT2_PIN = 18;
constexpr int ADXL_INT1_PIN = 19;
constexpr int I2C_SDA_PIN = 21;
constexpr int I2C_SCL_PIN = 22;
constexpr int DS18B20_PIN = 23;
constexpr int IR_PIN = 25;
constexpr int ACS712_ADC_PIN = 34;
constexpr uint8_t OLED_ADDRESS = 0x3C;
constexpr uint8_t ADXL345_ADDRESS = 0x53;
constexpr unsigned long UPDATE_INTERVAL_MS = 500;
Adafruit_SSD1306 display(128, 64, &Wire, -1);
OneWire oneWire(DS18B20_PIN);
DallasTemperature temperatureSensor(&oneWire);
unsigned long lastUpdate = 0;
float lastTemperatureC = -127.0f;
float lastCurrentVoltage = 0.0f;
bool lastObstacle = false;
bool displayAvailable = false;
void stopMotors() {
digitalWrite(L298_ENA, LOW);
digitalWrite(L298_ENB, LOW);
digitalWrite(L298_IN1, LOW);
digitalWrite(L298_IN2, LOW);
digitalWrite(L298_IN3, LOW);
digitalWrite(L298_IN4, LOW);
}
void configureAdxl345() {
Wire.beginTransmission(ADXL345_ADDRESS);
Wire.write(0x2D); // POWER_CTL register
Wire.write(0x08); // measurement mode
Wire.endTransmission();
}
void drawStatus(float temperatureC, float currentVoltage, bool obstacle) {
if (!displayAvailable) return;
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println(F("ESP32 SMART CAR"));
display.println(F("Motors: STOPPED"));
display.print(F("Temp: "));
if (temperatureC <= -100.0f) {
display.println(F("sensor check"));
} else {
display.print(temperatureC, 1);
display.println(F(" C"));
}
display.print(F("ACS ADC: "));
display.print(currentVoltage, 2);
display.println(F(" V"));
display.print(F("IR obstacle: "));
display.println(obstacle ? F("YES") : F("NO"));
display.display();
}
void setup() {
pinMode(L298_ENA, OUTPUT);
pinMode(L298_IN1, OUTPUT);
pinMode(L298_IN2, OUTPUT);
pinMode(L298_IN3, OUTPUT);
pinMode(L298_IN4, OUTPUT);
pinMode(L298_ENB, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(RED_LED_PIN, OUTPUT);
pinMode(GREEN_LED_PIN, OUTPUT);
pinMode(ADXL_INT1_PIN, INPUT);
pinMode(ADXL_INT2_PIN, INPUT);
pinMode(IR_PIN, INPUT);
digitalWrite(BUZZER_PIN, LOW);
digitalWrite(RED_LED_PIN, LOW);
digitalWrite(GREEN_LED_PIN, HIGH);
stopMotors();
Serial.begin(115200);
Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN);
configureAdxl345();
temperatureSensor.begin();
analogReadResolution(12);
displayAvailable = display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS);
if (displayAvailable) {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println(F("ESP32 Smart Car"));
display.println(F("Sensor monitor ready"));
display.display();
}
}
void loop() {
const unsigned long now = millis();
if (now - lastUpdate < UPDATE_INTERVAL_MS) return;
lastUpdate = now;
temperatureSensor.requestTemperatures();
lastTemperatureC = temperatureSensor.getTempCByIndex(0);
const int adcRaw = analogRead(ACS712_ADC_PIN);
lastCurrentVoltage = (adcRaw * 3.3f) / 4095.0f;
lastObstacle = (digitalRead(IR_PIN) == LOW);
digitalWrite(RED_LED_PIN, lastObstacle ? HIGH : LOW);
digitalWrite(GREEN_LED_PIN, lastObstacle ? LOW : HIGH);
digitalWrite(BUZZER_PIN, lastObstacle ? HIGH : LOW);
Serial.print(F("Temp C: "));
Serial.print(lastTemperatureC, 1);
Serial.print(F(" | ACS ADC V: "));
Serial.print(lastCurrentVoltage, 2);
Serial.print(F(" | Obstacle: "));
Serial.println(lastObstacle ? F("YES") : F("NO"));
drawStatus(lastTemperatureC, lastCurrentVoltage, lastObstacle);
}Remix this project
Make it yours in one click
Open a full copy of this project in your own Schematik workspace — diagram, code, parts, and assembly steps included. Swap the sensor, add features, or redesign the whole thing with AI. The author's original stays untouched.




