How to run several actuator parallely

Hi DaveX
I followed this link and modified my code. Although it doesn't show any error, when I ran the code, all the relay switches were turned on, and the Serial.print option was not working. I attached the modified code here. Would you please take a look at it?

#define valve1 23
#define valve2 22
#define valve3 25
#define valve4 24
#define valve5 27
#define valve6 26
#define valve7 29
#define valve8 28
#define valve9 47
#define valve10 46
#define valve11 49
#define valve12 48

int VWC1,VWC2,VWC3,VWC4,VWC5,VWC6,VWC7,VWC8,VWC9,VWC10,VWC11,VWC12; 
float mV1,mV2,mV3,mV4,mV5,mV6,mV7,mV8,mV9,mV10,mV11,mV12;
float VWC_1,VWC_2,VWC_3,VWC_4,VWC_5,VWC_6,VWC_7,VWC_8,VWC_9,VWC_10,VWC_11,VWC_12;

int VWC_1_threshold = 25; int VWC_2_threshold = 50;
int VWC_3_threshold = 75; int VWC_4_threshold = 100;
int VWC_5_threshold = 25; int VWC_6_threshold = 50; 
int VWC_7_threshold = 75; int VWC_8_threshold = 100;
int VWC_9_threshold = 25; int VWC_10_threshold = 50;
int VWC_11_threshold = 75; int VWC_12_threshold = 100;

unsigned long previousTime = millis();
long timeInterval = 30000;

void setup() 
{
  Serial.begin(9600);
  pinMode(VWC1, INPUT); pinMode(VWC2, INPUT); pinMode(VWC3, INPUT); pinMode(VWC4, INPUT); 
  pinMode(VWC5, INPUT); pinMode(VWC6, INPUT); pinMode(VWC7, INPUT); pinMode(VWC8, INPUT); 
  pinMode(VWC9, INPUT); pinMode(VWC10, INPUT); pinMode(VWC11, INPUT); pinMode(VWC12, INPUT);

  pinMode(valve1, OUTPUT); pinMode(valve2, OUTPUT); pinMode(valve3, OUTPUT); 
  pinMode(valve4, OUTPUT); pinMode(valve5, OUTPUT); pinMode(valve6, OUTPUT); 
  pinMode(valve7, OUTPUT); pinMode(valve8, OUTPUT); pinMode(valve9, OUTPUT); 
  pinMode(valve10, OUTPUT); pinMode(valve11, OUTPUT); pinMode(valve12, OUTPUT);
}

