Pro Mini hardware test program

A program to test all digital and analog IO works perfectly on an Arduino Uno (for which it was originally written).
When I test this (with a correctly set up hardware jig) on a Pro Mini this test fails on a 100% good board.
I tested with 16MHz 5V Pro Mini.

What could be the reason for failure?

Hardware setup:

  1. each IO (digital pins 2 thru 12; analog pins A0 thru A5) connected to a 220R resistor.
  2. all resistors connected to a common and isolated point
  3. this isolated point is connected with 2 100k resistors, to GND and to +5V.
/* YourDuino Arduino Board TEST 
 Tests all Arduino I/O and Analog pins for Source and Sink ability
 Tests Analog Read on A0..A5
 terry@yourduino.com 

 9600 baud
 
 This test assumes that pins 0 (RX Data) and 1 (TX Data) are OK
 if programs can be loaded, and that pin 13 is OK if it's attached LED
 can be blinked. Pin 13 is not tested for current sink ability.
 
 Test progress and pass-fail results are sent to the Serial Monitor.
 At the end of test, Pin 13 LED is blinked very slowly 
 for Pass and quickly for Fail.
 
 This test works with a "Test Shield" that is plugged on top
 of the Arduino under test. This shield has a common isolated 
 connection point. The Common Point has 17 220 ohm resistors 
 connected to every digital pin from 2 to 12, and to every analog
 pin from 0 to 5. It also has two 100,000 ohm resistors which 
 connect it to Ground and +5.0 volts, forming a voltage divider
 that sets the common point to 2.50 volts when all pins are in
 the reset high-impedance input condition. This is read by A0 to
 initially test if any of the pins are "stuck" or "leaking", which 
 will pull the common point away from 2.50 volts
 
 Next, pins 3 thru A5 are tested by setting them High or Low against
 an opposite load presented by pin 2. Each pin must be able to
 source and sink at least 10 ma to bring the common point near 2.50 volts.
 If pin 2 fails, all other pins will fail. 
 
 Next, A0 thru A5 are tested individually with voltages near 1.66, 2.50, 3.33volts
 and possibly others, using the resistors connected to the digital pins to
 make various voltage dividers.

 Test shield:
 1. from every IO pin except 0, 1, 13 one 220 Ohm resisotr
 2. all resistors join a common isolated point
 3. this point is connected to +5V with one 100kOhm and to GND with another 100kOhm resistor
 Test checks if every analog inout receives 2.5V
 Test then checks every single pin for sinking while the others for sourcing (about 10mA)
 Test then reads 3 different voltages with all analog inputs and displays them
 
 This design and software is licensed under a Creative Commons 
 Attribution-Noncommercial-Share Alike 3.0 License:
 http://creativecommons.org/licenses/by-nc-sa/3
 */

/*-----( Import needed libraries )-----*/
#include <LED.h>    // Easy HAL blink routines

/*-----( Declare Constants )-----*/

const  int    FirstDigPort =  3;  //Pin 2 is used as reference
const  int    LastDigPort  =  12;
const  int    FirstAnaPort =  15;
const  int    LastAnaPort  =  19;
const  int    A2D_Delay    =  10; //ms delay for A-D to settle

const  float  LowStuckResultOK     =  2.40 ; 
const  float  HighStuckResultOK    =  2.60 ;   
const  float  LowVoltResultOK      =  2.30 ;    
const  float  HighVoltResultOK     =  2.70 ;   

/*-----( Declare objects )-----*/
LED  LED13(13);        // The only LED we can blink!

/*-----( Declare Variables )-----*/

int    DigPort2Test;
int    AnaPort2Test;
int    IntVoltsRead;      // Result of AnalogRead 0..1023
float  FloatVoltsRead;    // Result of AnalogRead 0.0 .. 5.0
int    Failure;          // Count failures that occur
byte   FailArray[20];    // Save Pass-Fail during a test
int    FailArrayPtr;

