NodeMCU and ESP8266 compiling errors.

Good Day All,
I am 3D printing a OS Railway train set for my grandson which can be found on thingiverse.
I have never owned or programed an Arduino I am just trying to follow the instructions included with one of the engine print files.
If you could take a look at the following sketch and the errors and point me in the right direction it would be greatly appreciated.
Thank You.
Merry Christmas,
Terry N

Here is the sketch,

/* Copyright Olle Sköld 2017
*

  • Wifi accesspoitn using NodeMCU and ESP8266.
  • This software is provided free and you may use, change and distribute as you like.

*/

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include "TimerObject.h"

#define forward 0
#define backward 1
/* Set these to your desired credentials. */
const char *ssid = "OSRHector";
const char *password = "osrailway";

bool highBeamActive = false;
bool motionActive = false;
bool motionDirection = forward;
int target_speed;
int actual_speed;
int acceleration_step = 5;

int LED_BL2 = 15; // Red light on side 2 GPIO15
int LED_BL1 = 13; // Red light on side 1 GPIO13
int LED_HB2 = 14; // High beam side 2 GPIO12
int LED_HB1 = 12; // High beam side 1 GPIO14

int LED_HDL = 2; //PWM for headlights controlled by motor board

int motor_AIN1 = 5; //GPIO5
int motor_AIN2 = 4; //GPIO4
int motor_PWM = 0; //GPIO0

TimerObject *timer1 = new TimerObject(10);

ESP8266WebServer server(80);

/**************************************************************************
*

  • Server IP address is: http://192.168.4.1
  • When you have connected your device to the wifi network, open the browser and enter the IP address above.

/
void handleRoot() {
/
***********************************************************************

void motionControl(){
if(motionActive){
if(actual_speed < target_speed){
actual_speed = actual_speed + acceleration_step;
} else if(actual_speed > target_speed){
actual_speed = actual_speed - acceleration_step;
}
if(actual_speed > 1023){
actual_speed = 1023;
}
if(actual_speed < 0){
actual_speed = 0;
}
analogWrite(motor_PWM, actual_speed);
} else {
analogWrite(motor_PWM, 0);
}
}

/**************************************************

  • Motor operation
    */

void motorOperation(){

motionActive = true;
String move_dir = server.arg("dir");
String motion_speed = server.arg("speed");
target_speed = motion_speed.toInt();

//Execute change of direction, but only if actual_speed is below 100, otherwise set target speed to 0 and initiate a slowdown.
if(move_dir == "backward"){
if(motionDirection != backward && actual_speed > 100){
target_speed = 0;
} else {
motionDirection = backward;
}
} else {
if(motionDirection != forward && actual_speed > 100){
target_speed = 0;
} else {
motionDirection = forward;
}
}

digitalWrite(motor_AIN1, motionDirection);
digitalWrite(motor_AIN2, !motionDirection);
digitalWrite(LED_BL2, motionDirection);
digitalWrite(LED_BL1, !motionDirection);

if(highBeamActive){
digitalWrite(LED_HB2, motionDirection);
digitalWrite(LED_HB1, !motionDirection);
} else {
digitalWrite(LED_HB2, 0);
digitalWrite(LED_HB1, 0);
}

}

void updateSpeed(){
String motion_speed = server.arg("speed");
target_speed = motion_speed.toInt();
}

void switchLightOn(){
highBeamActive = true;
digitalWrite(LED_HB2, motionDirection);
digitalWrite(LED_HB1, !motionDirection);
}

void switchLightOff(){
highBeamActive = false;
digitalWrite(LED_HB2, 0);
digitalWrite(LED_HB1, 0);
}

void motionStop(){
motionActive = false;
analogWrite(motor_PWM, 0);
}

/*********************************************************************

  • SETUP
    */

void setup() {
delay(1000);

pinMode(LED_BL2, OUTPUT);
pinMode(LED_BL1, OUTPUT);
pinMode(LED_HB2, OUTPUT);
pinMode(LED_HB1, OUTPUT);

pinMode(LED_HDL, OUTPUT);

pinMode(motor_AIN1, OUTPUT);
pinMode(motor_AIN2, OUTPUT);
pinMode(motor_PWM, OUTPUT);

digitalWrite(LED_BL2, 0);
digitalWrite(LED_BL1, 0);
digitalWrite(LED_HB2, 0);
digitalWrite(LED_HB1, 0);

digitalWrite(motor_AIN1, 0);
digitalWrite(motor_AIN2, 1);

analogWrite(motor_PWM, 0);
analogWrite(LED_HDL, 1023);

timer1->setOnTimer(&motionControl);
timer1->Start();

WiFi.softAP(ssid, password);

IPAddress myIP = WiFi.softAPIP();

/****************************************************************************

  • Here you find the functions that are called when the browser sends commands.
    */
    server.on("/", handleRoot);
    server.on("/run", motorOperation);
    server.on("/stop", motionStop);
    server.on("/lighton", switchLightOn);
    server.on("/lightoff", switchLightOff);
    server.on("/updateSpeed", updateSpeed);
    server.begin();
    }

