Help with multiple millis()

Hello,

Can someone help me locate why my voltage is not flipping, from pin 13 to 12.

/*--- Declaration of I/Os ---*/ 

// Dc source for Soil moisture sensor Flipping voltage, preventing etching of probes.

const uint8_t voltageFlipPin01 = 13;
const uint8_t voltageFlipPin02 = 12;

// Definition of Analog pins for Soil Moisture Sensor Readings.

const uint8_t Moisture_Input = 5;


/*--- Declaration of Variables ---*/

// Switch case Variable
int Soil_Sensor = 1;

// Moisture Value Variables
int Moist_Val01;
int Moist_Val02;
int Moist_Avg01;

// Timer Parameters
unsigned long CurrentTimer;
unsigned long timerLastX;
unsigned long timerLastY;
unsigned long timerLastZ;
const unsigned long timerRateX = 1000UL;
const unsigned long timerRateY = 1000UL;
const unsigned long timerRateZ = 1000UL;

// Codes running only once at start up. Initialisation.

void setup(){
  Serial.begin(9600);
  pinMode(voltageFlipPin01, OUTPUT);
  pinMode(voltageFlipPin02, OUTPUT);
  
  digitalWrite(voltageFlipPin01, LOW);
  digitalWrite(voltageFlipPin02, LOW);
  
  pinMode(Moisture_Input, INPUT);
    
  timerLastX = millis();
  timerLastY = millis();
  timerLastZ = millis();

}



// Codes running forever.

void loop(){
  
  /* Switch function to compare Switch Case Variable 'Soil_Sensor', and to run appropriate 'case' */ 
  
// Keep track of milliseconds elapsed. 
 CurrentTimer = millis();
 
 /*-- Soil Moisture Reading Sequence--*/

// Allow current to flow in Forward and Reverse direction while reading value from Soil Moisture Probe in both direction.  
    digitalWrite(voltageFlipPin01, HIGH);
    digitalWrite(voltageFlipPin02, LOW);

// Delay timer with millis(); reading Moisture value in Fwd direction.
        if ((millis() - timerLastX) >= timerRateX) 
        {timerLastX = millis();
        Moist_Val01 = 1023 - analogRead(Moisture_Input);}
    
// Delay timer with millis(); Reverse direction of Vcc pin.
        if ((millis() - timerLastY) >= timerRateY) 
        {timerLastY = millis();
    digitalWrite(voltageFlipPin01, LOW);
    digitalWrite(voltageFlipPin02, HIGH);}

// Delay timer with millis(); reading Moisture value in RvS direction + Averaging.
        if ((millis() - timerLastZ) >= timerRateZ) 
        {timerLastZ = millis();
    Moist_Val02 = analogRead(Moisture_Input);
    Moist_Avg01 = (Moist_Val01 + Moist_Val02) / 2;
    digitalWrite(voltageFlipPin01, LOW);
    digitalWrite(voltageFlipPin02, LOW);}
 

 // case 3:
    Serial.print("Sensor Value #1: ");
    Serial.println(Moist_Avg01);
    Serial.println();
    
    Serial.print ("Moist_Val01 = ");
    Serial.println (Moist_Val01);
    
    Serial.print ("Moist_Val02 = ");
    Serial.println (Moist_Val02);
    Serial.println();
    
  delay(500UL);

  }

I can get reading from Moist_Val01 only and when i measure voltages across pin 13, it do fluctuates, but i cant read it , too fast. moreover, on pin 12, no voltage is read at all.

Any help in understanding the millis() and bring appropriate correction.

Thanks

// Keep track of milliseconds elapsed. 
 CurrentTimer = millis();

You don't use this variable anywhere.

const unsigned long timerRateX = 1000UL;
const unsigned long timerRateY = 1000UL;
const unsigned long timerRateZ = 1000UL;
...
  timerLastX = millis();
  timerLastY = millis();
  timerLastZ = millis();

These variables are pretty much set to the same thing, so.

if ((millis() - timerLastX) >= timerRateX) 
...
if ((millis() - timerLastY) >= timerRateY)
...
if ((millis() - timerLastZ) >= timerRateZ)

These if statements probably do their stuff all on the same loop, or with very little delay between, maybe change the initial timing or try to use 'else if' statements only match one of the conditions per iteration of loop.

Why do you believe your output pins aren't changing? I think they are, but you won't see it without
an oscilloscope since they change for about 0.1ms every second.

You have three timer variables yet they run in perfect lockstep since they have the same delay, thus
every time they get to fire up their code sections they all run, leaving both output pins LOW. Why
three variables?

// Keep track of milliseconds elapsed. 

CurrentTimer = millis();




You don't use this variable anywhere.

i did use it before, then i replaced it directly with millis() function was trying to sort out the bug.

These if statements probably do their stuff all on the same loop, or with very little delay between, maybe change the initial timing or try to use 'else if' statements only match one of the conditions per iteration of loop.

Initial timing meaning, more than 1000UL, or how should i do that, i will try with if else statement in the meanwhile.
Thanks . .

Why do you believe your output pins aren't changing? I think they are, but you won't see it without
an oscilloscope since they change for about 0.1ms every second.

You are right, that's why this explain the rapid fluctuations on my voltmeter on pin 13, but for pin 12 only some mV are able to be detected.

