Help with Code for Multiple Analog Inputs and Two Outputs (Test Fixture)

Hey everyone, hope all is well.

I am working on a project for work right now, that will be used to test these new cables that we are manufacturing. The cables have 5 wires and I plan on using an ATMega328p w/ bootloader to design a kind of cable scan. I have two connectors to plug the wires into and on one end it will be fed into an analog input (5x total) with a 10k resistor to ground. On the other end of the cable there will be 5 different value, precision resistors attached to VCC. So this will set up a voltage divider that will return a specific value for each wire, and if the cable is wired wrong and an analog input sees a different value, it will send out a FAIL (red LED connected to digital output driven by transistor) and if all the values are within specs, it will output a PASS (green LED connected to a second digital output driven by transistor). I am a hardware engineer, so my software capabilities are limited, which is why I am using the Arduino, since we used them in school.
So I am wondering if anyone has some example code that I could look at that does something similar to this, checking multiple analog inputs, and if all conditions are met, sending out a digital high signal to one pin, or if conditions are not met, send out a digital high to a separate pin.

I know I would use something like....

int AnalogValue = analogRead (analogPin);

if (analogValue > threshold) {
digitalWrite (ledPin, HIGH);
}
else {
digitalWrite (ledPin, LOW); }

I understand that is how to check an analog pin, and if it meets a certain condition, output to a digital pin. However I am unsure of how to string all 5 analog inputs together to make sure that each individual analog pin is within the tolerance specified, and then if all five analog lines are correct, then send a PASS indicator out, otherwise send out a FAIL.

If anyone could point me in the right direction, I would greatly appreciate the help. Thanks very much guys, all help is greatly appreciated, especially since I am under the gun on getting this tester on the line. Thanks again guys!

You can use an array of int. Every item is the number of analog pin to test.
If thresold are different for every pin, use another array for this.

int vPins[]={A0,A1,A2};
int vTh[]={100,200,300};
boolean okay;
...
okay=TRUE;
for(int i=0;i<3;i++)     
{ int AnalogVal = analogRead (vPins[i]);
  if (AnalogVal > vTh[i])  
  { // do nothing
  }
  else 
  { okay=FALSE;  // if only one fail set to FALSE. You can exit for if no next pins need to be tested !?!
    i=4;   
  }
}
if(okay==TRUE)
{
}
else
{
}

How would I set that up?

Like how would I use a "int" vector for 5 different analog values? Would that vector for the actual pins automatically start counting the number of analog pins to read from? Like I said, I am a hardware guy, so you'll have to bare with me on the software side of things... Sorry about that.

You are too fast. :grin:
Now I have write for you a little code (NOT tested) on previous post.

A array is like a multiple variable. So you can do operations on many variables using the same name and an index.
A array like vPins have size of 3 but elements are 0,1 and 2
Declare 3 variables using 3 names, no multiple operations

int a,b,c;
if(a>0) ...
if(b>0) ...

With array using an index you can work on many elements.

int arr[3];         // 3 number   arr[0], arr[1] and arr[2]

Okay, I think I am starting to see what is going on with that code. So will the analog pin "int" and the threshold "int" correspond with each other, or is there some kind of timing that needs to take place to get them to line up? Or does it just step through each pin and each value in line? So I'm guessing I could use something similar to the code in your first post?

whitnasty1:
Okay, I think I am starting to see what is going on with that code. So will the analog pin "int" and the threshold "int" correspond with each other, or is there some kind of timing that needs to take place to get them to line up? Or does it just step through each pin and each value in line? So I'm guessing I could use something similar to the code in your first post?

This, "the analog pin "int" and the threshold "int" correspond with each other"
The two arrays start with elements 0. On for loop of code before you can see that I use i variable for vPins and for vTh
First loop i=0, second loop i=1, etc. Using i as index for vPins and vTh I access the corresponding element.

Okay, I am going to try to piece something together and I will post it back in a minute and see if you think I'm heading in the right direction, thanks very much for the help, I really appreciate it. Hopefully I can get this working here soon!

Okay, please don’t laugh when you read this, because I know it is a mess, I’m telling ya’, I could never do software for a living haha.

