Reading Multiple Analog Inputs without a delay

Greetings All,

I am new to the Arduino world and I am starting a project using an UNO. I would like to be able to read several different analog inputs, which would correspond to a specific output (1 input = 1 output). I have it basically working as expected, but the results are intermittent. I feel like the issue resides in the "IF" statement in the code and the threshold crossing is being missed during the void loop cycle. I put the serial print in so I could see if the threshold was being crossed. I also think that is slowing down the code (by watching the TX LED on the board).

Is there a better way to do this? I am not a code guy, but this is all I have come up with so far. The analog input threshold crossing is going to be a quick event and I would like to see the output react consistently.

int analog01 = A0;    // pin that the sensor is attached to
int analog02 = A1;    // pin that the sensor is attached to
int led11 = 11;       // pin that the LED is attached to
int led10 = 10;       // pin that the LED is attached to
int threshold = 100;   // an threshold level that's in the range of the analog input
int outOnTime=3000; //Declare outOnTime an int 
int outOffTime=750; //Declare outOffTime an int

void setup() {
  
  pinMode(led11, OUTPUT); //  the LED11 pin as an output:
  pinMode(led10, OUTPUT); //  the LED10 pin as an output:
  Serial.begin(9600);
}

void loop() {
  
  int analogValue1 = analogRead(analog01); // read the value of A0

   if (analogValue1 > threshold) {  // if the analog value is high enough, turn on 11:
    digitalWrite(led11, HIGH);
    delay(outOnTime);             //Leave on for outOnTime
  } else {
    digitalWrite(led11, LOW);
    delay(outOffTime);            //Leave off for outOffTime
  }
    int analogValue2 = analogRead(analog02); // read the value of A1

   if (analogValue2 > threshold) {  // if the analog value is high enough, turn on 10:
    digitalWrite(led10, HIGH);
    delay(outOnTime);             //Leave on for outOnTime
  } else {
    digitalWrite(led10, LOW);
    delay(outOffTime);            //Leave off for outOffTime
  }


Serial.println(analogValue1);

}

Intermittent, explain?

When you use the delay() function, your sketch pauses for that amount of time.

Do you know how to use millis() to effect delays?

Intermittent meaning the input was enough to cross the threshold, but the output did not change its state. That was due to the delay that I think the IF condition and associated delays were creating.

I am honestly not familiar with the millis function you mentioned. I will try to research that.

I am not to familiar with any coding, as I have only been playing with the UNO for a few weeks.

My ultimate goal would be for each input and associated output work completely independant of the other I/O in real-time if possible.

I have years of Industrial Electronics experience working with PLC's (mostly digital I/O), so this is a new adventure for me.

Does Serial.println(analogValue1); print the correct value for analog A0 ?

I will say Yes that it was accurate, but times where I could make the input valve change (light sensor), the serial monitor output would just hang before showing the value. This was also confirmed by the TX LED on the board. It was normally about one update per second.

Back to the millis function... I would still want the output to be HIGH for several seconds when the input meets the conditions. Would using that allow me to achieve the desired result?

Try this, untested.

int analog01  = A0;             //pin that the sensor is attached to
int analog02  = A1;             //pin that the sensor is attached to
int led11     = 11;             //pin that the LED is attached to
int led10     = 10;             //pin that the LED is attached to
int threshold = 100;            //an threshold level that's in the range of the analog input

unsigned long outOnTime = 3000; //declare outOnTime

boolean led11OnFlag = false;    //if true, we are timing LED11 being ON 

unsigned long on11Millis;       //the time that LED11 went on

void setup()
{
  Serial.begin(9600);
  
  pinMode(led11, OUTPUT);       //the LED11 pin as an output:
  pinMode(led10, OUTPUT);       //the LED10 pin as an output:
}