void loop() 
{
    unsigned long currentTime = millis();

  // valve 1
  if(currentTime - previousTime > timeInterval) {
    VWC1 = analogRead(A0); mV1 = (VWC1*5.0/(1024))*1000; VWC_1 = (((0.00211*mV1)-0.675)*100)-13.9;

    if (VWC_1 < VWC_1_threshold) {
      digitalWrite(valve1, LOW);
      while (VWC_1 < VWC_1_threshold){
        VWC1 = analogRead(A0); mV1 = (VWC1*5.0/(1024))*1000; VWC_1 = (((0.00211*mV1)-0.675)*100)-13.9;}
        digitalWrite(valve1, HIGH);
    }
    else {
      digitalWrite(valve1, HIGH);
    }
    previousTime = currentTime;
  }

  // valve 2
  if(currentTime - previousTime > timeInterval) {
    VWC2 = analogRead(A1); mV2 = (VWC2*5.0/(1024))*1000; VWC_2 = (((0.00211*mV2)-0.675)*100)-13.9;

    if (VWC_2 < VWC_2_threshold) {
      digitalWrite(valve2, LOW);
      while (VWC_2 < VWC_2_threshold){
        VWC2 = analogRead(A1); mV2 = (VWC2*5.0/(1024))*1000; VWC_2 = (((0.00211*mV2)-0.675)*100)-13.9;}
        digitalWrite(valve2, HIGH);
    }
    else {
      digitalWrite(valve2, HIGH);
    }
    previousTime = currentTime;
  }  
  
  // valve 3
  if(currentTime - previousTime > timeInterval) {
    VWC3 = analogRead(A2); mV3 = (VWC3*5.0/(1024))*1000; VWC_3 = (((0.00211*mV3)-0.675)*100)-13.9;

    if (VWC_3 < VWC_3_threshold) {
      digitalWrite(valve3, LOW);
      while (VWC_3 < VWC_3_threshold){
        VWC3 = analogRead(A2); mV3 = (VWC3*5.0/(1024))*1000; VWC_3 = (((0.00211*mV3)-0.675)*100)-13.9;}
        digitalWrite(valve3, HIGH);
    }
    else {
      digitalWrite(valve3, HIGH);
    }
    previousTime = currentTime;
  }

    // valve 4
  if(currentTime - previousTime > timeInterval) {
    VWC4 = analogRead(A3); mV4 = (VWC4*5.0/(1024))*1000; VWC_4 = (((0.00211*mV4)-0.675)*100)-13.9;

    if (VWC_4 < VWC_4_threshold) {
      digitalWrite(valve4, LOW);
      while (VWC_4 < VWC_4_threshold){
        VWC4 = analogRead(A3); mV4 = (VWC4*5.0/(1024))*1000; VWC_4 = (((0.00211*mV4)-0.675)*100)-13.9;}
        digitalWrite(valve4, HIGH);
    }
    else {
      digitalWrite(valve4, HIGH);
    }
    previousTime = currentTime;
  }

    // valve 5
  if(currentTime - previousTime > timeInterval) {
    VWC5 = analogRead(A4); mV5 = (VWC5*5.0/(1024))*1000; VWC_5 = (((0.00211*mV5)-0.675)*100)-13.9;

    if (VWC_5 < VWC_5_threshold) {
      digitalWrite(valve5, LOW);
      while (VWC_5 < VWC_5_threshold){
        VWC5 = analogRead(A4); mV5 = (VWC5*5.0/(1024))*1000; VWC_5 = (((0.00211*mV5)-0.675)*100)-13.9;}
        digitalWrite(valve5, HIGH);
    }
    else {
      digitalWrite(valve5, HIGH);
    }
    previousTime = currentTime;
  }

    // valve 6
  if(currentTime - previousTime > timeInterval) {
    VWC6 = analogRead(A5); mV6 = (VWC6*5.0/(1024))*1000; VWC_6 = (((0.00211*mV6)-0.675)*100)-13.9;

    if (VWC_6 < VWC_6_threshold) {
      digitalWrite(valve6, LOW);
      while (VWC_6 < VWC_6_threshold){
        VWC6 = analogRead(A5); mV6 = (VWC6*5.0/(1024))*1000; VWC_6 = (((0.00211*mV6)-0.675)*100)-13.9;}
        digitalWrite(valve6, HIGH);
    }
    else {
      digitalWrite(valve6, HIGH);
    }
    previousTime = currentTime;
  }

    // valve 7
  if(currentTime - previousTime > timeInterval) {
    VWC7 = analogRead(A6); mV7 = (VWC7*5.0/(1024))*1000; VWC_7 = (((0.00211*mV7)-0.675)*100)-13.9;

    if (VWC_7 < VWC_7_threshold) {
      digitalWrite(valve7, LOW);
      while (VWC_7 < VWC_7_threshold){
        VWC7 = analogRead(A6); mV7 = (VWC7*5.0/(1024))*1000; VWC_7 = (((0.00211*mV7)-0.675)*100)-13.9;}
        digitalWrite(valve7, HIGH);
    }
    else {
      digitalWrite(valve7, HIGH);
    }
    previousTime = currentTime;
  }

    // valve 8
  if(currentTime - previousTime > timeInterval) {
    VWC8 = analogRead(A7); mV8 = (VWC8*5.0/(1024))*1000; VWC_8 = (((0.00211*mV8)-0.675)*100)-13.9;

    if (VWC_8 < VWC_8_threshold) {
      digitalWrite(valve8, LOW);
      while (VWC_8 < VWC_8_threshold){
        VWC8 = analogRead(A7); mV8 = (VWC8*5.0/(1024))*1000; VWC_8 = (((0.00211*mV8)-0.675)*100)-13.9;}
        digitalWrite(valve1, HIGH);
    }
    else {
      digitalWrite(valve8, HIGH);
    }
    previousTime = currentTime;
  }

    // valve 9
  if(currentTime - previousTime > timeInterval) {
    VWC9 = analogRead(A8); mV9 = (VWC9*5.0/(1024))*1000; VWC_9 = (((0.00211*mV9)-0.675)*100)-13.9;

    if (VWC_9 < VWC_9_threshold) {
      digitalWrite(valve9, LOW);
      while (VWC_9 < VWC_9_threshold){
        VWC9 = analogRead(A8); mV9 = (VWC9*5.0/(1024))*1000; VWC_9 = (((0.00211*mV9)-0.675)*100)-13.9;}
        digitalWrite(valve9, HIGH);
    }
    else {
      digitalWrite(valve9, HIGH);
    }
    previousTime = currentTime;
  }

    // valve 10
  if(currentTime - previousTime > timeInterval) {
    VWC10 = analogRead(A9); mV10 = (VWC10*5.0/(1024))*1000; VWC_10 = (((0.00211*mV10)-0.675)*100)-13.9;

    if (VWC_10 < VWC_10_threshold) {
      digitalWrite(valve10, LOW);
      while (VWC_10 < VWC_10_threshold){
        VWC10 = analogRead(A9); mV10 = (VWC10*5.0/(1024))*1000; VWC_10 = (((0.00211*mV10)-0.675)*100)-13.9;}
        digitalWrite(valve10, HIGH);
    }
    else {
      digitalWrite(valve10, HIGH);
    }
    previousTime = currentTime;
  }

    // valve 11
  if(currentTime - previousTime > timeInterval) {
    VWC11 = analogRead(A10); mV11 = (VWC11*5.0/(1024))*1000; VWC_11 = (((0.00211*mV11)-0.675)*100)-13.9;

    if (VWC_11 < VWC_11_threshold) {
      digitalWrite(valve11, LOW);
      while (VWC_1 < VWC_1_threshold){
        VWC11 = analogRead(A10); mV11 = (VWC11*5.0/(1024))*1000; VWC_11 = (((0.00211*mV11)-0.675)*100)-13.9;}
        digitalWrite(valve11, HIGH);
    }
    else {
      digitalWrite(valve11, HIGH);
    }
    previousTime = currentTime;
  }

    // valve 12
  if(currentTime - previousTime > timeInterval) {
    VWC12 = analogRead(A11); mV12 = (VWC12*5.0/(1024))*1000; VWC_12 = (((0.00211*mV12)-0.675)*100)-13.9;

    if (VWC_12 < VWC_12_threshold) {
      digitalWrite(valve12, LOW);
      while (VWC_12 < VWC_12_threshold){
        VWC12 = analogRead(A11); mV12 = (VWC12*5.0/(1024))*1000; VWC_12 = (((0.00211*mV12)-0.675)*100)-13.9;}
        digitalWrite(valve12, HIGH);
    }
    else {
      digitalWrite(valve12, HIGH);
    }
    previousTime = currentTime;
  }

  // Data recording
  if (currentTime - previousTime > timeInterval) {
    Serial.print(VWC_1); Serial.print(" , "); 
    Serial.print(VWC_2); Serial.print(" , ");
    Serial.print(VWC_3); Serial.print(" , ");
    Serial.print(VWC_4); Serial.print(" , "); 
    Serial.print(VWC_5); Serial.print(" , ");
    Serial.print(VWC_6); Serial.print(" , ");
    Serial.print(VWC_7); Serial.print(" , "); 
    Serial.print(VWC_8); Serial.print(" , ");
    Serial.print(VWC_9); Serial.print(" , ");
    Serial.print(VWC_10); Serial.print(" , "); 
    Serial.print(VWC_11); Serial.print(" , ");
    Serial.print(VWC_12); Serial.print(" , ");
    Serial.println();
    previousTime = currentTime;
  }
}

