Switching a relay on and off using "millis()" without interfering with the runtime of the other piece of code

Nope. When logging is enabled. Like this:

void useNewData()
{
  if (newData == true)
  {
    //Serial.print("This just in ... ");
    Serial.println(receivedChar);

    if (receivedChar.indexOf("2") > -1 || voltage > 2 )
    {
      creat_file();
      enableDataLogging = true;
      previousMillis = 0;    // <----------------
      alreadyRun = false;    // <----------------
      //Serial.println("Data logging enabled");
      //digitalWrite(LED_BUILTIN, HIGH);
    }
    if (receivedChar.indexOf("5") > -1)
    {
      enableDataLogging = false;
      //Serial.println("   Data logging disabled");
      //digitalWrite(LED_BUILTIN, LOW);

      if (file) file.close();
      //SysCall::halt();
    }
    newData = false;
  }
}//useNewData

Arduino main site Teaching Docs... a start point

Analog Pins explained well enough to code with.

The code technique has been the forum specialty for longer than I got here in 2011.

My favorite tutorials are on Nick Gammon's MCU blog site.
Menu to a WEALTH of HOW-TO.

Use of millis and the principle of non-blocking explined well.

Reading without blocking, introduces state machines.

Just how simultaneous do you need to analog read? Is 1/5th of a millisecond close enough or do cross or additive effects require real simultaneous reads? Because then it's use ATtinys to do the reading.

mr.ToddL1962

#include <SPI.h>
#include "SdFat.h"
#include "RTClib.h"
#include "HX711.h"//XFW-HX711 amplifier 80Hz


#define calibration_factor -7090.0
int LOADCELL_DOUT_PIN = 7;
int LOADCELL_SCK_PIN = 6;

int LOADCELL_DOUT_PIN_1 = 5;
int LOADCELL_SCK_PIN_1 = 4;

int LOADCELL_DOUT_PIN_2 = 3;
int LOADCELL_SCK_PIN_2 = 2;
HX711 scale;
HX711 scale1;
HX711 scale2;
int navoser;
int sensorPin = A0;
int relay1 = 8;
int relay2 = 9;

unsigned long previousMillis = 0;
long OnTime = 15000;
long OffTime = 500;
int relay2State = LOW;
boolean alreadyRun = false;

int sensorValue = 0;
float voltage;
RTC_DS1307 RTC;//using RTClib
DateTime now;

bool enableDataLogging = false;
String receivedChar;
boolean newData = false;

const uint8_t chipSelect = 10;



const uint32_t SAMPLE_INTERVAL_MS = 1;



#define FILE_BASE_NAME "Result"
#define error(msg) sd.errorHalt(F(msg))
//------------------------------------------------------------------------------

SdFat sd;

SdFile file;// Log file.

uint32_t logTime;

//==============================================================================


int Date_count = 1;
int Time_count = 1;
int Load_Cell1 = 1;
int Load_Cell2 = 1;
int Load_Cell3 = 1;
//------------------------------------------------------------------------------

void load_cell () {

  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.print("t3.txt=");
  Serial.write(0x22);
  Serial.print(scale.get_units(), 1);
  Serial.write(0x22);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.print("t4.txt=");
  Serial.write(0x22);
  Serial.print(scale1.get_units(), 1);
  Serial.write(0x22);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.print("t5.txt=");
  Serial.write(0x22);
  Serial.print(scale2.get_units(), 1);
  Serial.write(0x22);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  navoser = (scale.get_units() + scale1.get_units() + scale2.get_units() / 3);
  Serial.print("t8.txt=");
  Serial.write(0x22);
  Serial.print(navoser);
  Serial.write(0x22);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);





  /*
    Serial.print("Reading: ");
    Serial.print(scale.get_units(), 1);
    // Serial.print(" kg");
    Serial.print("\t");
    Serial.print(scale1.get_units(), 1);
    Serial.print("\t");
    Serial.print(scale2.get_units(), 1);
    Serial.print(" kg");
    Serial.println();
  */

}


void setup() {
  pinMode(sensorPin, INPUT);
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  Serial.begin(9600);//

  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
  scale1.begin(LOADCELL_DOUT_PIN_1, LOADCELL_SCK_PIN_1);
  scale2.begin(LOADCELL_DOUT_PIN_2, LOADCELL_SCK_PIN_2);

  scale.set_scale(calibration_factor);
  scale.tare();

  scale1.set_scale(calibration_factor);
  scale1.tare();

  scale2.set_scale(calibration_factor);
  scale2.tare();


  RTC.begin();


}
void creat_file() {
  const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
  char fileName[13] = FILE_BASE_NAME "00.csv";
  if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) {
    sd.initErrorHalt();
  }

  // Find an unused file name.

  if (BASE_NAME_SIZE > 7) {
    error("FILE_BASE_NAME long");
  }
  while (sd.exists(fileName)) {
    if (fileName[BASE_NAME_SIZE + 1] != '9') {
      fileName[BASE_NAME_SIZE + 1]++;
    } else if (fileName[BASE_NAME_SIZE] != '9') {
      fileName[BASE_NAME_SIZE + 1] = '0';
      fileName[BASE_NAME_SIZE]++;
    } else {
      error("filename not created");
    }
  }
  if (!file.open(fileName, O_WRONLY | O_CREAT | O_EXCL)) {
    error("file.open");
  }
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.print("page 4");
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.print("g1.txt=");
  Serial.write(0x22);
  Serial.print(fileName);
  Serial.write(0x22);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);

  //Serial.print(F("Recording: "));
  //Serial.println(fileName);
  //Serial.println(F("enter any character to stop"));
  writeHeader();

}
//------------------------------------------------------------------------------
void loop() {

  recvOneChar();
  useNewData();
  if (enableDataLogging) {

    logTime += SAMPLE_INTERVAL_MS;
    logData();


    if (!file.sync() || file.getWriteError()) {
      error("error write");
    }
  } else {
    load_cell();
  }
}
void recvOneChar()
{

  sensorValue = analogRead(sensorPin);
  voltage = sensorValue * (5.0 / 1023.0);
  if (Serial.available() > 0 || voltage > 2 ) {
    receivedChar = Serial.readStringUntil('#');


    newData = true;

  }
}//recvOneChar
void useNewData()
{
  if (newData == true)
  {
    //Serial.print("This just in ... ");
    Serial.println(receivedChar);

    if (receivedChar.indexOf("2") > -1 || voltage > 2 )
    {
      creat_file();
      enableDataLogging = true;
      previousMillis = 0;    // <----------------
      alreadyRun = false;    // <----------------

      //Serial.println("Data logging enabled");
      //digitalWrite(LED_BUILTIN, HIGH);
    }
    if (receivedChar.indexOf("5") > -1)
    {
      enableDataLogging = false;

      //Serial.println("   Data logging disabled");
      //digitalWrite(LED_BUILTIN, LOW);

      if (file) file.close();
      //SysCall::halt();
    }
    newData = false;
  }
}//useNewData