void loop()
{
  int analogValue1 = analogRead(analog01); //read the value of A0
  Serial.println(analogValue1);
  
  //if we are 'not' currently timing, check the sensor 
  if (led11OnFlag == false && analogValue1 > threshold)
  {
    digitalWrite(led11, HIGH); //turn LED11 ON
    on11Millis = millis();     //record the time that LED11 went ON
    led11OnFlag = true;        //enable LED11 timing
  }

  //when we are timing, has the LED11 ON time expired?
  if (led11OnFlag == true && millis() - on11Millis >= outOnTime)
  {
    digitalWrite(led11, LOW);  //turn LED11 OFF
    led11OnFlag = false;       //disable LED11 timing
  }


} //END of loop()

shooter5201:
I am not to familiar with any coding, as I have only been playing with the UNO for a few weeks.

You can get by well only learning C at first, and only the basics of that. Arduino is C/C++ underneath with a special structure...

Instead of C/C++

int main()
{
}

Arduino has

void setup()
{
}

void loop()
{
}

that serves automation code well. It saves me making my own, hey? But if you look in C books and teaching web sites you will see the standard which serves computer programs that run on an OS. The Arduino chip has no OS unless you put one on.

Your Arduino IDE has Examples (through File->Examples menu) up to date for your IDE version. The Arduino main site has a page for each with schematic(s) linked through the RESOURCES->TUTORIALS->BUILT- IN EXAMPLES pulldown menu at the top of your forum page. Sections 1,2,3 and 5 will get you through basics. Don't miss section 5 and do give section 4 a miss as it teaches habits okay on a PC but bad on any small memory device. Don't use C++ String, learn C char array strings when you're ready to use text variables.

RESOURCES->TUTORIALS->FOUNDATIONS AND MORE will give you grounding you may want before trying the Examples.

There's a book worth of help and lessons on the main site. If you keep a browser open with help pages in tabs along with your IDE while coding you will have references a click or two away.

Maybe the #1 page to keep in a tab is at RESOURCES->REFERENCE.

My ultimate goal would be for each input and associated output work completely independant of the other I/O in real-time if possible.

The Example in section 2, BlinkWithoutDelay can get you started on writing independent tasks rather than single-block code.
For an easier learning curve, see the 1st link in my signature space below, Nick's blogs are very good.

With event-driven non-blocking code a cheap Arduino can fairly fly.

I have years of Industrial Electronics experience working with PLC's (mostly digital I/O), so this is a new adventure for me.

You should be okay with circuits and datasheets? Less likely to smoke a part?

Final tips; don't use an int (16 bits) where a byte (8 bits) will do and set Serial.begin(115200) so that the print output buffer will clear quicker -- if it fills (64 chars) the sketch will slow down until it does at whatever baud (bit) rate you set, 10 bits per character. 9600 is 960 chars/sec, 115200 is 11520 cps.

Thanks to all that responded. I have been looking over all of the information and it has helped me tremendously. I hope I can get to the point of being able to "pay it forward" in helping others as I plan to get more proficient.

There is more that I want to do with my project, but time restraints will limit my dedication to implementing new things. I will say I would like to incorporate an LCD to indicate the number of times any of the analog inputs crosses the threshold.

That will be another battle for another time.......

If you don't learn about arrays and control structures you will spend a lot more time typing and being confused than if you had.

Like when you use a whole set of pins and only know how to give each one a different named variable (array elements, each a variable, are the array name and a number for which one) and then to use them you have to have a special line of code for each. With arrays you don't.

You know about if ( ) statements but what about the else that may cover the other condition?
The for loop with built-in counter that can index through the numbered elements of an array?
The do { }-while ( ); and while ( ) { }; loops that repeat as long as what's in the ( ) is true?
Or the switch-case structure that lets you divide tasks into steps or modes that are chosen by a value in a variable the steps can change?

Add basic knowledge of the digital pins and how to track the passage of time and you can begin to run instead of crawl.

Your sketch can sense ongoing process events in time. -- Pin change, time change, variable change are all events.
Your sketch can make events to control it over time. ------- ditto, LOL.

Be methodical, neat and always add meaningful comments to your code.

If you need help, ask for it.

Thanks to "larryd" as your code worked perfectly for what I am trying to do. I "think" I understand what you did to make that possible, but I will admit that I would have never tried that .

I have since connected an LCD (20X4) to my UNO and I have it communicating. I have it printing the first two rows with a static message, but I would like to have the 3rd row have a message along with the numeric value of the times the output messages have changed.

