Float variable handling in char array routine

Hi all

I'm building a remote system for my garden lights and wireless camera. The system consists of two parts: A small hand transmitter (Arduino Nano Every) and a box (Arduino Uno SMD) that will be placed outside. I programmed all the remote switching functions and the display functions. The code has a wireless feedback function, so I get to see on the display, whether the lights or the camera are on or off.

Now I'd like to add a function which sends the battery voltage in the same 1minute intervall. The analog reading an converting is no problem. But the handling in the char array read processing is an other thing. I guess I'd have to first compare the part of the char string ("Voltage") as a condition, then substracting this char string and finally printing the part with the float variable.

Here's the code of the transmitter:

#include <SoftwareSerial.h>
#include <U8g2lib.h>
#include <Arduino.h>
#include <SPI.h>
#include <Wire.h>


U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /*data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 4);

SoftwareSerial HC12(2, 3); // RX | TX
int button1 = 6;
int button2 = 7;
int button3 = 8;
int buttonState1 = LOW;
int buttonState2 = LOW;
int buttonState3 = LOW;
char command1[] = "ActivateTimer1!";
char command2[] = "StopTimer1!";
char command3[] = "ToggleRelais3!";
char keyWord4[] = "VideoLinkON";
char keyWord5[] = "VideoLinkOFF";
char keyWord6[] = "LightsON";
char keyWord7[] = "LightsOFF";
const byte numChars = 32;
char messageReceived[numChars];
char VideoLinkStatus[] = "OFF";
char LightsStatus[] = "OFF";
float BattVoltage;


void draw(){
  u8g2.setFont(u8g_font_profont12);
  u8g2.drawStr(0, 12, "VIDEO LINK:");
  u8g2.drawStr(0, 36, "GARDEN LIGHTS:");
  u8g2.drawStr(0, 60, "BATTERY:");
  u8g2.setCursor(90,12);
  u8g2.println(VideoLinkStatus);
  u8g2.setCursor(90,36);
  u8g2.println(LightsStatus);
  u8g2.setCursor(90,60);
  u8g2.println(BattVoltage);
  delay(10);
}

void setup() {
  pinMode(button1, INPUT);
  pinMode (button2, INPUT);
  pinMode (button3, INPUT);
  Serial.begin(9600);
  HC12.begin(9600);
  u8g2.begin();


}

void loop() {

  buttonState1 = digitalRead(button1);
  buttonState2 = digitalRead(button2);
  buttonState3 = digitalRead(button3);
  static byte ndx = 0;
  char charReceived;
  char endMarker1 = '!';
  char endMarker2 = '\r';


  if (buttonState1 == HIGH) {
    HC12.print(command1);
  }
  else if (buttonState2 == HIGH) {
    HC12.print(command2);
  }

  else if (buttonState3 == HIGH) {
    HC12.print(command3);
  }


  while (HC12.available() > 0) {
    charReceived = HC12.read();
    if (charReceived != endMarker1 && charReceived != endMarker2) {
      messageReceived[ndx] = charReceived;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else {
      messageReceived[ndx] = '\0';
      ndx = 0;
      
      delay(100);
      
      
      while (HC12.available() > 0) HC12.read(); //                 Read incoming
      if(strcmp(messageReceived, keyWord4) == 0) {
      strncpy( VideoLinkStatus, "ON", sizeof(VideoLinkStatus) );
      VideoLinkStatus[sizeof(VideoLinkStatus)-1] = 0;
      delay(100);
      
      }
      else if(strcmp(messageReceived, keyWord5) == 0) {
      strncpy( VideoLinkStatus, "OFF", sizeof(VideoLinkStatus) );
      VideoLinkStatus[sizeof(VideoLinkStatus)-1] = 0;
      delay(100);
      }

      else if(strcmp(messageReceived, keyWord6) == 0) {
      strncpy( LightsStatus, "ON", sizeof(LightsStatus) );
      LightsStatus[sizeof(LightsStatus)-1] = 0;
      delay(100);
      }

      else if(strcmp(messageReceived, keyWord7) == 0) {
      strncpy( LightsStatus, "OFF", sizeof(LightsStatus) );
      LightsStatus[sizeof(LightsStatus)-1] = 0;
      delay(100);
      }
    }
}
    u8g2.firstPage();  
  do 
    {
     draw();      
    }
  while( u8g2.nextPage() );
  delay(50);
  
  
  }

And the code for the box outside:

#include <SoftwareSerial.h>

int Relais1 = 12;
int Relais2 = 13;
int Relais3 =  8;
int LightsState = 11;
int VideoLinkState = 9;
float BatteryVoltage;
float BatteryValue;
float VoltagePrint;

const byte numChars = 32;
char messageReceived[numChars];
char keyWord1[] = "ActivateTimer1";
char keyWord2[] = "StopTimer1";
char keyWord3[] = "ToggleRelais3";
char command1[] = "VideoLinkON!";
char command2[] = "VideoLinkOFF!";
char command3[] = "LightsON!";
char command4[] = "LightsOFF!";
unsigned long last = millis(); //set timer
const unsigned long INTERVAL = 1000L*60*1; // Intervall 1 Min.
unsigned long lastRun = 0 - INTERVAL; // 

int StateOfLights;
int StateOfVideoLink;

SoftwareSerial HC12(2, 3);



void setup() {
  HC12.begin(9600);
  Serial.begin(9600); // set up Serial library at 9600 bps - this is the speed the serial interface will work all
  pinMode (Relais1, OUTPUT);
  pinMode (Relais2, OUTPUT);
  pinMode (Relais3, OUTPUT);
  pinMode (LightsState, INPUT);
  pinMode (VideoLinkState, INPUT);
}

void loop() {

  boolean Relais3state = digitalRead(Relais3); //check if Relais3 ist on or off. Returns 1 or 0
  static byte ndx = 0;
  char charReceived;
  char endMarker = '!';

  while (HC12.available() > 0) {
    charReceived = HC12.read();
    if (charReceived != endMarker) {
      messageReceived[ndx] = charReceived;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else {
      messageReceived[ndx] = '\0';
      ndx = 0;
      delay(100);
      
      while (HC12.available() > 0) HC12.read();
      if(strcmp(messageReceived, keyWord1) == 0) {
      digitalWrite(Relais1, HIGH);
      delay(100);
      digitalWrite(Relais1, LOW);
      }
      else if(strcmp(messageReceived, keyWord2) == 0) {
      digitalWrite(Relais2, HIGH);
      delay(100);
      digitalWrite(Relais2, LOW);
      }  
      else if(millis() - last > 250){
        if(Relais3state == 0 && (strcmp(messageReceived, keyWord3) == 0)){
        digitalWrite(Relais3, HIGH);
      }
      else if(Relais3state == 1 && (strcmp(messageReceived, keyWord3) == 0)){
          digitalWrite(Relais3, LOW); 
        }
      }
      
      last = millis();
    }
  }



  
if (millis() - lastRun >= INTERVAL) {

      StateOfLights = digitalRead(LightsState);
      StateOfVideoLink = digitalRead(VideoLinkState);
      Serial.print(StateOfVideoLink);
      BatteryValue = analogRead(BatteryVoltage);  //reading Voltage of Battery
      VoltagePrint = ((BatteryValue * 5.0) / 1024.0) * 3; //converting Voltage according to Resistor Divider
      //HC12.print("Voltage");
      //HC12.print(VoltagePrint); // send Voltage over RF
      

      if(StateOfLights == HIGH) {
      HC12.print(command3);
      delay(500);
      }
      
      else if(StateOfLights == LOW) {
      HC12.print(command4);
      delay(500);
      }
      
      if(StateOfVideoLink == HIGH) {
      HC12.print(command1);
      delay(500);
      }
      
      else if(StateOfVideoLink == LOW) {
      HC12.print(command2);
      }

      
  lastRun += INTERVAL;
  }
}

Any help is very much appreciated!

It would be easier to send commands and sensor data via binary packets instead of using char arrays. Might even be best to use a struct.

For example, you could have the following:

struct STRUCT {
  bool toggleTimer1;
  bool toggleRelais3;
  bool toggleVideoLink;
  bool toggleLights;
  bool dispVoltage;
} commandStruct;

You could then transfer the struct using a library like SerialTransfer.h (installable via the Arduino IDE's Libraries Manager):

TX Code:

#include "SerialTransfer.h"
#include <SoftwareSerial.h>


SoftwareSerial HC12(2, 3);
SerialTransfer myTransfer;

struct STRUCT {
  bool toggleTimer1;
  bool toggleRelais3;
  bool toggleVideoLink;
  bool toggleLights;
  bool dispVoltage;
} commandStruct;


void setup()
{
  Serial.begin(9600);
  HC12.begin(9600);
  myTransfer.begin(HC12);

  commandStruct.toggleTimer1 = true;
  commandStruct.toggleRelais3 = false;
  commandStruct.toggleVideoLink = true;
  commandStruct.toggleLights = false;
  commandStruct.dispVoltage = true;
}


void loop()
{
  myTransfer.txObj(commandStruct, sizeof(commandStruct));
  myTransfer.sendData(sizeof(commandStruct));
  delay(100);
}

RX Code:

#include "SerialTransfer.h"
#include <SoftwareSerial.h>


SoftwareSerial HC12(2, 3);
SerialTransfer myTransfer;

struct STRUCT {
  bool toggleTimer1;
  bool toggleRelais3;
  bool toggleVideoLink;
  bool toggleLights;
  bool dispVoltage;
} commandStruct;


void setup()
{
  Serial.begin(9600);
  HC12.begin(9600);
  myTransfer.begin(HC12);
}


void loop()
{
  if(myTransfer.available())
  {
    myTransfer.rxObj(commandStruct, sizeof(commandStruct));
    Serial.print(commandStruct.toggleTimer1);
    Serial.print(' ');
    Serial.print(commandStruct.toggleRelais3);
    Serial.print(' ');
    Serial.print(commandStruct.toggleVideoLink);
    Serial.print(' ');
    Serial.print(commandStruct.toggleLights);
    Serial.print(' ');
    Serial.println(commandStruct.dispVoltage);
  }
  else if(myTransfer.status < 0)
  {
    Serial.print("ERROR: ");
    Serial.println(myTransfer.status);
  }
}

You'll have to fill in the rest of your code, but the above gives you an easy to use, scalable framework to build your project's features off of.

Your code is not set up to receive keywords + parameters like "Voltage: xx.xx" You will have to modify your receiver code to check if the beginning of the string starts with "Voltage" [strstr()] vs. your strcmp() function for other keywords. If this check is true, then search for ':' and use to atof() function to convert the parameter that follows.

Thanks you both. I think I'm not gonna go for the struct, because I''ve never done anything with structs.

blh64:

I tried to start with your idea:

      else if(strcmp(messageReceived, keyWord7) == 0) { //last else if (existing)
      strncpy( LightsStatus, "OFF", sizeof(LightsStatus) );
      LightsStatus[sizeof(LightsStatus)-1] = 0;
      delay(100);
      }

      else if(strstr(messageReceived.c_str(), "Voltage") != 0)

But now I need to search for the ":" and read from there. I'm kind of struggling on how to do that.
Sorry!

laurin123:
Thanks you both. I think I'm not gonna go for the struct, because I''ve never done anything with structs.

Why not learn? They're super simple and I just showed how to use them. A struct is simply a collection of variables. Useful struct tutorial.

Taking my advice will save you a lot of effort and time in the long run...

laurin123:
But now I need to search for the ":" and read from there. I'm kind of struggling on how to do that.

Won't need to if you use something easier to work with than a char array. :wink:

Hi blh64

I googled and read based on the advice you gave me.
Now I came up with this:

      else if (strcasestr(messageReceived, "Voltage")) {
      char* ptr = strstr_P(messageReceived, PSTR(":"));
      BattVoltage = atoi(ptr + 5);

What do you think?

I don't think you need to over complicate your life with PSTR(":") and strstr_P() but your choice.

ptr will contain the position on ":" so you only need +1

Your battery is a floating point, which by default, print()'s using 2 decimal places so you can't use atoi(). You need atof(). You can also modify your sender code to only print an int value for your battery voltage.

thanks for your reply blh64!

I changed to atof, but the display still isn't correct. And I'm pretty sure why.
On the transmitter side, I printed the float variable like this:

      HC12.print("Voltage:"); // send Voltage over RF
      HC12.print(VoltagePrint);
      HC12.print("!");

Like this I probably have a CR and a LF in between "Voltage" and the variable. That's why I'm losing numbers..

No, print() does not insert a linefeed, println() does.

yep, that was it. thank you so much!

Hi again everyone!

My skteches are working fine. At the moment, the garden box (RX-sketch) sends the different states in a 1minute interval to the hand transmitter (TX-Sketch). Now I'd like to change the sketch of the garden box, so it will send the states immediately after a change of state (Relais On or Off) was done by the other side.

I tried it with a boolean, but the garden box now seems to send almost every second, even when no signal is beeing transmitted to it.

Here's the actual code of the garden box (RX):

#include <SoftwareSerial.h>

int Relais1 = 12;
int Relais2 = 13;
int Relais3 =  8;
int LightsState = 11;
int VideoLinkState = 9;
float BatteryVoltage = A0;
float BatteryValue;
float VoltagePrint;

const byte numChars = 32;
char messageReceived[numChars];
char keyWord1[] = "ActivateTimer1";
char keyWord2[] = "StopTimer1";
char keyWord3[] = "ToggleRelais3";
char command1[] = "VideoLinkON!";
char command2[] = "VideoLinkOFF!";
char command3[] = "LightsON!";
char command4[] = "LightsOFF!";
unsigned long last = millis(); //set timer
const unsigned long INTERVAL = 1000L*60*1; // Intervall 1 Min.
unsigned long lastRun = 0 - INTERVAL; // 

int StateOfLights;
int StateOfVideoLink;
boolean StateChange = false;

SoftwareSerial HC12(2, 3);



void setup() {
  HC12.begin(9600);
  Serial.begin(9600); // set up Serial library at 9600 bps - this is the speed the serial interface will work all
  pinMode (Relais1, OUTPUT);
  pinMode (Relais2, OUTPUT);
  pinMode (Relais3, OUTPUT);
  pinMode (LightsState, INPUT);
  pinMode (VideoLinkState, INPUT);
  pinMode (BatteryVoltage, INPUT);

}

void loop() {

  boolean Relais3state = digitalRead(Relais3); //check if Relais3 ist on or off. Returns 1 or 0
  static byte ndx = 0;
  char charReceived;
  char endMarker = '!';

  while (HC12.available() > 0) {
    charReceived = HC12.read();
    if (charReceived != endMarker) {
      messageReceived[ndx] = charReceived;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else {
      messageReceived[ndx] = '\0';
      ndx = 0;
      delay(100);
      
      while (HC12.available() > 0) HC12.read();
      if(strcmp(messageReceived, keyWord1) == 0) {
      digitalWrite(Relais1, HIGH);
      delay(100);
      digitalWrite(Relais1, LOW);
      StateChange = true;
      }
      else if(strcmp(messageReceived, keyWord2) == 0) {
      digitalWrite(Relais2, HIGH);
      delay(100);
      digitalWrite(Relais2, LOW);
      StateChange = true;
      }  
      else if(millis() - last > 250){
        if(Relais3state == 0 && (strcmp(messageReceived, keyWord3) == 0)){
        digitalWrite(Relais3, HIGH);
        StateChange = true;
      }
      else if(Relais3state == 1 && (strcmp(messageReceived, keyWord3) == 0)){
          digitalWrite(Relais3, LOW); 
          StateChange = true;
        }

      
      last = millis();
    
    }
  }
  


  
if ((millis() - lastRun >= INTERVAL)|| StateChange == true) {

      StateOfLights = digitalRead(LightsState);
      StateOfVideoLink = digitalRead(VideoLinkState);
      BatteryValue = analogRead(BatteryVoltage);  //reading Voltage of Battery
      VoltagePrint = ((BatteryValue * 5.0) / 1024.0) * 3; //converting Voltage according to Resistor Divider
      Serial.print(StateOfLights);
      HC12.print("Voltage:"); // send Voltage over RF
      HC12.print(VoltagePrint);
      HC12.print("!");
      delay(500);
      

      if(StateOfLights == HIGH) {
      HC12.print(command3);
      delay(500);
      }
      
      else {
      HC12.print(command4);
      delay(500);
      }
      
      if(StateOfVideoLink == HIGH) {
      HC12.print(command1);
      delay(500);
      }
      
      else {
      HC12.print(command2);
      }

      
  lastRun += INTERVAL;
  StateChange = false;
  }
  }
}

all of your code inside loop is inside your while() statement. Nothing will happen until it receives something. Your minute interval should be outside the while() statement.

Hi blh64

Thanks for your advice! The code seems to work better now, but the box still transmitts approx every second. Which means that at least one of the if statements much be true, although they shouldn't. Why?

The time interval will still be true every second, no?

Yes, but why? Before I added the boolean it transmitted once every minute.

I have to add: After reset, the interval works as designed once every minute. But after the first command from TX, the interval changes to once every second.

The Serial.Print shows that the boolean in the if statement oft the interval function is not true though. So it must be something wrong with the timer

When you change your code and say it is working better but still has problems, how are we supposed to know exactly how to changed it? Please post your latest code so we are all looking at the same code/problem.

This is the latest code:

#include <SoftwareSerial.h>

int Relais1 = 12;
int Relais2 = 13;
int Relais3 =  8;
int LightsState = 11;
int VideoLinkState = 9;
float BatteryVoltage = A0;
float BatteryValue;
float VoltagePrint;

const byte numChars = 32;
char messageReceived[numChars];
char keyWord1[] = "ActivateTimer1";
char keyWord2[] = "StopTimer1";
char keyWord3[] = "ToggleRelais3";
char command1[] = "VideoLinkON!";
char command2[] = "VideoLinkOFF!";
char command3[] = "LightsON!";
char command4[] = "LightsOFF!";
unsigned long last = millis(); //set timer
const unsigned long INTERVAL = 1000L*60*1; // Intervall 1 Min.
unsigned long lastRun = 0 - INTERVAL; // 

int StateOfLights;
int StateOfVideoLink;
boolean StateChange = false;

SoftwareSerial HC12(2, 3);



void setup() {
  HC12.begin(9600);
  Serial.begin(9600); // set up Serial library at 9600 bps - this is the speed the serial interface will work all
  pinMode (Relais1, OUTPUT);
  pinMode (Relais2, OUTPUT);
  pinMode (Relais3, OUTPUT);
  pinMode (LightsState, INPUT);
  pinMode (VideoLinkState, INPUT);
  pinMode (BatteryVoltage, INPUT);

}

void loop() {

  boolean Relais3state = digitalRead(Relais3); //check if Relais3 ist on or off. Returns 1 or 0
  static byte ndx = 0;
  char charReceived;
  char endMarker = '!';

  while (HC12.available() > 0) {
    charReceived = HC12.read();
    if (charReceived != endMarker) {
      messageReceived[ndx] = charReceived;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else {
      messageReceived[ndx] = '\0';
      ndx = 0;
      delay(100);
      
      while (HC12.available() > 0) HC12.read();
      if(strcmp(messageReceived, keyWord1) == 0) {
      digitalWrite(Relais1, HIGH);
      delay(100);
      digitalWrite(Relais1, LOW);
      StateChange = true;
      }
      else if(strcmp(messageReceived, keyWord2) == 0) {
      digitalWrite(Relais2, HIGH);
      delay(100);
      digitalWrite(Relais2, LOW);
      StateChange = true;
      }  
      else if(millis() - last > 250){
        if(Relais3state == 0 && (strcmp(messageReceived, keyWord3) == 0)){
        digitalWrite(Relais3, HIGH);
        StateChange = true;
      }
      else if(Relais3state == 1 && (strcmp(messageReceived, keyWord3) == 0)){
        digitalWrite(Relais3, LOW); 
        StateChange = true;
      }

      
      last = millis();
    
      }
  }
}

Serial.println(StateChange);  
if ((millis() - lastRun >= INTERVAL)|| StateChange == true) {
      Serial.println("if Statement true!!");
      StateOfLights = digitalRead(LightsState);
      StateOfVideoLink = digitalRead(VideoLinkState);
      BatteryValue = analogRead(BatteryVoltage);  //reading Voltage of Battery
      VoltagePrint = ((BatteryValue * 5.0) / 1024.0) * 3; //converting Voltage according to Resistor Divider
      //Serial.print(StateOfLights);
      HC12.print("Voltage:"); // send Voltage over RF
      HC12.print(VoltagePrint);
      HC12.print("!");
      delay(500);
      

      if(StateOfLights == HIGH) {
      HC12.print(command3);
      delay(500);
      }
      
      else {
      HC12.print(command4);
      delay(500);
      }
      
      if(StateOfVideoLink == HIGH) {
      HC12.print(command1);
      delay(500);
      }
      
      else {
      HC12.print(command2);
      }

      
  lastRun += INTERVAL;
  StateChange = false;
  
}
}

The serial Print "if Statement true!!" shows up after the first (random) transmission from the TX in an approx. 1 second interval. Which it's not supposed to.

The issue is that you are updating the lastRun time even when StateChange is true and that is happening at a different time. This causes lastRun to actually get ahead of millis() which gives a large number.

To solve this:

  1. if you want reporting every minute, regardless of StateChange, the put that reporting in a function and call and then call it on the interval or whenever StateChange is true but do that as two separate if() statements and only update the variables in each if() statement

  2. If you want to report 1 minute AFTER a StateChange, then reset lastRun to millis() rather than incrementing it

#include <SoftwareSerial.h>

const int Relais1 = 12;
const int Relais2 = 13;
const int Relais3 =  8;
const int LightsState = 11;
const int VideoLinkState = 9;
const int BatteryVoltage = A0;
//float BatteryValue;
//float VoltagePrint;

const byte numChars = 32;
char messageReceived[numChars];
char keyWord1[] = "ActivateTimer1";
char keyWord2[] = "StopTimer1";
char keyWord3[] = "ToggleRelais3";
char command1[] = "VideoLinkON!";
char command2[] = "VideoLinkOFF!";
char command3[] = "LightsON!";
char command4[] = "LightsOFF!";
unsigned long last = millis(); //set timer
const unsigned long INTERVAL = 1000L * 60 * 1; // Intervall 1 Min.
unsigned long lastRun;

//int StateOfLights;
//int StateOfVideoLink;
boolean StateChange = false;

SoftwareSerial HC12(2, 3);

void setup() {
  HC12.begin(9600);
  Serial.begin(9600); // set up Serial library at 9600 bps - this is the speed the serial interface will work all
  pinMode (Relais1, OUTPUT);
  pinMode (Relais2, OUTPUT);
  pinMode (Relais3, OUTPUT);
  pinMode (LightsState, INPUT);
  pinMode (VideoLinkState, INPUT);
  pinMode (BatteryVoltage, INPUT);
  lastRun = millis() - INTERVAL;  // make the first report happen immediately
}

void loop() {

  boolean Relais3state = digitalRead(Relais3); //check if Relais3 ist on or off. Returns 1 or 0
  static byte ndx = 0;
  char charReceived;
  char endMarker = '!';

  while (HC12.available() > 0) {
    charReceived = HC12.read();
    if (charReceived != endMarker) {
      messageReceived[ndx] = charReceived;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else {
      messageReceived[ndx] = '\0';
      ndx = 0;
      delay(100);

      while (HC12.available() > 0) HC12.read();
      if (strcmp(messageReceived, keyWord1) == 0) {
        digitalWrite(Relais1, HIGH);
        delay(100);
        digitalWrite(Relais1, LOW);
        StateChange = true;
      }
      else if (strcmp(messageReceived, keyWord2) == 0) {
        digitalWrite(Relais2, HIGH);
        delay(100);
        digitalWrite(Relais2, LOW);
        StateChange = true;
      }
      else if (millis() - last > 250) {
        last = millis();
        if (Relais3state == 0 && (strcmp(messageReceived, keyWord3) == 0)) {
          digitalWrite(Relais3, HIGH);
          StateChange = true;
        }
        else if (Relais3state == 1 && (strcmp(messageReceived, keyWord3) == 0)) {
          digitalWrite(Relais3, LOW);
          StateChange = true;
        }
      }
    }
  }

  if (StateChange == true) {
    report();
    StateChange = false;
    // uncomment the next line if you want to reset the reporting time
    // lastRun = millis();
  }

  if (millis() - lastRun >= INTERVAL) {
    report();
    lastRun += INTERVAL;
  }
}


void report() {
  int StateOfLights = digitalRead(LightsState);
  int StateOfVideoLink = digitalRead(VideoLinkState);
  int BatteryValue = analogRead(BatteryVoltage);  //reading Voltage of Battery
  float VoltagePrint = ((BatteryValue * 5.0) / 1024.0) * 3; //converting Voltage according to Resistor Divider
  //Serial.print(StateOfLights);
  HC12.print("Voltage:"); // send Voltage over RF
  HC12.print(VoltagePrint);
  HC12.print("!");
  delay(500);

  if (StateOfLights == HIGH) {
    HC12.print(command3);
    delay(500);
  }
  else {
    HC12.print(command4);
    delay(500);
  }

  if (StateOfVideoLink == HIGH) {
    HC12.print(command1);
    delay(500);
  }
  else {
    HC12.print(command2);
  }
}