void writeHeader() {

  file.print(F("time(us)"));
  for (int c = 0; c < Load_Cell1; c++) {
    file.print(F(",load1"));
    //file.print(c, DEC);
  } for (int d = 0; d < Load_Cell2; d++) {
    file.print(F(",load2"));
    //file.print(d, DEC);
  } for (int e = 0; e < Load_Cell3; e++) {
    file.print(F(",load3"));
    //file.print(e, DEC);
  }
  for (int a = 0; a < Date_count; a++) {
    now = RTC.now();
    file.print(F(",date:"));
    file.print(now.day(), DEC);
    file.print('/');
    file.print(now.month(), DEC);
    file.print('/');
    file.print(now.year(), DEC);

  } for (int b = 0; b < Time_count; b++) {
    file.print(F(",time(hour-minute-second)"));

  }
  file.println();
}
//------------------------------------------------------------------------------


void logData() {

  file.print(logTime);
  for (int c = 0; c < Load_Cell1; c++) {
    file.write(',');
    file.print(scale.get_units());
  } for (int d = 0; d < Load_Cell2; d++) {
    file.write(',');
    file.print(scale1.get_units());
  } for (int e = 0; e < Load_Cell3; e++) {
    file.write(',');
    file.print(scale2.get_units());//file.print(scale2.get_units(),DEC);
  }
  for (int a = 0; a < Date_count; a++) {
    file.write(',');
    //file.print("test");
  } for (int b = 0; b < Time_count; b++) {
    file.write(',');
    file.print(now.hour(), DEC);
    file.print(":");
    file.print(now.minute(), DEC);
    file.print(":");
    file.print(now.second(), DEC);
    file.print(":");
    file.print(micros(), DEC);
  }
  file.println();
  relay ();
}
//==============================================================================
void relay () {
  if (alreadyRun == false) {
    unsigned long currentMillis = millis();
    if ((relay2State == LOW) && (currentMillis - previousMillis >= OnTime) ) {

      relay2State = HIGH;  // Turn it off
      previousMillis = currentMillis;  // Remember the time
      digitalWrite(relay2, relay2State);  // Update the actual LED
    }
    else if ((relay2State == HIGH) && (currentMillis - previousMillis >= OffTime) ) {

      relay2State = LOW;  // Turn it off
      previousMillis = currentMillis;  // Remember the time
      digitalWrite(relay2, relay2State);  // Update the actual LED
      alreadyRun = true;
    }
  }
}

I refreshed the code like this, there is some change, but it doesn't work exactly as I want. The code works in this way, when the arduino is energized for the first time and after making the first analog reading; it does not wait for 15 seconds, it waits only for 5 seconds, and it closes the relay after remaining open for the specified time. the other function continues to work.
But if I start the loop again without disconnecting the power from the Arduino, this time the relay becomes "HIGH" without waiting, stays on for the specified time and then turns off. Again, other functions continue to work.

If a voltage appears at the analog input the flag bRelay would be set to true:

    sensorValue = analogRead(sensorPin);
    voltage = sensorValue * (5.0 / 1023.0);
    if (Serial.available() > 0 || voltage > 2 ) 
    { 
        receivedChar = Serial.readStringUntil('#');      
        newData = true; 

        bRelay = true;  //...after the analog voltage is read from the analog pin...
    }

If "voltage" is greater than 2 this flag would be set.

That should then allow the relay() state machine to move out of the IDLE state. You might try adding some Serial.prints() to show where the code is getting to help understand what's going on.

I tried the serial printing on your suggestion and came to the following conclusion. At the first voltage confirmation, it works partially correctly. However, after the next voltage confirmation, it opens the relay in the "relay()" function without waiting for the specified time. The "millis()" time runs from the moment the Arduino is powered up. This means that the specified waiting time expires before the voltage confirmation. So if I later confirm the voltage, nothing changes because of "currentmillis=millis()". I tried your suggestion but it still doesn't work as I want. I'm still struggling to solve this.

Hi parworker. Lets try this. first we have to define a few things.

previousMillis == 0 means the relay was never switched on and you still don't want anything changed with the relay
the function relay() checks if anything should be done with the relay

The following changes will be done:

  1. when you want the relay to turn on after 5 sec put the command
    if (previousMillis == 0) //has not been set before
    previousMillis = millis(); //will turn on after this time
  2. move the call to relay(); to the loop() function
  3. on the relay() function add the condition && !(previousMillis == 0) because you don't want to do anything if previousMillis == 0

See Code below:
#include <SPI.h>
#include "SdFat.h"
#include "RTClib.h"
#include "HX711.h"//XFW-HX711 amplifier 80Hz

#define calibration_factor -7090.0
int LOADCELL_DOUT_PIN = 7;
int LOADCELL_SCK_PIN = 6;

int LOADCELL_DOUT_PIN_1 = 5;
int LOADCELL_SCK_PIN_1 = 4;

int LOADCELL_DOUT_PIN_2 = 3;
int LOADCELL_SCK_PIN_2 = 2;
HX711 scale;
HX711 scale1;
HX711 scale2;
int navoser;
int sensorPin = A0;
int relay1 = 8;
int relay2 = 9;