void setup()   /****** SETUP: RUNS ONCE ******/
{
  delay(500);
  Serial.begin(9600);
  delay(500);
  Serial.println("Arduino Board Test V1.08");
  Serial.println("YourDuino.com terry@yourduino.com");
  delay(500);
  LED13.blink(300, 4);  // "HI" in Morse code
  delay(500);  
  LED13.blink(300, 2);  

}//--(end setup )---


void loop()   /****** LOOP: RUNS CONSTANTLY ******/
{
  Failure = 0;
  Serial.println();  
  Serial.println("--- TEST START ---");
  
//-------------( TEST 1 )---------------------------------------------
  Serial.println("TEST 001 - Any stuck pins??");
  delay(500);
  IntVoltsRead = analogRead(A0);
  FloatVoltsRead = a2d2float (IntVoltsRead);
  Serial.print("VoltsRead = ");
  Serial.print(FloatVoltsRead,2);  

  if (FloatVoltsRead > LowStuckResultOK
    &&  FloatVoltsRead < HighStuckResultOK)
  {
    Serial.println("  -- OK!");
  }
  else
  {
    Failure ++;
    Serial.println("  ** STUCK OR LEAKY PIN FAIL ** ");    
  }

//-----------------------( TEST 2 )--------------------------------
  Serial.println();    
  Serial.println("TEST 002 - Digital Pins Source Current");  
  pinMode(2, OUTPUT);      // Set Load pin to Output mode
  digitalWrite(2, LOW);              // Connect Low Load  
  FailArrayPtr    =  0 ;

  //---------( Write the Digital Pin Labels )---------------
  WriteDigitalPinLabels();

  //------( Loop thru pins, testing )-----------  
  for (  DigPort2Test = FirstDigPort; 
         DigPort2Test <= LastDigPort;
         DigPort2Test ++)
  {//Loop thru Source Tests
    FailArrayPtr ++ ;

    pinMode(DigPort2Test, OUTPUT);      // Set tested pin to Output mode
    digitalWrite(DigPort2Test, HIGH);  // Pin Sources current HIGH     
    delay(A2D_Delay);
    IntVoltsRead = analogRead(A0);
    FloatVoltsRead = a2d2float (IntVoltsRead);
    pinMode(DigPort2Test, INPUT);      // ReSet tested pin to Input mode   

    Serial.print(FloatVoltsRead,2);  
    Serial.print("   ");      

    if (FloatVoltsRead > LowVoltResultOK
      &&  FloatVoltsRead < HighVoltResultOK)
    {
      FailArray[FailArrayPtr]  = 0;      
    }
    else
    {
      Failure ++;   
      FailArray[FailArrayPtr]  = 1;
    }        

  }//END Loop thru Source Tests

  Serial.println();  

  //--------( Write the Digital Pin PASS-FAIL Strings )----------------------  
  WriteDigitalPassFail();


//--------------------( TEST 3 )----------------------------------------

  Serial.println("TEST 003 - Digital Pins Sink Current");  
  pinMode(2, OUTPUT);      // Set Load pin to Output mode
  digitalWrite(2, HIGH);              // Connect HIGH Load  
  FailArrayPtr    =  0 ;

  //---------( Write the Digital Pin Labels )------------
  WriteDigitalPinLabels();

  //------( Loop thru pins, testing )-----------  
  for (  DigPort2Test = FirstDigPort; 
         DigPort2Test <= LastDigPort;
         DigPort2Test ++)
  {//Loop thru Source Tests
    FailArrayPtr ++ ;

    pinMode(DigPort2Test, OUTPUT);      // Set tested pin to Output mode
    digitalWrite(DigPort2Test, LOW);  // Pin Sinks current LOW   
    delay(A2D_Delay);
    IntVoltsRead = analogRead(A0);
    FloatVoltsRead = a2d2float (IntVoltsRead);
    pinMode(DigPort2Test, INPUT);      // ReSet tested pin to Input mode   

    Serial.print(FloatVoltsRead,2);  
    Serial.print("   ");      

    if (FloatVoltsRead > LowVoltResultOK
      &&  FloatVoltsRead < HighVoltResultOK)
    {
      FailArray[FailArrayPtr]  = 0;      
    }
    else
    {
      Failure ++;   
      FailArray[FailArrayPtr]  = 1;
    }        

  }//END Loop thru Source Tests

  Serial.println();  

  //--------( Write the Digital Pin PASS-FAIL Strings )--------------  
  WriteDigitalPassFail();


//-------------------------( TEST 4 )----------------------------------------
  Serial.println();    
  Serial.println("TEST 004 - Analog Pins Source Current");  
  pinMode(2, OUTPUT);      // Set Load pin to Output mode
  digitalWrite(2, LOW);              // Connect Low Load  

  WriteAnalogPinLabels();

  for (  DigPort2Test = FirstAnaPort; 
         DigPort2Test <= LastAnaPort;
         DigPort2Test ++)
  {//Loop thru Source Tests

    pinMode(DigPort2Test, OUTPUT);      // Set tested pin to Output mode
    digitalWrite(DigPort2Test, HIGH);  // Pin Sources current HIGH     
    delay(A2D_Delay);
    IntVoltsRead = analogRead(A0);
    FloatVoltsRead = a2d2float (IntVoltsRead);
    pinMode(DigPort2Test, INPUT);      // ReSet tested pin to Input mode   
    Serial.print(FloatVoltsRead,2);  
    Serial.print("   ");   

    if (FloatVoltsRead > LowVoltResultOK
      &&  FloatVoltsRead < HighVoltResultOK)
    {
      FailArray[FailArrayPtr]  = 0;      
    }
    else
    {
      Failure ++;   
      FailArray[FailArrayPtr]  = 1;
    }        

  }//END Loop thru Source Tests
  Serial.println();
  WriteAnalogPassFail();

  /*---------( TEST 5 )----------------------*/

  Serial.println("TEST 005 - Analog Pins Sink Current");  
  pinMode(2, OUTPUT);      // Set Load pin to Output mode
  digitalWrite(2, HIGH);              // Connect HIGH Load  

  WriteAnalogPinLabels();

  for (  DigPort2Test = FirstAnaPort; 
         DigPort2Test <= LastAnaPort;
         DigPort2Test ++)
  {//Loop thru Sink Tests

    pinMode(DigPort2Test, OUTPUT);      // Set tested pin to Output mode
    digitalWrite(DigPort2Test, LOW);    // Pin Sinks current LOW   
    delay(A2D_Delay);
    IntVoltsRead = analogRead(A0);
    FloatVoltsRead = a2d2float (IntVoltsRead);
    pinMode(DigPort2Test, INPUT);      // ReSet tested pin to Input mode   
    Serial.print(FloatVoltsRead,2);  
    Serial.print("   ");   

    if (FloatVoltsRead > LowVoltResultOK
      &&  FloatVoltsRead < HighVoltResultOK)
    {
      FailArray[FailArrayPtr]  = 0;      
    }
    else
    {
      Failure ++;   
      FailArray[FailArrayPtr]  = 1;
    }        

  }//END Loop thru Source Tests
  Serial.println();
  WriteAnalogPassFail();



  /*---------( TEST 6 )----------------------*/
  Serial.println();
  Serial.println("TEST 006 - Analog Pins A0 to A5: A to D (About 2.50 V)");  
  pinMode(2, OUTPUT);      // Set Load pin to Output mode
  digitalWrite(2, HIGH);              // Connect HIGH Load
  pinMode(3, OUTPUT);      // Set Load pin to Output mode  
  digitalWrite(3, LOW);              // Connect LOW Load  

  WriteAnalogVoltLabels();

  for (  AnaPort2Test = FirstAnaPort -1; 
         AnaPort2Test <= LastAnaPort;
         AnaPort2Test ++)
  {// Loop thru Analog Tests
    delay(A2D_Delay);
    IntVoltsRead = analogRead(AnaPort2Test);
    FloatVoltsRead = a2d2float (IntVoltsRead);  
    Serial.print(FloatVoltsRead,2);  
    Serial.print("   ");     
  }// END Loop thru Analog Tests  


  /*---------( TEST 7 )----------------------*/
  Serial.println();
  Serial.println();
  Serial.println("TEST 007 - Analog Pins A0 to A5: A to D (About 3.33 V)");  
  pinMode(4, OUTPUT);      // Set Load pin to Output mode
  digitalWrite(4, HIGH);              // Connect 2nd Resistor

  WriteAnalogVoltLabels();

  for (  AnaPort2Test = FirstAnaPort -1; 
         AnaPort2Test <= LastAnaPort;
         AnaPort2Test ++)
  {// Loop thru Analog Tests
    delay(A2D_Delay);
    IntVoltsRead = analogRead(AnaPort2Test);
    FloatVoltsRead = a2d2float (IntVoltsRead);  
    Serial.print(FloatVoltsRead,2);  
    Serial.print("   ");     
  }// END Loop thru Analog Tests    


  /*---------( TEST 8 )----------------------*/
  Serial.println();
  Serial.println();  
  Serial.println("TEST 008 - Analog Pins A0 to A5: A to D (About 1.66 V)");  
  pinMode(4, OUTPUT);      // Set Load pin to Output mode
  digitalWrite(4, LOW);              // Connect 2nd Resistor

  WriteAnalogVoltLabels();

  for (  AnaPort2Test = FirstAnaPort -1; 
         AnaPort2Test <= LastAnaPort;
         AnaPort2Test ++)
  {// Loop thru Analog Tests
    delay(A2D_Delay);
    IntVoltsRead = analogRead(AnaPort2Test);
    FloatVoltsRead = a2d2float (IntVoltsRead);  
    Serial.print(FloatVoltsRead,2);  
    Serial.print("   ");     
  }// END Loop thru Analog Tests     

  //----------( End Test Digital and Analog Ports: Reset everything)-------
  pinMode(2, INPUT);      // Reset Load pin to Input mode
  pinMode(3, INPUT);      // Reset Load pin to Input mode  
  pinMode(4, INPUT);      // Reset Load pin to Input mode 
  MCUCR |= ( 1 << PUD ); //Disable all Pullups

  /*------------( TEST COMPLETE )----------------*/
  Serial.println();    
  Serial.println("TEST COMPLETE");  
  if (Failure > 0)
  {
    Serial.print("!!!!!!!!!!  THERE WERE ");  
    Serial.print(Failure, DEC);            
    Serial.print(" FAILURES !!!!!!!!!!");  
    LED13.blink(150, 50);
  }
  else
  {
    LED13.blink(4000, 4);
  }
  Serial.println();  
  //  delay(10000);
  //--(end main loop )---
}
//----------------( Declare User-written Functions )--------------------------

