Pots do not control relay times

Beginner´s question ahead...

Hello, I want to control the on/off state of a 4 ch. relay module (velleman) with 4 potentiometers.
I found a code to control the 4 relays at the same time in a non-blocking fashion.

// Which pins are connected to which RELAY
const byte RELAY01 = 2;
const byte RELAY02 = 3;
const byte RELAY03 = 4;
const byte RELAY04 = 5;

// Time periods of blinks in milliseconds.
const unsigned long RELAY01interval = 1000;
const unsigned long RELAY02interval = 1000;
const unsigned long RELAY03interval = 1000;
const unsigned long RELAY04interval = 1000;

// Variable holding the timer value so far. One for each "Timer"
unsigned long RELAY01timer;
unsigned long RELAY02timer;
unsigned long RELAY03timer;
unsigned long RELAY04timer;

void setup () 
  {
  pinMode (RELAY01, OUTPUT);
  pinMode (RELAY02, OUTPUT);
  pinMode (RELAY03, OUTPUT);
  pinMode (RELAY04, OUTPUT);

  RELAY01timer = millis ();
  RELAY02timer = millis ();
  RELAY03timer = millis ();
  RELAY04timer = millis ();

  }  // end of setup

void toggleRELAY01 ()
  {
   if (digitalRead (RELAY01) == LOW)
      digitalWrite (RELAY01, HIGH);
   else
      digitalWrite (RELAY01, LOW);
  // remember when we toggled it
  RELAY01timer = millis ();  
  }  // end of toggleRELAY01


  void toggleRELAY02 ()
  {
   if (digitalRead (RELAY02) == LOW)
      digitalWrite (RELAY02, HIGH);
   else
      digitalWrite (RELAY02, LOW);
  // remember when we toggled it
  RELAY02timer = millis ();  
  }  // end of toggleRELAY02


    void toggleRELAY03 ()
  {
   if (digitalRead (RELAY03) == LOW)
      digitalWrite (RELAY03, HIGH);
   else
      digitalWrite (RELAY03, LOW);
  // remember when we toggled it
  RELAY03timer = millis ();  
  }  // end of toggleRELAY03


      void toggleRELAY04 ()
  {
   if (digitalRead (RELAY04) == LOW)
      digitalWrite (RELAY04, HIGH);
   else
      digitalWrite (RELAY04, LOW);
  // remember when we toggled it
  RELAY04timer = millis ();  
  }  // end of toggleRELAY04

  



void loop ()
  {

  // Handling the blink of one relay. The other Relays are controlled the same way. Repeat for more Relays

  if ( (millis () - RELAY01timer) >= RELAY01interval)
     toggleRELAY01 ();

  if ( (millis () - RELAY02timer) >= RELAY02interval) 
    toggleRELAY02 ();

  if ( (millis () - RELAY03timer) >= RELAY03interval)
     toggleRELAY03 ();

  if ( (millis () - RELAY04timer) >= RELAY04interval)
     toggleRELAY04 ();

/* Other code that needs to execute goes here.
   It will be called many thousand times per second because the above code
   does not wait for the LED blink interval to finish. */

}  // end of loop

Now, instead of a set value of time period in blinking relays, I want to read that from analog input from 4 potentiometers. There is where I got stucked, I tried with analogread with no luck...maybe is very simple but I can´t find the way..

here is the code I have been using:

// Which pins are connected to which RELAY
const byte RELAY01 = 2;
const byte RELAY02 = 3;
const byte RELAY03 = 4;
const byte RELAY04 = 5;

// Time periods of blinks in milliseconds.
const unsigned long RELAY01interval = analogRead(A0);
const unsigned long RELAY02interval = analogRead(A1);
const unsigned long RELAY03interval = analogRead(A2);
const unsigned long RELAY04interval = analogRead(A3);

// Variable holding the timer value so far. One for each "Timer"
unsigned long RELAY01timer;
unsigned long RELAY02timer;
unsigned long RELAY03timer;
unsigned long RELAY04timer;

void setup () 
  {
  pinMode (RELAY01, OUTPUT);
  pinMode (RELAY02, OUTPUT);
  pinMode (RELAY03, OUTPUT);
  pinMode (RELAY04, OUTPUT);

  RELAY01timer = millis ();
  RELAY02timer = millis ();
  RELAY03timer = millis ();
  RELAY04timer = millis ();

  }  // end of setup

void toggleRELAY01 ()
  {
   if (digitalRead (RELAY01) == LOW)
      digitalWrite (RELAY01, HIGH);
   else
      digitalWrite (RELAY01, LOW);
  // remember when we toggled it
  RELAY01timer = millis ();  
  }  // end of toggleRELAY01


  void toggleRELAY02 ()
  {
   if (digitalRead (RELAY02) == LOW)
      digitalWrite (RELAY02, HIGH);
   else
      digitalWrite (RELAY02, LOW);
  // remember when we toggled it
  RELAY02timer = millis ();  
  }  // end of toggleRELAY02


    void toggleRELAY03 ()
  {
   if (digitalRead (RELAY03) == LOW)
      digitalWrite (RELAY03, HIGH);
   else
      digitalWrite (RELAY03, LOW);
  // remember when we toggled it
  RELAY03timer = millis ();  
  }  // end of toggleRELAY03


      void toggleRELAY04 ()
  {
   if (digitalRead (RELAY04) == LOW)
      digitalWrite (RELAY04, HIGH);
   else
      digitalWrite (RELAY04, LOW);
  // remember when we toggled it
  RELAY04timer = millis ();  
  }  // end of toggleRELAY04

  



