A one wire communication program with problems

I would like to know the solutions to two main problems:

  1. The communication pin is sending but not yet receiving.
  2. The PWM and forwarding pin are not toggling.

There also is some unfinished business on the read-out part so nevermind that.

I am currently getting the following error (which might be related to the set pinMode for a pin?):

 E (441189) gpio: gpio_set_level(226): GPIO output gpio_num error

There is no easy way to check the pinMode it seems?

The code compiles, the program boots, sends and several functions work:

// An example communication program using a single pin.
// Copyright © Wobbly, 2022.

#include <TimeLib.h>

// The program variables
const int PinCom = 16; // main digital bi-directional communication pin (on the ESP32)
const int PinForward = 17; // secondary forwarding communication pin (on the ESP32)
const int PinVoltage = 2; // analog pin (on the ESP32) to read a voltage from
const int PinPulse = 4; // analog pin (on the ESP32) to generate a pulse on
const int PinLED = 13; // LED indication pin for reception activity

int DeviceVoltage = 3300; // define your operating voltage in mV

int PinComState = LOW; // log the pin state
String SpeedMicrosInput = ""; // used for temporary speed input
unsigned long HighTime = 0; // duration for the HIGH status of the pin
float SpeedMicros = 2000; // set the time allowed for the signal
float Character = SpeedMicros * 2; // set the first character time, low-time and the end signal- time
float SignalDeviation = (SpeedMicros / 2) - 1; // sets the allowed deviation
// int CharacterDelay = 1; // set the delay in between character processing if required

int PWMState = LOW; // check the pulse pin state
float Frequency = 5000; // sets the frequency on the pulse pin in Hz
float DutyCycle = 50; // sets the duty cycle on the pulse pin
float High = (1000000 / Frequency) * (DutyCycle / 100); // used to calculate the HIGH time on the PWM (PulsPin)
float Low = (1000000 / Frequency) - High; // used calculate the LOW time on the PWM (PulsPin)

int AnalogRead = 0; // stores the read value
int Voltage = 0;  // stores the voltage
int VoltageReceived = 0;  // stores the received voltage
String VoltageRead = "";  // temporarily stores the voltage

String SerialSpeedString = ""; // used for temporary serial speed input
int SerialSpeed = 0; // stores the serial speed

char BootInput = ' '; // boot loading input

boolean PinComSend = false; // flag a send for the Pin
boolean PinComReceive = false; // flag a receive for the Pin

boolean BootMaster = false; // this registers the ID and thereby enables specific functions on the boot

boolean MessageReceived = false; // mark the reception of a message
boolean InitiateFunction = false; // this marks the reception of a function code

boolean TimeCodeReceived = false; // mark the reception of a time-code
boolean Ping = false; // mark the reply message ping

boolean PWM = false; // mark the PWM initiation

boolean Forward = false; // mark the forwarding initiation

char tempChar = ' ';
String MessageString = ""; // the string used for the message
int StringLength = 0; // log the string length
int CharacterCount = 0; // count the amount of characters in a message
int MessagesSent = 0; // count the amount of messages sent
int MessagesReceived = 0; // count the amount of messages received
int CharacterPosition = 0; // checkt the character postion

String ID = "9999";  //  used to identify the device, set to 9999 for creating masterboot functions
String IDsender = "0000";  // used to identify the sending device
const String IDadded = " DELIVERED THE FOLLOWING MESSAGE FOR YOU: "; // added string to identify the sender

char FunctionFirstDigit = ' '; // first function value digit picked up from message, combine this to: char FunctionDigits[4] = '';?
char FunctionSecondDigit = ' '; // etc.
char FunctionThirdDigit = ' ';
char FunctionFourthDigit = ' ';
const String SearchFunctionValue = "FUNCTIONVALUE=";  // search the position of a possible function value
String FunctionValue = "";  // temporary Function value storage
int FunctionValuePosition = 0;  // store the position of the function value within the string
int FunctionIncomingValue = 0;  // store the actual value of the function

char TimeCodeFirstDigit = ' '; // first timecode digit picked up from message, combine this to: char TimeCodeDigit[14] = '';?
char TImeCodeSecondDigit = ' ';
char TimeCodeThirdDigit = ' ';
char TimeCodeFourthDigit = ' ';
char TimeCodeFifthDigit = ' ';
char TimeCodeSixthDigit = ' ';
char TimeCodeSeventhDigit = ' ';
char TimeCodeEigthDigit = ' ';
char TimeCodeNinthDigit = ' ';
char TimeCodeTenthDigit = ' ';
char TimeCodeEleventhDigit = ' ';
char TimeCodeTwelvethDigit = ' ';
char TimeCodeThirteenthDigit = ' ';
char TimeCodeFourteenthDigit = ' ';
const String SearchTimeCode = "TIMECODE=";  // search the position of a possible Function value
String TimeCode = "";  // temporary Functionvalue storage
int TimeCodePosition = 0;  // store the position of the function value within the string

int Year = 0; // store values for the time
int Month = 0;
int Day = 0; 
int Hour = 0; 
int Minute = 0; 
int Second = 0;

String YearString = ""; // store temporary values for the time
String MonthString  = "";
String DayString  = ""; 
String HourString  = ""; 
String MinuteString  = ""; 
String SecondString  = "";

unsigned long TotalMillis = 0; // defines the total program running time
unsigned long Millis = 0; // stores the millis
unsigned long Micros = 0; // stores the micros
unsigned long MicrosPrevious = 0; // stores elapsed micros


void setup() {

analogReadResolution(10); // set this to 8 or 12 if required, adjust the code accordingly

pinMode(PinCom, INPUT); // configure the pins
pinMode(PinForward, OUTPUT);
pinMode(PinPulse, OUTPUT);
pinMode(PinLED, OUTPUT);

digitalWrite(PinForward, LOW);
digitalWrite(PinPulse, LOW);
digitalWrite(PinLED, LOW);

SerialSpeed = 9600;

Serial.begin(SerialSpeed); // set the serial at speed

delay(3000);

BeginInputSerial:

Millis = millis();

delay(1000);

Serial.println();
Serial.println("The default speed for the serial monitor is set to 9600, would you like to change it? If so press 'y' if not press 'n'...");
Serial.println();

  while (Serial.available() == 0) {
    if (millis() - Millis >= 20000) {
    delay(1000);
    Serial.println();
    Serial.println("20 seconds timed-out... A new serial speed was not set...");
    Serial.println();
    Millis = millis();
    delay(1000);
    goto escapeSetupSerial;
    }}
  
  if (Serial.available() > 0) {
     BootInput = Serial.read();
     Millis = millis();
     if (BootInput == 'y') {
     Serial.println();
     Serial.println("Please input the required serial speed in baud: ");
     Serial.println();
     Millis = millis();
     BootInput = ' ';
     delay(1000);
     
      ReInputSerial:
      while (Serial.available() == 0) {
      if (millis() - Millis >= 20000) {
      delay(1000);
      Serial.println();
      Serial.println("20 seconds timed-out... A new serial speed was not set...");
      Serial.println();
      Millis = millis();
      delay(1000);
      goto escapeSetupSerial;
      }}
      
      if (Serial.available() >= 1) {
      SerialSpeedString = Serial.readString();
      SerialSpeed = SerialSpeedString.toInt();
      delay(1000);
      if (SerialSpeed != 300 && SerialSpeed != 1200 && SerialSpeed != 2400 && SerialSpeed != 4800 && SerialSpeed != 9600 && SerialSpeed != 19200 && SerialSpeed != 38400 && SerialSpeed != 57600 && SerialSpeed != 74880 && SerialSpeed != 115200  && SerialSpeed != 230400 && SerialSpeed != 250000 && SerialSpeed != 500000 && SerialSpeed != 1000000  && SerialSpeed != 2000000) {
      Serial.println();
      Serial.println("This is number is not valid for the serial monitor speed.");
      Serial.print("You tried: ");
      Serial.print(SerialSpeed);
      Serial.println(" ;it accepts 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 250000, 500000, 1000000 or 2000000, please try again:");
      Serial.println();
      BootInput = ' ';
      Millis = millis();
      delay(1000);
      goto ReInputSerial;
      }
      
      Serial.println();
      Serial.print("The new serial speed is: ");
      Serial.println(SerialSpeed);
      Serial.println();
      Millis = millis();

      Serial.println();
      Serial.println("Restarting the serial...");
      Serial.println();

      delay(3000);
      Serial.end();
      delay(3000);
      Serial.begin(SerialSpeed); // restart the serial with the new requirements
      delay(3000);
      goto escapeSetupSerial;
      }
     }

     if (BootInput == 'n') {
      Serial.println();
      Serial.println("Proceeding with the default serial speed of 9600... ");
      Serial.println();
      Millis = millis();
      BootInput = ' ';
      delay(1000);
      goto escapeSetupSerial;
      }

     if (BootInput != 'n' && BootInput != 'y') {
      Serial.println();
      Serial.println("Input unknown, please try again...");
      Serial.println();
      Millis = millis();
      BootInput = ' ';
      Serial.flush();
      delay(1000);
      goto BeginInputSerial;
      }

}

escapeSetupSerial:

BeginInputTime:

TimeCode = "";

Millis = millis();

delay(1000);

Serial.println();
Serial.println("Would you like to set the internal program time using a time-code (YYYYMMDDHHMMSS)? If so press 'y' if not press 'n'...");
Serial.println();
delay(1000);

  while (Serial.available() == 0) {
    if (millis() - Millis >= 20000) {
    delay(1000);
    Serial.println();
    Serial.println("20 seconds timed-out... The time was not set...");
    Serial.println();
    Millis = millis();
    delay(1000);
    goto escapeSetupTime;
    }}
  
  if (Serial.available() > 0) {
     BootInput = Serial.read();
     if (BootInput == 'y') {
     Serial.println();
     Serial.println("Please input the fourteen digit time-code:");
     Serial.println();
     Millis = millis();
     BootInput = ' ';
     delay(1000);
     
      ReInputTime:
      while (Serial.available() == 0) {
      if (millis() - Millis >= 20000) {
      delay(1000);
      Serial.println();
      Serial.println("20 seconds timed-out... The new time was not set...");
      Serial.println();
      Millis = millis();
      delay(1000);
      goto escapeSetupTime;
      }}
      
      if (Serial.available() >= 1) {
      TimeCode = Serial.readString();
      delay(1000);
      Serial.println();
      Serial.println("Setting time, please wait...");
      Serial.println();
      delay(1000);
      
      TimeCodeFirstDigit = TimeCode.charAt(0); // read the chars
      TImeCodeSecondDigit = TimeCode.charAt(1);
      TimeCodeThirdDigit = TimeCode.charAt(2);
      TimeCodeFourthDigit = TimeCode.charAt(3);
      TimeCodeFifthDigit = TimeCode.charAt(4);
      TimeCodeSixthDigit = TimeCode.charAt(5);
      TimeCodeSeventhDigit = TimeCode.charAt(6);
      TimeCodeEigthDigit = TimeCode.charAt(7);
      TimeCodeNinthDigit = TimeCode.charAt(8);
      TimeCodeTenthDigit = TimeCode.charAt(9);
      TimeCodeEleventhDigit = TimeCode.charAt(10);
      TimeCodeTwelvethDigit = TimeCode.charAt(11);
      TimeCodeThirteenthDigit = TimeCode.charAt(12);
      TimeCodeFourteenthDigit = TimeCode.charAt(13);

      YearString.concat(TimeCodeFirstDigit);
      YearString.concat(TImeCodeSecondDigit);
      YearString.concat(TimeCodeThirdDigit);
      YearString.concat(TimeCodeFourthDigit);
      MonthString.concat(TimeCodeFifthDigit);
      MonthString.concat(TimeCodeSixthDigit);
      DayString.concat(TimeCodeSeventhDigit); 
      DayString.concat(TimeCodeEigthDigit); 
      HourString.concat(TimeCodeNinthDigit);
      HourString.concat(TimeCodeTenthDigit); 
      MinuteString.concat(TimeCodeEleventhDigit);
      MinuteString.concat(TimeCodeTwelvethDigit);
      SecondString.concat(TimeCodeThirteenthDigit);
      SecondString.concat(TimeCodeFourteenthDigit);

      Year = YearString.toInt();
      Month = MonthString.toInt();
      Day = DayString.toInt(); 
      Hour = HourString.toInt(); 
      Minute = MinuteString.toInt(); 
      Second = SecondString.toInt();
       
      TimeCodeFirstDigit = ' ';
      TImeCodeSecondDigit = ' ';
      TimeCodeThirdDigit = ' ';
      TimeCodeFourthDigit = ' ';
      TimeCodeFifthDigit = ' ';
      TimeCodeSixthDigit = ' ';
      TimeCodeSeventhDigit = ' ';
      TimeCodeEigthDigit = ' ';
      TimeCodeNinthDigit = ' ';
      TimeCodeTenthDigit = ' ';
      TimeCodeEleventhDigit = ' ';
      TimeCodeTwelvethDigit = ' ';
      TimeCodeThirteenthDigit = ' ';
      TimeCodeFourteenthDigit = ' ';
        
      YearString = "";
      MonthString  = "";
      DayString  = ""; 
      HourString  = ""; 
      MinuteString  = ""; 
      SecondString  = "";
      
      setTime(Hour,Minute,Second,Day,Month,Year); 

      delay(3000);
      
      Serial.println();
      Serial.print("The following time-code was received: ");
      Serial.println(TimeCode);
      Serial.println();
      Serial.print("Which makes the new time and date: ");
      Serial.print(hour());
      Serial.print(":");
      Serial.print(minute());
      Serial.print(":");
      Serial.print(second());
      Serial.print(" on day ");
      Serial.print(day());
      Serial.print(" in monthnumber ");
      Serial.print(month());
      Serial.print(" of the year ");
      Serial.println(year());
      Serial.println();

      Year = 0;
      Month = 0;
      Day = 0; 
      Hour = 0; 
      Minute = 0; 
      Second = 0;
      
      Millis = millis();
      delay(1000);
      goto escapeSetupTime;
      }
     }

     if (BootInput == 'n') {
      Serial.println();
      Serial.println("Proceeding without setting the time... ");
      Serial.println();
      Millis = millis();
      delay(1000);
      BootInput = ' ';
      goto escapeSetupTime;
      }

     if (BootInput != 'n' && BootInput != 'y') {
      Serial.println();
      Serial.println("Input unknown, please try again...");
      Serial.println();
      Millis = millis();
      BootInput = ' ';
      Serial.flush();
      delay(3000);
      goto BeginInputTime;
      }

}

escapeSetupTime:

ID = 9999;

Serial.println();
Serial.print("The default four digit device ID currently is: ");
Serial.println(ID);
Serial.println();
delay(1000);

BeginInputName:

Millis = millis();

delay(1000);

Serial.println();
Serial.println("Would you like to set a new four digit device ID (set it to '9999' to enable masterboot functions)? If so press 'y' if not press 'n'...");
Serial.println();
Serial.println("The masterboot functions currently entail the forwarding of time to all the listening devices.");
Serial.println();
delay(1000);

  while (Serial.available() == 0) {
    if (millis() - Millis >= 20000) {
    delay(1000);
    Serial.println();
    Serial.println("20 seconds timed-out... A new device ID was not set...");
    Serial.println();
    Millis = millis();
    delay(1000);
    goto escapeSetupName;
    }}
  
  if (Serial.available() > 0) {
     BootInput = Serial.read();
     Millis = millis();
     if (BootInput == 'y') {
     Serial.println();
     Serial.println("Please input a new device ID made from four digits (like: 0001): ");
     Serial.println();
     delay(1000);
     BootInput = ' ';
     
      ReInputName:
      while (Serial.available() == 0) {
      if (millis() - Millis >= 20000) {
      delay(1000);
      Serial.println();
      Serial.println("20 seconds timed-out... A new device ID was not set...");
      Serial.println();
      Millis = millis();
      delay(1000);
      goto escapeSetupName;
      }}
      
      if (Serial.available() == 4) {
      ID = Serial.readString();
      Serial.println();
      Serial.print("The new device ID is: ");
      Serial.println(ID);
      Serial.println();
      Millis = millis();
      delay(1000);
      goto escapeSetupName;
      }

      if (Serial.available() <= 3 || Serial.available() >= 5) {
      Serial.println();
      Serial.println("Please input four digit device ID (like: 0001), please try again:");
      Serial.println();
      Millis = millis();
      delay(1000);
      goto ReInputName;
      }
     }

     if (BootInput == 'n') {
      Serial.println();
      Serial.println("Proceeding with the old device ID... ");
      Serial.println();
      delay(1000);
      BootInput = ' ';
      goto escapeSetupName;
      }

     if (BootInput != 'n' && BootInput != 'y') {
      Serial.println();
      Serial.println("Input unknown, please try again...");
      Serial.println();
      BootInput = ' ';
      Serial.flush();
      delay(3000);
      goto BeginInputName;
      }

 }

escapeSetupName:

if (ID == "9999") {
   BootMaster = true;
   }

if (ID != "9999") {
   BootMaster = false;
   }
 
SpeedMicrosInput = "";
SpeedMicros = 2000;

Serial.println();
Serial.print("The current maximum signal speed is set at microseconds: ");
Serial.println(SpeedMicros);
Serial.println();
delay(1000);

BeginInputSpeed:

Millis = millis();

delay(1000);

Serial.println();
Serial.println("The default speed is 2000 microseconds. Would you like to set a new maximum signal speed? If so press 'y' if not press 'n'...");
Serial.println();
Serial.println("Please do not forget to match the maximum signal speed for all devices to enable communications.");
Serial.println();

  while (Serial.available() == 0) {
    if (millis() - Millis >= 20000) {
    delay(1000);
    Serial.println();
    Serial.println("20 seconds timed-out... A new signal speed was not set...");
    Serial.println();
    Millis = millis();
    delay(1000);
    goto escapeSetupSpeed;
    }}

  if (Serial.available() > 0) {
     BootInput = Serial.read();
     if (BootInput == 'y') {
     Serial.println();
     Serial.println("Please input a new maximum signal speed with a minimum of 2 and a maximum of 10000000 microseconds: ");
     Serial.println();
     Millis = millis();
     delay(1000);
     BootInput = ' ';
     
      ReInputSpeed:
      while (Serial.available() == 0) {
      if (millis() - Millis >= 20000) {
      delay(1000);
      Serial.println();
      Serial.println("20 seconds timed-out... A new maximum signal speed was not set...");
      Serial.println();
      Millis = millis();
      delay(1000);
      goto escapeSetupSpeed;
      }}
      
      if (Serial.available() >= 1 && Serial.available() <= 8) {
      SpeedMicrosInput = Serial.readString();
      SpeedMicros = SpeedMicrosInput.toInt();
      if (SpeedMicros <= 2 || SpeedMicros >= 10000000) {
      Serial.println();
      Serial.print("That is either too fast or too slow, please try again:");
      Serial.println();
      Millis = millis();
      delay(1000);;
      goto ReInputSpeed;
      }
      Serial.println();
      Serial.print("The maximum signal speed was set to: ");
      Serial.print(SpeedMicros);
      Serial.println(" microseconds.");
      Serial.println();
      delay(1000);
      goto escapeSetupSpeed;
      }

      if (Serial.available() >= 9) {
      Serial.println();
      Serial.println("That is too fast, please try again:");
      Millis = millis();
      delay(1000);
      goto ReInputSpeed;
      }
     }

     if (BootInput == 'n') {
      Serial.println();
      Serial.println("Proceeding with the old maximum signal speed... ");
      Serial.println();
      delay(1000);
      BootInput = ' ';
      goto escapeSetupSpeed;
      }

     if (BootInput != 'n' && BootInput != 'y') {
      Serial.println();
      Serial.println("Input unknown, please try again...");
      Serial.println();
      BootInput = ' ';
      Serial.flush();
      delay(3000);
      goto BeginInputSpeed;
      }

 } 

escapeSetupSpeed:

delay(1000);

Serial.println();
Serial.println("Exiting setup... ");
Serial.println();

Serial.println();
Serial.println("Welcome to the Wobbly demonstration communication program!");
Serial.println();

Serial.println();
Serial.println("Message length is limited to 800 Characters minus the included name and opening text added to each message.");
Serial.println();

Serial.println();
Serial.println("Not every character was coded. More characters, words or direct function recognization can be added with a change in code.");
Serial.println("Always use TABS for message letter input as seen below. The currently coded characters are:");
Serial.println("A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, -, ., , ?, -, =, :, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9");
Serial.println("Four digit function values or fourteen digit time-codes (YYYYMMDDHHMMSS) are detected inside the message automatically when using the following formats: FUNCTIONVALUE=, TIMECODE=");
Serial.println("The function values can be set at any time by inputting 'f' or fourteen digit time-codes (YYYYMMDDHHMMSS) by inputting 't' through the serial monitor, they are then initiated and transmitted.");
Serial.println("With added coded one can call and transmit function values or time-codes automatically at specific events. Or add things like an NTP retrieval, RTCs or RF transmissions");
Serial.println("Currently the following function values are programmed...");
Serial.println("Everything between 0000-5000 is reserved for a voltage, 6001-6999 sets the PWM output frequency in kHz, 7001-7100 sets the PWM duty-cycle, 7101 starts PWM, 7102 stops it, 7103 measures a voltage, 7104 sets the device voltage to 3.3V, 7105 sets it to 5V, 7107 starts foorwarding and 7106 stops forwarding, ");
Serial.println();

SpeedMicrosInput = "";

MessageString = "";

VoltageRead = "";

BootInput = ' ';

MessageReceived = false;
Ping = false;
TimeCodeReceived = false;
InitiateFunction = false;

PinComSend = false; 
PinComReceive = false;

Ping = false;

PWM = false;

Forward = false;

PWMState = LOW;
PinComState = LOW;

AnalogRead = 0;
Voltage = 0;

Frequency = 5000;
DutyCycle = 50;

MessagesSent = 0;
MessagesReceived = 0;

CharacterCount = 0;

StringLength = 0;

HighTime = 0;

MicrosPrevious = 0;

TotalMillis = millis();
Millis = millis();

Serial.flush();

delay(1000);
     
}