/*---( fmap: Converts int Analog readings of 0..1023 to float)---*/
float fmap(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
} 

float a2d2float (int raw)
{
  return fmap(raw, 0, 1023, 0.0, 5.0);
}

void WriteDigitalPinLabels()
{
  //---------( Write the Digital Pin Labels )---------------------
  for (  DigPort2Test = FirstDigPort; 
         DigPort2Test <= LastDigPort;
         DigPort2Test ++)     
  {//Write the label strings  
    Serial.print("PIN-"); 
    Serial.print(DigPort2Test, DEC);
    Serial.print("  ");         
  }// Write Labels  
  Serial.println();
}

void WriteAnalogPinLabels()
{
  //---------( Write the Analog Pin Labels )---------------------
  for (  DigPort2Test = FirstAnaPort; 
         DigPort2Test <= LastAnaPort;
         DigPort2Test ++)     
  {//Write the label strings  
    Serial.print("PIN-");                
    Serial.print(DigPort2Test -14 , DEC);
    Serial.print("  ");         
  }// Write Labels  
  Serial.println();
}


void WriteAnalogVoltLabels()
{
  //---------( Write the Analog Pin Labels )---------------------
  for (  DigPort2Test = FirstAnaPort - 1; 
         DigPort2Test <= LastAnaPort;
         DigPort2Test ++)     
  {//Write the label strings  
    Serial.print("PIN-");                
    Serial.print(DigPort2Test -14 , DEC);
    Serial.print("  ");         
  }// Write Labels  
  Serial.println();
}

