ESPDuino Sketch

Below is the source code i've used for the Espduino to connect into the central software.  The idea is that it powers up, connects to WIFI, then opens a TCP Connection to my central control software.  Once connected it will listen to commands, and send responses.

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

ESP8266WiFiMulti wifiMulti;
bool Connected;
bool DoDebug = 1;
const char* host = "10.243.10.102";
const int port = 31479;
unsigned long lastkeepalive = millis();
int NumberOfPins=16;
bool triggerpins[20];
bool triggerpinvalues[20];

void SerialDebugLn(String data) {
  if (DoDebug) {
    Serial.println(data);
  }
}
void SerialDebugLn(int data) {
  if (DoDebug) {
    Serial.println(data);
  }
}
void SerialDebug(String data) {
  if (DoDebug) {
    Serial.print(data);
  }
}
void SerialDebug(int data) {
  if (DoDebug) {
    Serial.print(data);
  }
}


void setup() {
    Serial.begin(115200);
    delay(10);

    if (!DoDebug) Serial.println("Carls Railway WIFI Node - Serial Debugging Disabled");

    for (int pin = 0; pin <= NumberOfPins; pin++) {
       triggerpins[pin]=0;
    }

    
    SerialDebugLn("");
    SerialDebugLn("**************************");
    SerialDebugLn("Carls Railway WIFI Node v4");
    SerialDebugLn("**************************");

    SerialDebug("Built in LED=");
    SerialDebugLn(BUILTIN_LED);

    //SETUP DEFAULT WATCHPINS.  Most are not.
    dowatchpin(16);
    
    wifiMulti.addAP("SSID", "PASSWORD");

 SerialDebugLn("Connecting Wifi...");

}

void loop() {
   //loop hits here multiple times per second
    if(wifiMulti.run() != WL_CONNECTED) {
        SerialDebugLn("WiFi not connected.");
        delay(1000);
        Connected=false;
    } else {
        // For the first time only display WIFI Connected parameters
        if (!Connected) {
            Connected=true;

            SerialDebugLn("WiFi connected!");
            SerialDebug("IP address: ");
            SerialDebugLn(WiFi.localIP());
            SerialDebug("Gateway address: ");
            SerialDebugLn(WiFi.gatewayIP());
            SerialDebug("Subnet mask: ");
            SerialDebugLn(WiFi.subnetMask());
            SerialDebug("Mac address: ");
            SerialDebugLn(WiFi.macAddress());
            SerialDebug("SSID: ");
            SerialDebugLn(WiFi.SSID());            
        }
        wifiConnectedLoop();
    }
}

WiFiClient client;

void wifiConnectedLoop() {

  if (client.connected()) {
     clientConnectedLoop();
  } else {
    SerialDebug("connecting to ");
    SerialDebugLn(host);
    
    // Use WiFiClient class to create TCP connections
    if (!client.connect(host, port)) {
      SerialDebugLn("connection failed");
      delay(1000);
      return;
    }

    SerialDebugLn("Connected.");

    // This will send the request to the server
    client.print(String("MAC\t") + WiFi.macAddress() + "\r\n");
    client.print(String("IP\t") + WiFi.localIP().toString() + "\r\n");
    client.print(String("SSID\t") + WiFi.SSID() + "\r\n");
    client.print(String("DONE\r\n"));
  }
}

void clientConnectedLoop() {
  //SerialDebug("Loop Took ");
  //SerialDebug((int)millis()-lastloop);
  //SerialDebugLn(" milliseconds");
  //lastloop=millis();
  
  ProcessCommands();
  ListenToSerial();
  KeepAlive();
  checkPins();
  
}



void ListenToSerial() {
  while (Serial.available()) {
    SerialDebugLn("Serial Reading...");
    String line = Serial.readStringUntil('\r');
    SerialDebug("Serial Relay ");
    SerialDebugLn(line);
    client.println(line);
  }
}



