Using Millis() Function to turn on/off relay for x amount of seconds

Hello:),
I am trying to turn on relays at a certain amount of seconds that the user inputs into a GUI.
My code works once after compiling and uploading but when I turn the relays off and try to turn them back on again at a different rate, they turn on immediately. I can’t understand what’s the problem causing it.
*When I want to turn off the relay’s I send the character B from the GUI.
*Please do not notice the interrupt code as that will be implemented later.

Code:
.ino

#include "Mimsarim.h"
#include "U8glib.h"

U8GLIB_ST7920_128X64_1X u8g(18, 16, 17);  // SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17
//PORTD PINOUT
//PH6 - digital Pin 9
//PH4 - digital Pin 7
Mimsarim mim(9, 7, 11);//assign initial values to class constructor

void lcdSetup () {
  // flip screen, if required
  // u8g.setRot180();

  // set SPI backup if required
  //u8g.setHardwareBackup(u8g_backup_avr_spi);

  // assign default color value
  if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
    u8g.setColorIndex(255);     // white
  }
  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
    u8g.setColorIndex(3);         // max intensity
  }
  else if ( u8g.getMode() == U8G_MODE_BW ) {
    u8g.setColorIndex(1);         // pixel on
  }
  else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255, 255, 255);
  }
  pinMode(8, OUTPUT);

}


void setup() {
  lcdSetup();
  Serial.begin(9600);
  Serial3.begin(9600);
 // mim.interruptSetup();
}
/*
ISR(TIMER1_COMPA_vect)
{
  mim.firstISR();
}
*/

/*
ISR(TIMER3_COMPA_vect)
{
  mim.secondISR();
}
*/

void loop() {
  lcdLoop();
  if (Serial3.available() > 0)
  {
    mim.Modes();
  }
}


void draw(void) {
  // graphic commands to redraw the complete screen should be placed here
  u8g.setFont(u8g_font_unifont);
  //u8g.setFont(u8g_font_osb21);
  u8g.drawStr( 0, 22, "STATUS1=" );
  u8g.setPrintPos(65, 22);
  u8g.drawStr( 97, 22, "sec" );
  u8g.print(mim.getIntervalA());
  u8g.drawStr( 0, 50, "STATUS2=" );
  u8g.setPrintPos(65, 50);
  u8g.print(mim.getIntervalB());
  u8g.drawStr( 97, 50, "sec" );

}


void lcdLoop(void) {
  // picture loop
  u8g.firstPage();
  do {
    draw();
  } while ( u8g.nextPage() );

  // rebuild the picture after some delay
  delay(50);
}

.cpp

#include "Mimsarim.h"

#define STARTM '<'
#define ENDM '>'

float Mimsarim::getIntervalA();
float Mimsarim::getIntervalB();

boolean Mimsarim::firstChecked;
boolean Mimsarim::secChecked;


int Mimsarim::index;
Mimsarim::Mimsarim(int relayPin2, int relayPin3, int ledPin)//assign initial value to class constructor
{
  _init = true;
  _running = false;
  index = 0;

  _relayPin2 = relayPin2;
  _relayPin3 = relayPin3;
  _ledPin = ledPin;

  digitalWrite(relayPin2, HIGH);
  digitalWrite(relayPin3, HIGH);
  pinMode(relayPin2, OUTPUT);
  // PORTH = B10101111;
  pinMode(relayPin3, OUTPUT);
  pinMode(ledPin, OUTPUT);
}


void Mimsarim::Modes()
{
  String myString;
  char c;

  while (Serial3.available())
  {
    delay(2);
    c = Serial3.read();
    myString += c;
  }

  switch (myString[0])
  {
    case 'B':

       Serial.println(myString);
      myString = "";
      _running = false;
      offPress = millis();
      digitalWrite(_relayPin2, HIGH);
      digitalWrite(_relayPin3, HIGH);
      // PORTH = B10101111;
      //    PORTB = B00100000;
      defaultRun();
      _running = false;
      break;


    case '<':
      //     PORTB = B11011111;
      parseData(myString);
      _running = true;
      defaultRun();
      break;


    case 'x':
      Serial3.println("<connected>"); //GUI indicator
      defaultRun();
      break;


  }
}

