ESP8266 - Programming
as if it is an Arduino for DCC++ Throttle  

revised d. bodnar 04-05-2016

Link to HTML Throttle: 
original:
DCC++ Mobile Controller  updated: DCC++ Mobile Controller
Please make sure you also update the ESP8266 with this file (you may need to right click and choose "save file as")
original:
Arduino File for ESP8266 updated: Arduino File for ESP8266

Thanks to Steve Lowry (UK Steve on TrainBoard) for the following procedure!

These notes should get you to the point where you can program the ESP8266.

  • Install Arduino 1.6.8 - during install allow driver to be installed, too
  • Add ESP8266 to board list - see: https://learn.sparkfun.com/tutorials/esp8266-thing-hookup-guide/installing-the-esp8266-arduino-addon
  • Add library for WebSocketsServer here:  https://github.com/Links2004/arduinoWebSockets - download Zip file, extract and copy to Arduino/library folder
  • Download and install Git - be sure to select the "Use Git from the Windows Command Prompt" option when installing - I also selected "Use Windows' default console window"
  • Download and install Python 27
  •  Get a command (CMD) prompt  - On Windows 10 hit the Windows key, type CMD, right click and choose "Run as Administrator"
  •  copy and paste the following prompts, hit the return key where stated
  • cd C:\Program Files (x86)\Arduino\hardware ------------->hit return
  • mkdir esp8266com ---------------------> hit return
  • cd esp8266com ---------------------------->hit return
  • git clone https://github.com/esp8266/Arduino.git esp8266 ----->hit return
  • the clone operation will run - wait till it completes
  • cd esp8266/tools ---------------------------->hit return
  • python get.py ---------------------------->hit return (Python was not in my path so I needed to type
    c:\python27\python get.py
  • exit ----------------------------------->hit return

For the ESP8266

  • The notes here will help with the wiring:  http://www.esp8266.com/wiki/doku.php?id=getting-started-with-the-esp8266 
  • Add a 10K resistor from VCC to CH_PD
  • To program ESP8266-2 connect GPIO0 to ground and briefly connect Reset to ground - I generally jumper GPIO0 to ground and jumper Reset to ground, start the programming and, once compiling is done, I remove the Reset jumper - when uploading starts (dots print across the screen) I remove the GPIO0 jumper - when upload is done I briefly pull Reset to ground

This image shows the info from the Command Line in Windows as I went through the steps above.

Steve's code for the ESP8266
//*** IMPORTANT *** Most of the libraries used are included in the ESP8266 Core package which you must install to the Arduino IDE for this sketch to compile.
//Please use the Git method here https://github.com/esp8266/Arduino and NOT the File > Preferences > Additional Boards Manager URL.
//WebSocketsServer.h appears to be broken using the later. And DO include the Python requirement (correct at Feb 15 2016) The author is aware of this issue.
//You will need to install Git to simplify that operation.
//If the sketch compiles OK but won't upload properly, then go Sketch > Export compiled Binary. A .bin file will be created in this sketch's folder.
//Then upload the binary with your favorite flashing tool.

//Please remember to fill in your home network SSID and PASSWORD. In this version when you reboot your esp8266 it will automatically log on to your WLAN.
//Make a note of the IP address assigned by your router by logging on to its home page. Your PC or Mobile also need to be on this same network.
//With the "Webpage" open on your chosen device, type the IP and Port in the following format eg. 192.168.11.55:81 (port == @line 28) press Enter(desktop) 
   //or tap the screen outside the box (mobile).
//With luck you are now connected enjoy. A message will confirm in later versions.
//Console Debugging is available in Chrome windows desktop for the html wireless side. And at the other end (Arduino) a serial monitor will let you know
   // whats happening there.
//You can also see serial out from esp8266 if you connect by usb and use a serial monitor there. (Debug from this sketch shows up there)

//In tests I hooked up 2 seperate clients at the same time so multi-client is confirmed. However as certain values are fixed assignment things start to 
   //go wrong quickly.  We can work that out ;)
//There is room for many more functions on the page, this is just Proof of Concept.

//Special thanks to Rahul 27 who created the original sketch on which this sketch is based. And also Markus Sattler for the WebSocketsServer library.

//This software is Free. Enjoy. Steve Lowry(indev2)2016.

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <WebSocketsServer.h>
#include <Hash.h>
#include <EEPROM.h>
WebSocketsServer webSocket = WebSocketsServer(81);

String c;
String d;
int cInt;
int dInt;
const char* ssid     = "YOUR SSID";
const char* password = "YOUR PASSWORD";
const int redPin = 15;  //Debug LED function not needed ***All debug lines can be deleted once you understand the code and you have it working, we like tidy code ;)***
const int greenPin = 12; //Debug LED function not needed
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) {

  switch (type) {
    case WStype_DISCONNECTED:

      break;
    case WStype_CONNECTED:
      {
        IPAddress ip = webSocket.remoteIP(num);


      }
      break;
    case WStype_TEXT:
      {

        String text = String((char *) &payload[0]);
        if (text == "PON") {

          digitalWrite(12, HIGH);//Visual Debug - Green LED will come on at Power ON
          digitalWrite(15, LOW);//Debug - not needed
          Serial.println("<1>");

        }

        if (text.startsWith("CAB1")) {

          String c = (text.substring(text.indexOf("CAB1") + 4, text.length()));
          int cInt = c.toInt();
          EEPROM.write (4, cInt);
          EEPROM.commit();
          delay (20);
          Serial.print("Cab# Entered t1 ");//Debug
          Serial.println(cInt);//Debug

        }

        if (text.startsWith("CAB2")) {

          String c = (text.substring(text.indexOf("CAB2") + 4, text.length()));
          int cInt = c.toInt();
          EEPROM.write (12, cInt);
          EEPROM.commit();
          delay (20);
          Serial.print("Cab# Entered t2 ");//Debug
          Serial.println(cInt);//Debug

        }

        if (text == "FOR1") {

          dInt = (1);
          EEPROM.write (0, dInt);
          EEPROM.commit();
          int Cab1 = EEPROM.read(4);
          Serial.print("Forward Entered t1 ");//Debug
          Serial.println(dInt);//Debug
          Serial.print("<t1 ");
          Serial.print(Cab1);
          Serial.println(" 0 1>");//Stops train (if not stopped) on direction change
          delay (20);

        }

        if (text == "FOR2") {

          dInt = (1);
          EEPROM.write (8, dInt);
          EEPROM.commit();
          int Cab2 = EEPROM.read(12);
          Serial.print("Forward Entered t2 ");//Debug
          Serial.println(dInt);//Debug
          Serial.print("<t2 ");
          Serial.print(Cab2);
          Serial.println(" 0 1>");
          delay (20);

        }

        if (text == "REV1") {

          dInt = (0);
          EEPROM.write (0, dInt);
          EEPROM.commit();
          int Cab1 = EEPROM.read(4);
          Serial.print("Reverse Entered t1 ");//Debug
          Serial.println(dInt);//Debug
          Serial.print("<t1 ");
          Serial.print(Cab1);
          Serial.println(" 0 0>");
          delay (20);


        }

        if (text == "REV2") {

          dInt = (0);
          EEPROM.write (8, dInt);
          EEPROM.commit();
          int Cab2 = EEPROM.read(12);
          Serial.print("Reverse Entered t2 ");//Debug
          Serial.println(dInt);//Debug
          Serial.print("<t2 ");
          Serial.print(Cab2);
          Serial.println(" 0 1>");
          delay (20);


        }

        if (text.startsWith("x")) {

          String xVal = (text.substring(text.indexOf("x") + 1, text.length()));
          int xInt = xVal.toInt();
          analogWrite(greenPin, xInt); //Debug - not needed, Green "ON" LED will brighten/dim according to throttle up/down
          int dvalue = EEPROM.read(0);
          int cvalue = EEPROM.read(4);
          Serial.print("<t1 ");
          Serial.print(cvalue);
          Serial.print(" ");
          Serial.print(xInt);
          Serial.print(" ");
          Serial.print(dvalue);
          Serial.println(">");

        }

        if (text.startsWith("y")) {

          String yVal = (text.substring(text.indexOf("y") + 1, text.length()));
          int yInt = yVal.toInt();
          int dvalue = EEPROM.read(8);
          int cvalue = EEPROM.read(12);
          Serial.print("<t2 ");
          Serial.print(cvalue);
          Serial.print(" ");
          Serial.print(yInt);
          Serial.print(" ");
          Serial.print(dvalue);
          Serial.println(">");

        }

        if (text == "RESET") {

          EEPROM.write (0, 0);
          EEPROM.write (4, 0);
          EEPROM.write (8, 0);
          EEPROM.write (12, 0);
          EEPROM.commit (); //All stored values set zero
          delay (20);
          digitalWrite(15, HIGH);//Visual Debug - not needed - Red LED will come on at Power OFF
          analogWrite(greenPin, 0); //LED function - not needed
          Serial.println("<0>");

        }
        break;

      }

      webSocket.sendTXT(num, payload, lenght);
      webSocket.broadcastTXT(payload, lenght);
      break;

    case WStype_BIN:

      hexdump(payload, lenght);

      // echo data back to browser
      webSocket.sendBIN(num, payload, lenght);
      break;
  }

}