unsigned long previousMillis = 0;
long OnTime = 15000;
long OffTime = 500;
int relay2State = LOW;
boolean alreadyRun = false;

int sensorValue = 0;
float voltage;
RTC_DS1307 RTC;//using RTClib
DateTime now;

bool enableDataLogging = false;
String receivedChar;
boolean newData = false;

const uint8_t chipSelect = 10;

const uint32_t SAMPLE_INTERVAL_MS = 1;

#define FILE_BASE_NAME "Result"
#define error(msg) sd.errorHalt(F(msg))
//------------------------------------------------------------------------------

SdFat sd;

SdFile file;// Log file.

uint32_t logTime;

//==============================================================================

int Date_count = 1;
int Time_count = 1;
int Load_Cell1 = 1;
int Load_Cell2 = 1;
int Load_Cell3 = 1;
//------------------------------------------------------------------------------

void load_cell () {

Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
Serial.print("t3.txt=");
Serial.write(0x22);
Serial.print(scale.get_units(), 1);
Serial.write(0x22);
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
Serial.print("t4.txt=");
Serial.write(0x22);
Serial.print(scale1.get_units(), 1);
Serial.write(0x22);
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
Serial.print("t5.txt=");
Serial.write(0x22);
Serial.print(scale2.get_units(), 1);
Serial.write(0x22);
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
navoser = (scale.get_units() + scale1.get_units() + scale2.get_units() / 3);
Serial.print("t8.txt=");
Serial.write(0x22);
Serial.print(navoser);
Serial.write(0x22);
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);

/*
Serial.print("Reading: ");
Serial.print(scale.get_units(), 1);
// Serial.print(" kg");
Serial.print("\t");
Serial.print(scale1.get_units(), 1);
Serial.print("\t");
Serial.print(scale2.get_units(), 1);
Serial.print(" kg");
Serial.println();
*/

}

void setup() {
pinMode(sensorPin, INPUT);
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
Serial.begin(9600);//

scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
scale1.begin(LOADCELL_DOUT_PIN_1, LOADCELL_SCK_PIN_1);
scale2.begin(LOADCELL_DOUT_PIN_2, LOADCELL_SCK_PIN_2);

scale.set_scale(calibration_factor);
scale.tare();

scale1.set_scale(calibration_factor);
scale1.tare();

scale2.set_scale(calibration_factor);
scale2.tare();

RTC.begin();

}
void creat_file() {
const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
char fileName[13] = FILE_BASE_NAME "00.csv";
if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) {
sd.initErrorHalt();
}

// Find an unused file name.

if (BASE_NAME_SIZE > 7) {
error("FILE_BASE_NAME long");
}
while (sd.exists(fileName)) {
if (fileName[BASE_NAME_SIZE + 1] != '9') {
fileName[BASE_NAME_SIZE + 1]++;
} else if (fileName[BASE_NAME_SIZE] != '9') {
fileName[BASE_NAME_SIZE + 1] = '0';
fileName[BASE_NAME_SIZE]++;
} else {
error("filename not created");
}
}
if (!file.open(fileName, O_WRONLY | O_CREAT | O_EXCL)) {
error("file.open");
}
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
Serial.print("page 4");
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
Serial.print("g1.txt=");
Serial.write(0x22);
Serial.print(fileName);
Serial.write(0x22);
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);

//Serial.print(F("Recording: "));
//Serial.println(fileName);
//Serial.println(F("enter any character to stop"));
writeHeader();

}
//------------------------------------------------------------------------------
void loop() {

recvOneChar();
useNewData();
if (enableDataLogging) {

logTime += SAMPLE_INTERVAL_MS;
logData();


if (!file.sync() || file.getWriteError()) {
  error("error write");
}

} else {
load_cell();
}
//MOD GERRY
relay (); //check if anything should be done on the relay
}
void recvOneChar()
{

sensorValue = analogRead(sensorPin);
voltage = sensorValue * (5.0 / 1023.0);
if (Serial.available() > 0 || voltage > 2 ) {
receivedChar = Serial.readStringUntil('#');

newData = true;

}
}//recvOneChar
void useNewData()
{
if (newData == true)
{
//Serial.print("This just in ... ");
Serial.println(receivedChar);

if (receivedChar.indexOf("2") > -1 || voltage > 2 )
{
  creat_file();
  enableDataLogging = true;
  //MOD GERRY
  //previousMillis = 0;    // <----------------
  //alreadyRun = false;    // <----------------
  if (previousMillis == 0)       //has not been set before
    previousMillis = millis();  //will turn on after this time

  //Serial.println("Data logging enabled");
  //digitalWrite(LED_BUILTIN, HIGH);
}
if (receivedChar.indexOf("5") > -1)
{
  enableDataLogging = false;

  //Serial.println("   Data logging disabled");
  //digitalWrite(LED_BUILTIN, LOW);

  if (file) file.close();
  //SysCall::halt();
}
newData = false;

}
}//useNewData

void writeHeader() {

file.print(F("time(us)"));
for (int c = 0; c < Load_Cell1; c++) {
file.print(F(",load1"));
//file.print(c, DEC);
} for (int d = 0; d < Load_Cell2; d++) {
file.print(F(",load2"));
//file.print(d, DEC);
} for (int e = 0; e < Load_Cell3; e++) {
file.print(F(",load3"));
//file.print(e, DEC);
}
for (int a = 0; a < Date_count; a++) {
now = RTC.now();
file.print(F(",date:"));
file.print(now.day(), DEC);
file.print('/');
file.print(now.month(), DEC);
file.print('/');
file.print(now.year(), DEC);

} for (int b = 0; b < Time_count; b++) {
file.print(F(",time(hour-minute-second)"));

}
file.println();
}
//------------------------------------------------------------------------------

