Hello, I am building a rover using a Lilygo T3S3 and an L298N motor driver.
The problem I am having is thatas soon as I connect my 7.4V LiPo battery and turn my rocker switch to the on position, the motor starts spinning really fast. I can see the commands to move the rover up, down, or stop on the monitor, but they do not do anything to the motor.
It does work, as I tested it, but with LEDs on Wowki.
Here are some things I have noticed about the hardware:
-
If I unplug the Lilygo T3S3 from both the usb and the 5V power supply, re the motor stops moving.
-
If I connect the 5V power wire from the L298N motor driver to the Lilygo T,3S3,, even if thUSBsb is unplugged, ed the motor starts spinning
I have checked the wiring. It seems to be correct: I have pin 33 connected to ENB pin 18, connected to I, N3, and pin 16 connected to IN4. I am using the motor B sidewhich is OUT3 and OUT4.
My current code is using a web server to control he Pis, on the Lilygo T3S3. I have tried setting the pins to low in the loop. This has not stopped the motor from spinning out of control.
`#include <WiFi.h>
#include <WebServer.h>
// --- WiFi Credentials ---
const char* ssid = "SKYR2PSQ-ext";
const char* password = "************";
// --- Pins for Motor B (OUT3 & OUT4) ---
#define ENB 33 // The "Speed" pin (Connect to the ENB pin on the driver)
#define IN3 18 // Direction Pin 1 (Connect to the IN3 pin on the driver)
#define IN4 16 // Direction Pin 2 (Connect to the IN4 pin on the driver)
// --- PWM Settings ---
const int pwmFreq = 5000; // 5 KHz
const int pwmChannel = 0;
const int pwmResolution = 8; // 8-bit resolution (0-255)
int motorSpeed = 200; // Default speed (0-255)
// Create WebServer object on port 80
WebServer server(80);
// --- HTML Web Page ---
const char webpage[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ESP32 Motor Control</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
background-color: #1a1a1a;
color: white;
margin: 0;
padding: 20px;
}
h1 {
color: #4CAF50;
}
.control-container {
display: inline-block;
margin: 30px auto;
}
.button-row {
display: flex;
justify-content: center;
margin: 10px 0;
}
button {
background-color: #4CAF50;
border: none;
color: white;
padding: 30px 40px;
text-align: center;
font-size: 24px;
margin: 5px;
cursor: pointer;
border-radius: 12px;
transition: all 0.3s;
min-width: 120px;
}
butto n:h over {
background-color: #45a049;
transform: scale(1.05);
}
butto n: active {
background-color: #367c39;
transform: scale(0.98);
}
.stop-btn {
background-color: #f44336;
}
.stop-btn:hover {
background-color: #da190b;
}
.speed-control {
margin: 30px auto;
max-width: 400px;
}
input[type="range"] {
width: 80%;
height: 8px;
margin: 20px 0;
}
.speed-value {
font-size: 20px;
color: #4CAF50;
}
</style>
</head>
<body>
<h1>ESP32 Motor Control</h1>
<div class="control-container">
<div class="button-row">
<button onclick="sendCommand('forward')">UP</button>
</div>
<div class="button-row">
<button onclick="sendCommand('stop')" class="stop-btn">STOP</button>
</div>
<div class="button-row">
<button onclick="sendCommand('backward')">DOWN</button>
</div>
</div>
<div class="speed-control">
<h3>Motor Speed</h3>
<input type="range" min="0" max="255" value="200" id="speedSlider" oninput="updateSpeed(this.value)">
<div class="speed-value">Speed: <span id="speedValue">200</span></div>
</div>
<script>
function sendCommand(cmd) {
fetch('/' + cmd)
.then(response => response.text())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
}
function updateSpeed(val) {
document.getElementById('speedValue').textContent = val;
fetch('/speed?value=' + val)
.then(response => response.text())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
}
</script>
</body>
</html>
)rawliteral";
// Track last command time for safety
unsigned long lastCommandTime = 0;
// --- Motor Control Functions ---
void motorForward() {
lastCommandTime = millis();
Serial.println("=== FORWARD Command ===");
// Detach PWM temporarily
ledcDetachPin(ENB);
pinMode(ENB, OUTPUT);
digitalWrite(ENB, HIGH); // Full power
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
delay(10);
// Reattach PWM
ledcAttachPin(ENB, pwmChannel);
ledcWrite(pwmChannel, motorSpeed);
Serial.print("IN3: HIGH, IN4: LOW, PWM: ");
Serial.println(motorSpeed);
}
void motorBackward() {
lastCommandTime = millis();
Serial.println("=== BACKWARD Command ===");
// Detach PWM temporarily
ledcDetachPin(ENB);
pinMode(ENB, OUTPUT);
digitalWrite(ENB, HIGH); // Full power
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
delay(10);
// Reattach PWM
ledcAttachPin(ENB, pwmChannel);
ledcWrite(pwmChannel, motorSpeed);
Serial.print("IN3: LOW, IN4: HIGH, PWM: ");
Serial.println(motorSpeed);
}
void motorStop() {
lastCommandTime = millis();
Serial.println("=== STOP Command ===");
// Force everything off
ledcDetachPin(ENB);
pinMode(ENB, OUTPUT);
digitalWrite(ENB, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
delay(10);
Serial.println("Motor STOPPED - all pins LOW");
}
// --- Web Server Handlers ---
void handleRoot() {
server.send(200, "text/html", webpage);
}
void handleForward() {
motorForward();
server.send(200, "text/plain", "Moving Forward");
}
void handleBackward() {
motorBackward();
server.send(200, "text/plain", "Moving Backward");
}
void handleLeft() {
// Fora single motor, left could mean backward or a specific pattern
motorBackward();
server.send(200, "text/plain", "Turning Left");
}
void handleRight() {
// Foa r single motor, right could mean forward or a specific pattern
motorForward();
server.send(200, "text/plain", "Turning Right");
}
void handleStop() {
motorStop();
server.send(200, "text/plain", "Motor Stopped");
}
void handleSpeed() {
if (server.hasArg("value")) {
motorSpeed = server.arg("value").toInt();
motorSpeed = constrain(motorSpeed, 0, 255);
Serial.print("Speed set to: ");
Serial.println(motorSpeed);
server.send(200, "text/plain", "Speed updated");
} else {
server.send(400, "text/plain", "Missing speed value");
}
}
void setup() {
Serial.begin(115200);
while(!Serial && millis() < 3000);
Serial.println("\n\nESP32-S3 Motor Control Starting...");
// --- Setup Motor Pins as INPUT first to prevent startup glitches ---
pinMode(IN3, INPUT);
pinMode(IN4, INPUT);
pinMode(ENB, INPUT);
delay(500); // Wait for pins to stabilize
// Now set as OUTPUT
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(ENB, OUTPUT);
// Force all pins LOW immediately
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
digitalWrite(ENB, LOW);
delay(100); // Small delay to ensure pins are stable
// Setup PWM for speed control
ledcSetup(pwmChannel, pwmFreq, pwmResolution);
ledcAttachPin(ENB, pwmChannel);
ledcWrite(pwmChannel, 0); // Ensure PWM starts at 0
// Safety: Start with motor OFF
motorStop();
Serial.println("Motor pins initialized - Motor should be STOPPED");
// --- Connect to WiFi ---
Serial.print("Connecting to WiFi: ");
Serial.println(ssid);
WiFi.mode(WIFI_STA); // Set WiFi to station mode
WiFi.disconnect(); // Clear any previous connections
delay(100);
WiFi.begin(ssid, password);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 30) {
delay(500);
Serial.print(".");
attempts++;
// Print WiFi status for debugging
if (attempts % 10 == 0) {
Serial.print("\nStatus: ");
Serial.print(WiFi.status());
Serial.print(" - ");
}
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\n✓ WiFi Connected!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
Serial.print("Signal Strength (RSSI): ");
Serial.print(WiFi.RSSI());
Serial.println(" dBm");
Serial.println("Open this IP in your browser to control the motor");
} else {
Serial.println("\n✗ WiFi Connection Failed!");
Serial.print("Final Status Code: ");
Serial.println(WiFi.status());
Serial.println("Possible issues:");
Serial.println("- Check if SSID is correct (case-sensitive)");
Serial.println("- Check if password is correct");
Serial.println("- Check if router is on 2.4GHz (ESP32 doesn't support 5GHz)");
Serial.println("- Try moving closer to the router");
}
// --- Setup Web Server Routes ---
server.on("/", handleRoot);
server.on("/forward", handleForward);
server.on("/backward", handleBackward);
server.on("/left", handleLeft);
server.on("/right", handleRight);
server.on("/stop", handleStop);
server.on("/speed", handleSpeed);
// Start server
server.begin();
Serial.println("Web server started!");
}
void loop() {
server.handleClient();
// Emergency safety: constantly force STOP if no recent command
static unsigned long lastCommandTime = 0;
static unsigned long lastCommand = millis();
// If no command received in last 100ms, force stop
if (millis() - lastCommand > 100) {
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
ledcWrite(pwmChannel, 0);
}
}`