In other words, create an "OR" condition where any of the outputs would increment the counter on the LCD. The 3rd row would be something like "Events: x", where x would be the actual times the "OR" condition was reached.

Using the code that larryd supplied, what would I need to do to make that happen?

Adding a new wrinkle.... could there be a way to start a count-down timer after the program starts and after the first output event occurs? That could be on the 4th row with "Remaining: Y", which could be in seconds starting at 60 for example.

Any guidance will be appreciated.

This could be done.

Show us your complete sketch, and describe ‘exactly what you want’.

I have included the code below..... the reading of the analog inputs to reach the threshold while enabling the output for a predetermined time is working as desired.

I have added the required code and library for the LCD and that is working fine. On the 3rd row, I would like a counter to increment to show how many times ANY of the outputs have been active. I realize this would be an OR condition, but I could not get the syntax figured out.

Once this is working, I would like to see if the 4th row could include a countdown timer from 120 seconds for example to zero after the first OR condition is met.

This is beyond my grasp of programming as I know what I want to do, but I am having trouble getting it all to work together.

I hope this makes a little sense on what I would like to accomplish.

// include the library code:
#include <LiquidCrystal.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
int analog00  = A0;             //pin that the sensor is attached to
int analog01  = A1;             //pin that the sensor is attached to
int led07     = 7;             //pin that the LED is attached to
int led08     = 8;             //pin that the LED is attached to
int led13     = 13;            //ping that the LED is attached to
int threshold = 800;            //an threshold level that's in the range of the analog input
int Hits = 0;                    // Hits Counter

unsigned long outOnTime = 10000; //declare outOnTime

boolean led07OnFlag = false;    //if true, we are timing LED07 being ON
unsigned long on07Millis;       //the time that LED07 went on
boolean led08OnFlag = false;    //if true, we are timing LED08 being ON
unsigned long on08Millis;       //the time that LED08 went on

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

pinMode(led07, OUTPUT);       //the LED11 pin as an output:
pinMode(led08, OUTPUT);       //the LED09 pin as an output
pinMode(led13, OUTPUT);       //the LED13 ping as an output
digitalWrite (led13,LOW);
 
  // set up the LCD's number of columns and rows:
  lcd.begin(20, 4);

  }

void loop() {

lcd.setCursor(2,0);              
lcd.print("Change Record");   
lcd.setCursor(0,1);              
lcd.print("Number of Changes");

 int analogValue0 = analogRead(analog00); //read the value of A0
// Serial.println(analogValue0);
  
  //if we are 'not' currently timing, check the sensor 
  if (led07OnFlag == false && analogValue0 > threshold)
  {
    digitalWrite(led07, HIGH); //turn LED07 ON
    on07Millis = millis();     //record the time that LED07 went ON
    led07OnFlag = true;        //enable LED07 timing
  }

  //when we are timing, has the LED07 ON time expired?
  if (led07OnFlag == true && millis() - on07Millis >= outOnTime)
  {
    digitalWrite(led07, LOW);  //turn LED07 OFF
    led07OnFlag = false;       //disable LED07 timing
  }
  
int analogValue1 = analogRead(analog01); //read the value of A1
 // Serial.println(analogValue1);
  
  //if we are 'not' currently timing, check the sensor 
  if (led08OnFlag == false && analogValue1 > threshold)
  {
    digitalWrite(led08, HIGH); //turn LED08 ON
    on08Millis = millis();     //record the time that LED08 went ON
    led08OnFlag = true;        //enable LED08 timing
  }

  //when we are timing, has the LED08 ON time expired?
  if (led08OnFlag == true && millis() - on08Millis >= outOnTime)
  {
    digitalWrite(led08, LOW);  //turn LED08 OFF
    led08OnFlag = false;       //disable LED08 timing
  }

}

Hopefully this will help illustrate what I am hoping to accomplish.

Use a variable to count how many times your output changes ONLY when time > 0

First, write your static text (changes: )

Then, clear everything after the static text.

After that, write the variable that is counting changes.

Repeat until time <= 0.