void Mimsarim::defaultRun()
{
  unsigned long currentMillis = 0;

  byte relayState1 = digitalRead(_relayPin2);
  byte relayState2 = digitalRead(_relayPin3);

  while (_running) {
    currentMillis = millis();
    if (((currentMillis - offPress) - previousRelay_A_Millis >= Relay_A_Interval ) && (relayState1))// ( Relay_A_Interval > 0 ))
    {
      Serial.println(Relay_A_Interval);
      digitalWrite(_relayPin2, LOW);
      //digitalWrite(_relayPin2, digitalRead(_relayPin2) ^ 1);
      previousRelay_A_Millis = currentMillis;//Relay_A_Interval;  //previousRelay_A_Millis += Relay_A_Interval;
    }

    if (((currentMillis - offPress) - previousRelay_B_Millis >= Relay_B_Interval ) && (relayState2))//( Relay_B_Interval > 0 ))
    {
      Serial.println(Relay_B_Interval);
      digitalWrite(_relayPin3, LOW);
      //digitalWrite(_relayPin3, digitalRead(_relayPin3) ^ 1);
      previousRelay_B_Millis = currentMillis;//Relay_B_Interval;//previousRelay_B_Millis += Relay_B_Interval;
    }

    while (Serial3.available()) {
      Modes();
    }
  }
}

void Mimsarim::parseData(String x)
{
  Mimsarim::Relay_A_Interval = (x.substring(x.indexOf('<') + 1, x.indexOf(':')).toInt())  * 1000; 
  // Serial.println(Relay_A_Interval);
  Mimsarim::Relay_B_Interval = (x.substring(x.indexOf(':') + 1 , x.length() - 1).toInt()) * 1000; 
  // Serial.println(Relay_B_Interval);
}


/*
float Mimsarim::getIntervalA()
{
  return Relay_A_Interval * 1000;
}

float Mimsarim::getIntervalB()
{
  return Relay_B_Interval * 1000;
}
*/



void Mimsarim::interruptSetup()
{
  noInterrupts(); // disable all interrupts
  TCCR1A = 0; //Initialize the Timer control register A for safety
  TCCR1B = 0; //Initialize the Timer control register B for safety
  TCNT1 = 0;  // intialize counter value to 0
  OCR1A = 6249;   //100 milliseconds interrupt on 256 prescaler timer1
  TCCR1B |= (1 << WGM12);   // CTC Mode ON
  TCCR1B |= (1 << CS12);  //set prescaler to 256
  TIMSK1 |= (1 << OCIE1A); //enable timer compare interrupt

  TCCR3A = 0; //Initialize the Timer control register A for safety
  TCCR3B = 0; //Initialize the Timer control register B for safety
  TCNT3 = 0;  // intialize counter value to 0
  OCR3A = 6249;   //100 milliseconds interrupt on 256 prescaler timer1
  TCCR3B |= (1 << WGM32);   // CTC Mode ON
  TCCR3B |= (1 << CS32);  //set prescaler to 256
  TIMSK3 |= (1 << OCIE3A); //enable timer compare interrupt
  interrupts();             // enable all interrupts
  // timer1 counter = (((16000000)/(256*(1/100msec)))-1) = 6249;   // preload timer1 - if the counter has reached this value, Compare Interrupt occurs.
}


