Arrays in monitoring program

Hi everyone!

I’m working on building a gizmo that will optically monitor the flow of fluids in a vinyl tube, then light a go/nogo indicator if there is a bubble or foam in the tube. The analog input is a simple voltage divider with a photoresistor. I’ve successfully made one that can monitor ONE line at a time, but I want to be able to monitor up to six lines, using the six analog inputs on my UNO, and have an LED correspond to each input. The idea I have is to use arrays to iterate through the (up to) six inputs, checking the reading from each sensor each time through and lighting an led if it’s above or below certain thresholds. Maybe I’m misunderstanding the way that arrays work, I don’t see any real problems with the code here.

The Calibration LED comes on, and then the Go LED, but when I change the light on the sensor the NoGo led never comes on. I suspect that there is some problem with the way the loop is accessing the upper or lower limit array values and comparing them to the sensor reading

– Current Sink LED wiring - HIGH is OFF and LOW is ON

*/

//Declare Constants
const int Taps = 2; //Number of taps being monitored, this will serve as the length of arrays used
int DigitalPin = {
0, 1, 2, 3, 4 , 6, 7, 8, 9, 10, 11, 12, 13}; //All digital pins
int AnalogPin = {
0, 1, 2, 3, 4, 5}; //All analog pins A0 through A5
int NoGo = {
2, 4, 6, 8, 10, 12}; //NoGo LEDs are on even pins
int Go = {
3, 5, 7, 9, 11, 13}; //Go LEDs are on odd pins
const int CalibrateTime = 5000;
const int Thresh = 0; //Buffer space for upper and lower limits

//Declare Variables
int UpperLimit = {
0, 0, 0, 0, 0, 0}; //Each tap line has its own limits
int LowerLimit = {
1023, 1023, 1023, 1023, 1023, 1023};
int Sensor;

void setup(){
Serial.begin(9600);
int n = 0;
for (int n = 0; n <= Taps; n++){
pinMode(Go[n], OUTPUT); //Set all digital pins to output
pinMode(NoGo[n], OUTPUT);
pinMode(AnalogPin[n], INPUT); //Set all analog pins to input
for (n = 0; n <= Taps; n++){ //Indicate Calibration period by setting all LEDs to Red
digitalWrite(Go[n], HIGH);
digitalWrite(NoGo[n], LOW);
}
}
}
void loop(){

// Self-Calibration to initial lighting conditions on sensors, stores limits in an array

while (millis() < CalibrateTime){
int n = 0;
for (int n = 0; n <= Taps; n++){
Sensor = analogRead(AnalogPin[n]);
if (Sensor < LowerLimit[n]) LowerLimit[n] = Sensor;
/*
Serial.println("Lower Limit: ");
Serial.print(LowerLimit[n]);
delay(250);
*/

if (Sensor > UpperLimit[n]);
UpperLimit[n] = Sensor;
/*
Serial.println("Upper Limit: ");
Serial.print(UpperLimit[n]);
delay(250);
*/

}
}
if (millis() >= CalibrateTime){ //Set all LEDs to Green to indicate Ready
for(int n=0; n <= Taps; n++){
digitalWrite(NoGo[n], HIGH);
digitalWrite(Go[n], LOW);
}
}

//Begin monitoring tap lines after calibration/setup is complete
//Light red LEDs if sensor reading is above or below the limits

for(int n = 0; n <= Taps; n++){
Sensor = analogRead(AnalogPin[n]);
if (Sensor > UpperLimit[n]){
digitalWrite(Go[n], LOW);
digitalWrite(NoGo[n], HIGH);
Serial.println("Exceeds upper limit: ");
Serial.print(Sensor);
}
if (Sensor < LowerLimit[n]){
digitalWrite(NoGo[n], LOW);
digitalWrite(Go[n], HIGH);
Serial.println("Exceeds lower limit: ");
Serial.print(Sensor);
}
if (n == Taps){
n = 0;
}
}
}

I think I've fixed this by including a break; after each if loop comparing the sensor reading to the upper or lower limit.

That said, I'm open to any suggestions for improvement. For example, is there a better way to monitor six analog inputs at once?

Thanks for any help!

const int Taps = 2;
for (int n = 0; n <= Taps; n++)

There’s a bug waiting to happen.

Hi,

The calibration process is only supposed to happen once, right? At the moment it is in your loop() function, so will get executed over and over. I suspect everything you have now in loop(), up to the "Begin monitoring" comment, should be in setup().

Paul

PS. You should use Code tags rather than Quote tags when posting a sketch (its the # button).

0, 1, 2, 3, 4 , 6, 7, 8, 9, 10, 11, 12, 13};      //All digital pins

You got some objection to pin 5?

I don’t think you’re using this variable. If you aren’t using it, get rid of it.

for(int n = 0; n <= Taps; n++){

I suggest you change the <= to a < and then get rid of the following bodge:

    if (n == Taps){
      n = 0;
    }
const int Taps = 2;                                 //Number of taps being monitored, this will serve as the length of arrays used

Why don’t you use it to define the array lengths, then? It already doesn’t match the actual length of the arrays.

sounds like this is crying out for hardware. a comparitor would be much faster and all you need to detect is a digital input.

how fast? how often? how important ?

Can you can accept a bubble from going undetected because the software is in not looking at that channel,?

what is the worst case senario ?

Wow, thanks for all the replies! I'm new to arduino and C programming, so getting this all worked out AND writing a neat, efficient code has been a fun challenge.

AWOL - What exactly is the bug waiting to happen? I thought I did this in the same way as the tutorials.

PaulRB - yes calibration only happens once. I included the little loop with the millis() function to make sure it only happens for the first few seconds that the circuit is activated, but I guess I should put it in to setup loop. Thanks for the pointer!

Peter H - pin 5 was a typo, and I had been using that array but changed the code recently. I'll drop it. As for your second recommendation, will n reset to 0 once it becomes equal to 'Taps'? Also, The arrays I've included are this long because I want to be able to monitor between 1 and 6 taps just by changing that variable. If I do something like int array[Taps] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} will the array just be 'trimmed' to whatever number Taps represents? Or should I just build each array using the Taps variable?

Dave-in-nj - This project will watch for bubbles or foam coming througha keg line. If there is a small enough bit of foam or a small bubble that slips by unnoticed, it's ok. Mostly this is just to alert the pourer when the keg is empty and there is just foam/CO2 coming through the line. So worst case scenario really is no worse than what already happens all the time anyway - you're pouring a beer and suddenly the thing sputters out pure foam. Also, if I used a comparitor I would have to set up each optical sensor to output the same voltage, which would be difficult enough I think without considering that each line will have a different beer in it (and therefore reflect a different light value to the sensor).

Thanks again for all the help!

The bug is that you look like you intend to iterate two times, when you're actually iterating three times.

setup() isn't a loop. It only gets called once when the Arduino gets switched/reset. loop() on the other hand is a loop (or rather it gets called repeatedly by a loop).