void logData() {

file.print(logTime);
for (int c = 0; c < Load_Cell1; c++) {
file.write(',');
file.print(scale.get_units());
} for (int d = 0; d < Load_Cell2; d++) {
file.write(',');
file.print(scale1.get_units());
} for (int e = 0; e < Load_Cell3; e++) {
file.write(',');
file.print(scale2.get_units());//file.print(scale2.get_units(),DEC);
}
for (int a = 0; a < Date_count; a++) {
file.write(',');
//file.print("test");
} for (int b = 0; b < Time_count; b++) {
file.write(',');
file.print(now.hour(), DEC);
file.print(":");
file.print(now.minute(), DEC);
file.print(":");
file.print(now.second(), DEC);
file.print(":");
file.print(micros(), DEC);
}
file.println();
//MOD GERRY

relay ();
}
//==============================================================================
void relay () {
if (alreadyRun == false) {
unsigned long currentMillis = millis();
//MOD GERRY
//if ((relay2State == LOW) && (currentMillis - previousMillis >= OnTime) ) {
if ((relay2State == LOW) && (currentMillis - previousMillis >= OnTime) && !(previousMillis == 0)) {

  relay2State = HIGH;  // Turn it off
  previousMillis = currentMillis;  // Remember the time
  digitalWrite(relay2, relay2State);  // Update the actual LED
}
else if ((relay2State == HIGH) && (currentMillis - previousMillis >= OffTime) ) {

  relay2State = LOW;  // Turn it off
  previousMillis = currentMillis;  // Remember the time
  digitalWrite(relay2, relay2State);  // Update the actual LED
  alreadyRun = true;
}

}
}

mr. gerivega
Thank you very much for your suggestion. Currently the program works partially correctly. But there is a problem as below. After the Arduino is energized, it can only open and close the relay once when the program runs.

The algorithm I want the program to run is as follows.
-Recording on the sd card should start with the character from the voltage or serial and the relay counter should work at the same time. After 15 seconds the relay should be HIGH and after 500ms remaining on it should be LOW again. The recording still continues. Until a character comes from the serial. If a character comes in, the recording stops.
-If a character comes back or the voltage is read, the loop should start all over again.

OK, I think I know what's going on there.

In the IDLE state within relay() I wait until the bRelay flag is set by the code that checks the voltage at the analog input. When that happens, I immediately clear that flag, log the current millis() count and move to time the relay delay.

I think the problem is that as soon as we get back to recvOneChar() a few 10s of microseconds later, the voltage is still present and so the flag, bReset, is set again. When the relay timing is done and we get back to IDLE state, it sees the flag is set and starts timing again.

You can try this slightly modified relay() function. In it, I clear the bReset flag after the relay timing is done so, if the bRelay flag was set "in error", it's cleared before we get back to IDLE.

void relay( void ) 
{
    uint8_t
        stateRelay = RLY_OFF;
    static uint32_t
        timeRelay;
    uint32_t
        timeNow = millis();
        
    switch( stateRelay )
    {
        case    RLY_IDLE:
            //waiting for flag to indicate relay sequence
            if( bRelay == true )
            {                
                timeRelay = timeNow;
                stateRelay = RLY_ON;
                
            }//if
            
        break;

        case    RLY_DELAY:
            //delay before turning the relay on
            if( millis() - timeRelay >= K_RELAY_DELAY_TIME )
            {
                digitalWrite( relay2, LOW );   //relay on 
                timeRelay = timeNow;
                stateRelay = RLY_HOLD;
                    
            }//if
            
        break;

        case    RLY_HOLD:
            //relay on-timing
            if( millis() - timeRelay >= K_RELAY_HOLD_TIME )
            {
                digitalWrite( relay2, HIGH );    
                bRelay = false;
                stateRelay = RLY_IDLE;
                    
            }//if
        
        break;
                
    }//switch

}//relay

mr. Blackfin