/*
  void Mimsarim::firstISR()
  {

  milliseconds += 0.1; //if want better resolution, change parameters to Int and milliseconds++
  if (_running) {
    if (( milliseconds >= getIntervalA() ) && ( getIntervalA() > 0 ))
    {
  //    ISR1 = true;
      milliseconds = 0;
    }
  }
  }

  /*
  void Mimsarim::secondISR()
  {
  milliseconds2 += 0.1; //if want better resolution, change parameters to Int and milliseconds++
  if (_running) {
    if ( (milliseconds2 >= getIntervalB() ) && ( getIntervalB() > 0 ))
    {
      secChecked = true;
      milliseconds2 = 0;
      //     digitalWrite(_relayPin3, digitalRead(_relayPin3) ^ 1);
      //  PORTH = B00001000;
      //    digitalWrite(_relayPin3, LOW);
    }
  }
  //      digitalWrite(_relayPin3, HIGH);
  }


  /*
  void TimerProto::interruptS() {

  ISR(TIMER1_COMPA_vect)
  {
    milliseconds += 0.1; //if want better resolution, change parameters to Int and milliseconds++
    if (_running) {
      if (( milliseconds >= getIntervalA() ) && ( getIntervalA() > 0 ))
      {
        firstChecked = true;
        milliseconds = 0;
        //digitalWrite(_relayPin2, digitalRead(_relayPin2) ^ 1);
        // digitalWrite(_relayPin2, LOW);
        PORTH = B01000000;

      }
    }
  }

  ISR(TIMER3_COMPA_vect)
  {
    milliseconds2 += 0.1; //if want better resolution, change parameters to Int and milliseconds++
    if (_running) {
      if ( (milliseconds2 >= getIntervalB() ) && ( getIntervalB() > 0 ))
      {
        secChecked = true;
        milliseconds2 = 0;
        //digitalWrite(_relayPin3, digitalRead(_relayPin3) ^ 1);
        PORTH = B00001000;
      }
    }

  }

  }
*/

Where is offPress declared?

You seem to have several delay()s in your program and also some WHILE loops. Both of the block them Arduino until they complete and they may be interfering with the timing using millis()

Use millis() to manage timing as illustrated in Several Things at a Time.

Note how each function runs very briefly and returns to loop() so the next one can be called. None of the functions tries to complete a task in one call. And there may be dozens of calls to a function before it is actually time for it to do anything.

Have a look at Using millis() for timing. A beginners guide if you need more explanation.

...R

Robin2:
You seem to have several delay()s in your program and also some WHILE loops. Both of the block them Arduino until they complete and they may be interfering with the timing using millis()

Use millis() to manage timing as illustrated in Several Things at a Time.

Note how each function runs very briefly and returns to loop() so the next one can be called. None of the functions tries to complete a task in one call. And there may be dozens of calls to a function before it is actually time for it to do anything.

Have a look at Using millis() for timing. A beginners guide if you need more explanation.

…R

I updated the code following the example. Now it turns the relays on immediately as opposed to turning on after the elapsed time.

.h

#include "Mimsarim.h"

#define STARTM '<'
#define ENDM '>'

float Mimsarim::getIntervalA();
float Mimsarim::getIntervalB();

boolean Mimsarim::firstChecked;
boolean Mimsarim::secChecked;


int Mimsarim::index;
Mimsarim::Mimsarim(int relayPin2, int relayPin3, int ledPin)//assign initial value to class constructor
{
  _init = true;
  _running = false;
  index = 0;

  _relayPin2 = relayPin2;
  _relayPin3 = relayPin3;
  _ledPin = ledPin;

  digitalWrite(relayPin2, HIGH);
  digitalWrite(relayPin3, HIGH);
  pinMode(relayPin2, OUTPUT);
  pinMode(relayPin3, OUTPUT);
  pinMode(ledPin, OUTPUT);
}


void Mimsarim::Modes()
{
  String myString;
  char c;

  while (Serial3.available())
  {
    c = Serial3.read();
    myString += c;
  }

  switch (myString[0])
  {
    case 'B':

      // Serial.println(myString);
      myString = "";
      _running = false;
      offPress = millis();  //save time when the relays were OFF
      previousRelay_A_Millis += offPress;
      previousRelay_B_Millis += offPress;
      digitalWrite(_relayPin2, HIGH);
      digitalWrite(_relayPin3, HIGH);
      defaultRun();
      break;


    case '<':
      parseData(myString);
      _running = true;
      defaultRun();
      break;


    case 'x':
      Serial3.println("<connected>"); //GUI indicator
      defaultRun();
      break;


  }
}

void Mimsarim::defaultRun()
{
  if (_running) {
    relayRun();
  } else Modes();
}