From serial output, i can have reading on analog pin in forward direction of current but constant value of 1023 while in reverse direction.

You have three timer variables yet they run in perfect lockstep since they have the same delay, thus
every time they get to fire up their code sections they all run, leaving both output pins LOW. Why
three variables?

Here is part of the code from 'Gardenbot' and taking account with some threads on this forum, for soil moisture which i brought some modifications, with its original delay timer function.

const int timer = 1000;
    digitalWrite(voltageFlipPin01, HIGH);
    digitalWrite(voltageFlipPin02, LOW);
    delay(Timer);
    Moist_Val01 = analogRead(Moisture_Input_0);
    delay(Timer);
    digitalWrite(voltageFlipPin01, LOW);
    digitalWrite(voltageFlipPin02, HIGH);
    delay(Timer);
    Moist_Val02 = 1023 - analogRead(Moisture_Input_0);
    Moist_Avg01 = (Moist_Val01 + Moist_Val02) / 2;
    digitalWrite(voltageFlipPin01, LOW);
    digitalWrite(voltageFlipPin02, LOW);

Any help will be appreciated. .

Thanks

Initial timing meaning, more than 1000UL, or how should i do that, i will try with if else statement in the meanwhile.
Thanks . .

If you used different intervals for each of the three variables:

const unsigned long timerRateX = 1000UL;
const unsigned long timerRateY = 1500UL;
const unsigned long timerRateZ = 2000UL;

This will cause each section to expire 500ms apart.

A better approach would be to use steps and a single timeout.

Here is a pseudo layout:

const unsigned long timerRate = 1000;
unsigned long lastCount = 0;
char itemIdx = 0;

void loop(){

  unsigned long thisCount = millis();

  if( thisCount >= ( lastCount + timerRate ) ){

    lastCount = thisCount;

    switch( ++itemIdx ){
      case 3:
        itemIdx = 0;

      //First action
      case 0:
      
        digitalWrite(voltageFlipPin01, HIGH);
        digitalWrite(voltageFlipPin02, LOW);
        break;

      //Second action
      case1:
      
        digitalWrite(voltageFlipPin01, LOW);
        digitalWrite(voltageFlipPin02, HIGH);
        break;

      //Third action
      case 2:
      
        digitalWrite(voltageFlipPin01, LOW);
        digitalWrite(voltageFlipPin02, LOW);
        break;
    }
  }
  

}

hello,

Thanks for the pseudo layout, that works like a charm with the switch case function.

:wink:

Here is the code :

/*--- Declaration of I/Os ---*/ 

// Dc source for Soil moisture sensor Flipping voltage, preventing etching of probes.

const uint8_t voltageFlipPin01 = 13;
const uint8_t voltageFlipPin02 = 12;

// Definition of Analog pins for Soil Moisture Sensor Readings.

const uint8_t Moisture_Input = 5;


/*--- Declaration of Variables ---*/

// Switch case Variable
char itemIdx = 0;

// Moisture Value Variables
int Moist_Val01;
int Moist_Val02;
int Moist_Avg01;

// Timer Parameters
unsigned long currentTimer;
unsigned long timerLast = 0;
const unsigned long timerRate = 1000UL;

// Codes running only once at start up. Initialisation.

void setup(){
  Serial.begin(9600);
  pinMode(voltageFlipPin01, OUTPUT);
  pinMode(voltageFlipPin02, OUTPUT);
  
  digitalWrite(voltageFlipPin01, LOW);
  digitalWrite(voltageFlipPin02, LOW);
  
  pinMode(Moisture_Input, INPUT);
  
}

// Codes running forever.

void loop(){
 
// Keep track of milliseconds elapsed. 
 currentTimer = millis();
 
// Delay Timer with millis()in executing each soil moisture sequence.
 if( currentTimer >= (timerLast + timerRate) ){
   timerLast = currentTimer;
 
/* Switch function to compare Switch Case Variable 'itemIdx', and to run appropriate 'case' */    
 switch(++itemIdx){
  
/*-- Soil Moisture Reading Sequence--*/
// Allow current to flow in Forward and Reverse direction while reading value from Soil Moisture Probe in both direction.  
    
     case 4: 
             itemIdx = 0;
     
     case 0: 
             digitalWrite(voltageFlipPin01, HIGH);
             digitalWrite(voltageFlipPin02, LOW);
             break;
    
     case 1:
             Moist_Val01 = 1023 - analogRead(Moisture_Input);
             break;
    
     case 2:
             digitalWrite(voltageFlipPin01, LOW);
             digitalWrite(voltageFlipPin02, HIGH);
             break;
    
     case 3:
             Moist_Val02 = analogRead(Moisture_Input);
             Moist_Avg01 = (Moist_Val01 + Moist_Val02) / 2;
             digitalWrite(voltageFlipPin01, LOW);
             digitalWrite(voltageFlipPin02, LOW);
             break;
             
   }
 }



 // case 3:
    Serial.print("Sensor Value #1: ");
    Serial.println(Moist_Avg01);
    Serial.println();
    
    Serial.print ("Moist_Val01 = ");
    Serial.println (Moist_Val01);
    
    Serial.print ("Moist_Val02 = ");
    Serial.println (Moist_Val02);
    Serial.println();
    
  delay(500UL);

  }

Thanks again Pyro_65 . .