Adding serial input delay timers to multiple pins

Hello, I am trying to add to my code a segment that allows me to dynamically change the on/off delay in real time through serial monitor. I am a novice to C++ but I have this written so far. These are basic on/off functions which I would like to keep, but I would like to add the option to the program to add timed delays for each pin along with this. I am stuck here and could use some pointers. Thank you!

String cmd; //Variable for storing incoming value
#define relayPin1 6
#define relayPin2 7
#define relayPin3 8
#define relayPin4 9 //Designates relayPin variable to pin
#define relayPin5 10
#define relayPin6 11
#define relayPin7 12
#define relayPin8 13
void setup()
{
//Sets relay control pins to output to sink supplied current and
//sets relays to OFF naturally to start the cycle
digitalWrite(relayPin1, HIGH);
digitalWrite(relayPin2, HIGH);
digitalWrite(relayPin3, HIGH);
digitalWrite(relayPin4, HIGH);
digitalWrite(relayPin5, HIGH);
digitalWrite(relayPin6, HIGH);
digitalWrite(relayPin7, HIGH);
digitalWrite(relayPin8, HIGH);
Serial.begin(9600); //Sets baud rate for bluetooth serial port
Serial.setTimeout(10); //Increases speed of output commands
pinMode(relayPin1, OUTPUT);
pinMode(relayPin2, OUTPUT);
pinMode(relayPin3, OUTPUT);
pinMode(relayPin4, OUTPUT);
pinMode(relayPin5, OUTPUT); //Sets output pins
pinMode(relayPin6, OUTPUT);
pinMode(relayPin7, OUTPUT);
pinMode(relayPin8, OUTPUT);
}
void loop()
{
if (Serial.available())
{
cmd = Serial.readString(); //Assign input command string to loop
if(cmd == "ON") // All relays ON command
{
digitalWrite(relayPin1, HIGH);
digitalWrite(relayPin2, HIGH);
digitalWrite(relayPin3, HIGH);
digitalWrite(relayPin4, HIGH);
digitalWrite(relayPin5, HIGH);
digitalWrite(relayPin6, HIGH);
digitalWrite(relayPin7, HIGH);
digitalWrite(relayPin8, HIGH);
Serial.println("All relays on");
}
if(cmd == "OFF") // All relays OFF command
{
digitalWrite(relayPin1, LOW);
digitalWrite(relayPin2, LOW);
digitalWrite(relayPin3, LOW);
digitalWrite(relayPin4, LOW);
digitalWrite(relayPin5, LOW);
digitalWrite(relayPin6, LOW);
digitalWrite(relayPin7, LOW);
digitalWrite(relayPin8, LOW);
Serial.println("All relays off");
}
// Individual relay on/off commands
if(cmd == "r1") //Relay 1 ON
{
digitalWrite(relayPin1, HIGH);
Serial.println("Relay 1 ON");
}
if(cmd == "R1") //Relay 1 OFF
{
digitalWrite(relayPin1, LOW);
Serial.println("Relay 1 OFF");
}
if(cmd == "r2") //Relay 2 ON
{
digitalWrite(relayPin2, HIGH);
Serial.println("Relay 2 ON");
}
if(cmd == "R2") //Relay 2 OFF
{
digitalWrite(relayPin2, LOW);
Serial.println("Relay 2 OFF");
}
if(cmd == "r3") //Relay 3 ON
{
digitalWrite(relayPin3, HIGH);
Serial.println("Relay 3 ON");
}
if(cmd == "R3") //Relay 3 OFF
{
digitalWrite(relayPin3, LOW);
Serial.println("Relay 3 OFF");
}
if(cmd == "r4") //Relay 4 ON
{
digitalWrite(relayPin4, HIGH);
Serial.println("Relay 4 ON");
}
if(cmd == "R4") //Relay 4 OFF
{
digitalWrite(relayPin4, LOW);
Serial.println("Relay 4 OFF");
}
if(cmd == "r5") //Relay 5 ON
{
digitalWrite(relayPin5, HIGH);
Serial.println("Relay 5 ON");
}
if(cmd == "R5") //Relay 5 OFF
{
digitalWrite(relayPin5, LOW);
Serial.println("Relay 5 OFF");
}
if(cmd == "r6") //Relay 6 ON
{
digitalWrite(relayPin6, HIGH);
Serial.println("Relay 6 ON");
}
if(cmd == "R6") //Relay 6 OFF
{
digitalWrite(relayPin6, LOW);
Serial.println("Relay 6 OFF");
}
if(cmd == "r7") //Relay 7 ON
{
digitalWrite(relayPin7, HIGH);
Serial.println("Relay 7 ON");
}
if(cmd == "R7") //Relay 7 OFF
{
digitalWrite(relayPin7, LOW);
Serial.println("Relay 7 OFF");
}
if(cmd == "r8") //Relay 8 ON
{
digitalWrite(relayPin8, HIGH);
Serial.println("Relay 8 ON");
}
if(cmd == "R8") //Relay 8 OFF
{
digitalWrite(relayPin8, LOW);
Serial.println("Relay 8 OFF");
}
}
}