void Mimsarim::parseData(String x)
{
  Mimsarim::Relay_A_Interval = (x.substring(x.indexOf('<') + 1, x.indexOf(':')).toInt())  * 1000; 
  // Serial.println(Relay_A_Interval);
  Mimsarim::Relay_B_Interval = (x.substring(x.indexOf(':') + 1 , x.length() - 1).toInt()) * 1000; 
  // Serial.println(Relay_B_Interval);
}



float Mimsarim::getIntervalA()
{
  return Relay_A_Interval * 1000;
}

float Mimsarim::getIntervalB()
{
  return Relay_B_Interval * 1000;
}

void Mimsarim::relayRun() {

  unsigned long currentMillis = 0;

  byte relayState1 = digitalRead(_relayPin2);
  byte relayState2 = digitalRead(_relayPin3);

  currentMillis = millis();

  if (relayState1) {
    if (currentMillis - previousRelay_A_Millis >= Relay_A_Interval )
    {
      Serial.println(Relay_A_Interval);
      digitalWrite(_relayPin2, LOW);
      //digitalWrite(_relayPin2, digitalRead(_relayPin2) ^ 1);
      previousRelay_A_Millis += Relay_A_Interval;
    }
  }
  if (relayState2) {
    //  if (((currentMillis - offPress) - previousRelay_B_Millis >= Relay_B_Interval ) && (relayState2))//( Relay_B_Interval > 0 ))
    if (currentMillis - previousRelay_B_Millis >= Relay_B_Interval )
    {
      Serial.println(Relay_B_Interval);
      digitalWrite(_relayPin3, LOW);
      //digitalWrite(_relayPin3, digitalRead(_relayPin3) ^ 1);
      previousRelay_B_Millis += Relay_B_Interval;
    }
  }
  _running = false;
}

BennyGol:
I updated the code following the example. Now it turns the relays on immediately as opposed to turning on after the elapsed time.

Try changing this

previousRelay_A_Millis += Relay_A_Interval;

to this

previousRelay_A_Millis = curMillis;

Your problem may be due to a long time having elapsed between the moment when previousRelay_A_millis was initialized and the moment when it was first used.

...R

Robin2:
Try changing this

previousRelay_A_Millis += Relay_A_Interval;

to this

previousRelay_A_Millis = curMillis;

Your problem may be due to a long time having elapsed between the moment when previousRelay_A_millis was initialized and the moment when it was first used.

…R

I have tried it before but to no avail.
I changed the code a bit and got back to square one. I still can’t see where my problem lies, even though I tried many variations.

#include "Mimsarim.h"

#define STARTM '<'
#define ENDM '>'

float Mimsarim::getIntervalA();
float Mimsarim::getIntervalB();

boolean Mimsarim::firstChecked;
boolean Mimsarim::secChecked;


int Mimsarim::index;
Mimsarim::Mimsarim(int relayPin2, int relayPin3, int ledPin)//assign initial value to class constructor
{
  _init = true;
  _running = false;
  index = 0;

  _relayPin2 = relayPin2;
  _relayPin3 = relayPin3;
  _ledPin = ledPin;

  digitalWrite(relayPin2, HIGH);
  digitalWrite(relayPin3, HIGH);
  pinMode(relayPin2, OUTPUT);
  pinMode(relayPin3, OUTPUT);
  pinMode(ledPin, OUTPUT);
}


void Mimsarim::Modes()
{
  String myString;
  char c;

  while (Serial3.available())
  {
    c = Serial3.read();
    myString += c;
  }

  switch (myString[0])
  {
    case 'B':

      myString = "";
      _running = false;
      offPress = millis();  //save time when the state was changed
      previousRelay_A_Millis += offPress;
      previousRelay_B_Millis += offPress;
      digitalWrite(_relayPin2, HIGH);
      digitalWrite(_relayPin3, HIGH);

      defaultRun();
      break;


    case '<':
      parseData(myString);
      _running = true;
      defaultRun();
      break;


    case 'x':
      Serial3.println("<connected>"); //GUI indicator
      defaultRun();
      break;


  }
}