//--------( Write the Digital Pin PASS-FAIL Strings )----------------------  
void WriteDigitalPassFail()
{
  FailArrayPtr   = 0;
  for (  DigPort2Test = FirstDigPort; 
         DigPort2Test <= LastDigPort;
         DigPort2Test ++)  
  {//Write the PASS-FAIL strings  
    FailArrayPtr ++;  
    if   (FailArray[FailArrayPtr]  == 1)  // Was a Fail
    {
      Serial.print("FAIL   "); 
    }
    else
    {
      Serial.print("-OK-   ");  
    }       

  }// Write PASS-FAIL
  Serial.println();  
}//End  WriteDigitalPassFail



//--------( Write the Analog Pin PASS-FAIL Strings )----------------------  
void WriteAnalogPassFail()
{
  FailArrayPtr   = 0;
  for (  DigPort2Test = FirstAnaPort; 
         DigPort2Test <= LastAnaPort;
         DigPort2Test ++)  
  {//Write the PASS-FAIL strings  
    FailArrayPtr ++;  
    if   (FailArray[FailArrayPtr]  == 1)  // Was a Fail
    {
      Serial.print("FAIL   "); 
    }
    else
    {
      Serial.print("-OK-   ");  
    }       

  }// Write PASS-FAIL
  Serial.println();  
}//End  WriteDigitalPassFail