You should post code by using code-tags
There is an automatic function for doing this in the Arduino-IDE
just three steps

  1. press Ctrl-T for autoformatting your code
  2. do a rightclick with the mouse and choose "copy for forum"
  3. paste clipboard into write-window of a posting

for re-editing an existing post

  • simply click on the pencil icon
  • mark all plain text
  • press Ctrl-X to cut out
  • do steps like described above

best regards Stefan

There are very different ways to create such a functionality.
What do you prefer:

  • understanding what the code does through programming it "by hand"

  • using an existing library that hides away almost all details how it works just writing a few lines of code that call functions of the library

best regards Stefan

I would like to know by hand, and thanks!

String cmd;                  //Variable for storing incoming value

#define relayPin1 6
#define relayPin2 7
#define relayPin3 8
#define relayPin4 9          //Designates relayPin variable to pin
#define relayPin5 10
#define relayPin6 11
#define relayPin7 12
#define relayPin8 13
 

void setup() 
{

//Sets relay control pins to output to sink supplied current and
//sets relays to OFF naturally to start the cycle
    digitalWrite(relayPin1, HIGH);
    digitalWrite(relayPin2, HIGH);
    digitalWrite(relayPin3, HIGH);
    digitalWrite(relayPin4, HIGH);
    digitalWrite(relayPin5, HIGH);
    digitalWrite(relayPin6, HIGH);
    digitalWrite(relayPin7, HIGH);
    digitalWrite(relayPin8, HIGH);

    Serial.begin(9600);            //Sets baud rate for bluetooth serial port
    Serial.setTimeout(10);         //Increases speed of output commands
    pinMode(relayPin1, OUTPUT);
    pinMode(relayPin2, OUTPUT);
    pinMode(relayPin3, OUTPUT);
    pinMode(relayPin4, OUTPUT);
    pinMode(relayPin5, OUTPUT);    //Sets output pins
    pinMode(relayPin6, OUTPUT);
    pinMode(relayPin7, OUTPUT);
    pinMode(relayPin8, OUTPUT);
}