void loop ()
  {

  // Handling the blink of one relay. The other Relays are controlled the same way. Repeat for more Relays

  if ( (millis () - RELAY01timer) >= RELAY01interval)
     toggleRELAY01 ();

  if ( (millis () - RELAY02timer) >= RELAY02interval) 
    toggleRELAY02 ();

  if ( (millis () - RELAY03timer) >= RELAY03interval)
     toggleRELAY03 ();

  if ( (millis () - RELAY04timer) >= RELAY04interval)
     toggleRELAY04 ();

/* Other code that needs to execute goes here.
   It will be called many thousand times per second because the above code
   does not wait for the LED blink interval to finish. */

}  // end of loop```

What potentiometer(s) are you using and how have you connected them up to your Arduino?

1 Like

Do you want to vary the times while the code is running, or read once after a reset/power up?
If the latter, move your 4 analog reads into setup (but leave the variable declarations before setup, minus the "CONST" declaration).
If you want to vary the pots during running, the reads will have to go into loop().

Secondly, you'll have to scale each analog read to give a suitable time period; as it is, you'll get a value between 0 and 1023, presuming you're using an Uno or Nano, but you probably want to change that to a number between, say, 500, and 2500.

1 Like
const unsigned long RELAY01interval = analogRead(A0);
const unsigned long RELAY02interval = analogRead(A1);
const unsigned long RELAY03interval = analogRead(A2);
const unsigned long RELAY04interval = analogRead(A3);

You only read the value of the inputs once when declaring the interval variables and to make things worse they are declared as const which means that they cannot be changed later even if you wanted to

Is that what you want to do, bearing in mind that the maximum value read will be 1023 on most Arduinos. Which Arduino are you using ?

2 Likes

look this over

const byte PinLed [] = { LED_BUILTIN };     // just one
const int  Nled = sizeof(PinLed);

const byte PinPot = A0;

unsigned long msecPeriod;
unsigned long msecLst;

// -----------------------------------------------------------------------------
void
loop ()
{
    unsigned long msec = millis ();

    msecPeriod = 10 * analogRead (PinPot);

    if (msec - msecLst >= msecPeriod)  {
        msecLst = msec;

        for (int n = 0; n < Nled; n++)
            digitalWrite (PinLed [n], ! digitalRead (PinLed [n]));
    }
}

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

    for (int n = 0; n < Nled; n++)
        pinMode (PinLed [n], OUTPUT);
}
1 Like

My goal is to run the code and have the relay times interacting with the potentiometer dial in real time. I would be changing the values repeatedly moving the knob...
so obviously const is not the way to go

1 Like

I have 100K and 20K which one do you recommend?
I am connecting left to 5v, right to Ground and center to Digital input pin in arduino

I would like to vary the times while the code is running

Arduino UNO, as mention above i want to "vary the times while the code is running"
so obviously CONST is not the way to go I see

Nor is only reading the pot values once in the sketch. They need to be read in loop() or in a function called from it. Depending on how responsive you need the reaction to changing values to be you could either read them each time through loop() or at fixed intervals. You should also consider only updating the timing values if the pot position has changed significantly

What range of relay timing values are you hoping to use ?

1 Like

great, thanks, but how can I include that in my code?

I was hoping something like 300 to 3000 milliseconds

The posting #23 has the complete code

This code divides all lines that are nescessary to make it work into sub-units
where each sub-unit has that lines of code that build the senseful sub-unit.
with this structure void loop() looks like this

void loop (){
  readPotentiometers();

  checkRelayTimers_and_toggle();

}  // end of loop

This gives you the overview. More in the next postings...

1 Like

before presenting more of the code.
You have 4 very very similar things:

  • 4 IO-pins
  • 4 timers
  • 4 potentiometers
  • 4 intervalls
1 Like

If things are so similar there is a programming-technique called arrays
Your original code defines 4 IO-pins this way

const byte RELAY01 = 2;
const byte RELAY02 = 3;
const byte RELAY03 = 4;
const byte RELAY04 = 5;
1 Like
unsigned long RELAY01interval = 1000;

void toggleRELAY01 ()
  {
   if (digitalRead (RELAY01) == LOW)
      digitalWrite (RELAY01, HIGH);
   else
      digitalWrite (RELAY01, LOW);
  // remember when we toggled it
  RELAY01timer = millis ();  
  RELAY01interval = map(analogRead(A0), 0, 1024, 300, 3000)  // map to 300 milliseconds to 3000 milliseconds
  }  // end of toggleRELAY01
1 Like

sounds like you don't really understand it.

you can add additional relay pin to PinRelay [] without needing to add any additional code