I’m just trying to see if I am starting to figure this out somewhat, because there is no way in hell this code works the way it is haha.

int vPins[] = {A0,A1,A2,A3,A4};
int vTh[] = (150,255,512,768,1000};
boolean okay;

void setup() {
	pinMode (9, OUTPUT); // PASS indicator
	pinMode (11, OUTPUT); // FAIL indicator
 }

void loop() {

okay = TRUE;

 for (int i=0; i<5; i++)
{ int AnalogVal = analogRead (vPins[i]);
  if (AnalogVal > vTh{i}){  // need to make it so anything above or below that value is a fail
}
  else
 { okay=False;
   i=4;
}
}
if (okay==TRUE);
{ digitalWrite (9, HIGH);
}
else {
 digitalWrite (11, HIGH);}

delay (100);
}

Yeah… I know… ha

....or would something like this work as well? I know it is long and kind of hard to read, but it is pretty much the only way I know ha....

const int analogPin = A0;
const int analogPin1 = A1;
const int analogPin2 = A2;
const int analogPin3 = A3;
const int analogPin4 = A4;
const int passLed = 11;
const int failLed = 9;
const int threshold = 200;
const int threshold1 = 300;
const int threshold2 = 400;
const int threshold3 = 500;
const int threshold4 = 600;

void setup () {
	pinMode (passLed, OUTPUT);
	pinMode (failLed, OUTPUT);
 }

