// wac 13 April 2016 modified 
// wac 10 July 2018 added SoftwareSerial
// wac sep 2018 added CV1 display data
// wac 1 June 2019 used updated Adafruit libraries

#include <SoftwareSerial.h>
SoftwareSerial dcc(A3,A4);  // RX TX

#include "Adafruit_GFX.h"    // Core graphics library
#include "Adafruit_ILI9341.h" // Hardware-specific library
#include "SPI.h"

// hardware SPI pins for Nano
#define _sck 13
#define _mosi 11
#define _cs 10
#define _dc_rs 9
#define _reset 7

Adafruit_ILI9341 tft = Adafruit_ILI9341(_cs, _dc_rs, _reset);

boolean newData = false;
boolean cv1 = false;
int loco = 0, fd, fl, f1, f2, f3,f4, f5, f6, f7, f8, Speed, function, e_stop, A, Amax;
String  inString;
String speedString1;
String speedString2;
String string_alarm1, string_alarm2, string_alarm3;
String option;
int a[30];
int count; 
int Atrig;
int cv_set;
   
void setup() {
  dcc.begin(9600);
  Serial.begin(9600);
  tft.begin();
  tft.setRotation(3);
  tft.fillScreen(ILI9341_BLUE);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(1);
  tft.setCursor(10,10);
  tft.println("DCC Command Station 1 June 2019");
         tft.setTextSize(2);
         tft.setCursor(10, 35);
         tft.println("'A' on start up: CV1");
         tft.setCursor(10, 60);
         tft.println("A: Functions");
         tft.setCursor(10, 85);
         tft.println("B: Turnout 1-8");
         tft.setCursor(10, 110);
         tft.println("C: Turnout 9-16");
         tft.setCursor(10, 135);
         tft.println("D: Emergency Stop");
         tft.setCursor(10, 160);
         tft.println("*: Direction");
         tft.setCursor(10, 185);
         tft.println("0: Lights");
         tft.setCursor(10, 210);
         tft.println("#: Locos 10-19");
  Serial.println("DCC Command Station 1 June 2019");
delay(2000);
 
}
void loop(){
      recvdata();
  if (newData == true){
      string();
    }
  if (cv1 == true){
      cv_one();
    }
}
          
 void recvdata() {  
  newData = false; 
  cv1 = false;    
  if(dcc.available() == true);
    {
        inString = dcc.readStringUntil('\n');
    }
    if (inString.substring(0,1)== "A") 
    {
      newData = true;       
    }
    if (inString.substring(0,1)== "B") 
    {
      cv1 = true;       
    }
  }

void string(){
  count = 0;
    unsigned long z = inString.length();
    int y = 0;
    for (int i = 0; i<=30; i++){
      a[i] = 0;
    }
String inChar;
String temp ="";
   for (int i = 0; i<=z; i++){
    inChar = inString.substring(i,i+1);
    if (inChar != "," && inChar != "A") {
      temp += inChar;
    }
    if (inChar == ",") {
      a[y] = (temp.toInt());
      y = y +1;
      temp = "";
      count = count + 1;
    }
   }
   if (count == 18){
      //Serial.println(inString);
      inString = "";
      count = 0;
      showNewData();
   }
  }
  
 void cv_one(){
  count = 0;
    unsigned long z = inString.length();
    int y = 0;
    for (int i = 0; i<=30; i++){
      a[i] = 0;
    }
String inChar;
String temp ="";
   for (int i = 0; i<=z; i++){
    inChar = inString.substring(i,i+1);
    if (inChar != "," && inChar != "B") {
      temp += inChar;
    }
    if (inChar == ",") {
      a[y] = (temp.toInt());
      y = y +1;
      temp = "";
      count = count + 1;
    }
   }
   if (count == 6){
      //Serial.println(inString);
      inString = "";
      count = 0;
      showCV1();
   }
  } 
  
void showCV1() {
  loco = a[1];A = a[2];Amax = a[3];Atrig = a[4];cv_set = a[5];
  
  if (Atrig == 0){
    string_alarm1 = "Loco# = " + String(loco);
    string_alarm2 = "Current  mA:" + String(A);
    string_alarm3 = "Press 'A' to set CV1";
    if (cv_set == 1){
      string_alarm3 = "CV1 is set to " + String(loco);
    }
    
  }   
  if (Atrig == 1){
  string_alarm1 = "Current = " + String(A);
  string_alarm2 = "Over Current: " + String(Amax);
  string_alarm3 = "Reset: Power on/off";
  }
  display3();
  cv1 = false;
}
  