void setup() {

  Serial.begin(115200);
  pinMode(15, OUTPUT);
  pinMode(12, OUTPUT);
  EEPROM.begin(512);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
  }
  Serial.println(WiFi.localIP());
  webSocket.begin();
  webSocket.onEvent(webSocketEvent);
}

void loop() {
  webSocket.loop();
}

 

Programming the ESP8266
I built up this board to program  the ESP8266 -
the USB to serial adapter is set to 3.3 volts and supplies power to the circuit.  The reset and program buttons are circled in blue, the power in buttons are circled in yellow and the serial out (to the DCC++ board) are circled in red.  Note that there is a diode in series with the TX out pin.

Note that the IP address that the ESP8266 gets from the router appears in the terminal window when it is reset, circled in red.  The commands that it receives are shown in the terminal as well (circled in yellow)

Shield for the ESP8266
To facilitate testing I added a shield to the stack (Arduino + Motor Shield) of boards that houses the ESP8266.  It only requires 3 connections to the shield.

All wiring was done on the bottom of the shield.  Please note that many shields, including this one, have hard-to-see connections between pads.  I ran a Dremel cutting wheel down the row of pads that I used, both sides, to cut any connections - I then tested the adjoining pads to make sure there were no shorts between then.

The black wire goes from ground on the shield to the pin circled in black.  The orange wire goes from the 3.3 volt power pin on the shield to the pin circled in red.  The TX pin (circled in white) goes to the RX pin on the Arduino via a small diode.  Note that the ring on the diode goes towards the ESP8266.