void loop () {

int analogValue = analogRead(analogPin);
int analogValue1 = analogRead(analogPin1);
int analogValue2 = analogRead(analogPin2);
int analogValue3 = analogRead(analogPin3);
int analogValue4 = analogRead(analogPin4);

if (analogValue > threshold){
	analogRead (A1);
}
else { 
	digitalWrite (failLed, HIGH);
}

if (analogValue1 > threshold1) {
	analogRead (A2); 
}
else {
	digitalWrite (failLed, HIGH);
}

if (analogValue2 > threshold2) {
	analogRead (A3);
}
else {
	digitalWrite (failLED, HIGH);
}
if (analogValue3 > threshold3) {
	analogRead (A4);
}
else {
	digitalWrite (failLed, HIGH);
}
if (analogValue4 > threshold4) {
	digitalWrite (passLED, HIGH);
}
else {
	digitalWrite (failLed, HIGH);
delay(250);
}

On previous code, some syntax errors, try this:

int vPins[] = {A0,A1,A2,A3,A4};
int vTh[]   = {150,255,512,768,1000};
#define DIMARR 5
boolean okay;

void setup() 
{ delay(1000);
  for(int i=0;i<DIMARR;i++)
  { pinMode(vPins[i],INPUT);
  }
  pinMode (9, OUTPUT); // PASS indicator
  pinMode (11, OUTPUT); // FAIL indicator
}

void loop() 
{ okay = true;
  for (int i=0; i<DIMARR; i++)
  { int AnalogVal = analogRead(vPins[i]);
    if (AnalogVal > vTh[i])  // need to make it so anything above or below that value is a fail
    {}
    else
    { okay=false;
      i=DIMARR+1;
    }
  }
  if (okay==true)
  { digitalWrite (9, HIGH);
  }
  else 
  { digitalWrite (11, HIGH);
  }
  delay (100);
}

The second code using only simple variables and not arrays? But when no fail test why another analogRead and not a digitalwrite on another led?

whitnasty1:
…or would something like this work as well? I know it is long and kind of hard to read, but it is pretty much the only way I know ha…

Noooo… this is exactly the situation that arrays were made for. BTW, nid69ita is referring to them as vectors, but I think the proper term is arrays. A vector is a dynamically-adjustable array, but I don’t think that is called for in this situation.

An array is just a group of data elements. So:

int foo[] = {1, 2, 3, 100, 200, 300};

Serial.println(foo[0]); // prints "1"
Serial.println(foo[1]); // prints "2"
Serial.println(foo[5]); // prints "300"

You can put the pin numbers into the array as such:

byte pinNums[] = {a0, a1, a2, a3, a4}
int voltageAnalogValues[] = {100, 200, 300, 400, 500}

for (int x = 0; x < 5; x++)
{
  if (analogRead(pinNums[x]) > voltageAnalogValues[x])
    Serial.println("Failed!");
}

Yeah that is a whole lot neater and easier to read, so would I just be able to take out all of those "if" statements in my code and drop that in there and instead of the serial command I can just tell it to turn on my PASS led and then "else" turn on the Fail LED?

Something like that, yes. Start with the "PASS" LED turned on, and then if any line is found to be out of specification, switch to the "FAIL" LED. Alternatively, track pass/fail status internally with a boolean variable and leave the LEDs off until the test completes, then turn on pass or fail LED. That way, if, for example, the test failed to complete or something, no LED would be turned on. It all just depends exactly how you want to implement the logic.

BTW, if you are going to implement this code, IMO, a better way to do it would be to explicitly declare the array’s size, as such:

const byte numLines = 5;
const byte pinNums[numLines] = {a0, a1, a2, a3, a4};
const int voltageAnalogValues[numLines] = {100, 200, 300, 400, 500};

for (byte x = 0; x < numLines; x++)
{
  if (analogRead(pinNums[x]) > voltageAnalogValues[x])
    Serial.println("Failed!");
}

This allows you to easily change the number of lines you are testing, and also provides explicit checking (by the compiler) that your arrays have the correct number of elements. Also, I have changed the pinNum and voltageAnalogValues arrays to constants, since they never change during the course of the program. Finally, I changed x to a byte from an int. Realistically, this won’t matter at all, but it keeps the data type of x consistent with the data type of numLines.

… just to extend this idea, here is an approach that lights a different LED depending on which line has failed. This continues to illustrate the usefulness of arrays.

const byte numLines = 5;
const byte inputPinNums[numLines] = {a0, a1, a2, a3, a4};
const int voltageAnalogValues[numLines] = {100, 200, 300, 400, 500};
const byte outputPinNums[numLines] = {2, 3, 4, 5, 6};

for (byte x = 0; x < numLines; x++)
{
  if (analogRead(inputPinNums[x]) > voltageAnalogValues[x])
    digitalWrite(outputPinNums[x], HIGH); // turn "failed" LED on
  else
    digitalWrite(outputPinNums[x], LOW); // turn "failed" LED off
}

This is just a code snippet and some necessary stuff is missing, such as setting the pins to OUTPUT. It’s just intended to give you the concept.

joshuabardwell:
Something like that, yes. Start with the “PASS” LED turned on, and then if any line is found to be out of specification, switch to the “FAIL” LED. Alternatively, track pass/fail status internally with a boolean variable and leave the LEDs off until the test completes, then turn on pass or fail LED. That way, if, for example, the test failed to complete or something, no LED would be turned on. It all just depends exactly how you want to implement the logic.

^^ I like doing it that way better, waiting for the test to complete to give an output, I also need to make it so if the value is above or below a certain range, it will fail. I just tried adding that little part into my code though and it gives giving me an error saying a0,a1,a2,a3, and a4 are not declared in this scope…

byte pinNums[] = {a0, a1, a2, a3, a4};
int voltageAnalogValues[] = {100, 200, 300, 400, 500};

const int passLed = 11;
const int failLed = 9;

void setup () {
	pinMode (passLed, OUTPUT);
	pinMode (failLed, OUTPUT);
 }

void loop () {

for (int x = 0; x < 5; x++)
{
  if (analogRead(pinNums[x]) > voltageAnalogValues[x]); {
	digitalWrite (failLed, HIGH);
}
else {
	digitalWrite (passLed, HIGH);
}
delay (250);
}

joshuabardwell:
Noooo… this is exactly the situation that arrays were made for. BTW, nid69ita is referring to them as vectors, but I think the proper term is arrays. A vector is a dynamically-adjustable array, but I don’t think that is called for in this situation.

Sorry for mistake. Yes I used the word vector for array, my english is terrible :blush:

As writed by @joshua normally for pin number you can use byte (unsigned char 0-255) instead int (-32768+32767)
So you can ask to compiler the dimension of an array of byte directly using sizeof() function (only for byte arrays!!!):

for (int x = 0; x < sizeof(pinNums); x++)

It’s not calculated at run-time. When you compile the code compiler replace this function with a constant.

A note: I don’t think the compiler know a0,a1 but A0,A1…

whitnasty1:
^^ I like doing it that way better, waiting for the test to complete to give an output, I also need to make it so if the value is above or below a certain range, it will fail. I just tried adding that little part into my code though and it gives giving me an error saying a0,a1,a2,a3, and a4 are not declared in this scope…

I apologize for my sloppy example. I think the constants are actually defined as A0, A1, etc… Capital A, not lowercase.

for (int x = 0; x < 5; x++)

{
 if (analogRead(pinNums) > voltageAnalogValues); {
digitalWrite (failLed, HIGH);
}
else {
digitalWrite (passLed, HIGH);
}
delay (250);
}

You should check your curly-brackets. I think that you haven’t closed the curly-bracket for the for{} statement. The semicolon following your if() statement is syntactically correct, but will cause the if() statement to end immediately such that the code block following it is no longer contingent on the if() statement. In other words, you pretty much never want that semicolon.

if (analogRead(pinNums[x]) > voltageAnalogValues[x]); /* GET RID OF THIS SEMICOLON */ {

If your if/else has only a single line of code following it, the brackets can be omitted, as such:

if (analogRead(pinNums[x]) > voltageAnalogValues[x])
  digitalWrite (failLed, HIGH);
else
  digitalWrite (passLed, HIGH);

This is a bit cleaner and easier to read than the bracketed version.

If I understand correctly how you’re going to use the device, your circuit should implement pullup/down resistors to pull the analog pins to a fixed reference value in the absence of a test harness. Otherwise, they will be floating when no test harness is plugged in, and will return invalid pass/fail values. The ideal scenario, as I see it, would be to pullup the lines to 5v and have the code turn all LEDs off if all lines are at 5v. This would be an “idle” state. When the test harness is plugged in, one or more of the lines will go below 5v, which will cue the code that a test is in progress, and the pass/fail LEDs can be turned on. I don’t exactly understand how your test harness will be wired up, so it may be necessary to tweak the details of this situation accordingly. Like, for example, it may be necessary to use a very high-resistance pullup resistor so that your test harness presents a sufficiently low-resistance path to ground so as not to have the pullup resistor affect your measurements.

Would the 10k pull down resistor on each of the analog lines pull the voltages down enough so I won't be getting false readings?

I have 5 analog pins going to a connector with 10k resistors to ground on each of those lines, on the other end there is another connector that the cable will plug into, and each of those lines have a specific, precision (1%) resistor on each line, so each should return a unique adc reading to that wire. I think the 10k's to ground should pull all of those pins low. Is there a way I can tell each analog input to look for a reading between two points? Like instead of it just being 200, make it anything between 195 and 205 is considered good? I have done this on a previous test fixture, but I was only sampling one analog pin. I'm really just having problems getting all of the analog pins to work together correctly.

I am about to try the code that you just posted and see what that does for me, I will post back with results shortly. I can't tell you guys how much I appreciate the help, I gave all you guys who have been helping +Karma by the way! Thanks

Made the changes that you suggested to the code, and the only error that I am getting now is… “expected if, before else statement”, it’s saying that there is an else statement without an if statement. I am thinking it has something to do with my curly brackets somewhere, I don’t see how you guys do this software thing all day, I’m going crazy already. I know my hardware is good, this software is just giving me problems. I would normally ask our software team to just throw something together for me really quick, but they are all busy doing production software releases, so us hardware guys are having to fend for ourselves haha. Anyways, here is the code that is giving me that syntax error…

byte pinNums[] = {A0,A1,A2,A3,A4};
int voltageAnalogValues[] = {40, 840, 640, 8, 85};

void setup () {
	pinMode (11, OUTPUT);
	pinMode (9, OUTPUT);
 }

void loop () {
 for (int x = 0; x < 5; x++)
{
  if (analogRead(pinNums[x]) > voltageAnalogValues[x]); {
	digitalWrite (11, HIGH);
}
else {
	digitalWrite (9, HIGH);
}
delay (250);
}
}