To control DC trains using your phone, you will need two boards. They are:
esp32 DEVKIT
L298n
And the app at this link called Arduino Train DEMO
And you will need a sketch. The sketch comes from entry level.
A copy of the sketch is at the bottom of this page.
Programming the boards requires a bit of attention. It is best to watch how it is done.
Here is a good video. Not that it opens with a screen that says, “Finally after days of working I did control my ho scale train on my phone. ”
I have broken it down into specific images and put them in a gallery below. I will update the images with my own as I build this system myself using his video as a guide.
You need the following boards
This gallery shows the step by step process.
//-------------------------------------------------------------------// // WWW.ARDUINORAILWAYCONTROL.COM // //-------------------------------------------------------------------// // QUICK START // // ESP32 // // ANDROID TRAIN APPS // // https://play.google.com/store/apps/dev?id=8362636330024617247 // // PROTOCOL 2.4 // // V.1.2020 Steve Massikker // //-------------------------------------------------------------------// #include "BluetoothSerial.h" #define LED_BUILTIN 2 #define L298_ENA 13 #define L298_IN1 12 #define L298_IN2 14 #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED) #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it #endif BluetoothSerial SerialBT; // VARIABLES // bool stringComplete = false; String inputString = ""; // 24 speed byte speedArray [] = {20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,255}; byte speedTrain = 0; // Setting PWM properties const int freq = 100; const int pwmChannel_A = 0; const int resolution = 8; int dutyCycle = 0; void setup() { SerialBT.begin("ArduinoTrain"); //Bluetooth device name SerialBT.register_callback(callback); // Check connection inputString.reserve(4); // Configure GPIO ledcSetup(pwmChannel_A, freq, resolution); // Attach GPIO ledcAttachPin(L298_ENA, pwmChannel_A); pinMode(L298_IN1, OUTPUT); pinMode(L298_IN2, OUTPUT); pinMode(LED_BUILTIN, OUTPUT); // Set default direction to FORWARD digitalWrite(L298_IN1, HIGH); digitalWrite(L298_IN2, LOW); } void loop() { // ---- START PARSING INCOMING APP COMMANDS if (stringComplete) { if (inputString.charAt(0) =='a') { // Speed if (inputString.charAt(1) =='0') { if (inputString.charAt(2) =='0') speedTrain = 0; if (inputString.charAt(2) =='1') speedTrain = speedArray[0]; if (inputString.charAt(2) =='2') speedTrain = speedArray[1]; if (inputString.charAt(2) =='3') speedTrain = speedArray[2]; if (inputString.charAt(2) =='4') speedTrain = speedArray[3]; if (inputString.charAt(2) =='5') speedTrain = speedArray[4]; if (inputString.charAt(2) =='6') speedTrain = speedArray[5]; if (inputString.charAt(2) =='7') speedTrain = speedArray[6]; if (inputString.charAt(2) =='8') speedTrain = speedArray[7]; if (inputString.charAt(2) =='9') speedTrain = speedArray[8]; } if (inputString.charAt(1) =='1') { if (inputString.charAt(2) =='0') speedTrain = speedArray[9]; if (inputString.charAt(2) =='1') speedTrain = speedArray[10]; if (inputString.charAt(2) =='2') speedTrain = speedArray[11]; if (inputString.charAt(2) =='3') speedTrain = speedArray[12]; if (inputString.charAt(2) =='4') speedTrain = speedArray[13]; if (inputString.charAt(2) =='5') speedTrain = speedArray[14]; if (inputString.charAt(2) =='6') speedTrain = speedArray[15]; if (inputString.charAt(2) =='7') speedTrain = speedArray[16]; if (inputString.charAt(2) =='8') speedTrain = speedArray[17]; if (inputString.charAt(2) =='9') speedTrain = speedArray[18]; } if (inputString.charAt(1) =='2') { if (inputString.charAt(2) =='0') speedTrain = speedArray[19]; if (inputString.charAt(2) =='1') speedTrain = speedArray[20]; if (inputString.charAt(2) =='2') speedTrain = speedArray[21]; if (inputString.charAt(2) =='3') speedTrain = speedArray[22]; if (inputString.charAt(2) =='4') speedTrain = speedArray[23]; } // Direction and Stop if (inputString.charAt(1) =='d') { if (inputString.charAt(2) =='f') { // (f) Forward digitalWrite(L298_IN1, HIGH); digitalWrite(L298_IN2, LOW); } if (inputString.charAt(2) =='b') { // (b) Backward digitalWrite(L298_IN1, LOW); digitalWrite(L298_IN2, HIGH); } if (inputString.charAt(2) =='s') { // (s) Stop button speedTrain = 0; } } ledcWrite(pwmChannel_A, speedTrain); } inputString = ""; stringComplete = false; } bluetoothEvent(); } //// FUNCTIONS //// void bluetoothEvent() { if (SerialBT.available()) { char inChar = (char)SerialBT.read(); inputString += inChar; if (inChar == 'z') { stringComplete = true; } } } void callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param){ if(event == ESP_SPP_SRV_OPEN_EVT) digitalWrite(LED_BUILTIN, HIGH); if(event == ESP_SPP_CLOSE_EVT ) { digitalWrite(LED_BUILTIN, LOW); digitalWrite(L298_IN1, HIGH); digitalWrite(L298_IN2, LOW); ledcWrite(pwmChannel_A, 0); } }