Hi a7
Thanks for your guidelines. I ran your code also, but some relay switches are blinking continuously; please check the attached video. I think the sensor data was pretty stable or not fluctuating quickly. I'm using Arduino Mega 2560 and 16 channel Arduino relay.
IMG_4909.zip (4.8 MB)

int Apins[] = {A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11}; 
int valvePins[] = {23, 22, 25, 24, 27, 26, 29, 28, 47, 46, 49, 48};
int threshold[] = {25, 50, 75, 100, 25, 50, 75, 100, 25, 50, 75, 100};

float VWC_(int i){
  float VWC1 =  analogRead(Apins[i]);
  float mV1 = (VWC1*5.0/(1024))*1000;
  float VWC_1 = ((0.00211*mV1)-0.675)*100;
  return VWC_1;
}

struct VALVE {
  const char * id;
  int sensor_pin;
  int valve_pin;
  int threshold;
  int valve_state;
  float reading;
} valves[] = {
  {"Valve 1", A0, 23, 25, LOW, 0},
  {"Valve 2", A1, 22, 50, LOW, 0},
  {"Valve 3", A2, 25, 75, LOW, 0},
  {"Valve 4", A3, 24, 100, LOW, 0},
  {"Valve 5", A4, 27, 25, LOW, 0},
  {"Valve 6", A5, 26, 50, LOW, 0},
  {"Valve 7", A6, 29, 75, LOW, 0},
  {"Valve 8", A7, 28, 100, LOW, 0},
  {"Valve 9", A8, 47, 25, LOW, 0},
  {"Valve 10", A9, 46, 50, LOW, 0},
  {"Valve 11", A10, 49, 75, LOW, 0},
  {"Valve 12", A11, 48, 100, LOW, 0},
};