void relay( void ) 
{
    uint8_t
        stateRelay = RLY_OFF;
    static uint32_t
        timeRelay;
    uint32_t
        timeNow = millis();
        
    switch( stateRelay )
    {
        case    RLY_IDLE:
            //waiting for flag to indicate relay sequence
            if( bRelay == true )
            {                
                timeRelay = timeNow;
                stateRelay = RLY_ON;

I also tried your last suggestion, but there was a compilation error in this part. I fixed it as follows, but there is no movement in the relay.

//==============================================================================
void relay( void ) 
{
    uint8_t
        stateRelay = RLY_IDLE;
    static uint32_t
        timeRelay;
    uint32_t
        timeNow = millis();
        
    switch( stateRelay )
    {
        case    RLY_IDLE:
            //waiting for flag to indicate relay sequence
            if( bRelay == true )
            {
                bRelay = false;
                timeRelay = timeNow;
                stateRelay = RLY_IDLE;
                
            }//if
            
        break;

        case    RLY_DELAY:
            //delay before turning the relay on
            if( millis() - timeRelay >= K_RELAY_DELAY_TIME )
            {
                digitalWrite( relay2, LOW );   //relay on 
                timeRelay = timeNow;
                stateRelay = RLY_HOLD;
                    
            }//if
            
        break;

        case    RLY_HOLD:
            //relay on-timing
            if( millis() - timeRelay >= K_RELAY_HOLD_TIME )
            {
                digitalWrite( relay2, HIGH );    
                stateRelay = RLY_IDLE;
                    
            }//if
        
        break;
                
    }//switch

}//relay

What was the compilation error? Your "fix" put bRelay = false; back in the IDLE state (essentially erasing my correction.). You want to move that to RLY_HOLD, just before stateRelay is set to RLY_IDLE.

The compilation error is as follows.

void relay( void ) 
{
    uint8_t
        **stateRelay = RLY_OFF;**
    static uint32_t
        timeRelay;

"RLY_OFF" was not declared in this scope

Gah. I didn't fix my source from the first time you saw this error. Pls change RLY_OFF to RLY_IDLE and ensure that bRelay = false; occurs in RLY_HOLD, just before stateRelay = RLY_IDLE, like this:

void relay( void ) 
{
    uint8_t
        stateRelay = RLY_IDLE;
    static uint32_t
        timeRelay;
    uint32_t
        timeNow = millis();
        
    switch( stateRelay )
    {
        case    RLY_IDLE:
            //waiting for flag to indicate relay sequence
            if( bRelay == true )
            {                
                timeRelay = timeNow;
                stateRelay = RLY_ON;
                
            }//if
            
        break;

        case    RLY_DELAY:
            //delay before turning the relay on
            if( millis() - timeRelay >= K_RELAY_DELAY_TIME )
            {
                digitalWrite( relay2, LOW );   //relay on 
                timeRelay = timeNow;
                stateRelay = RLY_HOLD;
                    
            }//if
            
        break;

        case    RLY_HOLD:
            //relay on-timing
            if( millis() - timeRelay >= K_RELAY_HOLD_TIME )
            {
                digitalWrite( relay2, HIGH );    
                bRelay = false;
                stateRelay = RLY_IDLE;
                    
            }//if
        
        break;
                
    }//switch

}//relay

It still gives a compilation error.

void relay( void ) 
{
    uint8_t
        **stateRelay = RLY_IDLE;**
    static uint32_t
        timeRelay;
    uint32_t
        timeNow = millis();
        
    switch( stateRelay )
    {
        case    RLY_IDLE:
            //waiting for flag to indicate relay sequence
            if( bRelay == true )
            {                
                timeRelay = timeNow;
                stateRelay = RLY_ON;
                
            }//if
            
        break;

        case    RLY_DELAY:
            //delay before turning the relay on
            if( millis() - timeRelay >= K_RELAY_DELAY_TIME )
            {
                digitalWrite( relay2, LOW );   //relay on 
                timeRelay = timeNow;
                stateRelay = RLY_HOLD;
                    
            }//if
            
        break;

        case    RLY_HOLD:
            //relay on-timing
            if( millis() - timeRelay >= K_RELAY_HOLD_TIME )
            {
                digitalWrite( relay2, HIGH );    
                bRelay = false;
                stateRelay = RLY_IDLE;
                    
            }//if
        
        break;
                
    }//switch

}//relay

"RLY_IDLE" was not declared in this scope

OK. I got tired of not being able to compile and test your code here and posting erroneous replies (there are a couple more bugs I missed...) so I made a minimally viable example of the relay timing I'm trying to relate , compiled and debugged it and it works here. You should be able to copy the relay() function into your code but you'll need to change the name of the relay pin from what I used.

In this example I used the built-in LED to mimic the LED so the sense of "on" and "off" are switched (i.e. HIGH on pinRelay turns the LED on but this turns your relay off...) so if you want to adapt it, you'll need to sort that stuff out too...


//"Turning on a relay 5 seconds after the analog voltage is read from the 
//analog pin, and closing it again 5 seconds after opening it
#define K_RELAY_DELAY_TIME  5000ul
#define K_RELAY_HOLD_TIME   5000ul
typedef enum
{
    RLY_IDLE=0,
    RLY_DELAY,
    RLY_HOLD
    
}e_statesRelay_t;

const uint8_t pinSensor = A0;        
const uint8_t pinRelay = LED_BUILTIN;

boolean bRelay = false;

void setup() 
{
    pinMode( pinSensor, INPUT );
    pinMode( pinRelay, OUTPUT );
    Serial.begin(9600);
    
}//setup

void loop() 
{
    chkVolts();   
    relay();    
    
}//loop

void chkVolts()  
{
    static uint32_t
        timeSample = 0ul;
    uint32_t
        timeNow = millis();

    if( (timeNow - timeSample) >= 100ul )
    {
        timeSample = timeNow;
        int sensorValue = analogRead( pinSensor );
        float voltage = (float)sensorValue * 5.0 / 1023.0;
        
        if( voltage > 2.0 ) 
        {
            Serial.print( "Sensor: " ); Serial.println( voltage, 2 );
            bRelay = true;  //...after the analog voltage is read from the analog pin...
            
        }//if
                    
    }//if
    
}//chkVolts

void relay( void ) 
{
    static uint8_t
        stateRelay = RLY_IDLE;
    static uint32_t
        timeRelay;
    uint32_t
        timeNow = millis();
        
    switch( stateRelay )
    {
        case    RLY_IDLE:
            //waiting for flag to indicate relay sequence
            if( bRelay == true )
            {
                Serial.println( "Relay delay" );                
                timeRelay = timeNow;
                stateRelay = RLY_DELAY;
                
            }//if
            
        break;

        case    RLY_DELAY:
            //delay before turning the relay on
            if( timeNow - timeRelay >= K_RELAY_DELAY_TIME )
            {
                Serial.println( "Relay on and hold" );                
                digitalWrite( pinRelay, HIGH );   //relay on 
                timeRelay = timeNow;
                stateRelay = RLY_HOLD;
                    
            }//if
            
        break;

        case    RLY_HOLD:
            //relay on-timing
            if( timeNow - timeRelay >= K_RELAY_HOLD_TIME )
            {
                Serial.println( "Relay off" );                
                digitalWrite( pinRelay, LOW );    
                bRelay = false;
                stateRelay = RLY_IDLE;
                    
            }//if
        
        break;
                
    }//switch

}//relay

mr. Blackfin
the code works fine, I will have to adapt it to the code. I am working for this.
but this code works fine as below. Thank you for your help and suggestions.

Finally, the code that works as I want is below. I don't know if it slows down the arduino. But it seems to be working. I can record 760-800 samples in 10 seconds.
I created this code based on mr.gerivega's idea.
does this code need improvement? is there any error?

#include <SPI.h>
#include "SdFat.h"
#include "RTClib.h"
#include "HX711.h"//XFW-HX711 amplifier 80Hz

#define calibration_factor -7090.0
int LOADCELL_DOUT_PIN = 7;
int LOADCELL_SCK_PIN = 6;

int LOADCELL_DOUT_PIN_1 = 5;
int LOADCELL_SCK_PIN_1 = 4;

int LOADCELL_DOUT_PIN_2 = 3;
int LOADCELL_SCK_PIN_2 = 2;
HX711 scale;
HX711 scale1;
HX711 scale2;
int navoser;
int sensorPin = A0;
int relay1 = 8;
int relay2 = 9;
int a = 0;
unsigned long previousMillis = 0;
long OnTime = 10000;
long OffTime = 50;
int relay2State = LOW;
boolean alreadyRun = false;

int sensorValue = 0;
float voltage;
RTC_DS1307 RTC;//using RTClib
DateTime now;

bool enableDataLogging = false;
String receivedChar;
boolean newData = false;

const uint8_t chipSelect = 10;

const uint32_t SAMPLE_INTERVAL_MS = 1;

#define FILE_BASE_NAME "Result"
#define error(msg) sd.errorHalt(F(msg))
//------------------------------------------------------------------------------

SdFat sd;

SdFile file;// Log file.

uint32_t logTime;

//==============================================================================

int Date_count = 1;
int Time_count = 1;
int Load_Cell1 = 1;
int Load_Cell2 = 1;
int Load_Cell3 = 1;
//------------------------------------------------------------------------------

void load_cell () {

  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.print("t3.txt=");
  Serial.write(0x22);
  Serial.print(scale.get_units(), 1);
  Serial.write(0x22);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.print("t4.txt=");
  Serial.write(0x22);
  Serial.print(scale1.get_units(), 1);
  Serial.write(0x22);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.print("t5.txt=");
  Serial.write(0x22);
  Serial.print(scale2.get_units(), 1);
  Serial.write(0x22);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  navoser = (scale.get_units() + scale1.get_units() + scale2.get_units() / 3);
  Serial.print("t8.txt=");
  Serial.write(0x22);
  Serial.print(navoser);
  Serial.write(0x22);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);

  /*
    Serial.print("Reading: ");
    Serial.print(scale.get_units(), 1);
    // Serial.print(" kg");
    Serial.print("\t");
    Serial.print(scale1.get_units(), 1);
    Serial.print("\t");
    Serial.print(scale2.get_units(), 1);
    Serial.print(" kg");
    Serial.println();
  */

}

void setup() {
  pinMode(sensorPin, INPUT);
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  Serial.begin(9600);//

  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
  scale1.begin(LOADCELL_DOUT_PIN_1, LOADCELL_SCK_PIN_1);
  scale2.begin(LOADCELL_DOUT_PIN_2, LOADCELL_SCK_PIN_2);

  scale.set_scale(calibration_factor);
  scale.tare();

  scale1.set_scale(calibration_factor);
  scale1.tare();

  scale2.set_scale(calibration_factor);
  scale2.tare();

  RTC.begin();

}
void creat_file() {
  const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
  char fileName[13] = FILE_BASE_NAME "00.csv";
  if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) {
    sd.initErrorHalt();
  }

  // Find an unused file name.

  if (BASE_NAME_SIZE > 7) {
    error("FILE_BASE_NAME long");
  }
  while (sd.exists(fileName)) {
    if (fileName[BASE_NAME_SIZE + 1] != '9') {
      fileName[BASE_NAME_SIZE + 1]++;
    } else if (fileName[BASE_NAME_SIZE] != '9') {
      fileName[BASE_NAME_SIZE + 1] = '0';
      fileName[BASE_NAME_SIZE]++;
    } else {
      error("filename not created");
    }
  }
  if (!file.open(fileName, O_WRONLY | O_CREAT | O_EXCL)) {
    error("file.open");
  }
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.print("page 4");
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.print("g1.txt=");
  Serial.write(0x22);
  Serial.print(fileName);
  Serial.write(0x22);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);

  //Serial.print(F("Recording: "));
  //Serial.println(fileName);
  //Serial.println(F("enter any character to stop"));
  writeHeader();

}
//------------------------------------------------------------------------------
void loop() {

  recvOneChar();
  useNewData();
  if (enableDataLogging) {

    logTime += SAMPLE_INTERVAL_MS;
    logData();


    if (!file.sync() || file.getWriteError()) {
      error("error write");
    }
  } else {
    load_cell();
  }
  //MOD GERRY
  relay (); //check if anything should be done on the relay
}
void recvOneChar()
{

  sensorValue = analogRead(sensorPin);
  voltage = sensorValue * (5.0 / 1023.0);
  if (Serial.available() > 0 || voltage > 2 ) {
    receivedChar = Serial.readStringUntil('#');

    newData = true;
  }
}//recvOneChar
void useNewData()
{
  if (newData == true)
  {
    //Serial.print("This just in ... ");
    Serial.println(receivedChar);

    if (receivedChar.indexOf("2") > -1 || voltage > 2 )
    {

      creat_file();
      enableDataLogging = true;
      //MOD GERRY
      previousMillis = 0;    // <----------------
      //alreadyRun = false;    // <----------------
      if (previousMillis == 0)       //has not been set before
        previousMillis = millis();  //will turn on after this time
      a = 0;
      //Serial.println("Data logging enabled");
      //digitalWrite(LED_BUILTIN, HIGH);
    }
    if (receivedChar.indexOf("5") > -1)
    {
      enableDataLogging = false;

      //Serial.println("   Data logging disabled");
      //digitalWrite(LED_BUILTIN, LOW);

      if (file) file.close();
      //SysCall::halt();
    }
    newData = false;
  }
}//useNewData

void writeHeader() {

  file.print(F("time(us)"));
  for (int c = 0; c < Load_Cell1; c++) {
    file.print(F(",load1"));
    //file.print(c, DEC);
  } for (int d = 0; d < Load_Cell2; d++) {
    file.print(F(",load2"));
    //file.print(d, DEC);
  } for (int e = 0; e < Load_Cell3; e++) {
    file.print(F(",load3"));
    //file.print(e, DEC);
  }
  for (int a = 0; a < Date_count; a++) {
    now = RTC.now();
    file.print(F(",date:"));
    file.print(now.day(), DEC);
    file.print('/');
    file.print(now.month(), DEC);
    file.print('/');
    file.print(now.year(), DEC);

  } for (int b = 0; b < Time_count; b++) {
    file.print(F(",time(hour-minute-second)"));

  }
  file.println();
}
//------------------------------------------------------------------------------

void logData() {

  file.print(logTime);
  for (int c = 0; c < Load_Cell1; c++) {
    file.write(',');
    file.print(scale.get_units());
  } for (int d = 0; d < Load_Cell2; d++) {
    file.write(',');
    file.print(scale1.get_units());
  } for (int e = 0; e < Load_Cell3; e++) {
    file.write(',');
    file.print(scale2.get_units());//file.print(scale2.get_units(),DEC);
  }
  for (int a = 0; a < Date_count; a++) {
    file.write(',');
    //file.print("test");
  } for (int b = 0; b < Time_count; b++) {
    file.write(',');
    file.print(now.hour(), DEC);
    file.print(":");
    file.print(now.minute(), DEC);
    file.print(":");
    file.print(now.second(), DEC);
    file.print(":");
    file.print(micros(), DEC);
  }
  file.println();
  //MOD GERRY

  //relay ();
}
//==============================================================================
void relay () {

  if ( a < 1) {
    unsigned long currentMillis = millis();
    //MOD GERRY
    //if ((relay2State == LOW) && (currentMillis - previousMillis >= OnTime) ) {
    if ((relay2State == LOW) && (currentMillis - previousMillis >= OnTime) && !(previousMillis == 0)) {

      relay2State = HIGH;  // Turn it off
      previousMillis = currentMillis;  // Remember the time
      digitalWrite(relay2, relay2State);  // Update the actual LED
    }
    else if ((relay2State == HIGH) && (currentMillis - previousMillis >= OffTime) ) {

      relay2State = LOW;  // Turn it off
      previousMillis = currentMillis;  // Remember the time
      digitalWrite(relay2, relay2State);  // Update the actual LED
      //alreadyRun = true;
      a++;
      Serial.println(a);

    }
  }
}

There's little commenting and I don't have time to figure out what, say, a variable anonymously named 'a' does but if it works for you that's all you really need.

There are a number of ways to get to a solution to most any problem. If this one works and you're happy with it use it.

What happens if the signal goes high before the process is done?
I will help you get through this if you want, then add the loop counter to prove it runs non-blocking. A button to toggle halt/resume is another proof of functionality and flexibility.

int trigger;
byte state = 0;
const int threshold = 511;
unsigned long msBegin, msLength;

setup() { whatever }

loop()
{
  switch ( state )
  {
    case 0  :  // waiting for signal
    trigger = analogRead();
    msLength = 5000;
    msBegin = millis();
    if ( trigger > threshold )
    {
      state = 1;
    }
    break;

    case 1  :
    if ( millis() - msBegin < msLength )    return;
    ----- turn the relay on
    msBegin = millis();
    state = 2;
    break;

    case 2  :
    if ( millis() - msBegin < msLength )    return;
    ----- turn the relay off
    state = 0;   // go back to wait for signal
    break;
  }
}

The variable a is only for the relay function to run once.
This code seems to work. Also, thanks for your ideas.

Recording and timer start when analog voltage is read. The relay function works once and stops until the recording function is stopped and restarted.
But your point is important. If the recording and timer are started, what if the voltage rises again? I'll have to tweak the code a bit for that.
-It should ignore the voltage spike when the loop is started. Because if it looped on the first voltage spike, it is sufficient. If it is in the loop, if I try to start the loop again, it may cause errors. For this, it should ignore it.

mr. GoForSmoke

What happens if the signal goes high before the process is done?

This is my last edit, so I fixed the last mistake. Thinking about your question, I added a little bit, the code is working now, but I still have a problem, I'm trying to solve it.
I have a situation where I need 4 different validations in an if condition.

There are four situations as follows.
1-Button information
2- voltage information
3- Checking if it is in the loop?
4- Did the correct number come from the serial to start the voltage loop?
I want to check these 4 conditions in 1 if state.
My new code is below.

#include <SPI.h>
#include "SdFat.h"
#include "RTClib.h"
#include "HX711.h"//XFW-HX711 amplifier 80Hz

#define calibration_factor -7090.0
int LOADCELL_DOUT_PIN = 7;
int LOADCELL_SCK_PIN = 6;

int LOADCELL_DOUT_PIN_1 = 5;
int LOADCELL_SCK_PIN_1 = 4;

int LOADCELL_DOUT_PIN_2 = 3;
int LOADCELL_SCK_PIN_2 = 2;
HX711 scale;
HX711 scale1;
HX711 scale2;
int navoser;
int sensorPin = A0;
int relay1 = 8;
int relay2 = 9;
int counterRelay = 0;
unsigned long previousMillis = 0;
long OnTime = 10000;
long OffTime = 50;
int relay2State = LOW;
boolean alreadyRun = false;

int sensorValue = 0;
float voltage;
RTC_DS1307 RTC;//using RTClib
DateTime now;

bool enableDataLogging = false;
String receivedChar;
boolean newData = false;

const uint8_t chipSelect = 10;

const uint32_t SAMPLE_INTERVAL_MS = 1;

#define FILE_BASE_NAME "Result"
#define error(msg) sd.errorHalt(F(msg))
//------------------------------------------------------------------------------

SdFat sd;

SdFile file;// Log file.

uint32_t logTime;

//==============================================================================

int Date_count = 1;
int Time_count = 1;
int Load_Cell1 = 1;
int Load_Cell2 = 1;
int Load_Cell3 = 1;
//------------------------------------------------------------------------------

void load_cell () {

  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.print("t3.txt=");
  Serial.write(0x22);
  Serial.print(scale.get_units(), 1);
  Serial.write(0x22);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.print("t4.txt=");
  Serial.write(0x22);
  Serial.print(scale1.get_units(), 1);
  Serial.write(0x22);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.print("t5.txt=");
  Serial.write(0x22);
  Serial.print(scale2.get_units(), 1);
  Serial.write(0x22);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  navoser = (scale.get_units() + scale1.get_units() + scale2.get_units() / 3);
  Serial.print("t8.txt=");
  Serial.write(0x22);
  Serial.print(navoser);
  Serial.write(0x22);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);

  /*
    Serial.print("Reading: ");
    Serial.print(scale.get_units(), 1);
    // Serial.print(" kg");
    Serial.print("\t");
    Serial.print(scale1.get_units(), 1);
    Serial.print("\t");
    Serial.print(scale2.get_units(), 1);
    Serial.print(" kg");
    Serial.println();
  */

}