void Mimsarim::defaultRun()
{

  while (_running) {
    relayRun();
    Modes();
    if (Serial3.available()) {
      break;
    }
  }
  
}


void Mimsarim::parseData(String x)
{
  Mimsarim::Relay_A_Interval = (x.substring(x.indexOf('<') + 1, x.indexOf(':')).toInt())  * 1000;

  Mimsarim::Relay_B_Interval = (x.substring(x.indexOf(':') + 1 , x.length() - 1).toInt()) * 1000; 

}



float Mimsarim::getIntervalA()
{
  return Relay_A_Interval * 1000;
}

float Mimsarim::getIntervalB()
{
  return Relay_B_Interval * 1000;
}

void Mimsarim::relayRun() {


  byte relayState1 = digitalRead(_relayPin2);
  byte relayState2 = digitalRead(_relayPin3);

  unsigned long currentMillis = millis();
  
  if ((currentMillis - previousRelay_A_Millis >= Relay_A_Interval ) && ( Relay_A_Interval > 0 )){
    
    previousRelay_A_Millis = currentMillis;

    if (relayState1)
    {
      relayState1 = LOW;
      Serial.println(Relay_A_Interval);
      digitalWrite(_relayPin2, relayState1);
    } else relayState1 = HIGH;
  }
  if ((currentMillis - previousRelay_B_Millis >= Relay_B_Interval ) && ( Relay_B_Interval > 0 )){
    
    previousRelay_B_Millis = currentMillis;

    if (relayState2)
    {
      relayState2 = LOW;
      Serial.println(Relay_B_Interval);
      digitalWrite(_relayPin3, relayState2);
    } else relayState2 = HIGH;
  }
}

BennyGol:
I have tried it before but to no avail.

Post that version and I will have a look at it.

...R

Robin2:
Post that version and I will have a look at it.

…R

#include "Mimsarim.h"

#define STARTM '<'
#define ENDM '>'





int Mimsarim::index;
Mimsarim::Mimsarim(int relayPin2, int relayPin3, int ledPin)//assign initial value to class constructor
{
  _init = true;
  _running = false;
  index = 0;

  _relayPin2 = relayPin2;
  _relayPin3 = relayPin3;
  _ledPin = ledPin;

  digitalWrite(relayPin2, HIGH);
  digitalWrite(relayPin3, HIGH);
  pinMode(relayPin2, OUTPUT);
  pinMode(relayPin3, OUTPUT);
  pinMode(ledPin, OUTPUT);
}


void Mimsarim::Modes()
{
  String myString;
  char c;

  while (Serial3.available())
  {
    c = Serial3.read();
    myString += c;
  }

  switch (myString[0])
  {
    case 'B':

      myString = "";
      _running = false;
      offPress = millis();  //save time when the state was changed
      previousRelay_A_Millis += offPress;
      previousRelay_B_Millis += offPress;
      digitalWrite(_relayPin2, HIGH);
      digitalWrite(_relayPin3, HIGH);

      defaultRun();
      break;


    case '<':
      parseData(myString);
      _running = true;
      defaultRun();
      break;


    case 'x':
      Serial3.println("<connected>"); //GUI indicator
      defaultRun();
      break;


  }
}

void Mimsarim::defaultRun()
{

  if (_running)
 {
    relayRun();

 }else Modes();

}



void Mimsarim::parseData(String x)
{
  Mimsarim::Relay_A_Interval = (x.substring(x.indexOf('<') + 1, x.indexOf(':')).toInt())  * 1000;

  Mimsarim::Relay_B_Interval = (x.substring(x.indexOf(':') + 1 , x.length() - 1).toInt()) * 1000;

}