void loop() {

Millis = millis();
Micros = micros();

// temporarily catch a sub-zero value, some problem occured
//if (Frequency <= 0 || DutyCycle <= 0 || SpeedMicros <= 0 || DeviceVoltage <= 0) {
//   Frequency = 5000;
//   DutyCycle = 50;
//   SpeedMicros = 2000;
//   DeviceVoltage = 3300;
//   }

// monitor the communication pin 
PinComState = digitalRead(PinCom);

if (PinComState == HIGH) {
   HighTime = Micros;
   digitalWrite(PinLED, HIGH);
   }

if (PinComState == LOW) {
   digitalWrite(PinLED, LOW);
   }

// pulseInt compiles but provides a in-program error on the ESP32
//PinPulseTimeOut = (Character + (44 * SpeedMicros) + (SignalDeviation); // calculates the time-out
//HighTime = pulseIn(PinCom, HIGH, PinPulseTimeOut);

// drive the PWM if enabled
if (PWM == true && PWMState == LOW && (Micros - MicrosPrevious) >= Low) {
   PWMState = HIGH;
   digitalWrite(PinPulse, PWMState);
   MicrosPrevious = micros();
   }

if (PWM == true && PWMState == HIGH && (Micros - MicrosPrevious >= High)) {
   PWMState = LOW;
   digitalWrite(PinPulse, PWMState);
   MicrosPrevious = micros();
   }

if (PWM == false) {
   PWMState = LOW;
   digitalWrite(PinPulse, PWMState);
   }

// drive the forwarding pin (it forwards receiving messages only)
if (Forward == true) {
   if (PinComState == HIGH){
      digitalWrite(PinForward, PinComState);
      }

   else if (PinComState == LOW){
      digitalWrite(PinForward, PinComState);
      }
   }

if (Forward == false) {
      digitalWrite(PinForward, LOW);
      }
      

// start receiving
if (PinComSend == false && (HighTime - Micros) >= (Character - SignalDeviation)) {
   
    if (HighTime >= (Character - SignalDeviation) && HighTime <= (Character + SignalDeviation) && PinComReceive == true) // detect a character
    {
      MessageString.concat(tempChar);
      CharacterCount = CharacterCount + 1; // count the characters
      tempChar = ' ';
    }
    
    else if (HighTime >= (Character + (1 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (1 * SpeedMicros) + SignalDeviation) && Ping == false) // message opening signal
    {
      CharacterCount = 0;
      PinComReceive = true;
    }

    else if (HighTime >= (Character + (1 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (1 * SpeedMicros) + SignalDeviation)  && PinComReceive == true && Ping == true) // message block opening signal
    {
      Ping = false; // this ignores the opening signal and blocks the return message from going back and forth
      PinComReceive = false;
    }
    
    else if (HighTime >= (Character + (2 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (2 * SpeedMicros) + SignalDeviation)  && PinComReceive == true) // message closing signal
    { 
      MessageReceived = true;
      PinComReceive = false;

      delay(1000);
      
      Serial.println();
      Serial.print("Here is your message with ");
      Serial.print(StringLength);
      Serial.println(" characters in the string:");
      Serial.println();
      Serial.println(MessageString); // and print them all together
      Serial.println();

      delay(5000);

      IDsender = "";
      IDsender = MessageString.concat(0);
      IDsender = MessageString.concat(1);
      IDsender = MessageString.concat(2);
      IDsender = MessageString.concat(3);
      
      FunctionValuePosition = 0;
      FunctionValuePosition = MessageString.indexOf(SearchFunctionValue); // add Function value or other recognization functionality later
      
      if (FunctionValuePosition >= 0) {
       FunctionFirstDigit = ' ';
       FunctionSecondDigit = ' ';
       FunctionThirdDigit = ' ';
       FunctionFourthDigit = ' ';
       
       FunctionFirstDigit = MessageString.charAt(FunctionValuePosition + 1); // possible add 12 more depending on the reported position
       FunctionSecondDigit = MessageString.charAt(FunctionValuePosition + 2);
       FunctionThirdDigit = MessageString.charAt(FunctionValuePosition + 3);
       FunctionFourthDigit = MessageString.charAt(FunctionValuePosition + 4);
       FunctionValue += FunctionFirstDigit;
       FunctionValue += FunctionSecondDigit;
       FunctionValue += FunctionThirdDigit;
       FunctionValue += FunctionFourthDigit;
       FunctionIncomingValue = FunctionValue.toInt();
       Serial.println();
       Serial.print("We picked up a Function value stating: ");
       Serial.println(FunctionIncomingValue);
       Serial.println();

       FunctionValue = "";

       FunctionFirstDigit = ' ';
       FunctionSecondDigit = ' ';
       FunctionThirdDigit = ' ';
       FunctionFourthDigit = ' ';

       InitiateFunction = true;

       delay(3000);
       }

      TimeCodePosition = 0;
      TimeCodePosition = MessageString.indexOf(SearchTimeCode); // retrieve the time-code and thereby the time
      
      if (TimeCodePosition >= 0) {

       TimeCodeFirstDigit = ' ';
       TImeCodeSecondDigit = ' ';
       TimeCodeThirdDigit = ' ';
       TimeCodeFourthDigit = ' ';
       TimeCodeFifthDigit = ' ';
       TimeCodeSixthDigit = ' ';
       TimeCodeSeventhDigit = ' ';
       TimeCodeEigthDigit = ' ';
       TimeCodeNinthDigit = ' ';
       TimeCodeTenthDigit = ' ';
       TimeCodeEleventhDigit = ' ';
       TimeCodeTwelvethDigit = ' ';
       TimeCodeThirteenthDigit = ' ';
       TimeCodeFourteenthDigit = ' ';

       Year = 0;
       Month = 0;
       Day = 0; 
       Hour = 0; 
       Minute = 0; 
       Second = 0;
        
       YearString = "";
       MonthString  = "";
       DayString  = ""; 
       HourString  = ""; 
       MinuteString  = ""; 
       SecondString  = "";
       
       TimeCodeFirstDigit = MessageString.charAt(TimeCodePosition + 1); // possible add 9 (TIMECODE=) more depending on the reported position
       TImeCodeSecondDigit = MessageString.charAt(TimeCodePosition + 2);
       TimeCodeThirdDigit = MessageString.charAt(TimeCodePosition + 3);
       TimeCodeFourthDigit = MessageString.charAt(TimeCodePosition + 4);
       TimeCodeFifthDigit = MessageString.charAt(TimeCodePosition + 5);
       TimeCodeSixthDigit = MessageString.charAt(TimeCodePosition + 6);
       TimeCodeSeventhDigit = MessageString.charAt(TimeCodePosition + 7);
       TimeCodeEigthDigit = MessageString.charAt(TimeCodePosition + 8);
       TimeCodeNinthDigit = MessageString.charAt(TimeCodePosition + 9);
       TimeCodeTenthDigit = MessageString.charAt(TimeCodePosition + 10);
       TimeCodeEleventhDigit = MessageString.charAt(TimeCodePosition + 11);
       TimeCodeTwelvethDigit = MessageString.charAt(TimeCodePosition + 12);
       TimeCodeThirteenthDigit = MessageString.charAt(TimeCodePosition + 13);
       TimeCodeFourteenthDigit = MessageString.charAt(TimeCodePosition + 14);
       TimeCode += TimeCodeFirstDigit;
       TimeCode += TImeCodeSecondDigit;
       TimeCode += TimeCodeThirdDigit;
       TimeCode += TimeCodeFourthDigit;
       TimeCode += TimeCodeFifthDigit;
       TimeCode += TimeCodeSixthDigit;
       TimeCode += TimeCodeSeventhDigit;
       TimeCode += TimeCodeEigthDigit;
       TimeCode += TimeCodeNinthDigit;
       TimeCode += TimeCodeTenthDigit;
       TimeCode += TimeCodeEleventhDigit;
       TimeCode += TimeCodeTwelvethDigit;
       TimeCode += TimeCodeThirteenthDigit;
       TimeCode += TimeCodeFourteenthDigit;
       YearString.concat(TimeCodeFirstDigit);
       YearString.concat(TImeCodeSecondDigit);
       YearString.concat(TimeCodeThirdDigit);
       YearString.concat(TimeCodeFourthDigit);
       MonthString.concat(TimeCodeFifthDigit);
       MonthString.concat(TimeCodeSixthDigit);
       DayString.concat(TimeCodeSeventhDigit); 
       DayString.concat(TimeCodeEigthDigit); 
       HourString.concat(TimeCodeNinthDigit);
       HourString.concat(TimeCodeTenthDigit); 
       MinuteString.concat(TimeCodeEleventhDigit);
       MinuteString.concat(TimeCodeTwelvethDigit);
       SecondString.concat(TimeCodeThirteenthDigit);
       SecondString.concat(TimeCodeFourteenthDigit);

       Year = YearString.toInt();
       Month = MonthString.toInt();
       Day = DayString.toInt(); 
       Hour = HourString.toInt(); 
       Minute = MinuteString.toInt(); 
       Second = SecondString.toInt();

       setTime(Hour,Minute,Second,Day,Month,Year); 

       Year = 0;
       Month = 0;
       Day = 0; 
       Hour = 0; 
       Minute = 0; 
       Second = 0;
       
       TimeCodeFirstDigit = ' ';
       TImeCodeSecondDigit = ' ';
       TimeCodeThirdDigit = ' ';
       TimeCodeFourthDigit = ' ';
       TimeCodeFifthDigit = ' ';
       TimeCodeSixthDigit = ' ';
       TimeCodeSeventhDigit = ' ';
       TimeCodeEigthDigit = ' ';
       TimeCodeNinthDigit = ' ';
       TimeCodeTenthDigit = ' ';
       TimeCodeEleventhDigit = ' ';
       TimeCodeTwelvethDigit = ' ';
       TimeCodeThirteenthDigit = ' ';
       TimeCodeFourteenthDigit = ' ';
        
       YearString = "";
       MonthString  = "";
       DayString  = ""; 
       HourString  = ""; 
       MinuteString  = ""; 
       SecondString  = "";
      
       Serial.println();
       Serial.print("The following time-code was received: ");
       Serial.println(TimeCode);
       Serial.print("Which makes the new time and date: ");
       Serial.print(hour());
       Serial.print(":");
       Serial.print(minute());
       Serial.print(":");
       Serial.print(second());
       Serial.print(" on the ");
       Serial.print(day());
       Serial.print(" day in monthnumber ");
       Serial.print(month());
       Serial.print(" of the year ");
       Serial.println(year());
       Serial.println();

       TimeCodeReceived = true;

       TimeCode = "";

       delay(1000);
       }
      
      Serial.println();
      Serial.println("Waiting to send or receive a new message...");
      Serial.println();

      Serial.flush();

      delay(1000);

      CharacterCount = 0;

      ++MessagesReceived;

      TotalMillis = millis();

      MessageString = "";

      Ping = false;
    }
    
    else if (HighTime >= (Character + (3 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (3 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '0';
    }
    else if (HighTime >= (Character + (4 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (4 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '1';
    }
    else if (HighTime >= (Character + (5 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (5 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '2';
    }
    else if (HighTime >= (Character + (6 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (6 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '3';
    }
    else if (HighTime >= (Character + (7 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (7 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '4';
    }
    else if (HighTime >= (Character + (8 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (8 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '5';
    }
    else if (HighTime >= (Character + (9 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (9 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '6';
    }
    else if (HighTime >= (Character + (10 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (10 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '7';
    }
    else if (HighTime >= (Character + (11 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (11 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '8';
    }
    else if (HighTime >= (Character + (12 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (12 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '9';
    }
    else if (HighTime >= (Character + (13 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (13 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '-';
    }
    else if (HighTime >= (Character + (14 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (14 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '.';
    }
    else if (HighTime >= (Character + (15 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (15 * SpeedMicros) + SignalDeviation))
    {
      tempChar = ' ';
    }
    else if (HighTime >= (Character + (16 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (16 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '?';
    }
    else if (HighTime >= (Character + (17 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (17 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '=';
    }
    else if (HighTime >= (Character + (18 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (18 * SpeedMicros) + SignalDeviation))
    {
      tempChar = ':';
    }
    else if (HighTime >= (Character + (19 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (19 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'A';
    }
    else if (HighTime >= (Character + (20 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (20 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'B';
    }
    else if (HighTime >= (Character + (21 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (21 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'C';
    }
    else if (HighTime >= (Character + (22 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (22 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'D';
    }
    else if (HighTime >= (Character + (23 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (23 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'E';
    }
    else if (HighTime >= (Character + (24 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (24 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'F';
    }
    else if (HighTime >= (Character + (25 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (25 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'G';
    }
    else if (HighTime >= (Character + (26 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (26 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'H';
    }
    else if (HighTime >= (Character + (27 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (27 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'I';
    }
    else if (HighTime >= (Character + (28 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (28 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'J'; 
    }
    else if (HighTime >= (Character + (29 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (29 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'K';
    }
    else if (HighTime >= (Character + (30 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (30 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'L';
    }
    else if (HighTime >= (Character + (31 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (31 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'M';
    }
    else if (HighTime >= (Character + (32 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (32 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'N';
    }
    else if (HighTime >= (Character + (33 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (33 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'O';
    }
    else if (HighTime >= (Character + (34 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (34 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'P';
    }
    else if (HighTime >= (Character + (35 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (35 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'Q';
    }
    else if (HighTime >= (Character + (36 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (36 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'R';
    }
    else if (HighTime >= (Character + (37 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (37 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'S';
    }
    else if (HighTime >= (Character + (38 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (38 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'T';
    }
    else if (HighTime >= (Character + (39 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (39 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'U';
    }
    else if (HighTime >= (Character + (40 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (40 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'V';
    }
    else if (HighTime >= (Character + (41 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (41 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'W';
    }
    else if (HighTime >= (Character + (42 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (42 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'X';
    }
    else if (HighTime >= (Character + (43 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (43 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'Y';
    }
    else if (HighTime >= (Character + (44 * SpeedMicros) - SignalDeviation) && HighTime <= (Character + (44 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'Z';
    }
    
    else if (HighTime > (Character + (44 * SpeedMicros) + SignalDeviation)) // unknown signal
    {
     tempChar = ' ';
     goto EscapeInput;

     Serial.println();
     Serial.println("Reception error: signals too long...");
     Serial.println();
     
     PinComReceive = false;
    }
   
   HighTime = 0;
     
 }


// confirm the message reception
if (MessageReceived == true && Ping == false && PinComSend == false && PinComReceive == false) {

   if (TimeCodeReceived == true && InitiateFunction == true){
   MessageString = " WE HAVE RECEIVED YOUR MESSAGE CONTAINING THE TIME-CODE AND FUNCTION VALUE!";
   MessageString = IDsender + MessageString;
   MessageString = ID + IDadded + MessageString;
   }

   if (TimeCodeReceived == true){
   MessageString = " WE HAVE RECEIVED YOUR MESSAGE CONTAINING THE TIME-CODE!";
   MessageString = IDsender + MessageString;
   MessageString = ID + IDadded + MessageString;   
   }

   if (InitiateFunction == true){
   MessageString = " WE HAVE RECEIVED YOUR MESSAGE CONTAINING THE FUNCTION VALUE!";
   MessageString = IDsender + MessageString;
   MessageString = ID + IDadded + MessageString;  
   }
   
   else {
   MessageString = " WE HAVE RECEIVED YOUR MESSAGE!";
   MessageString = IDsender + MessageString;
   MessageString = ID + IDadded + MessageString;
   }

   MessageReceived = false;

   Ping = true;

   goto DigitalInput;
   }
 

// boot routine for the massterboot functions, add more if you like
if (BootMaster == true && PinComReceive == false) {

   Serial.println();
   Serial.println("Entering bootmaster sequence... Sending time-code...");
   Serial.println();
   // create time-code and provide functionvalue  

   delay(1000);

   MessageString = "TIMECODE=";

   MessageString = ID + IDadded + MessageString + TimeCode;

   Serial.println();
   Serial.println("The following bootmessage was generated containing a time-code (YYYYMMHHMMSS): ");
   Serial.println(MessageString);
   Serial.println();

   BootMaster = false; 

   TimeCode = "";

   delay(1000);
   goto DigitalInput;
   }
   
  
if (Millis - TotalMillis >= 60000 && PinComSend == false && PinComReceive == false) {
    Serial.println();
    Serial.println("No message activity for 60 seconds...");
    Serial.print("The program has been running for ");
    Serial.print(Millis/1000);
    Serial.print(" seconds. With ");
    Serial.print(MessagesSent);
    Serial.print(" messages sent and ");
    Serial.print(MessagesReceived);
    Serial.println(" received.");
    Serial.println();
    Serial.flush();
    delay(1000);
    TotalMillis = millis();
    }
    
    
EscapeInput:

while (Serial.available() == 0 && PinComSend == false && PinComReceive == false) {}
   if (Serial.available() >= 1 && PinComSend == false && PinComReceive == false) {
   MessageString = Serial.readString();
   
   Serial.flush();

   delay(1000);

   if (MessageString == "f") {
   MessageString = "";
   Millis = millis();
   Serial.println();
   Serial.println("Please input a four digit function value to initiate the function: ");
   Serial.println();
   delay(1000);
     
      ReInputFunction:
      while (Serial.available() == 0) {
      if (millis() - Millis >= 20000) {
      delay(1000);
      Serial.println();
      Serial.println("20 seconds timed-out... No function value was received...");
      Serial.println();
      pinMode (PinCom, INPUT);
      delay(1000);
      goto EscapeInput;
      }}
      
      if (Serial.available() == 4) {
      FunctionValue = Serial.readString();
      FunctionIncomingValue = FunctionValue.toInt();
      delay(1000);
      Serial.println();
      Serial.print("Function: ");
      Serial.print(FunctionIncomingValue);
      Serial.println(", initiated...");
      Serial.println();
      delay(1000);
      AutoInitiateFunction: // entrypoint for automatic trigger
      MessageString = "FUNCTIONVALUE=";
      MessageString = MessageString + FunctionValue;
      MessageString = ID + IDadded + MessageString;
      InitiateFunction = true;
      goto DigitalInput;
      }
      
      if (Serial.available() <= 3 || Serial.available() >= 5) {
      Serial.println();
      Serial.println("Input a four digit value from 0001 to 9999, please try again:");
      delay(1000);
      Millis = millis();
      goto ReInputFunction;
      }
   
   }

   if (MessageString == "t") {
   MessageString = "";
   Millis = millis();
   Serial.println();
   Serial.println("Please input the time-code (YYYYMMDDHHMMSS):");
   Serial.println();
   delay(1000);

   ReInputTime:
   while (Serial.available() == 0) {
    if (millis() - Millis >= 20000) {
    delay(1000);
    Serial.println();
    Serial.println("20 seconds timed-out... The time was not set...");
    Serial.println();
    pinMode (PinCom, INPUT);
    delay(1000);
    goto EscapeInput;
    }}
      
      if (Serial.available() == 14) {
      TimeCode = Serial.readString();
      delay(1000);
      TimeCodeFirstDigit = TimeCode.charAt(0); // read the chars
      TImeCodeSecondDigit = TimeCode.charAt(1);
      TimeCodeThirdDigit = TimeCode.charAt(2);
      TimeCodeFourthDigit = TimeCode.charAt(3);
      TimeCodeFifthDigit = TimeCode.charAt(4);
      TimeCodeSixthDigit = TimeCode.charAt(5);
      TimeCodeSeventhDigit = TimeCode.charAt(6);
      TimeCodeEigthDigit = TimeCode.charAt(7);
      TimeCodeNinthDigit = TimeCode.charAt(8);
      TimeCodeTenthDigit = TimeCode.charAt(9);
      TimeCodeEleventhDigit = TimeCode.charAt(10);
      TimeCodeTwelvethDigit = TimeCode.charAt(11);
      TimeCodeThirteenthDigit = TimeCode.charAt(12);
      TimeCodeFourteenthDigit = TimeCode.charAt(13);

      YearString.concat(TimeCodeFirstDigit);
      YearString.concat(TImeCodeSecondDigit);
      YearString.concat(TimeCodeThirdDigit);
      YearString.concat(TimeCodeFourthDigit);
      MonthString.concat(TimeCodeFifthDigit);
      MonthString.concat(TimeCodeSixthDigit);
      DayString.concat(TimeCodeSeventhDigit); 
      DayString.concat(TimeCodeEigthDigit); 
      HourString.concat(TimeCodeNinthDigit);
      HourString.concat(TimeCodeTenthDigit); 
      MinuteString.concat(TimeCodeEleventhDigit);
      MinuteString.concat(TimeCodeTwelvethDigit);
      SecondString.concat(TimeCodeThirteenthDigit);
      SecondString.concat(TimeCodeFourteenthDigit);

      Year = YearString.toInt();
      Month = MonthString.toInt();
      Day = DayString.toInt(); 
      Hour = HourString.toInt(); 
      Minute = MinuteString.toInt(); 
      Second = SecondString.toInt();
       
      TimeCodeFirstDigit = ' ';
      TImeCodeSecondDigit = ' ';
      TimeCodeThirdDigit = ' ';
      TimeCodeFourthDigit = ' ';
      TimeCodeFifthDigit = ' ';
      TimeCodeSixthDigit = ' ';
      TimeCodeSeventhDigit = ' ';
      TimeCodeEigthDigit = ' ';
      TimeCodeNinthDigit = ' ';
      TimeCodeTenthDigit = ' ';
      TimeCodeEleventhDigit = ' ';
      TimeCodeTwelvethDigit = ' ';
      TimeCodeThirteenthDigit = ' ';
      TimeCodeFourteenthDigit = ' ';
        
      YearString = "";
      MonthString  = "";
      DayString  = ""; 
      HourString  = ""; 
      MinuteString  = ""; 
      SecondString  = "";
      
      setTime(Hour,Minute,Second,Day,Month,Year); 

      Year = 0;
      Month = 0;
      Day = 0; 
      Hour = 0; 
      Minute = 0; 
      Second = 0;

      delay(1000);
      
      Serial.println();
      Serial.print("The following time-code was received: ");
      Serial.println(TimeCode);
      Serial.print("Which makes the new time and date: ");
      Serial.print(hour());
      Serial.print(":");
      Serial.print(minute());
      Serial.print(":");
      Serial.print(second());
      Serial.print(" on ");
      Serial.print(day());
      Serial.print(" in monthnumber ");
      Serial.print(month());
      Serial.print(" of the year ");
      Serial.println(year());
      Serial.println();

      delay(1000);

      AutoInitiateTime: // entrypoint for automatic trigger
      MessageString = "TIMECODE=";
      MessageString = MessageString + TimeCode;
      MessageString = ID + IDadded + MessageString;
      TimeCode = "";

      delay(1000);
      goto DigitalInput;
      }
      
      if (Serial.available() <= 13 || Serial.available() >= 15) {
      Serial.println();
      Serial.println("Input a fourteen digit value for the time-code , please try again:");
      Serial.println();
      pinMode (PinCom, INPUT);
      delay(1000);
      Millis = millis();
      goto ReInputTime;
      }
      
   }

   delay(1000);
   
   MessageString = ID + IDadded + MessageString;

   DigitalInput:

   PinComSend = true;

   pinMode(PinCom, OUTPUT);

   StringLength = 0;
   CharacterCount = 0;
   CharacterPosition = 0;

   StringLength = MessageString.length() + 1;

   CharacterPosition = 0;
   tempChar = MessageString.charAt(CharacterPosition);
  
   if (StringLength >= 800) {
    Serial.println();
    Serial.println("Your message contained more than 800 Characters, this is not allowed. Please try again. You tried the following message:");
    Serial.println(MessageString);
    Serial.println();
    delay(1000);
    goto EscapeInput;
    }

   digitalWrite(PinCom, HIGH); // pre-pulse the pin
   delayMicroseconds(SpeedMicros);
   digitalWrite(PinCom, LOW);
   delayMicroseconds(SpeedMicros);
   digitalWrite(PinCom, HIGH); // send the opening signal
   delayMicroseconds(Character + (1 * SpeedMicros));
   digitalWrite(PinCom, LOW);
   delayMicroseconds(Character);

   ReadChars:

    if (tempChar == '0') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (3 * SpeedMicros)); // set these values to change the speed of the connection, decreasing the signal width will improve connection speed but reliability might lack depending on the microprocessor
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character); // the LOW time is not detected but one could change the code to detcct a LOW using the PinMode PULLUP funcion ofr PinCom
      
      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters send
      }
    else if (tempChar == '1') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (4 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '2') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (5 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '3') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (6 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '4') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (7 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '5') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (8 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '6') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (9 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '7') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (10 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '8') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (11 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '9') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (12 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '-') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (13 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '.') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (14 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == ' ') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (15 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '?') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (16 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '=') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (17 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == ':') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (18 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'A') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (19 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'B') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (20 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'C') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (21 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'D') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (22 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'E') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (23 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'F') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (24 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'G') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (25 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'H') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (26 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'I') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (27 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'J') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (28 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'K') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (29 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'L') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (30 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'M') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (31 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'N') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (32 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'O') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (33 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'P') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (34 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'Q') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (35 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'R') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (36 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'S') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (37 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'T') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (38 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'U') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (39 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'V') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (40 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'W') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (41 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'X') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (42 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'Y') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (43 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }

    else if (tempChar == 'Z') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (44 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }

     else { // used when the character a not recognized
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (15 * SpeedMicros)); // sends an empty space
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }  

    if (CharacterPosition <= StringLength) {
    ++CharacterPosition;
    tempChar = MessageString.charAt(CharacterPosition);
    // delayMicroseconds(CharacterDelay); // check if required
    goto ReadChars;
    }

    if (CharacterPosition > StringLength) {
    digitalWrite(PinCom,  HIGH); // send the messsage end signal
    delayMicroseconds(Character + (2 * SpeedMicros));
    digitalWrite(PinCom,  LOW);
    delayMicroseconds(Character);
    
    Serial.println();
    Serial.print("The following message was sent containing ");
    Serial.print(StringLength);
    Serial.println(" characters:");
    Serial.println(MessageString);
    Serial.println();

    delay(1000);

    tempChar = ' ';
    CharacterCount = 0;
    CharacterPosition = 0;
    StringLength = 0;
    MessageString = "";

    ++MessagesSent;
    
    digitalWrite(PinCom,  LOW);
    pinMode(PinCom, INPUT);
    
    PinComSend = false;
    
    TotalMillis = millis();
    
    Serial.flush();
    
    delay(1000);
    }
   
 }
   

// used for several example program features based on the detected function value, the numbers chosen are totally random, 9999 options here...
if (FunctionIncomingValue >= 0001 && FunctionIncomingValue <= 5000 && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   VoltageReceived = FunctionIncomingValue;  // converts the voltage to mV
   Serial.println();
   Serial.print("The voltage from the sender with device ID: ");
   Serial.print(IDsender);
   Serial.print(" reads");
   Serial.print(VoltageReceived);
   Serial.println(" mV");
   Serial.println();
   FunctionIncomingValue = 0;
   InitiateFunction = false;
   delayMicroseconds(1000);
   }

// set the Frequency in kHz
if (FunctionIncomingValue >= 6001 && FunctionIncomingValue <= 6999 && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   Frequency = (FunctionIncomingValue - 6000) * 1000;
   InitiateFunction = false;
   Serial.println();
   Serial.print("The frequency was set to: ");
   Serial.print(Frequency);
   Serial.println("Hz");
   Serial.println();
   FunctionIncomingValue = 0;
   delayMicroseconds(1000);
   }

// set the DutyCycle
if (FunctionIncomingValue >= 7001 && FunctionIncomingValue <= 7100 && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   DutyCycle = FunctionIncomingValue - 7000;
   InitiateFunction = false;
   Serial.println();
   Serial.print("The duty-cycle for the frequency was set to: ");
   Serial.print(DutyCycle);
   Serial.println("%");
   Serial.println();
   FunctionIncomingValue = 0;
   delayMicroseconds(1000);
   }

// start the PWM
if (FunctionIncomingValue == 7101 && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   PWM = true;
   digitalWrite(PinPulse, LOW);
   PWMState = LOW;
   InitiateFunction = false;
//   if (Frequency <= 0 || DutyCycle <= 0) {
//   Frequency = 5000;
//   DutyCycle = 50;
//   Serial.println();
//   Serial.println("Either the frequency or duty-cycle was smaller than zero and both were resetted to default, how did that happen?");
//   Serial.println();
//   }
   delayMicroseconds(1000);
   Serial.println();
   Serial.print("PWM engaged at ");
   Serial.print(Frequency);
   Serial.print("Hz with a ");
   Serial.print(DutyCycle);
   Serial.print("% duty-cycle with a low-time of ");
   Serial.print(Low);
   Serial.print(" microseconds and a high-time ");
   Serial.print(High);
   Serial.println(" microseconds.");
   Serial.println();
   FunctionIncomingValue = 0;
   delayMicroseconds(1000);
   MicrosPrevious = micros();
   }

// stop the PWM
if (FunctionIncomingValue == 7102 && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   PWM = false;
   digitalWrite(PinPulse, LOW);
   PWMState = LOW;
   InitiateFunction = false;
   Serial.println();
   Serial.println("PWM disengaged...");
   Serial.println();
   FunctionIncomingValue = 0;
   delayMicroseconds(1000);
   }

// read and report the analog voltage
if (FunctionIncomingValue == 7103 && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   AnalogRead = analogRead(PinVoltage);
   Voltage = DeviceVoltage / 1024 * AnalogRead; // in mV

   VoltageRead = String(Voltage);

   MessageString = "THE FUNCTIONVALUE=";
   MessageString = MessageString + VoltageRead;
   MessageString = ID + IDadded + MessageString;

   InitiateFunction = false;

   Serial.println();
   Serial.print("The voltage reads: ");
   Serial.print(Voltage);
   Serial.println("mV");
   Serial.println();

   InitiateFunction = false;

   VoltageRead = "";
   
   FunctionIncomingValue = 0;
   delayMicroseconds(1000);
   goto DigitalInput;
   }

// start communication forwarding on the forwarding pin
if (FunctionIncomingValue == 7104 && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   DeviceVoltage = 3300;
   InitiateFunction = false;
   Serial.println();
   Serial.println("Device operating voltage set to 3.3V...");
   Serial.println();
   FunctionIncomingValue = 0;
   delay(1000);
   }
   
// stop communication forwarding on the forwarding pin
if (FunctionIncomingValue == 7105 && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   DeviceVoltage = 5000;
   InitiateFunction = false;
   Serial.println();
   Serial.println("Device operating voltage set to 5V...");
   Serial.println();
   FunctionIncomingValue = 0;
   delay(1000);
   }

// start communication forwarding on the forwarding pin
if (FunctionIncomingValue == 7106 && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   Forward = true;
   InitiateFunction = false;
   Serial.println();
   Serial.println("Forwarding enabled...");
   Serial.println();
   FunctionIncomingValue = 0;
   delay(1000);
   }
   
// stop communication forwarding on the forwarding pin
if (FunctionIncomingValue == 7107 && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   Forward = false;
   InitiateFunction = false;
   Serial.println();
   Serial.println("Forwarding disabled...");
   Serial.println();
   FunctionIncomingValue = 0;
   delay(1000);
   }

}

I made it suitable for use on most microprocessors and therefore I removed EEPROM, NTP and RTC functions. Let me know what you think. Things I might change or add: goto to boolean functions, replace String if needed and generally try to improve operational speed and reliability.

Thanks for your interest in the program.

1 Like

What did you expect this to do? cording to the documentation, pinMode() returns nothing. The ';' ends the 'if' so regardless of the value returned by pinMode(), nothing will be done.

All that can be reduced to:

  // drive the forwarding pin (it forwards receiving messages only)
  if (Forward) 
  {
    digitalWrite(PinForward, PinComState);
  }
  else
    digitalWrite(PinForward, LOW);
1 Like

Worse, it does not even compile because of a missing ).

1 Like

What did you expect this to do? cording to the documentation, pinMode() returns nothing. The ';' ends the 'if' so regardless of the value returned by pinMode(), nothing will be done.

That was some left-over code and a obvious mistake, I did not notice it was in (changed it). I might work in your fine suggestions, I wonder how much actual difference these things make after compilation in terms of size or speed?

Yes, there is a way you can always know the state of an output port or other write only channel. Instead of writing it directly, update a variable instead and then use the variable to set the port or destination data.

somePinState = INPUT;
...
pinMode(somePin, somePinState);
...
// hmm, I wonder what I set the pin mode to?
if (somePinState == INPUT) {...

OP is 1 IQ

Moderator response to that should be interesting.

Yes, there is a way you can always know the state of an output port or other write only channel. Instead of writing it directly, update a variable instead and then use the variable to set the port or destination data.

Good point. Thanks. The compiler does not mind a variable inside pinMode? Regardless... If the code is correct (which it is now) I would not need to check the state.

hes iq 1

Explain? Do not tell me your unkind like that... It does not compile anyway as it is: He is IQ 1.

Moderator response to that should be interesting.

Response to what?

I need to optimize the digitalRead and digitalWrite on the communication pin also. Possibly by accessing it more directly, I am trying to figure that out right now.

In the past Arduino IDEs used to have a function called AnalogSetFrequency() (feature request!). It might have been ESP specific but they chopped it out for some reason. It ran in the background and functioned fast and without problems in the code I used back then. I think it also featured a duty-cycle. It was a great function to have because it removes the need to toggle pins back and forth manually. Does anyone here know why it was removed, compatibility issues maybe?

1 Like

If people help me out with this code a little bit (because I get too cross-eyed at times) I will share a project of mine called project plant on the forum (with some board and plant photos and in-depth explanation on the workings of it all). I might do it anyway...

It is a project directed at optimising plant growth. Pretty cool if I say so myself.

I know what I am asking here is essentially blackmail but ok.

Feel free to add requests for additional program features.

1 Like
if (pinMode(PinCom, OUTPUT); 

I removed the trash code, please try it. Strangely it did compile, this is how I got the error!

You have made 4 edits to your original post. Please don't do that. Post updated code in a new message.

Google doesn't know about that function. Did you mean "AnalogWriteFrequency"? That seems to be a Teensy feature:
https://www.pjrc.com/teensy/td_pulse.html

Also if you want us to "try" it, you have to explain what it does, what hardware it requires if any, and what tests to perform.

You have made 4 edits to your original post. Please don't do that. Post updated code in a new message.

The code is long and that would influence the forum read-ability a bit but note taken, probably will do that from now on.

Google doesn't know about that function. Did you mean "AnalogWriteFrequency"? That seems to be a Teensy feature:
Pulse Width and Tone on Teensy with Arduino

It might have been AnalogWriteFrequency instead of AnalogSetFrequency. I had it working on a ESP8266 for the mentioned project but it now is somehow completely burried on the web. However I still have the old IDE so I can check if I want.

Also if you want us to "try" it, you have to explain what it does, what hardware it requires if any, and what tests to perform.

Ok good point, I should have added that. When completely functional It essentially holds center between a human readable and a bus style one-wire messaging program adding: functionvalue, time-code and byte recognition when these are entered inside the message.

It should run on every type of Arduino board but you could easily add additional board or sensor specific features. For that I would recommend using the functionvalue initiation section at the bottom of the code.

Say you type a message saying: PROGRAM PLEASE UPDATE THE TIME BY INITIATING FUNCTIONVALUE=8345, then program a NTP routine under section 8345 at the receiver end (which would likely be the same code as the sender but you could change that up).

I added sections in the code (you can read the boot message on that) for several basic function codes like code 7101 which initiates the PWM. You can initiate it at the receiver side and through the serial monitor by typing FUNCTIONVALUE= or locally by first entering t and have it then ask for a code, then input 7101 to initiate PWM.

You could add code to call the four digit function int FunctionValue automatically at some specific event by setting it and then have it goto towards AutoInitiateFunction: // entrypoint for automatic trigger

I also added the injecting of a time code during boot and inside the program using the same principal. This is working (I need to check reception still) so you could already use the program to update the time through the serial monitor with YYYYMMDDHHMMSS, it asks for it. Just chop that part out if you would like to use it for something.

Currently I am working on a strategy to detect the communication PinCom correctly and with maximum speed. Also I somehow seem to fail at getting something relatively simple as PWM going, my mind is blocked on both at the moment so I am first adding all the features.

I hope this explains it a bit more, program pin outputs are measured using an oscilloscope.

// An example communication program using a single pin.
// Copyright © Wobbly, 2022.

#include <TimeLib.h> // get it here (or inside Arduino): https://github.com/PaulStoffregen/Time/blob/master/TimeLib.h

// The program variables
const int PinCom = 16; // main digital bi-directional communication pin (on the ESP32)
const int PinForward = 17; // secondary digital forwarding communication pin (on the ESP32)
const int PinVoltage = 2; // analog pin (on the ESP32) to read a voltage from
const int PinPulse = 4; // analog pin (on the ESP32) to generate a pulse on
const int PinLED = 13; // LED indication pin (on the ESP32) for reception activity

int i = 0; // counter

int DeviceVoltage = 3300; // define your operating voltage in mV

boolean ReadHigh = false; // mark the measuring time

int PinComState = LOW; // log the pin state
String SpeedMicrosInput = ""; // used for temporary speed input
unsigned long HighTime = 0; // duration of the HIGH status for the commuication pin
float SpeedMicros = 2000; // set the time allowed for the signal
float Character = SpeedMicros * 2; // set the first character time, low-time and the end signal- time
float SignalDeviation = SpeedMicros / 4; // sets the allowed deviation
// int CharacterDelay = 1; // set the delay in between character processing if required

int PWMState = LOW; // check the pulse pin state
int Frequency = 5000; // sets the frequency on the pulse pin in Hz
int DutyCycle = 50; // sets the duty cycle on the pulse pin
unsigned long High = (10000 / Frequency) * DutyCycle; // used to calculate the HIGH time for the PWM (PulsePin)
unsigned long Low = (1000000 / Frequency) - High; // used calculate the LOW time for the PWM (PulsePin)
unsigned long MicrosPrevious = 0; // stores elapsed micros

int AnalogRead = 0; // stores the read value
int Voltage = 0;  // stores the voltage
int VoltageReceived = 0;  // stores the received voltage
String VoltageRead = "";  // temporarily stores the voltage

String SerialSpeedString = ""; // used for temporary serial speed input
int SerialSpeed = 0; // stores the serial speed

char BootInput = ' '; // boot loading input

boolean PinComSend = false; // flag a send for the Pin
boolean PinComReceive = false; // flag a receive for the Pin

boolean BootMaster = false; // this registers the ID and thereby enables specific functions on the boot

boolean MessageReceived = false; // mark the reception of a message
boolean ByteReceived = false; // mark the reception of a byte
boolean InitiateFunction = false; // this marks the reception of a function code
boolean TimeCodeReceived = false; // mark the reception of a time-code

boolean Ping = false; // mark the reply message ping

boolean PWM = false; // mark the PWM initiation

boolean Forward = false; // mark the forwarding initiation

char tempChar = ' ';
String MessageString = ""; // the string used for the message
int StringLength = 0; // log the string length
int CharacterCount = 0; // count the amount of characters in a message
int MessagesSent = 0; // count the amount of messages sent
int MessagesReceived = 0; // count the amount of messages received
int CharacterPosition = 0; // checkt the character postion

String ID = "9999";  //  used to identify the device, set to 9999 for creating masterboot functions
String IDsender = "0000";  // used to identify the sending device
const String IDadded = " DELIVERED THE FOLLOWING MESSAGE FOR YOU: "; // added string to identify the sender

char FunctionFirstDigit = ' '; // function value digits picked up from message, combine this to: char FunctionDigits[4] = '';?
char FunctionSecondDigit = ' ';
char FunctionThirdDigit = ' ';
char FunctionFourthDigit = ' ';
const String SearchFunctionValue = "FUNCTIONVALUE=";  // search the position of a possible function value
String FunctionValue = "";  // temporary Function value storage
int FunctionValuePosition = 0;  // store the position of the function value within the string
int FunctionIncomingValue = 0;  // store the actual value of the function

char ByteFirstBit = ' '; // byte digits picked up from message, combine this to: char ByteDigits[8] = '';?
char ByteSecondBit = ' ';
char ByteThirdBit = ' ';
char ByteFourthBit = ' ';
char ByteFifthBit = ' ';
char ByteSixthBit = ' ';
char ByteSeventhBit = ' ';
char ByteEigthBit = ' ';
const String SearchByte = "BYTE=";  // search the position of a possible Byte
int BytePosition = 0;  // store the position of the function value within the string
byte ReceivedByte = 0;  // store it as an actual byte

char TimeCodeFirstDigit = ' '; // first timecode digit picked up from message, combine this to: char TimeCodeDigit[14] = '';?
char TImeCodeSecondDigit = ' ';
char TimeCodeThirdDigit = ' ';
char TimeCodeFourthDigit = ' ';
char TimeCodeFifthDigit = ' ';
char TimeCodeSixthDigit = ' ';
char TimeCodeSeventhDigit = ' ';
char TimeCodeEigthDigit = ' ';
char TimeCodeNinthDigit = ' ';
char TimeCodeTenthDigit = ' ';
char TimeCodeEleventhDigit = ' ';
char TimeCodeTwelvethDigit = ' ';
char TimeCodeThirteenthDigit = ' ';
char TimeCodeFourteenthDigit = ' ';
const String SearchTimeCode = "TIMECODE=";  // search the position of a possible time code
String TimeCode = "";  // temporary Functionvalue storage
int TimeCodePosition = 0;  // store the position of the function value within the string

int Year = 0; // store values for the time
int Month = 0;
int Day = 0; 
int Hour = 0; 
int Minute = 0; 
int Second = 0;

String YearString = ""; // store temporary values for the time
String MonthString  = "";
String DayString  = ""; 
String HourString  = ""; 
String MinuteString  = ""; 
String SecondString  = "";

unsigned long Millis = 0; // stores the millis
unsigned long NoteMillis = 0; // marks a 60 second interval
unsigned long ProgramMillis = 0; // stores the program running time


void setup() {

analogReadResolution(8); // set this to 10 or 12 if required, adjust the code accordingly
// analogWriteResolution(8); // set this to 10 or 12 if required, adjust the code accordingly

pinMode(PinCom, INPUT); // configure the pins
pinMode(PinVoltage, INPUT); // no  here as it is used in a analog fashion
pinMode(PinForward, OUTPUT);
pinMode(PinPulse, OUTPUT);
pinMode(PinLED, OUTPUT);

digitalWrite(PinForward, LOW);
digitalWrite(PinPulse, LOW);
digitalWrite(PinLED, LOW);

SerialSpeed = 9600;

Serial.begin(SerialSpeed); // set the serial at speed

delay(3000);

BeginInputSerial:

Millis = millis();

delay(1000);

Serial.println();
Serial.println(F("The default speed for the serial monitor is set to 9600, would you like to change it? If so press 'y' if not press 'n'..."));
Serial.println();

  while (Serial.available() == 0) {
    if (millis() - Millis >= 20000) {
    delay(1000);
    Serial.println();
    Serial.println(F("20 seconds timed-out... A new serial speed was not set..."));
    Serial.println();
    Millis = millis();
    delay(1000);
    goto escapeSetupSerial;
    }}
  
  if (Serial.available() > 0) {
     BootInput = Serial.read();
     Millis = millis();
     if (BootInput == 'y') {
     Serial.println();
     Serial.println(F("Please input the required serial speed in baud: "));
     Serial.println();
     Millis = millis();
     BootInput = ' ';
     delay(1000);
     
      ReInputSerial:
      while (Serial.available() == 0) {
      if (millis() - Millis >= 20000) {
      delay(1000);
      Serial.println();
      Serial.println(F("20 seconds timed-out... A new serial speed was not set..."));
      Serial.println();
      Millis = millis();
      delay(1000);
      goto escapeSetupSerial;
      }}
      
      if (Serial.available() >= 1) {
      SerialSpeedString = Serial.readString();
      SerialSpeed = SerialSpeedString.toInt();
      delay(1000);
      if (SerialSpeed != 300 && SerialSpeed != 1200 && SerialSpeed != 2400 && SerialSpeed != 4800 && SerialSpeed != 9600 && SerialSpeed != 19200 && SerialSpeed != 38400 && SerialSpeed != 57600 && SerialSpeed != 74880 && SerialSpeed != 115200  && SerialSpeed != 230400 && SerialSpeed != 250000 && SerialSpeed != 500000 && SerialSpeed != 1000000  && SerialSpeed != 2000000) {
      Serial.println();
      Serial.println(F("This is number is not valid for the serial monitor speed."));
      Serial.print(F("You tried: "));
      Serial.print(SerialSpeed);
      Serial.println(F(" ;it accepts 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 250000, 500000, 1000000 or 2000000, please try again:"));
      Serial.println();
      BootInput = ' ';
      Millis = millis();
      delay(1000);
      goto ReInputSerial;
      }
      
      Serial.println();
      Serial.print(F("The new serial speed is: "));
      Serial.println(SerialSpeed);
      Serial.println();
      Millis = millis();

      Serial.println();
      Serial.println(F("Restarting the serial..."));
      Serial.println();

      delay(3000);
      Serial.end();
      delay(3000);
      Serial.begin(SerialSpeed); // restart the serial with the new requirements
      delay(3000);
      goto escapeSetupSerial;
      }
     }

     if (BootInput == 'n') {
      Serial.println();
      Serial.println(F("Proceeding with the default serial speed of 9600... "));
      Serial.println();
      Millis = millis();
      BootInput = ' ';
      delay(1000);
      goto escapeSetupSerial;
      }

     if (BootInput != 'n' && BootInput != 'y') {
      Serial.println();
      Serial.println(F("Input unknown, please try again..."));
      Serial.println();
      Millis = millis();
      BootInput = ' ';
      Serial.flush();
      delay(1000);
      goto BeginInputSerial;
      }

}

escapeSetupSerial:

BeginInputTime:

TimeCode = "";

Millis = millis();

delay(1000);

Serial.println();
Serial.println(F("Would you like to set the internal program time using a time-code (YYYYMMDDHHMMSS)? If so press 'y' if not press 'n'..."));
Serial.println();
delay(1000);

  while (Serial.available() == 0) {
    if (millis() - Millis >= 20000) {
    delay(1000);
    Serial.println();
    Serial.println(F("20 seconds timed-out... The time was not set..."));
    Serial.println();
    Millis = millis();
    delay(1000);
    goto escapeSetupTime;
    }}
  
  if (Serial.available() > 0) {
     BootInput = Serial.read();
     if (BootInput == 'y') {
     Serial.println();
     Serial.println(F("Please input the fourteen digit time-code:"));
     Serial.println();
     Millis = millis();
     BootInput = ' ';
     delay(1000);
     
      ReInputTime:
      while (Serial.available() == 0) {
      if (millis() - Millis >= 20000) {
      delay(1000);
      Serial.println();
      Serial.println(F("20 seconds timed-out... The new time was not set..."));
      Serial.println();
      Millis = millis();
      delay(1000);
      goto escapeSetupTime;
      }}
      
      if (Serial.available() >= 1) {
      TimeCode = Serial.readString();
      delay(1000);
      Serial.println();
      Serial.println(F("Setting time, please wait..."));
      Serial.println();
      delay(1000);
      
      TimeCodeFirstDigit = TimeCode.charAt(0); // read the chars
      TImeCodeSecondDigit = TimeCode.charAt(1);
      TimeCodeThirdDigit = TimeCode.charAt(2);
      TimeCodeFourthDigit = TimeCode.charAt(3);
      TimeCodeFifthDigit = TimeCode.charAt(4);
      TimeCodeSixthDigit = TimeCode.charAt(5);
      TimeCodeSeventhDigit = TimeCode.charAt(6);
      TimeCodeEigthDigit = TimeCode.charAt(7);
      TimeCodeNinthDigit = TimeCode.charAt(8);
      TimeCodeTenthDigit = TimeCode.charAt(9);
      TimeCodeEleventhDigit = TimeCode.charAt(10);
      TimeCodeTwelvethDigit = TimeCode.charAt(11);
      TimeCodeThirteenthDigit = TimeCode.charAt(12);
      TimeCodeFourteenthDigit = TimeCode.charAt(13);

      YearString.concat(TimeCodeFirstDigit);
      YearString.concat(TImeCodeSecondDigit);
      YearString.concat(TimeCodeThirdDigit);
      YearString.concat(TimeCodeFourthDigit);
      MonthString.concat(TimeCodeFifthDigit);
      MonthString.concat(TimeCodeSixthDigit);
      DayString.concat(TimeCodeSeventhDigit); 
      DayString.concat(TimeCodeEigthDigit); 
      HourString.concat(TimeCodeNinthDigit);
      HourString.concat(TimeCodeTenthDigit); 
      MinuteString.concat(TimeCodeEleventhDigit);
      MinuteString.concat(TimeCodeTwelvethDigit);
      SecondString.concat(TimeCodeThirteenthDigit);
      SecondString.concat(TimeCodeFourteenthDigit);

      Year = YearString.toInt();
      Month = MonthString.toInt();
      Day = DayString.toInt(); 
      Hour = HourString.toInt(); 
      Minute = MinuteString.toInt(); 
      Second = SecondString.toInt();
       
      TimeCodeFirstDigit = ' ';
      TImeCodeSecondDigit = ' ';
      TimeCodeThirdDigit = ' ';
      TimeCodeFourthDigit = ' ';
      TimeCodeFifthDigit = ' ';
      TimeCodeSixthDigit = ' ';
      TimeCodeSeventhDigit = ' ';
      TimeCodeEigthDigit = ' ';
      TimeCodeNinthDigit = ' ';
      TimeCodeTenthDigit = ' ';
      TimeCodeEleventhDigit = ' ';
      TimeCodeTwelvethDigit = ' ';
      TimeCodeThirteenthDigit = ' ';
      TimeCodeFourteenthDigit = ' ';
        
      YearString = "";
      MonthString  = "";
      DayString  = ""; 
      HourString  = ""; 
      MinuteString  = ""; 
      SecondString  = "";
      
      setTime(Hour,Minute,Second,Day,Month,Year); 

      delay(3000);
      
      Serial.println();
      Serial.print(F("The following time-code was received: "));
      Serial.println(TimeCode);
      Serial.println();
      Serial.print(F("Which makes the new time and date: "));
      Serial.print(hour());
      Serial.print(F(":"));
      Serial.print(minute());
      Serial.print(F(":"));
      Serial.print(second());
      Serial.print(F(" on day "));
      Serial.print(day());
      Serial.print(F(" in monthnumber "));
      Serial.print(month());
      Serial.print(F(" of the year "));
      Serial.println(year());
      Serial.println();

      Year = 0;
      Month = 0;
      Day = 0; 
      Hour = 0; 
      Minute = 0; 
      Second = 0;
      
      Millis = millis();
      delay(1000);
      goto escapeSetupTime;
      }
     }

     if (BootInput == 'n') {
      Serial.println();
      Serial.println(F("Proceeding without setting the time... "));
      Serial.println();
      Millis = millis();
      delay(1000);
      BootInput = ' ';
      goto escapeSetupTime;
      }

     if (BootInput != 'n' && BootInput != 'y') {
      Serial.println();
      Serial.println(F("Input unknown, please try again..."));
      Serial.println();
      Millis = millis();
      BootInput = ' ';
      Serial.flush();
      delay(3000);
      goto BeginInputTime;
      }

}

escapeSetupTime:

ID = 9999;

Serial.println();
Serial.print(F("The default four digit device ID currently is: "));
Serial.println(ID);
Serial.println();
delay(1000);

BeginInputName:

Millis = millis();

Serial.println();
Serial.println(F("Would you like to set a new four digit device ID (set it to '9999' to enable masterboot functions)? If so press 'y' if not press 'n'..."));
Serial.println();
Serial.println(F("The masterboot functions currently entail the forwarding of time to all the listening devices."));
Serial.println();
delay(1000);

  while (Serial.available() == 0) {
    if (millis() - Millis >= 20000) {
    delay(1000);
    Serial.println();
    Serial.println(F("20 seconds timed-out... A new device ID was not set..."));
    Serial.println();
    Millis = millis();
    delay(1000);
    goto escapeSetupName;
    }}
  
  if (Serial.available() > 0) {
     BootInput = Serial.read();
     Millis = millis();
     if (BootInput == 'y') {
     Serial.println();
     Serial.println(F("Please input a new device ID made from four digits (like: 0001): "));
     Serial.println();
     delay(1000);
     BootInput = ' ';
     
      ReInputName:
      while (Serial.available() == 0) {
      if (millis() - Millis >= 20000) {
      delay(1000);
      Serial.println();
      Serial.println(F("20 seconds timed-out... A new device ID was not set..."));
      Serial.println();
      Millis = millis();
      delay(1000);
      goto escapeSetupName;
      }}
      
      if (Serial.available() == 4) {
      ID = Serial.readString();
      Serial.println();
      Serial.print(F("The new device ID is: "));
      Serial.println(ID);
      Serial.println();
      Millis = millis();
      delay(1000);
      goto escapeSetupName;
      }

      if (Serial.available() <= 3 || Serial.available() >= 5) {
      Serial.println();
      Serial.println(F("Please input four digit device ID (like: 0001), please try again:"));
      Serial.println();
      Millis = millis();
      delay(1000);
      goto ReInputName;
      }
     }

     if (BootInput == 'n') {
      Serial.println();
      Serial.println(F("Proceeding with the old device ID... "));
      Serial.println();
      delay(1000);
      BootInput = ' ';
      goto escapeSetupName;
      }

     if (BootInput != 'n' && BootInput != 'y') {
      Serial.println();
      Serial.println(F("Input unknown, please try again..."));
      Serial.println();
      BootInput = ' ';
      Serial.flush();
      delay(3000);
      goto BeginInputName;
      }

 }

escapeSetupName:

if (ID == "9999") {
   BootMaster = true;
   }

if (ID != "9999") {
   BootMaster = false;
   }
 
SpeedMicrosInput = "";
SpeedMicros = 1000;

Serial.println();
Serial.print(F("The maximum signal speed is currently set at: "));
Serial.print(SpeedMicros);
Serial.println(F(" microseconds."));
Serial.println();
delay(1000);

BeginInputSpeed:

Millis = millis();

delay(1000);

Serial.println();
Serial.println(F("The default maximum signal speed is 1000 microseconds, the minimum speed. Would you like to change it? If so press 'y' if not press 'n'..."));
Serial.println();
Serial.println(F("Please do not forget to match the maximum signal speed for all devices to enable communications, normally they should all load the default."));
Serial.println();

  while (Serial.available() == 0) {
    if (millis() - Millis >= 20000) {
    delay(1000);
    Serial.println();
    Serial.println(F("20 seconds timed-out... A new signal speed was not set..."));
    Serial.println();
    Millis = millis();
    delay(1000);
    goto escapeSetupSpeed;
    }}

  if (Serial.available() > 0) {
     BootInput = Serial.read();
     if (BootInput == 'y') {
     Serial.println();
     Serial.println(F("Please input a new maximum signal speed with a minimum of 1 and a maximum of 1000 microseconds: "));
     Serial.println();
     Millis = millis();
     delay(1000);
     BootInput = ' ';
     
      ReInputSpeed:
      while (Serial.available() == 0) {
      if (millis() - Millis >= 20000) {
      delay(1000);
      Serial.println();
      Serial.println(F("20 seconds timed-out... A new maximum signal speed was not set..."));
      Serial.println();
      Millis = millis();
      delay(1000);
      goto escapeSetupSpeed;
      }}
      
      if (Serial.available() >= 1 && Serial.available() <= 4) {
      SpeedMicrosInput = Serial.readString();
      SpeedMicros = SpeedMicrosInput.toInt();
      if (SpeedMicros < 1 || SpeedMicros >= 1001) {
      Serial.println();
      Serial.print(F("That is either too fast or too slow (you can input 1-1000), please try again:"));
      Serial.println();
      Millis = millis();
      delay(1000);;
      goto ReInputSpeed;
      }
      Serial.println();
      Serial.print(F("The maximum signal speed was set to: "));
      Serial.print(SpeedMicros);
      Serial.println(F(" microseconds."));
      Serial.println();
      delay(1000);
      goto escapeSetupSpeed;
      }

      if (Serial.available() >= 9) {
      Serial.println();
      Serial.println(F("That is too , please try again:"));
      Millis = millis();
      delay(1000);
      goto ReInputSpeed;
      }
     }

     if (BootInput == 'n') {
      Serial.println();
      Serial.println(F("Proceeding with the old maximum signal speed... "));
      Serial.println();
      delay(1000);
      BootInput = ' ';
      goto escapeSetupSpeed;
      }

     if (BootInput != 'n' && BootInput != 'y') {
      Serial.println();
      Serial.println(F("Input unknown, please try again..."));
      Serial.println();
      BootInput = ' ';
      Serial.flush();
      delay(3000);
      goto BeginInputSpeed;
      }

 } 

escapeSetupSpeed:

delay(1000);

Serial.println();
Serial.println(F("Exiting setup... "));
Serial.println();

Serial.println();
Serial.println(F("Welcome to the Wobbly demonstration communication program!"));
Serial.println();

Serial.println();
Serial.println(F("Message length is limited to 800 Characters minus the included name and opening text added to each message."));
Serial.println();

Serial.println();
Serial.println(F("Not every character was coded. More characters, words or direct function recognization can be added with a change in code."));
Serial.println(F("Always use TABS for message letter input as seen below. The currently coded characters are:"));
Serial.println(F("A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, -, ., , ?, -, =, :, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9"));
Serial.println(F("Four digit function values or fourteen digit time-codes (YYYYMMDDHHMMSS) are detected inside the message automatically when using the following formats: FUNCTIONVALUE=, TIMECODE="));
Serial.println(F("The function values can be set at any time by inputting 'f' or fourteen digit time-codes (YYYYMMDDHHMMSS) by inputting 't' through the serial monitor, they are then initiated and transmitted."));
Serial.println(F("With added coded one can call and transmit function values or time-codes automatically at specific events. Or add things like an NTP retrieval, RTCs or RF transmissions"));
Serial.println(F("Currently the following standard functions values are programmed and can be called..."));
Serial.println(F("Everything between 0000-5000 is reserved for a voltage, 6001-6999 sets the PWM output frequency in kHz, 7001-7100 sets the PWM duty-cycle, 7101 starts PWM, 7102 stops it, 7103 measures a voltage, 7104 sets the device voltage to 3.3V, 7105 sets it to 5V, 7107 starts foorwarding and 7106 stops forwarding."));
Serial.println(F("Finally: call a function value between 8001-9000 to update the maximum signal speed in microseconds on both the sending and receiving end. Call 9001 to retrieve the amount messages send and received."));
Serial.println();

SpeedMicrosInput = "";

MessageString = "";

VoltageRead = "";

BootInput = ' ';

ReadHigh = false;

MessageReceived = false;
Ping = false;
TimeCodeReceived = false;
ByteReceived = false;
InitiateFunction = false;

PinComSend = false; 
PinComReceive = false;

Ping = false;

PWM = false;

Forward = false;

PWMState = LOW;
PinComState = LOW;

AnalogRead = 0;
Voltage = 0;

Frequency = 5000;
DutyCycle = 50;

MessagesSent = 0;
MessagesReceived = 0;

CharacterCount = 0;

StringLength = 0;

HighTime = 0;

MicrosPrevious = 0;

Millis = millis();
NoteMillis = millis();
ProgramMillis = millis();

Serial.flush();

delay(3000);
     
}


void loop() {

// boot routine for the massterboot functions, add more if you like
if (BootMaster == true && PinComReceive == false) {

   Serial.println();
   Serial.println(F("Entering bootmaster sequence... Sending time-code..."));
   Serial.println();
   // create time-code and provide functionvalue  

   delay(1000);

   MessageString = "TIMECODE=";

   MessageString = ID + IDadded + MessageString + TimeCode;

   Serial.println();
   Serial.println(F("The following bootmessage was generated containing a time-code (YYYYMMHHMMSS): "));
   Serial.println(MessageString);
   Serial.println();
   Serial.flush();

   BootMaster = false; 

   TimeCode = "";

   delay(1000);
   goto DigitalInput;
   }
   

// a value above 1000 should never happen, added for now and just to be sure
if (SpeedMicros > 1000) {
   SpeedMicros = 1000;
   }

// monitor the communication pin
if (PinComSend == false) {
   PinComState = digitalRead(PinCom);
   if (PinComState == HIGH && ReadHigh == false && PinComSend == false) {
   HighTime = micros();
   ReadHigh = true;
   digitalWrite(PinLED, HIGH);
   }
   }

// alternative option
//PinPulseTimeOut = Character + (44 * SpeedMicros) + (SignalDeviation + 1); // calculates the time-out
//HighTime = pulseIn(PinCom, HIGH, PinPulseTimeOut);

// drive the PWM
if (PWM == true) {
   if (PWMState == LOW && (micros() - MicrosPrevious) > Low) {
      PWMState = HIGH;
      digitalWrite(PinPulse, PWMState);
      MicrosPrevious = micros();
      }
   if (PWMState == HIGH && (micros() - MicrosPrevious) > High) {
      PWMState = LOW;
      digitalWrite(PinPulse, PWMState);
      MicrosPrevious = micros();
      }
   }

if (PWM == false) {
   PWMState = LOW;
   digitalWrite(PinPulse, PWMState);
   MicrosPrevious = 0;
   }

// drive the forwarding pin (it forwards receiving messages only)
if (Forward == true && PinComSend == false) {
   if (PinComState == HIGH){
      digitalWrite(PinForward, PinComState);
      }

   else if (PinComState == LOW){
      digitalWrite(PinForward, PinComState);
      }
   }

if (Forward == false) {
      digitalWrite(PinForward, LOW);
      }
      
// reject and start counting again or actually start receiving
if (PinComState == LOW && ReadHigh == true && PinComSend == false && (micros() - HighTime) <= round(Character - SignalDeviation)) {
   ReadHigh = false;
   HighTime = 0;
   }

if (PinComState == LOW && ReadHigh == true && PinComSend == false && (micros() - HighTime) >= round(Character - SignalDeviation)) {

    ReadHigh = false;
    digitalWrite(PinLED, LOW);
   
    if (HighTime >= round(Character - SignalDeviation) && HighTime <= round(Character + SignalDeviation) && PinComReceive == true) // detect a character
    {
      MessageString.concat(tempChar);
      CharacterCount = CharacterCount + 1; // count the characters
      tempChar = ' ';
    }
    
    else if (HighTime >= round(Character + (1 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (1 * SpeedMicros) + SignalDeviation) && Ping == false) // message opening signal
    {
      CharacterCount = 0;
      PinComReceive = true;
    }

    else if (HighTime >= round(Character + (1 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (1 * SpeedMicros) + SignalDeviation)  && PinComReceive == true && Ping == true) // message block opening signal
    {
      Ping = false; // this ignores the opening signal and blocks the return message from going back and forth
      PinComReceive = false;
    }
    
    else if (HighTime >= round(Character + (2 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (2 * SpeedMicros) + SignalDeviation)  && PinComReceive == true) // message closing signal
    { 
      MessageReceived = true;
      PinComReceive = false;

      delay(1000);
      
      Serial.println();
      Serial.print(F("Here is your message with "));
      Serial.print(StringLength);
      Serial.println(F(" characters in the string:"));
      Serial.println();
      Serial.println(MessageString); // and print them all together
      Serial.println();

      delay(5000);

      IDsender = "";
      IDsender = MessageString.concat(0);
      IDsender = MessageString.concat(1);
      IDsender = MessageString.concat(2);
      IDsender = MessageString.concat(3);
      
      FunctionValuePosition = 0;
      FunctionValuePosition = MessageString.indexOf(SearchFunctionValue); // add Function value or other recognization functionality later
      
      if (FunctionValuePosition >= 0) {
       FunctionValue = "";
       FunctionIncomingValue  = 0;
        
       FunctionFirstDigit = ' ';
       FunctionSecondDigit = ' ';
       FunctionThirdDigit = ' ';
       FunctionFourthDigit = ' ';
       
       FunctionFirstDigit = MessageString.charAt(FunctionValuePosition + 1); // possible add 12 more depending on the reported position
       FunctionSecondDigit = MessageString.charAt(FunctionValuePosition + 2);
       FunctionThirdDigit = MessageString.charAt(FunctionValuePosition + 3);
       FunctionFourthDigit = MessageString.charAt(FunctionValuePosition + 4);
       FunctionValue += FunctionFirstDigit;
       FunctionValue += FunctionSecondDigit;
       FunctionValue += FunctionThirdDigit;
       FunctionValue += FunctionFourthDigit;
       FunctionIncomingValue = FunctionValue.toInt();
       Serial.println();
       Serial.print(F("We picked up a function value stating: "));
       Serial.println(FunctionIncomingValue);
       Serial.println();

       FunctionValue = "";

       FunctionFirstDigit = ' ';
       FunctionSecondDigit = ' ';
       FunctionThirdDigit = ' ';
       FunctionFourthDigit = ' ';

       InitiateFunction = true;

       delay(1000);
       }

       BytePosition = 0;
       BytePosition = MessageString.indexOf(SearchByte); // add Function value or other recognization functionality later
      
      if (BytePosition >= 0) {
       ReceivedByte = 0;

       ByteFirstBit = ' ';
       ByteSecondBit = ' ';
       ByteThirdBit = ' ';
       ByteFourthBit = ' ';
       ByteFifthBit = ' ';
       ByteSixthBit = ' ';
       ByteSeventhBit = ' ';
       ByteEigthBit = ' ';
       
       ByteFirstBit = MessageString.charAt(BytePosition + 1); // possible add 5 more depending on the reported position
       ByteSecondBit = MessageString.charAt(BytePosition + 2);
       ByteThirdBit = MessageString.charAt(BytePosition + 3);
       ByteFourthBit = MessageString.charAt(BytePosition + 4);
       ByteFifthBit = MessageString.charAt(BytePosition + 5);
       ByteSixthBit = MessageString.charAt(BytePosition + 6);
       ByteSeventhBit = MessageString.charAt(BytePosition+ 7);
       ByteEigthBit = MessageString.charAt(BytePosition + 8);

       byte array[8] = {ByteFirstBit,ByteSecondBit,ByteThirdBit,ByteFourthBit,ByteFifthBit,ByteSixthBit,ByteSeventhBit,ByteEigthBit};

       i = 0;

       for (i = 0; i < 8; i++){
       ReceivedByte += (array[i] << (7-i));
       }

       i = 0;
       
       Serial.println();
       Serial.print(F("We picked up a byte with a value of: "));
       Serial.println(ReceivedByte);
       Serial.println();

       ByteSecondBit = ' ';
       ByteThirdBit = ' ';
       ByteFourthBit = ' ';
       ByteFifthBit = ' ';
       ByteSixthBit = ' ';
       ByteSeventhBit = ' ';
       ByteEigthBit = ' ';

       ByteReceived = true;

       delay(1000);
       }

      TimeCodePosition = 0;
      TimeCodePosition = MessageString.indexOf(SearchTimeCode); // retrieve the time-code and thereby the time
      
      if (TimeCodePosition >= 0) {
       TimeCode = "";

       TimeCodeFirstDigit = ' ';
       TImeCodeSecondDigit = ' ';
       TimeCodeThirdDigit = ' ';
       TimeCodeFourthDigit = ' ';
       TimeCodeFifthDigit = ' ';
       TimeCodeSixthDigit = ' ';
       TimeCodeSeventhDigit = ' ';
       TimeCodeEigthDigit = ' ';
       TimeCodeNinthDigit = ' ';
       TimeCodeTenthDigit = ' ';
       TimeCodeEleventhDigit = ' ';
       TimeCodeTwelvethDigit = ' ';
       TimeCodeThirteenthDigit = ' ';
       TimeCodeFourteenthDigit = ' ';

       Year = 0;
       Month = 0;
       Day = 0; 
       Hour = 0; 
       Minute = 0; 
       Second = 0;
        
       YearString = "";
       MonthString  = "";
       DayString  = ""; 
       HourString  = ""; 
       MinuteString  = ""; 
       SecondString  = "";
       
       TimeCodeFirstDigit = MessageString.charAt(TimeCodePosition + 1); // possible add 9 (TIMECODE=) more depending on the reported position
       TImeCodeSecondDigit = MessageString.charAt(TimeCodePosition + 2);
       TimeCodeThirdDigit = MessageString.charAt(TimeCodePosition + 3);
       TimeCodeFourthDigit = MessageString.charAt(TimeCodePosition + 4);
       TimeCodeFifthDigit = MessageString.charAt(TimeCodePosition + 5);
       TimeCodeSixthDigit = MessageString.charAt(TimeCodePosition + 6);
       TimeCodeSeventhDigit = MessageString.charAt(TimeCodePosition + 7);
       TimeCodeEigthDigit = MessageString.charAt(TimeCodePosition + 8);
       TimeCodeNinthDigit = MessageString.charAt(TimeCodePosition + 9);
       TimeCodeTenthDigit = MessageString.charAt(TimeCodePosition + 10);
       TimeCodeEleventhDigit = MessageString.charAt(TimeCodePosition + 11);
       TimeCodeTwelvethDigit = MessageString.charAt(TimeCodePosition + 12);
       TimeCodeThirteenthDigit = MessageString.charAt(TimeCodePosition + 13);
       TimeCodeFourteenthDigit = MessageString.charAt(TimeCodePosition + 14);
       TimeCode += TimeCodeFirstDigit;
       TimeCode += TImeCodeSecondDigit;
       TimeCode += TimeCodeThirdDigit;
       TimeCode += TimeCodeFourthDigit;
       TimeCode += TimeCodeFifthDigit;
       TimeCode += TimeCodeSixthDigit;
       TimeCode += TimeCodeSeventhDigit;
       TimeCode += TimeCodeEigthDigit;
       TimeCode += TimeCodeNinthDigit;
       TimeCode += TimeCodeTenthDigit;
       TimeCode += TimeCodeEleventhDigit;
       TimeCode += TimeCodeTwelvethDigit;
       TimeCode += TimeCodeThirteenthDigit;
       TimeCode += TimeCodeFourteenthDigit;
       YearString.concat(TimeCodeFirstDigit);
       YearString.concat(TImeCodeSecondDigit);
       YearString.concat(TimeCodeThirdDigit);
       YearString.concat(TimeCodeFourthDigit);
       MonthString.concat(TimeCodeFifthDigit);
       MonthString.concat(TimeCodeSixthDigit);
       DayString.concat(TimeCodeSeventhDigit); 
       DayString.concat(TimeCodeEigthDigit); 
       HourString.concat(TimeCodeNinthDigit);
       HourString.concat(TimeCodeTenthDigit); 
       MinuteString.concat(TimeCodeEleventhDigit);
       MinuteString.concat(TimeCodeTwelvethDigit);
       SecondString.concat(TimeCodeThirteenthDigit);
       SecondString.concat(TimeCodeFourteenthDigit);

       Year = YearString.toInt();
       Month = MonthString.toInt();
       Day = DayString.toInt(); 
       Hour = HourString.toInt(); 
       Minute = MinuteString.toInt(); 
       Second = SecondString.toInt();

       setTime(Hour,Minute,Second,Day,Month,Year); 

       Year = 0;
       Month = 0;
       Day = 0; 
       Hour = 0; 
       Minute = 0; 
       Second = 0;
       
       TimeCodeFirstDigit = ' ';
       TImeCodeSecondDigit = ' ';
       TimeCodeThirdDigit = ' ';
       TimeCodeFourthDigit = ' ';
       TimeCodeFifthDigit = ' ';
       TimeCodeSixthDigit = ' ';
       TimeCodeSeventhDigit = ' ';
       TimeCodeEigthDigit = ' ';
       TimeCodeNinthDigit = ' ';
       TimeCodeTenthDigit = ' ';
       TimeCodeEleventhDigit = ' ';
       TimeCodeTwelvethDigit = ' ';
       TimeCodeThirteenthDigit = ' ';
       TimeCodeFourteenthDigit = ' ';
        
       YearString = "";
       MonthString  = "";
       DayString  = ""; 
       HourString  = ""; 
       MinuteString  = ""; 
       SecondString  = "";
      
       Serial.println();
       Serial.print(F("The following time-code was received: "));
       Serial.println(TimeCode);
       Serial.print(F("Which makes the new time and date: "));
       Serial.print(hour());
       Serial.print(F(":"));
       Serial.print(minute());
       Serial.print(F(":"));
       Serial.print(second());
       Serial.print(F(" on the "));
       Serial.print(day());
       Serial.print(F(" day in monthnumber "));
       Serial.print(month());
       Serial.print(F(" of the year "));
       Serial.println(year());
       Serial.println();

       TimeCodeReceived = true;

       TimeCode = "";

       delay(1000);
       }
      
      Serial.println();
      Serial.println(F("Waiting to send or receive a new message..."));
      Serial.println();

      Serial.flush();

      delay(1000);

      CharacterCount = 0;

      ++MessagesReceived;

      NoteMillis = millis();

      MessageString = "";

      Ping = false;
    }
    
    else if (HighTime >= round(Character + (3 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (3 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '0';
    }
    else if (HighTime >= round(Character + (4 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (4 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '1';
    }
    else if (HighTime >= round(Character + (5 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (5 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '2';
    }
    else if (HighTime >= round(Character + (6 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (6 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '3';
    }
    else if (HighTime >= round(Character + (7 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (7 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '4';
    }
    else if (HighTime >= round(Character + (8 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (8 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '5';
    }
    else if (HighTime >= round(Character + (9 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (9 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '6';
    }
    else if (HighTime >= round(Character + (10 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (10 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '7';
    }
    else if (HighTime >= round(Character + (11 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (11 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '8';
    }
    else if (HighTime >= round(Character + (12 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (12 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '9';
    }
    else if (HighTime >= round(Character + (13 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (13 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '-';
    }
    else if (HighTime >= round(Character + (14 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (14 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '.';
    }
    else if (HighTime >= round(Character + (15 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (15 * SpeedMicros) + SignalDeviation))
    {
      tempChar = ' ';
    }
    else if (HighTime >= round(Character + (16 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (16 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '?';
    }
    else if (HighTime >= round(Character + (17 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (17 * SpeedMicros) + SignalDeviation))
    {
      tempChar = '=';
    }
    else if (HighTime >= round(Character + (18 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (18 * SpeedMicros) + SignalDeviation))
    {
      tempChar = ':';
    }
    else if (HighTime >= round(Character + (19 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (19 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'A';
    }
    else if (HighTime >= round(Character + (20 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (20 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'B';
    }
    else if (HighTime >= round(Character + (21 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (21 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'C';
    }
    else if (HighTime >= round(Character + (22 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (22 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'D';
    }
    else if (HighTime >= round(Character + (23 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (23 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'E';
    }
    else if (HighTime >= round(Character + (24 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (24 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'F';
    }
    else if (HighTime >= round(Character + (25 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (25 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'G';
    }
    else if (HighTime >= round(Character + (26 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (26 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'H';
    }
    else if (HighTime >= round(Character + (27 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (27 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'I';
    }
    else if (HighTime >= round(Character + (28 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (28 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'J'; 
    }
    else if (HighTime >= round(Character + (29 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (29 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'K';
    }
    else if (HighTime >= round(Character + (30 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (30 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'L';
    }
    else if (HighTime >= round(Character + (31 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (31 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'M';
    }
    else if (HighTime >= round(Character + (32 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (32 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'N';
    }
    else if (HighTime >= round(Character + (33 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (33 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'O';
    }
    else if (HighTime >= round(Character + (34 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (34 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'P';
    }
    else if (HighTime >= round(Character + (35 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (35 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'Q';
    }
    else if (HighTime >= round(Character + (36 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (36 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'R';
    }
    else if (HighTime >= round(Character + (37 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (37 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'S';
    }
    else if (HighTime >= round(Character + (38 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (38 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'T';
    }
    else if (HighTime >= round(Character + (39 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (39 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'U';
    }
    else if (HighTime >= round(Character + (40 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (40 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'V';
    }
    else if (HighTime >= round(Character + (41 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (41 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'W';
    }
    else if (HighTime >= round(Character + (42 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (42 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'X';
    }
    else if (HighTime >= round(Character + (43 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (43 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'Y';
    }
    else if (HighTime >= round(Character + (44 * SpeedMicros) - SignalDeviation) && HighTime <= round(Character + (44 * SpeedMicros) + SignalDeviation))
    {
      tempChar = 'Z';
    }
    
    else if (HighTime > (Character + (44 * SpeedMicros) + SignalDeviation)) // unknown signal
    {
     tempChar = ' ';
     goto EscapeInput;

     Serial.println();
     Serial.println(F("Reception error: signals too long..."));
     Serial.println();
     
     PinComReceive = false;
    }
   
   HighTime = 0;
     
 }


// confirm the message reception
if (MessageReceived == true && Ping == false && PinComSend == false && PinComReceive == false) {

   if (TimeCodeReceived == true && InitiateFunction == true && ByteReceived == true){
   MessageString = " WE HAVE RECEIVED YOUR MESSAGE CONTAINING A TIME-CODE, FUNCTION VALUE AND BYTE, WOW THAT ARE ALOT OF INPUTS JUST THERE!";
   MessageString = IDsender + MessageString;
   MessageString = ID + IDadded + MessageString;
   }

   if (TimeCodeReceived == true && InitiateFunction == true){
   MessageString = " WE HAVE RECEIVED YOUR MESSAGE CONTAINING A TIME-CODE AND FUNCTION VALUE, TIMELY FUNCTIONS... IS THAT NOT GREAT!";
   MessageString = IDsender + MessageString;
   MessageString = ID + IDadded + MessageString;
   }

   if (TimeCodeReceived == true && ByteReceived == true){
   MessageString = " WE HAVE RECEIVED YOUR MESSAGE CONTAINING A TIME-CODE AND BYTE, ROGER THAT MY FRIEND!";
   MessageString = IDsender + MessageString;
   MessageString = ID + IDadded + MessageString;
   }

   if (InitiateFunction == true && ByteReceived == true){
   MessageString = " WE HAVE RECEIVED YOUR MESSAGE CONTAINING A FUNCTION VALUE AND BYTE, ALL AT THE SAME TIME!";
   MessageString = IDsender + MessageString;
   MessageString = ID + IDadded + MessageString;
   }

   if (InitiateFunction == true){
   MessageString = " WE HAVE RECEIVED YOUR MESSAGE CONTAINING A FUNCTION VALUE, WE MIGHT INITIATE THAT!";
   MessageString = IDsender + MessageString;
   MessageString = ID + IDadded + MessageString;  
   }

   if (ByteReceived == true){
   MessageString = " WE HAVE RECEIVED YOUR MESSAGE CONTAINING A BYTE, LET US SEE WHAT IT DOES!";
   MessageString = IDsender + MessageString;
   MessageString = ID + IDadded + MessageString;  
   }
    
   if (TimeCodeReceived == true){
   MessageString = " WE HAVE RECEIVED YOUR MESSAGE CONTAINING A TIME-CODE, RIGHT ON TIME!";
   MessageString = IDsender + MessageString;
   MessageString = ID + IDadded + MessageString;   
   }
   
   else {
   MessageString = " WE HAVE RECEIVED YOUR TEXT MESSAGE!";
   MessageString = IDsender + MessageString;
   MessageString = ID + IDadded + MessageString;
   }

   MessageReceived = false;

   Ping = true;

   goto DigitalInput;
   }
       
    
EscapeInput:

while (Serial.available() == 0 && PinComSend == false && PinComReceive == false) {}
   if (Serial.available() >= 1 && PinComSend == false && PinComReceive == false) {
   MessageString = Serial.readString();
   
   Serial.flush();

   delay(1000);

   if (MessageString == "f") {
   MessageString = "";
   Millis = millis();
   Serial.println();
   Serial.println(F("Please input a four digit function value to initiate the function: "));
   Serial.println();
   delay(1000);
     
      ReInputFunction:
      while (Serial.available() == 0) {
      if (millis() - Millis >= 20000) {
      delay(1000);
      Serial.println();
      Serial.println(F("20 seconds timed-out... No function value was received..."));
      Serial.println();
      pinMode (PinCom, INPUT);
      delay(1000);
      goto EscapeInput;
      }}
      
      if (Serial.available() >= 1) {
      FunctionValue = Serial.readString();
      FunctionIncomingValue = FunctionValue.toInt();
      if (FunctionIncomingValue <= 0 || FunctionIncomingValue >= 9999) {
      Serial.println();
      Serial.println(F("Input a four digit value from 0001 to 9999, please try again:"));
      Serial.println();
      Serial.flush();
      delay(1000);
      Millis = millis();
      goto ReInputFunction;
      }
      delay(1000);
      Serial.println();
      Serial.print(F("Function: "));
      Serial.print(FunctionIncomingValue);
      Serial.println(F(", initiated..."));
      Serial.println();
      delay(1000);
      AutoInitiateFunction: // entrypoint for automatic trigger
      MessageString = "FUNCTIONVALUE=";
      MessageString = MessageString + FunctionValue;
      MessageString = ID + IDadded + MessageString;
      InitiateFunction = true;
      goto DigitalInput;
      }
   
   }

   if (MessageString == "t") {
   MessageString = "";
   Millis = millis();
   Serial.println();
   Serial.println(F("Please input the time-code (YYYYMMDDHHMMSS):"));
   Serial.println();
   delay(1000);

   ReInputTime:
   while (Serial.available() == 0) {
    if (millis() - Millis >= 20000) {
    delay(1000);
    Serial.println();
    Serial.println(F("20 seconds timed-out... The time was not set..."));
    Serial.println();
    pinMode (PinCom, INPUT);
    delay(1000);
    goto EscapeInput;
    }}
      
      if (Serial.available() == 14) {
      TimeCode = Serial.readString();
      delay(1000);
      TimeCodeFirstDigit = TimeCode.charAt(0); // read the chars
      TImeCodeSecondDigit = TimeCode.charAt(1);
      TimeCodeThirdDigit = TimeCode.charAt(2);
      TimeCodeFourthDigit = TimeCode.charAt(3);
      TimeCodeFifthDigit = TimeCode.charAt(4);
      TimeCodeSixthDigit = TimeCode.charAt(5);
      TimeCodeSeventhDigit = TimeCode.charAt(6);
      TimeCodeEigthDigit = TimeCode.charAt(7);
      TimeCodeNinthDigit = TimeCode.charAt(8);
      TimeCodeTenthDigit = TimeCode.charAt(9);
      TimeCodeEleventhDigit = TimeCode.charAt(10);
      TimeCodeTwelvethDigit = TimeCode.charAt(11);
      TimeCodeThirteenthDigit = TimeCode.charAt(12);
      TimeCodeFourteenthDigit = TimeCode.charAt(13);

      YearString.concat(TimeCodeFirstDigit);
      YearString.concat(TImeCodeSecondDigit);
      YearString.concat(TimeCodeThirdDigit);
      YearString.concat(TimeCodeFourthDigit);
      MonthString.concat(TimeCodeFifthDigit);
      MonthString.concat(TimeCodeSixthDigit);
      DayString.concat(TimeCodeSeventhDigit); 
      DayString.concat(TimeCodeEigthDigit); 
      HourString.concat(TimeCodeNinthDigit);
      HourString.concat(TimeCodeTenthDigit); 
      MinuteString.concat(TimeCodeEleventhDigit);
      MinuteString.concat(TimeCodeTwelvethDigit);
      SecondString.concat(TimeCodeThirteenthDigit);
      SecondString.concat(TimeCodeFourteenthDigit);

      Year = YearString.toInt();
      Month = MonthString.toInt();
      Day = DayString.toInt(); 
      Hour = HourString.toInt(); 
      Minute = MinuteString.toInt(); 
      Second = SecondString.toInt();
       
      TimeCodeFirstDigit = ' ';
      TImeCodeSecondDigit = ' ';
      TimeCodeThirdDigit = ' ';
      TimeCodeFourthDigit = ' ';
      TimeCodeFifthDigit = ' ';
      TimeCodeSixthDigit = ' ';
      TimeCodeSeventhDigit = ' ';
      TimeCodeEigthDigit = ' ';
      TimeCodeNinthDigit = ' ';
      TimeCodeTenthDigit = ' ';
      TimeCodeEleventhDigit = ' ';
      TimeCodeTwelvethDigit = ' ';
      TimeCodeThirteenthDigit = ' ';
      TimeCodeFourteenthDigit = ' ';
        
      YearString = "";
      MonthString  = "";
      DayString  = ""; 
      HourString  = ""; 
      MinuteString  = ""; 
      SecondString  = "";
      
      setTime(Hour,Minute,Second,Day,Month,Year); 

      Year = 0;
      Month = 0;
      Day = 0; 
      Hour = 0; 
      Minute = 0; 
      Second = 0;

      delay(1000);
      
      Serial.println();
      Serial.print(F("The following time-code was received: "));
      Serial.println(TimeCode);
      Serial.print(F("Which makes the new time and date: "));
      Serial.print(hour());
      Serial.print(F(":"));
      Serial.print(minute());
      Serial.print(F(":"));
      Serial.print(second());
      Serial.print(F(" on "));
      Serial.print(day());
      Serial.print(F(" in monthnumber "));
      Serial.print(month());
      Serial.print(F(" of the year "));
      Serial.println(year());
      Serial.println();

      delay(1000);

      AutoInitiateTime: // entrypoint for automatic trigger
      MessageString = "TIMECODE=";
      MessageString = MessageString + TimeCode;
      MessageString = ID + IDadded + MessageString;
      TimeCode = "";

      delay(1000);
      goto DigitalInput;
      }
      
      if (Serial.available() <= 13 || Serial.available() >= 15) {
      Serial.println();
      Serial.println(F("Input a fourteen digit value for the time-code , please try again:"));
      Serial.println();
      pinMode (PinCom, INPUT);
      delay(1000);
      Millis = millis();
      goto ReInputTime;
      }
      
   }

   delay(1000);
   
   MessageString = ID + IDadded + MessageString;

   DigitalInput:

   PinComSend = true;

   pinMode(PinCom, OUTPUT);

   StringLength = 0;
   CharacterCount = 0;
   CharacterPosition = 0;

   StringLength = MessageString.length() + 1;

   CharacterPosition = 0;
   tempChar = MessageString.charAt(CharacterPosition);
  
   if (StringLength >= 800) {
    Serial.println();
    Serial.println(F("Your message contained more than 800 Characters, this is not allowed. Please try again. You tried the following message:"));
    Serial.println(MessageString);
    Serial.println();
    delay(1000);
    goto EscapeInput;
    }

   digitalWrite(PinCom, HIGH); // pre-pulse the pin
   delayMicroseconds(SpeedMicros);
   digitalWrite(PinCom, LOW);
   delayMicroseconds(SpeedMicros);
   digitalWrite(PinCom, HIGH); // send the opening signal
   delayMicroseconds(Character + (1 * SpeedMicros));
   digitalWrite(PinCom, LOW);
   delayMicroseconds(Character);

   ReadChars:

    if (tempChar == '0') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (3 * SpeedMicros)); // set these values to change the speed of the connection, decreasing the signal width will improve connection speed but reliability might lack depending on the microprocessor
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character); // the LOW time is not detected but one could change the code to detcct a LOW using the PinMode PULLUP funcion ofr PinCom
      
      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters send
      }
    else if (tempChar == '1') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (4 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '2') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (5 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '3') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (6 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '4') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (7 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '5') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (8 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '6') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (9 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '7') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (10 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '8') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (11 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '9') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (12 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '-') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (13 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '.') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (14 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == ' ') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (15 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '?') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (16 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == '=') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (17 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == ':') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (18 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'A') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (19 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'B') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (20 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'C') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (21 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'D') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (22 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'E') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (23 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'F') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (24 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'G') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (25 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'H') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (26 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'I') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (27 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'J') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (28 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'K') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (29 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'L') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (30 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'M') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (31 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'N') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (32 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'O') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (33 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'P') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (34 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'Q') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (35 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'R') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (36 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'S') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (37 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'T') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (38 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'U') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (39 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'V') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (40 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'W') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (41 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'X') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (42 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }
    else if (tempChar == 'Y') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (43 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }

    else if (tempChar == 'Z') {
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (44 * SpeedMicros));
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }

     else { // used when the character a not recognized
      digitalWrite(PinCom,  HIGH);
      delayMicroseconds(Character + (15 * SpeedMicros)); // sends an empty space
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);

      digitalWrite(PinCom,  HIGH); // send the character end signal
      delayMicroseconds(Character);
      digitalWrite(PinCom,  LOW);
      delayMicroseconds(Character);
  
      CharacterCount = CharacterCount + 1; // count the characters
      }  

    if (CharacterPosition <= StringLength) {
    ++CharacterPosition;
    tempChar = MessageString.charAt(CharacterPosition);
    // delayMicroseconds(CharacterDelay); // check if required
    goto ReadChars;
    }

    if (CharacterPosition > StringLength) {
    digitalWrite(PinCom,  HIGH); // send the messsage end signal
    delayMicroseconds(Character + (2 * SpeedMicros));
    digitalWrite(PinCom,  LOW);
    delayMicroseconds(Character);
    
    Serial.println();
    Serial.print(F("The following message was sent containing "));
    Serial.print(StringLength);
    Serial.println(F(" characters:"));
    Serial.println(MessageString);
    Serial.println();

    delay(1000);

    tempChar = ' ';
    CharacterCount = 0;
    CharacterPosition = 0;
    StringLength = 0;
    MessageString = "";

    ++MessagesSent;
    
    digitalWrite(PinCom,  LOW);
    pinMode(PinCom, INPUT);
    
    PinComSend = false;
    
    NoteMillis = millis();
    
    Serial.flush();
    
    delay(1000);
    }
   
 }

// marks 60 seconds of inactivity
if (millis() - NoteMillis >= 60000 && PinComSend == false && PinComReceive == false) {
    Serial.println();
    Serial.println(F("No message activity for 60 seconds..."));
    Serial.print(F("The program has been running for "));
    Serial.print(ProgramMillis/1000);
    Serial.print(F(" seconds. With "));
    Serial.print(MessagesSent);
    Serial.print(F(" messages sent and "));
    Serial.print(MessagesReceived);
    Serial.println(F(" received."));
    Serial.println();
    Serial.flush();
    delay(1000);
    NoteMillis = millis();
    }

// used for several example program features based on the detected function value, the numbers chosen are totally random, 9999 options here...
if (FunctionIncomingValue >= 0001 && FunctionIncomingValue <= 5000 && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   VoltageReceived = FunctionIncomingValue;  // converts the voltage to mV
   Serial.println();
   Serial.print(F("The voltage from the sender with device ID: "));
   Serial.print(IDsender);
   Serial.print(F(" reads"));
   Serial.print(VoltageReceived);
   Serial.println(F(" mV"));
   Serial.println();
   FunctionIncomingValue = 0;
   InitiateFunction = false;
   delayMicroseconds(1000);
   }

// set the Frequency in kHz
if (FunctionIncomingValue >= 6001 && FunctionIncomingValue <= 6999 && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   PWM = true;
   digitalWrite(PinPulse, LOW);
   PWMState = LOW;
   Frequency = (FunctionIncomingValue - 6000) * 1000;
   InitiateFunction = false;
   Serial.println();
   Serial.print(F("The PWM initiated with the frequency set to: "));
   Serial.print(Frequency);
   Serial.println(F("Hz"));
   Serial.println();
   FunctionIncomingValue = 0;
   delayMicroseconds(1000);
   MicrosPrevious = micros();
   }

// set the DutyCycle
if (FunctionIncomingValue >= 7001 && FunctionIncomingValue <= 7100 && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   PWM = true;
   digitalWrite(PinPulse, LOW);
   PWMState = LOW;
   DutyCycle = FunctionIncomingValue - 7000;
   InitiateFunction = false;
   Serial.println();
   Serial.print(F("The PWM initiated with the duty-cycle set to: "));
   Serial.print(DutyCycle);
   Serial.println(F("%"));
   Serial.println();
   FunctionIncomingValue = 0;
   delayMicroseconds(1000);
   MicrosPrevious = micros();
   }

// start the PWM
if (FunctionIncomingValue == 7101 && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   PWM = true;
   digitalWrite(PinPulse, LOW);
   PWMState = LOW;
   InitiateFunction = false;
   Serial.println();
   Serial.print(F("PWM engaged at "));
   Serial.print(Frequency);
   Serial.print(F("Hz with a "));
   Serial.print(DutyCycle);
   Serial.print(F("% duty-cycle with a low-time of "));
   Serial.print(Low);
   Serial.print(F(" microseconds and a high-time of "));
   Serial.print(High);
   Serial.println(F(" microseconds."));
   Serial.println();
   FunctionIncomingValue = 0;
   delayMicroseconds(1000);
   MicrosPrevious = micros();
   }

// stop the PWM
if (FunctionIncomingValue == 7102 && PWM == true && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   PWM = false;
   PWMState = LOW;
   InitiateFunction = false;
   Serial.println();
   Serial.println(F("PWM disengaged..."));
   Serial.println();
   FunctionIncomingValue = 0;
   delayMicroseconds(1000);
   MicrosPrevious = 0;
   }

// read and report the analog voltage
if (FunctionIncomingValue == 7103 && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   AnalogRead = analogRead(PinVoltage);
   Voltage = (AnalogRead + 0.5) * (DeviceVoltage / 1024); // in mV // possibly use a float here and convert it back to int or remove the 0.5 for slightly less accuracy

   VoltageRead = String(Voltage);

   MessageString = "FUNCTIONVALUE=";
   MessageString = MessageString + VoltageRead;
   MessageString = ID + IDadded + MessageString;

   InitiateFunction = false;

   Serial.println();
   Serial.print(F("The voltage reads: "));
   Serial.print(Voltage);
   Serial.println(F("mV"));
   Serial.println();

   InitiateFunction = false;

   VoltageRead = "";
   
   FunctionIncomingValue = 0;
   delayMicroseconds(1000);
   goto DigitalInput;
   }

// start communication forwarding on the forwarding pin
if (FunctionIncomingValue == 7104 && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   DeviceVoltage = 3300;
   InitiateFunction = false;
   Serial.println();
   Serial.println(F("Device operating voltage set to 3.3V..."));
   Serial.println();
   FunctionIncomingValue = 0;
   delay(1000);
   }
   
// stop communication forwarding on the forwarding pin
if (FunctionIncomingValue == 7105 && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   DeviceVoltage = 5000;
   InitiateFunction = false;
   Serial.println();
   Serial.println(F("Device operating voltage set to 5V..."));
   Serial.println();
   FunctionIncomingValue = 0;
   delay(1000);
   }

// start communication forwarding on the forwarding pin
if (FunctionIncomingValue == 7106 && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   Forward = true;
   InitiateFunction = false;
   Serial.println();
   Serial.println(F("Forwarding enabled..."));
   Serial.println();
   FunctionIncomingValue = 0;
   delay(1000);
   }
   
// stop communication forwarding on the forwarding pin
if (FunctionIncomingValue == 7107 && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   Forward = false;
   InitiateFunction = false;
   Serial.println();
   Serial.println(F("Forwarding disabled..."));
   Serial.println();
   FunctionIncomingValue = 0;
   delay(1000);
   }

// process the incoming byte
if (ReceivedByte == 1 && ByteReceived == true && PinComSend == false && PinComReceive == false && Ping == false) {
   // add forwarding to sensor or otherwise
   ByteReceived = false;
   }

// update the signal speed
if (FunctionIncomingValue >= 8001 && FunctionIncomingValue <= 9000 && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   SpeedMicros = FunctionIncomingValue - 8000;

   InitiateFunction = false;

   Serial.println();
   Serial.print(F("The new maximum signal speed was set to: "));
   Serial.print(SpeedMicros);
   Serial.println(F(" microseconds."));
   Serial.println();

   InitiateFunction = false;
   
   FunctionIncomingValue = 0;
   delayMicroseconds(1000);
   }

// update the signal speed
if (FunctionIncomingValue == 9001 && InitiateFunction == true && PinComSend == false && PinComReceive == false && Ping == false) {
   Serial.println();
   Serial.print(F("The amount of received meesages is "));
   Serial.print(MessagesReceived);
   Serial.print(F(" and we sent"));
   Serial.print(MessagesSent);
   Serial.println(F(" messages"));
   Serial.println();

   InitiateFunction = false;
   
   FunctionIncomingValue = 0;
   delayMicroseconds(1000);
   }

}

Currently there is some logical problem inside the loop because the elapsed time in millis is not being picked up. Likely because of this communication pin reception and PWM are still not working, I think it hangs on something but I can not seem to find on what, basically the same problem as I asked in the topic opening.

The forum code tag feature makes long code posts readable by constricting them to a fixed sized window. That is not a worry.

It's easier to read the thread if the posts are presented in chronological order. Going back and changing things, doesn't take into account the replies.

True, what I really was trying to say is that keeping track of all the code variations becomes a bit more difficult. The readability is fine.

I really don't see how that is possible. Any code variations that you post in consecutive messages appear in chronological order. That isn't hard to keep track of. The most serious problem with not doing it, the replies become nonsensical because they refer to code that isn't posted, or has been modified. That destroys the continuity and meaning of the replies, which tarnishes the entire time line of the thread.

The most important "variation" is the most up to date, which can be easily found by looking at the latest posted code. It is the norm here, so it's what people expect.

The main importance of variations that are not the latest one, are in relation to the replies. It should be self evident why those are important.

Agreed. Let us get back on topic.

You have quite a big raft of issues/questions, so what is the topic? The original one was answered in reply #5.

Your reply #14 is somewhat general and laced with implementation details that aren't sufficiently obvious or explained. So that one isn't enough to understand your needs.

The last paragraph starts to take the reader there, but doesn't indicate specific code elements or actions that would help understand the issues. Examples are often useful. Can you provide one?

For example, you say that the time value is not being "picked up". That has no technical meaning and we are left wondering what is doing the "picking up".

You are right, the code is a bit of stretch so I should provide some pointers.

I have a simple routine that measures inactivity at:

// marks 60 seconds of inactivity

This does not work and I am not sure why. I would appreciate it if you could focus on:

// monitor the communication pin
if (PinComSend == false) {
   PinComState = digitalRead(PinCom);
   if (PinComState == HIGH && ReadHigh == false && PinComSend == false) {
   HighTime = micros();
   ReadHigh = true;
   digitalWrite(PinLED, HIGH);
   }
   }

// alternative option
//PinPulseTimeOut = Character + (44 * SpeedMicros) + (SignalDeviation + 1); // calculates the time-out
//HighTime = pulseIn(PinCom, HIGH, PinPulseTimeOut);

// drive the PWM
if (PWM == true) {
   if (PWMState == LOW && (micros() - MicrosPrevious) > Low) {
      PWMState = HIGH;
      digitalWrite(PinPulse, PWMState);
      MicrosPrevious = micros();
      }
   if (PWMState == HIGH && (micros() - MicrosPrevious) > High) {
      PWMState = LOW;
      digitalWrite(PinPulse, PWMState);
      MicrosPrevious = micros();
      }
   }

if (PWM == false) {
   PWMState = LOW;
   digitalWrite(PinPulse, PWMState);
   MicrosPrevious = 0;
   }

This holds most of the important pin activity. And it is the most likely place were the problem resides. It might be due to some missing boolean logic. The sending side and initiation of the FunctionIncomingValue all work. Thanks.