void setup() {
  pinMode(sensorPin, INPUT);
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  Serial.begin(9600);//

  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
  scale1.begin(LOADCELL_DOUT_PIN_1, LOADCELL_SCK_PIN_1);
  scale2.begin(LOADCELL_DOUT_PIN_2, LOADCELL_SCK_PIN_2);

  scale.set_scale(calibration_factor);
  scale.tare();

  scale1.set_scale(calibration_factor);
  scale1.tare();

  scale2.set_scale(calibration_factor);
  scale2.tare();

  RTC.begin();

}
void creat_file() {
  const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
  char fileName[13] = FILE_BASE_NAME "00.csv";
  if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) {
    sd.initErrorHalt();
  }

  // Find an unused file name.

  if (BASE_NAME_SIZE > 7) {
    error("FILE_BASE_NAME long");
  }
  while (sd.exists(fileName)) {
    if (fileName[BASE_NAME_SIZE + 1] != '9') {
      fileName[BASE_NAME_SIZE + 1]++;
    } else if (fileName[BASE_NAME_SIZE] != '9') {
      fileName[BASE_NAME_SIZE + 1] = '0';
      fileName[BASE_NAME_SIZE]++;
    } else {
      error("filename not created");
    }
  }
  if (!file.open(fileName, O_WRONLY | O_CREAT | O_EXCL)) {
    error("file.open");
  }
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.print("page 4");
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.print("g1.txt=");
  Serial.write(0x22);
  Serial.print(fileName);
  Serial.write(0x22);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);

  //Serial.print(F("Recording: "));
  //Serial.println(fileName);
  //Serial.println(F("enter any character to stop"));
  writeHeader();

}
//------------------------------------------------------------------------------
void loop() {

  recvOneChar();
  useNewData();
  if (enableDataLogging) {

    logTime += SAMPLE_INTERVAL_MS;
    logData();
    relay ();

    if (!file.sync() || file.getWriteError()) {
      error("error write");
    }
  } else {
    load_cell();
  }
  //MOD GERRY
  //check if anything should be done on the relay
}
void recvOneChar()
{

  sensorValue = analogRead(sensorPin);
  voltage = sensorValue * (5.0 / 1023.0);
  if (Serial.available() > 0 || voltage > 2 ) {
    receivedChar = Serial.readStringUntil('#');

    newData = true;
  }
}//recvOneChar
void useNewData()
{
  if (newData == true)
  {
    //Serial.print("This just in ... ");
    //Serial.println(receivedChar);

    if (enableDataLogging == 0 && (receivedChar.indexOf("2") > -1 || voltage > 2 ) )
    {

      creat_file();
      enableDataLogging = true;
      //MOD GERRY
      previousMillis = 0;    // <----------------
      //alreadyRun = false;    // <----------------
      if (previousMillis == 0)       //has not been set before
        previousMillis = millis();  //will turn on after this time
      counterRelay = 0;
      //Serial.println("Data logging enabled");
      //digitalWrite(LED_BUILTIN, HIGH);
    }
    if (receivedChar.indexOf("5") > -1 )
    {
      enableDataLogging = false;

      //Serial.println("   Data logging disabled");
      //digitalWrite(LED_BUILTIN, LOW);

      if (file) file.close();
      //SysCall::halt();
    }
    newData = false;
  }
}//useNewData