you can also create an array or analog pins and arrays for msecPeriod and msecLast so that each relay is controlled by a separate analog pin.

why don't you study the code some more and give it a try

1 Like

This can be replaced by an array with 4 elements
this looks like this

const byte relayPin[4] = {2, 3, 4, 5};
// relayPin[0] contains value 2
// relayPin[1] contains value 3
// relayPin[2] contains value 4
// relayPin[3] contains value 5

inside the brackets "[" "]" there is an index-number counting from 0 to 3

1 Like

The major logic problem is that the OP's code did not read the pots in real time, not the consts.

They are global constants in the code. You could move them down into the loop() and they would be local constants within the loop and be re-initialized to new and different values as the code runs, and destroyed at the end of loop().

// Which pins are connected to which RELAY
const byte RELAY01 = 2;
const byte RELAY02 = 3;
const byte RELAY03 = 4;
const byte RELAY04 = 5;

// Variable holding the timer value so far. One for each "Timer"
unsigned long RELAY01timer;
unsigned long RELAY02timer;
unsigned long RELAY03timer;
unsigned long RELAY04timer;

void setup () 
  {
  pinMode (RELAY01, OUTPUT);
  pinMode (RELAY02, OUTPUT);
  pinMode (RELAY03, OUTPUT);
  pinMode (RELAY04, OUTPUT);

  RELAY01timer = millis ();
  RELAY02timer = millis ();
  RELAY03timer = millis ();
  RELAY04timer = millis ();

  }  // end of setup

void toggleRELAY01 ()
  {
   if (digitalRead (RELAY01) == LOW)
      digitalWrite (RELAY01, HIGH);
   else
      digitalWrite (RELAY01, LOW);
  // remember when we toggled it
  RELAY01timer = millis ();  
  }  // end of toggleRELAY01


  void toggleRELAY02 ()
  {
   if (digitalRead (RELAY02) == LOW)
      digitalWrite (RELAY02, HIGH);
   else
      digitalWrite (RELAY02, LOW);
  // remember when we toggled it
  RELAY02timer = millis ();  
  }  // end of toggleRELAY02


    void toggleRELAY03 ()
  {
   if (digitalRead (RELAY03) == LOW)
      digitalWrite (RELAY03, HIGH);
   else
      digitalWrite (RELAY03, LOW);
  // remember when we toggled it
  RELAY03timer = millis ();  
  }  // end of toggleRELAY03


      void toggleRELAY04 ()
  {
   if (digitalRead (RELAY04) == LOW)
      digitalWrite (RELAY04, HIGH);
   else
      digitalWrite (RELAY04, LOW);
  // remember when we toggled it
  RELAY04timer = millis ();  
  }  // end of toggleRELAY04

  



void loop ()
  {

// Time periods of blinks in milliseconds.
const unsigned long RELAY01interval = analogRead(A0);
const unsigned long RELAY02interval = analogRead(A1);
const unsigned long RELAY03interval = analogRead(A2);
const unsigned long RELAY04interval = analogRead(A3);


  // Handling the blink of one relay. The other Relays are controlled the same way. Repeat for more Relays

  if ( (millis () - RELAY01timer) >= RELAY01interval)
     toggleRELAY01 ();

  if ( (millis () - RELAY02timer) >= RELAY02interval) 
    toggleRELAY02 ();

  if ( (millis () - RELAY03timer) >= RELAY03interval)
     toggleRELAY03 ();

  if ( (millis () - RELAY04timer) >= RELAY04interval)
     toggleRELAY04 ();

/* Other code that needs to execute goes here.
   It will be called many thousand times per second because the above code
   does not wait for the LED blink interval to finish. */

}  // end of loop

Within loop() the 'const' might be confusing and unnececessary, but the code will work.

2 Likes

This principle can be repeated for:

  • the Potentiometer-Pins
  • the intervals
  • the timers
// Which pins are connected to which RELAY
/*
const byte RELAY01 = 2;
const byte RELAY02 = 3;
const byte RELAY03 = 4;
const byte RELAY04 = 5;
*/
// replaced with an array
const byte relayPin[4] = {2, 3, 4, 5};
// relayPin[0] contains value 2
// relayPin[1] contains value 3
// relayPin[2] contains value 4
// relayPin[3] contains value 5


const byte potPin[4] = {A0,A1,A2,A3};


// Time periods of blinks in milliseconds.
/*
const unsigned long RELAY01interval = analogRead(A0);
const unsigned long RELAY02interval = analogRead(A1);
const unsigned long RELAY03interval = analogRead(A2);
const unsigned long RELAY04interval = analogRead(A3);
*/

// replaced by an array
unsigned long RELAYinterval[4];


// Variable holding the timer value so far. One for each "Timer"
/*
unsigned long RELAY01timer;
unsigned long RELAY02timer;
unsigned long RELAY03timer;
unsigned long RELAY04timer;
*/
// replaced by an array
unsigned long RelayTimer[4];
// RelayTimer[0] contains value for timer 1
// RelayTimer[1] contains value for timer 2
// RelayTimer[2] contains value for timer 3
// RelayTimer[3] contains value for timer 4
1 Like