void Mimsarim::relayRun() {


  byte relayState1 = digitalRead(_relayPin2);
  byte relayState2 = digitalRead(_relayPin3);

  unsigned long currentMillis = millis();
 
  if ((currentMillis - previousRelay_A_Millis >= Relay_A_Interval ) && ( Relay_A_Interval > 0 )){
   
    previousRelay_A_Millis = currentMillis;

    if (relayState1)
    {
      relayState1 = LOW;
      Serial.println(Relay_A_Interval);
      digitalWrite(_relayPin2, relayState1);
    } else relayState1 = HIGH;
  }

  if ((currentMillis - previousRelay_B_Millis >= Relay_B_Interval ) && ( Relay_B_Interval > 0 )){
   
    previousRelay_B_Millis = currentMillis;

    if (relayState2)
    {
      relayState2 = LOW;
      Serial.println(Relay_B_Interval);
      digitalWrite(_relayPin3, relayState2);
    } else relayState2 = HIGH;
  }
}
Mimsarim::Mimsarim(int relayPin2, int relayPin3, int ledPin)//assign initial value to class constructor

Don't do that. The class constructor runs before setup() and before all the hardware is set up. pinMode and other things may get changed back to the default after you just set them to your settings.

Provide a .begin() method and use that to set up the hardware.

while (Serial3.available())

So this library you are writing, it will only work on Arduino variants that have Serial3? You will never change that, even when the next version of the circuit board will be 10mm smaller by running the traces to Serial2 instead?

This has a smell:

parseData(myString)

It smells of "my code is so damn slow that it it possible to type a complete message in between the times that it looks at Serial 3." It also smells of "my external system sending these messages magically knows not to start sending a message in the middle of a read."

You must always be prepared for receiving partial messages. Serial is S. L. O. W. You should expect to only get one character at a time. Add it to a persistent storage (not a local variable) and then check if the message is complete. Also think about what might happen if you get the tail of one message on the front of the next message.

State1 is read from Pin2 and then IntervalA is applied to that? Go ahead and use Roman numerals to make it less understandable.

Referring to the code in Reply #7 ...

What is "Mimsarim" - this is the first time I have heard of it. A wild guess is that the problem is somewhere within that code.

...R

author=MorganS link=msg=4346821 date=1571852166]
Don’t do that. The class constructor runs before setup() and before all the hardware is set up. pinMode and other things may get changed back to the default after you just set them to your settings.

Provide a .begin() method and use that to set up the hardware.
So this library you are writing, it will only work on Arduino variants that have Serial3? You will never change that, even when the next version of the circuit board will be 10mm smaller by running the traces to Serial2 instead?

This has a smell:It smells of “my code is so damn slow that it it possible to type a complete message in between the times that it looks at Serial 3.” It also smells of “my external system sending these messages magically knows not to start sending a message in the middle of a read.”

You must always be prepared for receiving partial messages. Serial is S. L. O. W. You should expect to only get one character at a time. Add it to a persistent storage (not a local variable) and then check if the message is complete. Also think about what might happen if you get the tail of one message on the front of the next message.

State1 is read from Pin2 and then IntervalA is applied to that? Go ahead and use Roman numerals to make it less understandable.

Sorry for the long reply but regards to your remarks, I changed the data receiving function. Also, my code has to work with Serial3 because of the RS232 connection that takes the normal Serial TX RX pins.

I’ve worked on the code and it seems to work well after the upload but when I stop sending serial data via the gui(sending the char B), I must start it quickly again. My problem seems to related to offPress but I can’t quite figure it out.

#include "Mimsarim.h"

#define STARTM '<'
#define ENDM '>'


int Mimsarim::index;
Mimsarim::Mimsarim(int relayPinA, int relayPinB, int ledPin)//assign initial value to class constructor
{
 _init = true;
 _running = false;
 index = 0;

 _relayPinA = relayPinA;
 _relayPinB = relayPinB;
 _ledPin = ledPin;

 digitalWrite(relayPinA, HIGH);
 digitalWrite(relayPinB, HIGH);
 pinMode(relayPinA, OUTPUT);
 pinMode(relayPinB, OUTPUT);
 pinMode(ledPin, OUTPUT);
}