void writeHeader() {

  file.print(F("time(us)"));
  for (int c = 0; c < Load_Cell1; c++) {
    file.print(F(",load1"));
    //file.print(c, DEC);
  } for (int d = 0; d < Load_Cell2; d++) {
    file.print(F(",load2"));
    //file.print(d, DEC);
  } for (int e = 0; e < Load_Cell3; e++) {
    file.print(F(",load3"));
    //file.print(e, DEC);
  }
  for (int a = 0; a < Date_count; a++) {
    now = RTC.now();
    file.print(F(",date:"));
    file.print(now.day(), DEC);
    file.print('/');
    file.print(now.month(), DEC);
    file.print('/');
    file.print(now.year(), DEC);

  } for (int b = 0; b < Time_count; b++) {
    file.print(F(",time(hour-minute-second)"));

  }
  file.println();
}
//------------------------------------------------------------------------------

void logData() {

  file.print(logTime);
  for (int c = 0; c < Load_Cell1; c++) {
    file.write(',');
    file.print(scale.get_units());
  } for (int d = 0; d < Load_Cell2; d++) {
    file.write(',');
    file.print(scale1.get_units());
  } for (int e = 0; e < Load_Cell3; e++) {
    file.write(',');
    file.print(scale2.get_units());//file.print(scale2.get_units(),DEC);
  }
  for (int a = 0; a < Date_count; a++) {
    file.write(',');
    //file.print("test");
  } for (int b = 0; b < Time_count; b++) {
    file.write(',');
    file.print(now.hour(), DEC);
    file.print(":");
    file.print(now.minute(), DEC);
    file.print(":");
    file.print(now.second(), DEC);
    file.print(":");
    file.print(micros(), DEC);
  }
  file.println();
  //MOD GERRY

  //relay ();
}
//==============================================================================
void relay () {

  if ( counterRelay < 1) {
    unsigned long currentMillis = millis();
    //MOD GERRY
    //if ((relay2State == LOW) && (currentMillis - previousMillis >= OnTime) ) {
    if ((relay2State == LOW) && (currentMillis - previousMillis >= OnTime) && !(previousMillis == 0)) {

      relay2State = HIGH;  // Turn it off
      previousMillis = currentMillis;  // Remember the time
      digitalWrite(relay2, relay2State);  // Update the actual LED
    }
    else if ((relay2State == HIGH) && (currentMillis - previousMillis >= OffTime) ) {

      relay2State = LOW;  // Turn it off
      previousMillis = currentMillis;  // Remember the time
      digitalWrite(relay2, relay2State);  // Update the actual LED
      //alreadyRun = true;
      counterRelay++;

    }
  }
}