void loop() 
{
    if (Serial.available()) 
    {
        cmd = Serial.readString();   //Assign input command string to loop

        if(cmd == "ON")      // All relays ON command
        {
            digitalWrite(relayPin1, HIGH);
            digitalWrite(relayPin2, HIGH);
            digitalWrite(relayPin3, HIGH);
            digitalWrite(relayPin4, HIGH);
            digitalWrite(relayPin5, HIGH);
            digitalWrite(relayPin6, HIGH);
            digitalWrite(relayPin7, HIGH);
            digitalWrite(relayPin8, HIGH);
            Serial.println("All relays on");
        }
        if(cmd == "OFF")     // All relays OFF command
        {
            digitalWrite(relayPin1, LOW);
            digitalWrite(relayPin2, LOW);
            digitalWrite(relayPin3, LOW);
            digitalWrite(relayPin4, LOW);
            digitalWrite(relayPin5, LOW);
            digitalWrite(relayPin6, LOW);
            digitalWrite(relayPin7, LOW);
            digitalWrite(relayPin8, LOW);
            Serial.println("All relays off");
        } 
// Individual relay on/off commands
        if(cmd == "r1")                    //Relay 1 ON
        {
          digitalWrite(relayPin1, HIGH);
          Serial.println("Relay 1 ON");
        }
        if(cmd == "R1")                    //Relay 1 OFF
        {
          digitalWrite(relayPin1, LOW);
          Serial.println("Relay 1 OFF");
        }
        if(cmd == "r2")                    //Relay 2 ON
        {
          digitalWrite(relayPin2, HIGH);
          Serial.println("Relay 2 ON");
        }
        if(cmd == "R2")                    //Relay 2 OFF
        {
          digitalWrite(relayPin2, LOW);
          Serial.println("Relay 2 OFF");
        }
        if(cmd == "r3")                    //Relay 3 ON
        {
          digitalWrite(relayPin3, HIGH);
          Serial.println("Relay 3 ON");
        }
        if(cmd == "R3")                    //Relay 3 OFF
        {
          digitalWrite(relayPin3, LOW);
          Serial.println("Relay 3 OFF");
        }
        if(cmd == "r4")                    //Relay 4 ON
        {
          digitalWrite(relayPin4, HIGH);
          Serial.println("Relay 4 ON");
        }
        if(cmd == "R4")                    //Relay 4 OFF
        {
          digitalWrite(relayPin4, LOW);
          Serial.println("Relay 4 OFF");
        }
        if(cmd == "r5")                    //Relay 5 ON
        {
          digitalWrite(relayPin5, HIGH);
          Serial.println("Relay 5 ON");
        }
        if(cmd == "R5")                    //Relay 5 OFF
        {
          digitalWrite(relayPin5, LOW);
          Serial.println("Relay 5 OFF");
        }
        if(cmd == "r6")                    //Relay 6 ON
        {
          digitalWrite(relayPin6, HIGH);
          Serial.println("Relay 6 ON");
        }
        if(cmd == "R6")                    //Relay 6 OFF
        {
          digitalWrite(relayPin6, LOW);
          Serial.println("Relay 6 OFF");
        }
        if(cmd == "r7")                    //Relay 7 ON
        {
          digitalWrite(relayPin7, HIGH);
          Serial.println("Relay 7 ON");
        }
        if(cmd == "R7")                    //Relay 7 OFF
        {
          digitalWrite(relayPin7, LOW);
          Serial.println("Relay 7 OFF");
        }
        if(cmd == "r8")                    //Relay 8 ON
        {
          digitalWrite(relayPin8, HIGH);
          Serial.println("Relay 8 ON");
        }
        if(cmd == "R8")                    //Relay 8 OFF
        {
          digitalWrite(relayPin8, LOW);
          Serial.println("Relay 8 OFF");
        }
    }
}

please re-edit your first post by clicking on the pencil-button below your post

Your code can be written much shorter by the use of arrays.
Here is an explanation how it works

additionally I want to introduce you to serial debug-output which makes visible what you code is really doing. This makes it much easier to find bugs

Here is a democode that shows how it works