void ProcessCommands() {
  // Read all the lines of the reply from server and print them to Serial
  while(client.available()){

    String line = client.readStringUntil('\r');
    SerialDebug("RX: ");
    SerialDebugLn(line);
    String command = getValue(line, '\t', 0);
    
    if (command=="") {
        //ignore blank command
    } else if (command=="KEEPALIVE") {
        SerialDebugLn("I received a keepalive");
    } else if (command=="SERIAL") {
        Serial.print(getValue(line, '\t', 1));
    } else if (command=="SETPIN") {
        int pin = getValue(line, '\t', 1).toInt();
        SerialDebug("Setting Pin ");
        SerialDebug(pin);
        SerialDebug(" to state ");
        int state = getValue(line, '\t', 2).toInt();
        SerialDebugLn(state);
        pinMode(pin, OUTPUT);
        digitalWrite(pin, state);
        client.println("OK");
    } else if (command=="MOMENTARYPIN") {
        int pin = getValue(line, '\t', 1).toInt();
        int waitfor = getValue(line, '\t', 2).toInt();
        SerialDebug("Momentary Pin ");
        SerialDebugLn(pin);
        pinMode(pin, OUTPUT);
        digitalWrite(pin, 1);
        delay(waitfor);
        digitalWrite(pin, 0);
        client.println("OK");
    } else if (command=="REVMOMENTARYPIN") {
        int pin = getValue(line, '\t', 1).toInt();
        int waitfor = getValue(line, '\t', 2).toInt();
        SerialDebug("Momentary Pin ");
        SerialDebugLn(pin);
        pinMode(pin, OUTPUT);
        digitalWrite(pin, 0);
        delay(waitfor);
        digitalWrite(pin, 1);
        client.println("OK");
    } else  if (command=="POLLPIN") {
        int pin = getValue(line, '\t', 1).toInt();
        SerialDebug("Polling Pin ");
        SerialDebug(pin);
        pinMode(pin, INPUT);
        int state = digitalRead(pin);
        SerialDebug(" at state ");
        SerialDebugLn(state);
        client.print("PINVALUE\t");
        client.print(pin);
        client.print("\t");
        client.println(state);
    } else if (command=="WATCHPIN") {
        int pin = getValue(line, '\t', 1).toInt();
        int state = dowatchpin(pin);
        client.print("WATCHINGPIN\t");
        client.print(pin);
        client.print("\t");
        client.println(state);
    } else if (command=="OK") {
        String okcommand = getValue(line, '\t', 1);
        SerialDebug("OK for ");
        SerialDebugLn(okcommand);
    } else {
        SerialDebug("Unknown Command: ");
        SerialDebugLn(command);
    }

  }
}


int dowatchpin(int pin) {
    SerialDebug("Watching Pin ");
    SerialDebugLn(pin);
    pinMode(pin, INPUT);
    int state = digitalRead(pin);
    triggerpinvalues[pin]=state;
    triggerpins[pin]=1;
    return state;
}


void KeepAlive() {  
  if (millis() - lastkeepalive > 5000) {
      SerialDebugLn("TX: KEEPALIVE");
      client.println("KEEPALIVE");
      lastkeepalive = millis();
  }
}





void checkPins() {
  for (int pin = 0; pin <= NumberOfPins; pin++) {
    if (triggerpins[pin]) {
       int state = digitalRead(pin);
       if (triggerpinvalues[pin]!=state) {
         SerialDebug("Changed Trigger Pin");
         SerialDebug(pin);
         SerialDebug("=");
         SerialDebugLn(state);

         //this is remarkably slow - it blocks while the transmission completes.
         //this means up to 600MS can be wasted here, during which time presumably sensors will be missed.
         client.print("PINVALUE\t");
         client.print(pin);
         client.print("\t");
         client.println(state);
         
         triggerpinvalues[pin]=state;
       }
    }
  }
  
}





String getValue(String data, char separator, int index)
{
    int found = 0;
    int strIndex[] = { 0, -1 };
    int maxIndex = data.length() - 1;

    for (int i = 0; i <= maxIndex && found <= index; i++) {
        if (data.charAt(i) == separator || i == maxIndex) {
            found++;
            strIndex[0] = strIndex[1] + 1;
            strIndex[1] = (i == maxIndex) ? i+1 : i;
        }
    }
    return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}

Comments