void showNewData() {
  loco = a[1];fd = a[2];fl = a[3];
  f1 = a[4];f2 = a[5];f3 = a[6];f4 = a[7];f5 = a[8];f6 = a[9];f7 = a[10];f8 = a[11]; 
  Speed = a[12];function = a[13];e_stop = a[14];A = a[15];Amax = a[16];Atrig = a[17];
  
  speedString1 = "#" + String(loco) + " Speed: ";
  speedString2 = String(Speed) + "  mA:" + String(A);
  
  if (e_stop == 1){string_alarm1 = "EMERGENCY  STOP";
  string_alarm2 = "Reset: press 'D'";
  string_alarm3 = "";display3();
  return;}
  if (Atrig == 1){string_alarm1 = "Current = " + String(A);
  string_alarm2 = "Over Current: " + String(Amax);
  string_alarm3 = "Reset: Power on/off";display3();
  return;}
  
  switch (function){
  case 0: display1();display4();return; // loco data display
  case 1: display2();display4();return; // function data display
  case 3: display5();display4();return; // turnout 1-8
  case 4: display5();display4();return; // turnout 9-16
  case 5: display6();return; // speed and current only
  }    
  newData = false;
}

 void display1() { 
         tft.fillScreen(ILI9341_BLUE);
         tft.setTextColor(ILI9341_WHITE);
         tft.setTextSize(1);
         tft.setCursor(10,10);
         tft.println("DCC Command Station 1 June 2019");
         tft.setTextSize(2);
         tft.setCursor(10, 30);
         tft.println("THROTTLE  MODE");
         delay(20);
  }
void display2() { 
         tft.fillScreen(ILI9341_BLACK);
         tft.setTextColor(ILI9341_WHITE);
         tft.setTextSize(1);
         tft.setCursor(10,10);
         tft.println("DCC Command Station 1 June 2019");
         tft.setTextSize(2);
         tft.setCursor(10, 30);
         tft.println("FUNCTION MODE");
         delay(20);
  }
void display3() { 
         tft.fillScreen(ILI9341_RED);
         tft.setTextColor(ILI9341_WHITE);
         tft.setTextSize(2);
         tft.setCursor(10, 100);
         tft.setCursor(10, 30);
         tft.println(string_alarm1);
         tft.setCursor(10, 60);
         tft.println(string_alarm2);
         tft.setCursor(10, 90);
         tft.println(string_alarm3);
         delay(20);
  }
void display4(){     
         tft.setTextSize(2);
         tft.setTextColor(ILI9341_WHITE);
         if (function <= 2){
         tft.setCursor(10, 70);
         tft.print("Loco :");
         tft.setCursor(80, 70);
         tft.print(loco);
         tft.setCursor(120, 70);
         tft.print("Dir :");
         tft.setCursor(170, 70);
         tft.print(fd);
         tft.setCursor(200, 70);
         tft.print("FL :");
         tft.setCursor(250, 70);
         tft.print(fl);
         } 
         if (function == 3 ){
          tft.setCursor(10, 90);
          tft.setTextColor(ILI9341_BLACK);
          tft.print("1  2  3  4  5  6  7  8 ");
          tft.setCursor(10, 120);
          tft.setTextColor(ILI9341_RED);
          tft.print("T1 2  3  4  5  6  7  8");
          tft.setTextColor(ILI9341_BLACK);
          }
         if (function == 4){
          tft.setCursor(10, 90);
          tft.setTextColor(ILI9341_BLACK);
          tft.print("1  2  3  4  5  6  7  8 ");
          tft.setCursor(10, 120);
          tft.setTextColor(ILI9341_RED);
          tft.print("T9 10 11 12 13 14 15 16");
          tft.setTextColor(ILI9341_BLACK);
          }
          if (function <= 2){
            tft.setCursor(10, 120);
            tft.setTextColor(ILI9341_WHITE);
            tft.print("F1 F2 F3 F4 F5 F6 F7 F8");
            }
         tft.setCursor(10, 150);
         tft.print(f1);
         tft.setCursor(45, 150);
         tft.print(f2);
         tft.setCursor(80, 150);
         tft.print(f3);
         tft.setCursor(115, 150);
         tft.print(f4);
         tft.setCursor(150, 150);
         tft.print(f5);
         tft.setCursor(185, 150);
         tft.print(f6);
         tft.setCursor(220, 150);
         tft.print(f7);
         tft.setCursor(255, 150);
         tft.print(f8);
         if (function <= 2){
         tft.setCursor(10, 190);
         tft.print(speedString1 + speedString2);
         }
}

void display5() { 
         tft.fillScreen(ILI9341_GREEN);
         tft.setTextColor(ILI9341_BLACK);
         tft.setTextSize(2);
         tft.setCursor(10, 190);
         tft.print(speedString1);
         tft.setCursor(10, 30);
         if (function == 3){
         tft.println("TURNOUTS 1 to 8");}
         if (function == 4){
         tft.println("TURNOUTS 9 to 16");}
         delay(20);
  }

  void display6() { 
         tft.setTextSize(2);
         tft.setTextColor(ILI9341_BLUE);
         for (int i = 130; i<=290; i = i + 5){
          tft.setCursor(i, 190);
          tft.print(char(220));
         }
         tft.setCursor(135, 190);
         tft.setTextColor(ILI9341_WHITE);
         tft.print(speedString2);
  }