//*********( THE END )***********
void setup() {
  // put your setup code here, to run once:

}

void loop() {
digitalWrite(13,HIGH);
delay(250);
digitalWrite(13,LOW);
delay(250);

}

try this code and see if it works.

Yes it does. There is no issue with the Pro Mini under test.

What reason is reported on serial monitor for the failure?

then it's the code you're trying to use.

as far as I know the Pro Mini does not have 19 ports.

I think the code is optimised for the larger arduino boards.

what does it say in the serial monitor?

Hi Paul,
this is the serial monitor output:

--- TEST START ---
TEST 001 - Any stuck pins??
VoltsRead = 0.00 ** STUCK OR LEAKY PIN FAIL **

TEST 002 - Digital Pins Source Current
PIN-3 PIN-4 PIN-5 PIN-6 PIN-7 PIN-8 PIN-9 PIN-10 PIN-11 PIN-12
1.65 1.65 1.65 2.37 2.37 1.65 1.64 1.64 1.64 1.64
FAIL FAIL FAIL -OK- -OK- FAIL FAIL FAIL FAIL FAIL
TEST 003 - Digital Pins Sink Current
PIN-3 PIN-4 PIN-5 PIN-6 PIN-7 PIN-8 PIN-9 PIN-10 PIN-11 PIN-12
1.65 1.64 1.65 1.29 1.29 1.65 1.65 1.65 1.65 1.65
FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL

TEST 004 - Analog Pins Source Current
PIN-1 PIN-2 PIN-3 PIN-4 PIN-5
1.65 0.25 1.65 0.00 0.00
FAIL FAIL FAIL FAIL FAIL
TEST 005 - Analog Pins Sink Current
PIN-1 PIN-2 PIN-3 PIN-4 PIN-5
1.64 2.15 1.65 2.48 2.48
FAIL FAIL FAIL FAIL -OK-

TEST 006 - Analog Pins A0 to A5: A to D (About 2.50 V)
PIN-0 PIN-1 PIN-2 PIN-3 PIN-4 PIN-5
1.65 1.64 1.66 1.65 1.22 0.93

TEST 007 - Analog Pins A0 to A5: A to D (About 3.33 V)
PIN-0 PIN-1 PIN-2 PIN-3 PIN-4 PIN-5
2.48 2.49 2.50 2.49 2.01 1.61

TEST 008 - Analog Pins A0 to A5: A to D (About 1.66 V)
PIN-0 PIN-1 PIN-2 PIN-3 PIN-4 PIN-5
1.23 1.23 1.26 1.23 1.46 1.48
TEST COMPLETE
!!!!!!!!!! THERE WERE 27 FAILURES !!!!!!!!!!