void loop() {
server.handleClient();
timer1->Update();
}

Here are the errors.

Arduino: 1.8.13 (Windows Store 1.8.42.0) (Windows 10), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Legacy (new can return nullptr), All SSL ciphers (most compatible), 4MB (FS:2MB OTA:~1019KB), 2, v2 Lower Memory, Disabled, None, Only Sketch, 115200"

c:/users/terry/documents/arduinodata/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\OSR_Hectorrail_WifiAP.ino.cpp.o: in function `esp8266webserver::ESP8266WebServerTemplate::_prepareHeader(String&, int, char const*, unsigned int)':

C:\Users\Terry\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\libraries\ESP8266WebServer\src/ESP8266WebServer-impl.h:427: undefined reference to `TimerObject::setOnTimer(void (*)())'

c:/users/terry/documents/arduinodata/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: C:\Users\Terry\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\libraries\ESP8266WebServer\src/ESP8266WebServer-impl.h:427: undefined reference to `TimerObject::Start()'

c:/users/terry/documents/arduinodata/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\OSR_Hectorrail_WifiAP.ino.cpp.o:(.text.setup+0x137): undefined reference to TimerObject::setOnTimer(void (*)())' c:/users/terry/documents/arduinodata/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\OSR_Hectorrail_WifiAP.ino.cpp.o:(.text.setup+0x13f): undefined reference to TimerObject::Start()'
c:/users/terry/documents/arduinodata/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\OSR_Hectorrail_WifiAP.ino.cpp.o: in function esp8266webserver::ESP8266WebServerTemplate<WiFiServer>::~ESP8266WebServerTemplate()': C:\Users\Terry\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\libraries\ESP8266WebServer\src/ESP8266WebServer-impl.h:100: undefined reference to TimerObject::TimerObject(unsigned long)'
c:/users/terry/documents/arduinodata/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\OSR_Hectorrail_WifiAP.ino.cpp.o:C:\Users\Terry\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\libraries\ESP8266WiFi\src/WiFiServer.h:82: undefined reference to TimerObject::TimerObject(unsigned long)' c:/users/terry/documents/arduinodata/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\OSR_Hectorrail_WifiAP.ino.cpp.o: in function esp8266webserver::ESP8266WebServerTemplate::handleClient()':
C:\Users\Terry\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\libraries\ESP8266WebServer\src/ESP8266WebServer-impl.h:347: undefined reference to TimerObject::Update()' c:/users/terry/documents/arduinodata/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\OSR_Hectorrail_WifiAP.ino.cpp.o: in function loop':
C:\Users\Terry\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4\libraries\ESP8266WebServer\src/ESP8266WebServer-impl.h:355: undefined reference to `TimerObject::Update()'
collect2.exe: error: ld returned 1 exit status
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Read this before posting a programming question

I could not duplicate your errors, but your code has other basic mistakes that it wouldn't compile. You have mismatched braces and a function is commented out.

After correcting those errors, it compiles fine.

I don't understand.

You are 3D-printing an OS-railway and the 3D-printing works through uploading the code posted above??

The error-messages tell that additional libraries were not found.
As a minimum of information can you please post the link where you found the manual how to compile and upload the code you have posted above.

best regards Stefan

OK the website you have this code from seems to be one of those lower-quality projects where the uploader did not test everything at the end if everything will work finde.

A standard Arduino-IDE-installation does not include the TimerObject-library.
So I googled for it and found it on Github same thing here.
If you just download the library as a zip-file and try to use Add-zip-library the subfolder-names are wrong

I have renamed the zip-file and the foldername to obey the subfolder-rules of the Arduino-IDE.

You have to donwload the file TimerObject.zip that I have attached to this posting.
Then you have to install this library

inside Arduino-IDE click on Sketch - include library - add zip-library
and choose the file TimerObject.zip

Then there are some closing curly brackets misplaced in the code you have posted.
Did you copy & pasted in on one piece?
Did you try to modify it?

I modified the position of the closing brackes.

This resulted in an empty function

void handleRoot() {

}

Which makes no sense to me. Again. Question did you copy and paste the full code in one piece?
Did you download it from somewhere? If downloaded provide the link.

So here is the version that does compile. But I have no idea if this empty function handleroot() makes sense or if there is missing something.

/* Copyright Olle Sköld 2017

  Wifi accesspoint using NodeMCU and ESP8266.

  This software is provided free and you may use, change and distribute as you like.

*/

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <TimerObject.h>

#define forward 0
#define backward 1
/* Set these to your desired credentials. */
const char *ssid = "OSRHector";
const char *password = "osrailway";


bool highBeamActive = false;
bool motionActive = false;
bool motionDirection = forward;
int target_speed;
int actual_speed;
int acceleration_step = 5;

