5 Inch gauge locomotive
Print Profile(0)
Bill of Materials
- H Bridge Motor Driver x 1: Rated for current of motor and 12 V tolerant.
- 12 V Motor x 1: Within current requirements of motor driver and battery
- ESP32 Development Board x 1: Most should work
- 12 V battery x 1: A drill battery or a sealed lead asid battery.
- 12 V to 5V convertor x 1: I used a bredboard power supply but i also tried a car usb adaptor that worked until the adapter broke.
- 12 V Fuse x 1: An automotive fuse rated for the current capacity of the motor driver should stop it burning out. Any automative one should do.
- Belt drive x 1: Ensure it fits the motor and the axle and can handle the torque. Mine was a gt3 timing belt and sliped a bit but was mostly fine.
- Logic level convertor x 1: If the motor driver requiers 5 V logic. The ESP 32 only only outputs 3.3V
Description
Note: The chasis I used was mostly printed in PLA but I had some problems with warping in the sun. I would recomend PETG for most of it but TPU for the tyres on the wheels because my PLA ones cracked and derailed the loco.
Boost Me (for free)
Show the designer your appreciation with a single click. Your Boost helps them earn store credit for more filament and future projects. It's the best way to say 'Thanks for the model'!.
Logic level convertor - https://www.amazon.co.uk/Qusedwey-Channel-Converter-Bi-Directional-Shifter-blue/dp/B0DV57CYQG/ref=asc_df_B0DV57CYQG?mcid=0af502139f683f1a8b9fa186f1706f28&hvocijid=10723513870068977404-B0DV57CYQG-&hvexpln=74&tag=googshopuk-21&linkCode=df0&hvadid=696285193871&hvpos=&hvnetw=g&hvrand=10723513870068977404&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=9045652&hvtargid=pla-2281435176658&psc=1&gad_source=1 - I made my own with a breadbord and some transistors but this one will do.
Voltage converter - https://www.amazon.co.uk/Jadeshay-Converter-Step-down-Waterproof-Vehicles/dp/B0CZDPQWJ3/ref=sr_1_13?crid=1TI3XV19723H8&dib=eyJ2IjoiMSJ9.0Vd9wkX8enpHVU91MGGJOEn7zcvxSuM7-U4lgGht3EhEb5Z4MwTNu8u9LmCPX01UAiVRL0qo7Axn-RBVYivAybxys9aoY4A9vsR8ZDowPu6NfDTHddtQ_CIm6HvJEOrVjOyOjgRF9VuZIFXsf1jihh68y5CZ6sP_NpzaSsVP38lvmv_NjX0PLiZbQS_UMNaDFvhqhB_vCT0HDVrT_h-fs5U1CFk8B6U4dskAgpNDq2B48HAa710jJTwX059Kwc2rsOZbw7LiOo1b0PCsQlCQD8DbuvVdjlB_QsegciT8a8w.paZuhDPjkj_gTQsJTq-u7r06CBt54FItTDDn40ioSZQ&dib_tag=se&keywords=12v+to+5v&qid=1757863809&s=industrial&sprefix=12v+to+5v%2Cindustrial%2C116&sr=1-13
Belt drive - https://www.amazon.co.uk/dp/B0CQQYT9QM?ref=ppx_pop_dt_b_product_details&th=1
Arduino IDE sketch -
#include <WiFi.h>
#include <NetworkClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <WiFiAP.h>
// Motor 1
int motor1Pin1 = 26;
int motor1Pin2 = 25;
int enable1Pin = 14;
// Setting PWM properties
const int resolution = 8;
int dutyCycle = 0;
const char *ssid = "Train Controller";
const char *password = "";
String valueString = String(0);
WebServer server(80);
void handleRoot() {
const char html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
<style>
html { font-family: Helvetica; text-align: center; }
.button {
user-select: none; background-color: #4CAF50; border: none;
color: white; padding: 12px 28px; font-size: 26px;
margin: 1px; cursor: pointer;
}
.button2 { background-color: #ff0000; }
input[type=range]:disabled {
opacity: 0.5;
}
</style>
<script>
function moveForward() {
fetch('/forward').then(() => {
document.getElementById('motorSpeed').innerText = 0;
document.getElementById('motorSlider').value = 0;
document.getElementById('motorSlider').disabled = false;
document.getElementById('motorDirection').innerText = "Forward";
});
}
function stopMotor() {
fetch('/stop').then(() => {
document.getElementById('motorSpeed').innerText = 0;
document.getElementById('motorSlider').value = 0;
document.getElementById('motorSlider').disabled = true;
document.getElementById('motorDirection').innerText = "Stopped";
});
}
function moveReverse() {
fetch('/reverse').then(() => {
document.getElementById('motorSpeed').innerText = 0;
document.getElementById('motorSlider').value = 0;
document.getElementById('motorSlider').disabled = false;
document.getElementById('motorDirection').innerText = "Reverse";
});
}
function updateMotorSpeed(pos) {
document.getElementById('motorSpeed').innerText = pos;
fetch(`/speed?value=${pos}`);
}
document.getElementById('motorSpeed').innerText = 0;
document.getElementById('motorSlider').value = 0;
document.getElementById('motorSlider').disabled = true;
</script>
</head>
<body>
<h1>5 inch locomotive controll</h1>
<p><button class="button" onclick="moveForward()">FORWARD</button></p>
<p><button class="button button2" onclick="stopMotor()">Neutral</button></p>
<p><button class="button" onclick="moveReverse()">REVERSE</button></p>
<p>Power: <span id="motorSpeed">0</span></p>
<p>Direction: <span id="motorDirection">Stopped</span></p>
<p>Throttle:</p>
<input type="range" min="0" max="100" step="5" id="motorSlider" oninput="updateMotorSpeed(this.value)" value="0" disabled=true/>
</body>
</html>)rawliteral";
server.send(200, "text/html", html);
}
void handleSpeed() {
if (server.hasArg("value")) {
valueString = server.arg("value");
int value = valueString.toInt();
if (value == 0) {
analogWrite(enable1Pin, 0);
} else {
dutyCycle = map(value, 5, 100, 100, 255);
analogWrite(enable1Pin, dutyCycle);
}
}
server.send(200);
}
void handleStop() {
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor1Pin2, LOW);
analogWrite(enable1Pin, 0);
dutyCycle = 0;
server.send(200);
}
void handleForward() {
digitalWrite(motor1Pin1, HIGH);
digitalWrite(motor1Pin2, LOW);
analogWrite(enable1Pin, 0); // Reset speed to 0
server.send(200);
}
void handleReverse() {
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor1Pin2, HIGH);
analogWrite(enable1Pin, 0); // Reset speed to 0
server.send(200);
}
void handleNotFound() {
server.send(404, "text/plain", "File Not Found");
}
void setup(void) {
pinMode(motor1Pin1, OUTPUT);
pinMode(motor1Pin2, OUTPUT);
analogWrite(enable1Pin, 0);
analogWriteResolution(enable1Pin, resolution);
WiFi.softAP(ssid, password);
server.begin();
MDNS.begin("esp32");
server.on("/", handleRoot);
server.on("/speed", handleSpeed);
server.on("/forward", handleForward);
server.on("/stop", handleStop);
server.on("/reverse", handleReverse);
server.onNotFound(handleNotFound);
}
void loop(void) {
server.handleClient();
}














Comment & Rating (13)