Suspect you will find that A0 is also 14, up to A5 which is also 19.

Correct, but the same has to be declared as A0 and A5 respectively rather than 14 and 19.

No, either convention can be used.

I had to change it with my Nano, when I put 4 instead of A4 the program didn't work as desired.

Can you post some clear, sharp, bright photos of the circuit, so every wire can be traced?

And this is the output from a Arduino Uno:

Arduino Board Test V1.08
YourDuino.com terry@yourduino.com

--- TEST START ---
TEST 001 - Any stuck pins??
VoltsRead = 2.50 -- OK!

TEST 002 - Digital Pins Source Current
PIN-3 PIN-4 PIN-5 PIN-6 PIN-7 PIN-8 PIN-9 PIN-10 PIN-11 PIN-12
2.50 2.50 2.49 2.48 2.49 2.50 2.48 2.49 2.49 2.48
-OK- -OK- -OK- -OK- -OK- -OK- -OK- -OK- -OK- -OK-
TEST 003 - Digital Pins Sink Current
PIN-3 PIN-4 PIN-5 PIN-6 PIN-7 PIN-8 PIN-9 PIN-10 PIN-11 PIN-12
2.48 2.48 2.48 2.48 2.48 2.47 2.48 2.47 2.47 2.48
-OK- -OK- -OK- -OK- -OK- -OK- -OK- -OK- -OK- -OK-

TEST 004 - Analog Pins Source Current
PIN-1 PIN-2 PIN-3 PIN-4 PIN-5
2.50 2.50 2.49 2.49 2.50
-OK- -OK- -OK- -OK- -OK-
TEST 005 - Analog Pins Sink Current
PIN-1 PIN-2 PIN-3 PIN-4 PIN-5
2.48 2.48 2.48 2.49 2.48
-OK- -OK- -OK- -OK- -OK-

TEST 006 - Analog Pins A0 to A5: A to D (About 2.50 V)
PIN-0 PIN-1 PIN-2 PIN-3 PIN-4 PIN-5
2.48 2.48 2.48 2.48 2.48 2.48

TEST 007 - Analog Pins A0 to A5: A to D (About 3.33 V)
PIN-0 PIN-1 PIN-2 PIN-3 PIN-4 PIN-5
3.32 3.32 3.32 3.32 3.32 3.32

TEST 008 - Analog Pins A0 to A5: A to D (About 1.66 V)
PIN-0 PIN-1 PIN-2 PIN-3 PIN-4 PIN-5
1.65 1.65 1.65 1.65 1.65 1.65
TEST COMPLETE

18 would correspond to A4, I think.

Then I guess the nomenclature I used was incorrect.

Maybe OP is making the same mistake?

I don't think so. The test runs ok on Uno, apparently. Uno and Pro Mini share the same chip, although depending on the model of Uno, maybe same chip in a different package.

Both use the same chip: Atmega 328P.
IO's are identical except the Pro Mini also breaks out A6 and A7 which are not relevant for this test program / issue.
For the Pro Mini: A4 and A5 are connected via the 2 jumper wires.
Photo's attached


I can't immediately see any problems in the photos, but I would check and double-check for shorts caused by wires inadvertently touching or solder blobs, bad/dry joints etc. Can you unplug the Pro Mini and check continuity and resistance between points are as expected?

The first test "001" is failing with a very different reading to that seen with the Uno: 0.00V rather than 2.50V. That test involves pin A0, and that same pin is used in most or all of the successive tests. So focus on getting that test working first. Put a long delay in the code after test 001, so you can verify that 0.00V with your multimeter. If it is 0.00V, I think there could be a bad joint or short circuit around there somewhere. Maybe try removing the 220R from the other pins, one-by-one, and re-testing until, hopefully, that 2.50V figure is seen.

Yep.

When disconnecting the resistor to A0 voltage climbs to 2.25V.
Next step is removing one by one the other resistors.

Without that resistor, A0 is floating and could read any value at random. Leave that resistor in place and remove the other 220R, so that only the 220R on A0 and the 2 x 100K are connected. A0 should then read 2.50V.