const int nVlaves = (sizeof valves) / (sizeof valves[0]);

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

  for (unsigned char tt = 0; tt < nVlaves; tt++) {
    struct VALVE *v = valves + tt;
    pinMode(v->sensor_pin, INPUT);
    pinMode(v->valve_pin, OUTPUT);
    Serial.print(v->id);
    Serial.println(": Setup");
  }
}

void loop() {

  for (unsigned char tt = 0; tt < nVlaves; tt++) {
    struct VALVE *v = valves + tt;
    if (v->valve_state == LOW && !valveAboveThreshold(v)) {
      digitalWrite(v->valve_pin, HIGH);
      v->valve_state = HIGH;
      Serial.print(v->id);
      Serial.print(": On at ");
      Serial.println(v->reading);
    }
    if (!v->valve_state == LOW && valveAboveThreshold(v)) {
      digitalWrite(v->valve_pin, LOW);
      v->valve_state = LOW;
      Serial.print(v->id);
      Serial.print(": Off at ");
      Serial.println(v->reading);
    }
  }
}

unsigned char valveAboveThreshold(struct VALVE *v) {
  float VWC1 = analogRead(v->sensor_pin);
  float mV1 = (VWC1 * 5.0 / (1024)) * 1000;
  float VWC_1 = ((0.00211 * mV1) - 0.675) * 100;
  v->reading = VWC_1;
  return (VWC_1 > v->threshold);
}

@nixon_silvara Please supply a schematic diagram showing all parts, how they are connected and paying special attention to where power comes from and how it is provided to all parts.

You will find ppl are reluctant to download a zip to see a video. You could put it on youtube. But don't bother on my account! I do not need to see it.

Is the behaviour of my code, as seen in the wokwi simulation I linked to, not what you are trying to accomplish?

Is the behaviour of my code, as seen in real life, different to its behaviour in the wokwi?

If the sim doesn't do what you want, please describe what it does that it should not, or does not do what it should.

If the sim behaves differently to the sketch ecexuting on your hardware… you have a hardware problem. This is a simple sketch, and the simulator is very faithful.At a very high level,of confidence it can be relied on to be accurately running the code.

HTH

a7

1 Like

Two items stand out:

  • The previousTime persistent memory seems to be shared by all of the conditionals. If the first conditional is true, it updates the value, and then the rest of the conditionals won't trigger.
  • The while(VWC_?? < VWC_?_threshold){...} in each conditional will trap the attention of the processor until the physical process changes. It would be better to write each of these whiles as a separate, independent test:
if (digitalRead(valve5)==LOW && VWC_5 > VWC_5_threshold){
    digitalWrite(valve5, HIGH);
}

...then the processor could quickly check if the valve is in the wrong place and switch if necessary, and move on to the next item in the checklist, instead of devoting 100% of the processing time on measuring, watching, and waiting until that one threshold until it changes.

Think of the loop(){if(){};if(){};if(){};if(){}...} as a checklist of everything that needs to be managed.

1 Like

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