void Mimsarim::Modes()
{

 static boolean recvInProgress = false;
 static byte ndx = 0;
 char startMarker = '<'; //startmarker for the arduino to start reading the packet - HEADER
 char endMarker = '>'; //endmarker for the arduino to end reading the packet - FOOTER
 char c;

 while ((Serial3.available() > 0) && (!newData)) {
   c = Serial3.read();
 
   if ( c == 'B') {
     Serial.println("relays off");
     _running = false;
     previousRelay_A_Millis = 0;
     previousRelay_B_Millis = 0;
     currentMillis = 0;
     offPress = millis();  //records the time when the relay state was changed
     digitalWrite(_relayPinA, HIGH);
     digitalWrite(_relayPinB, HIGH);
     defaultRun();
   }

   else if (c == 'x' ) {
     Serial3.println("<connected>"); //GUI indicator
     defaultRun();
   }

   else if (recvInProgress) {
     if (c != endMarker) {
       receivedChars[ndx] = c;
       ndx++;
       if (ndx >= numChars) {
         ndx = numChars - 1;
       }
     }
     else {
       receivedChars[ndx] = '\0'; // terminate the string
       recvInProgress = false;
       ndx = 0;
       newData = true;
       defaultRun();
     }
   }

   else if (c == startMarker) {
     recvInProgress = true;
     _running = true;
   }
 }

}

void Mimsarim::defaultRun()
{

 if (Serial3.available() > 0) { //proceed if there are characters to read
   Modes();
 }
 while(newData) { //as long as there is new data to be processed
   parseData(); //split to two halves
   relayRun();//check if the time was reached, if so turn the relays on after the elapsed time
   if(Serial3.available() > 0) {newData = false;}//if a character was sent from the pc, get out of loop
 }
}






void Mimsarim::parseData()
{

 char * strtokIndx; // this is used by strtok() as an index

 strcpy(dataBefore, receivedChars);

 strtokIndx = strtok(dataBefore, ":");     // get the first part - the string
 strcpy(messageFromPC, strtokIndx); // copy it to messageFromPC
 Relay_A_Interval = atoi(messageFromPC);// convert this part from ASCII to integer

 strtokIndx = strtok(NULL, " ");// this continues where the previous call left off
 strcpy(intFromPC, strtokIndx); //copy it to intFromPC
 Relay_B_Interval = atoi(intFromPC);     // convert this part from ASCII to integer

 Relay_A_Interval *= 100;
 Relay_B_Interval *= 100;

}



//  After some time, actually just over 49 days, the value returned by millis() will get so large that it will not fit in an unsigned long variable and it will roll over to zero and start incrementing again.
void Mimsarim::relayRun() {

 byte relayStateA = digitalRead(_relayPinA);
 byte relayStateB = digitalRead(_relayPinB);

 currentMillis = millis(); //get current time value
   Serial.println(currentMillis - offPress);
 if (( currentMillis - offPress )>= Relay_A_Interval  )  { //if the relays were off, check that relay state change time was accounted for
   
   if (((currentMillis - previousRelay_A_Millis )>= Relay_A_Interval ) && ( Relay_A_Interval > 0 )) {//check that the time interval was reached
     Serial.println("inside first relay");
     if (relayStateA)
     {
       relayStateA = LOW; //change state of flag after the interval time was reached
       digitalWrite(_relayPinA, relayStateA);
     } else relayStateA = HIGH;

     previousRelay_A_Millis = currentMillis; //update the time when we made the change
   }
 }

 if (( currentMillis - offPress )>= Relay_B_Interval )  { //if the relays were off, check that relay state change time was accounted for
        
   if (((currentMillis - previousRelay_B_Millis )>= Relay_B_Interval ) && ( Relay_B_Interval > 0 )) { //check 
     that the time interval was reached
     Serial.println("inside second relay");
     if (relayStateB)
     {
       relayStateB = LOW;
       digitalWrite(_relayPinB, relayStateB);
     } else relayStateB = HIGH;

     previousRelay_B_Millis = currentMillis;
   }
 }
}

Robin2:
Referring to the code in Reply #7

What is “Mimsarim” - this is the first time I have heard of it. A wild guess is that the problem is somewhere within that code.

…R

Relays in Hebrew :slight_smile:

BennyGol:
Relays in Hebrew :slight_smile:

I don't think the question was actually "what does the word mimsarim mean?", but rather "what is this mimsarim.h library of which you speak?". I suspect Robin2 meant he had never heard of the library, whether or not he may have heard the word before.