int LED_BL2 = 15; // Red light on side 2 GPIO15
int LED_BL1 = 13; // Red light on side 1 GPIO13
int LED_HB2 = 14; // High beam side 2 GPIO12
int LED_HB1 = 12; // High beam side 1 GPIO14

int LED_HDL = 2;  //PWM for headlights controlled by motor board

int motor_AIN1 = 5; //GPIO5
int motor_AIN2 = 4; //GPIO4
int motor_PWM = 0; //GPIO0

TimerObject *timer1 = new TimerObject(10);

ESP8266WebServer server(80);

/**************************************************************************
   Server IP address is: http://192.168.4.1
   When you have connected your device to the wifi network, open the browser and enter the IP address above.
*/

void handleRoot() {

}

void motionControl() {
  if (motionActive) {
    if (actual_speed < target_speed) {
      actual_speed = actual_speed + acceleration_step;
    } 
    else if (actual_speed > target_speed) {
      actual_speed = actual_speed - acceleration_step;
    }
    
    if (actual_speed > 1023) {
      actual_speed = 1023;
    }
    
    if (actual_speed < 0) {
      actual_speed = 0;
    }
    
    analogWrite(motor_PWM, actual_speed);
  }  
  else {
    analogWrite(motor_PWM, 0);
  }
}


void motorOperation() {

  motionActive = true;
  String move_dir = server.arg("dir");
  String motion_speed = server.arg("speed");
  target_speed = motion_speed.toInt();

  //Execute change of direction, but only if actual_speed is below 100, otherwise set target speed to 0 and initiate a slowdown.
  if (move_dir == "backward") {
    if (motionDirection != backward && actual_speed > 100) {
      target_speed = 0;
    } 
    else {
      motionDirection = backward;
    }
  } 
  else {
    if (motionDirection != forward && actual_speed > 100) {
      target_speed = 0;
    } 
    else {
      motionDirection = forward;
    }
  }

  digitalWrite(motor_AIN1, motionDirection);
  digitalWrite(motor_AIN2, !motionDirection);
  digitalWrite(LED_BL2, motionDirection);
  digitalWrite(LED_BL1, !motionDirection);

  if (highBeamActive) {
    digitalWrite(LED_HB2, motionDirection);
    digitalWrite(LED_HB1, !motionDirection);
  } 
  else {
    digitalWrite(LED_HB2, 0);
    digitalWrite(LED_HB1, 0);
  }

}

void updateSpeed() {
  String motion_speed = server.arg("speed");
  target_speed = motion_speed.toInt();
}

void switchLightOn() {
  highBeamActive = true;
  digitalWrite(LED_HB2, motionDirection);
  digitalWrite(LED_HB1, !motionDirection);
}

void switchLightOff() {
  highBeamActive = false;
  digitalWrite(LED_HB2, 0);
  digitalWrite(LED_HB1, 0);
}

void motionStop() {
  motionActive = false;
  analogWrite(motor_PWM, 0);
}


void setup() {
  delay(1000);

  pinMode(LED_BL2, OUTPUT);
  pinMode(LED_BL1, OUTPUT);
  pinMode(LED_HB2, OUTPUT);
  pinMode(LED_HB1, OUTPUT);

  pinMode(LED_HDL, OUTPUT);

  pinMode(motor_AIN1, OUTPUT);
  pinMode(motor_AIN2, OUTPUT);
  pinMode(motor_PWM, OUTPUT);


  digitalWrite(LED_BL2, 0);
  digitalWrite(LED_BL1, 0);
  digitalWrite(LED_HB2, 0);
  digitalWrite(LED_HB1, 0);

  digitalWrite(motor_AIN1, 0);
  digitalWrite(motor_AIN2, 1);

  analogWrite(motor_PWM, 0);
  analogWrite(LED_HDL, 1023);

  timer1->setOnTimer(&motionControl);
  timer1->Start();

  WiFi.softAP(ssid, password);

  IPAddress myIP = WiFi.softAPIP();

  /****************************************************************************
     Here you find the functions that are called when the browser sends commands.
  */
  server.on("/", handleRoot);
  server.on("/run", motorOperation);
  server.on("/stop", motionStop);
  server.on("/lighton", switchLightOn);
  server.on("/lightoff", switchLightOff);
  server.on("/updateSpeed", updateSpeed);
  server.begin();
}

void loop() {
  server.handleClient();
  timer1->Update();
}

merry Christmas to all of you
Stefan

TimerObject.zip (15.6 KB)

Hello and thanks for the reply.

I downloaded the sketch file and did not modify it at all,

I will follow your recommendations and let you know how I make out.

My grandson an I greatly appreciate your help.

Terry N

Sorry here is the link.

The file is included in the 3D files for this train engine.

Hectorrail 141 Wifi locomotive for OS-Railway - fully 3D-printable railway system by Depronized - Thingiverse

Hello Again,

I followed your recommendations and it worked perfectly.

The board is now programed.

I will wire it up and let you know how it works.

Thanks Again.

Merry Christmas and Happy New Year!!!

Terry N