#define dbg(myFixedText, variableName) \
        Serial.print( F(#myFixedText " "  #variableName"=") ); \
        Serial.println(variableName); 
// usage dbg("fixed Text", variableName)
// example printing name and content of a variable called "myCounter"
// dbg("Demo-Text",myCounter);
// serialoutput will be '"Demo-Text" myCounter=1'
// which means this macro does three things
// 1. print the fixed text 
// 2. print the NAME of the variable
// 3. print the content of the variable 
// all in one line

int myCounter;

void setup() {
  Serial.begin(115200);
  Serial.print( F("\n Setup-Start  \n") );
  myCounter =0;
}

void loop() {
  myCounter++;
  
  dbg("Demo-Text",myCounter);
  // whenever possible replace delay() 
  // by non-blocking timing based on millis()
  delay(1000); 
}
// serial output will look like this
/*
 Setup-Start  
"Demo-Text" myCounter=1
"Demo-Text" myCounter=2
"Demo-Text" myCounter=3
"Demo-Text" myCounter=4
...
*/

best regards Stefan

Sorry, I can’t post the underlying code, but this might give some ideas (4 channels only), or I could take a contract to write your code using the same methods for 8 channels of relay.

CM user guide

Take a look at the outputs in particular, and
SET commands :
SET PULSE
SET FLASH
OUT XXX ON/OFF/TOGgle

Timers, OUTON, OUTOFF etc.

not exactly sure what you want to delay

consider following that that handles many LEDs a bit more efficiently and can support more commands

#undef MyHW
#ifdef MyHW
byte pinsLed [] = { 10, 11, 12, 13 };
#else
byte pinsLed [] = { 6, 7, 8, 9, 10, 11, 12, 13 };
#endif

#define N_LED   (int)sizeof(pinsLed)

enum { Off = HIGH, On = LOW };

char c;
int  val;

int  ledDelay = 0;

// -----------------------------------------------------------------------------
void
loop ()
{
    if (! Serial.available ())
        return;

    String cmd = Serial.readString ();
    Serial.println (cmd);

    sscanf (cmd.c_str (), "%c%d", &c, &val);

    if (cmd == "ON")
        for (unsigned n = 0; n < N_LED; n++)
            digitalWrite (pinsLed [n], On);

    else if (cmd == "OFF")
        for (unsigned n = 0; n < N_LED; n++)
            digitalWrite (pinsLed [n], Off);

    else if ('d' == c)
        ledDelay = val;

    else if ('t' == c)  {
        if (0 <= val && val < N_LED)
            digitalWrite (pinsLed [val], ! digitalRead (pinsLed [val]));
    }

    if (ledDelay)  {
        delay (ledDelay);
        digitalWrite (pinsLed [val], ! digitalRead (pinsLed [val]));
    }
}

// -----------------------------------------------------------------------------
void
setup ()
{
    Serial.begin (9600);

    for (unsigned n = 0; n < N_LED; n++)  {
        digitalWrite (pinsLed [n], Off);
        pinMode      (pinsLed [n], OUTPUT);
    }
}

Hello
For a simple command line interface take a view here:
https://www.norwegiancreations.com/2018/02/creating-a-command-line-interface-in-arduinos-serial-monitor/

add

cmd.trim(); //to remove any trailing \r\n the IDE may have added.
cmd.toupper(); // all tests are upper case so force that

As for adding time delays set by Serial input
That can get messy. You need to 'parse' the input for the commands.
Here is a menu system I used in a recent job
It uses my SafeString library to do the tokenizing so it may not satisfy your requirement of "by hand".

menu.cpp (6.5 KB)
menu.h (254 Bytes)

you should give an example how the delaying shall work

one way would be to send a command "od3,25" where
"o" switch ON
"d" keep switched on
"3" relay 3
"," separator for the waiting time
"25" delay switching OFF 25 seconds.

delaying could go beyond this that you can send commands that setup each relay to switch on/off in a certain pattern like
relay 1 5 seconds ON 12 seconds OFF - repeat
relay 2 permanently ON
relay 3 120 seconds ON 34 seconds OFF - repeat
etc.

and this would require extending your code more.

To be not misunderstood: any kind of programming as a hobby or to learn is OK.
As you have described you have this 8 channel-relay-board: is this just a programming exercise or do you have a real world application in mind?
Do you have the next steps "next I want to learn...." in mind?
I'm asking this just out of curiosity and how input to you should be to match your wishes.

best regards Stefan

Thanks, I figured out what I needed to do and then some. Thank you all for the guidance

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.