Pages: [1]   Go Down
Author Topic: Arduino Board Testing  (Read 2932 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 28
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi everybody!

I don't see if there is a special topic about testing of Arduino boards. So I've made a simple testing board and a sketch.

The main idea is that we need to test an ability of a board to transfer the state of ATmega i/o pins to the Arduino pins. And to obtain the state of Arduino pins on the ATmege i/o pins. If it is the case, most of the board functionality is OK! If not - our test program have to show us the source of error ("bad port").

The schematic is so simple that I've described it in comments.

I use the tester with the Nano and now I want to make it for Mega. More resistors smiley
Code:
/*
  Arduino inputs-outputs test
  Analog and digital pins are tested as digital i/o ports. Exceptions:
  a) pins D0 and D1 are regarded as tested if USB-channel works well.
  b) analog inputs A6 and A7 are tested in analoge mode
  
  The circuit:
  All Arduino pins D2...D12 and A0...A7 are connected to a common
  point via small resistors (200 Ohm).
  Ports' numbers are regarded as Arduino pins: D2...D12 are Ports 2...12
  D13 is tested visually with BLINK), then A0...A5 are Ports 14...19
  
  Idea: Each port pin (in sequence) is configured as output while
  all other pins are inputs (without pullup resistors). The TESTED pin
  sets HIGH and LOW levels and ATmega168 measures the voltage via A6
  and A7 ADC channels. Then the pin is read via the next digital input.
  
  Operator can observe the results of complete test (a table is printed,
  2 seconds are waited an the allports test is repeated) or he can give
  commands:
  s - toggles STEP mode. In the mode onle ome Port is tested and only in
  one level (initially HIGH). The result is printed and the test is repeated.
  When operator gives a SPACE command, the level is set to LOW and next
  SPACE increases the port number (level HIGH). So operator can test all
  ports at both levels.
  The "b" command skips to the first Potr (number 2).
  The "q" command stops the program.
*/

#define VERSION 1

#define SHORT_TICK 50
#define LONG_TICK 2000
#define smillis() ((long)millis())

#define TESTED port[OutIndx]
#define READ port[InpIndx]

typedef enum TEST_PHASE { RUN, DIGITAL_HIGH, DIGITAL_LOW} phases;

const int port[] =     // All ports that are to be tested
// 0 1 2 3 4 5 6 7 8  9  10        11 12 13 14 15 16     it is "Indx"
 { 2,3,4,5,6,7,8,9,10,11,12,/*13,*/14,15,16,17,18,19};
//D2D3D4D5D6D7D8D9D10D11D12   D13  A0 A1 A2 A3 A4 A5
const byte portsNmb = sizeof(port)/2;

  byte Return[ portsNmb][2];    // for accumulating the result of test
  int InpIndx, OutIndx, i, j;
  int inpHiLevel[ portsNmb][2], inpLoLevel[ portsNmb][2];
  char s[80], Char;
  long StopTime, Millis, TickDuration;
  phases Phase = RUN;
 
void setup()
{
  for( InpIndx = 0; InpIndx < portsNmb-1; InpIndx++)
  {
    pinMode( READ, INPUT);
    digitalWrite( READ, LOW);
  }
  Serial.begin(9600);
  Serial.println( " ");
  Serial.print( "Arduino Nano ports test.       version: ");
  Serial.println(VERSION);  
  Serial.println( "DrVlas, 2010");
  Serial.println( " ");
  OutIndx = 0;  
  TickDuration = SHORT_TICK;
}
/********************************************* L O O P *************************/
void loop()
{
/************************************** Timeout 1 ******************************/  
  Millis = smillis();
  if( Millis - StopTime > 0)
  {
//    Serial.print(StopTime); Serial.print( " "); Serial.println( Millis);
    StopTime = (Millis / TickDuration + 1) * TickDuration;
    pinMode( 13, OUTPUT);            // BLINK output is not tested as others
    digitalWrite( 13, HIGH);
    
 /******************************* Get command and parse it ************/    
    if( Serial.available() > 0)
    {
      Char = Serial.read();
      switch( Char)
      {
        case 'b':          // BEGIN command
        case 'B':
          OutIndx = 0;
          break;
        case 's':          // STEP toggle command
        case 'S':
          if( Phase == RUN)
          {
            Phase = DIGITAL_HIGH;      // Set STEP mode
            TickDuration = LONG_TICK;
          }
          else
          {
            Phase = RUN;
            TickDuration = SHORT_TICK;
          }
          break;
        case ' ':          // Next port command
          switch( Phase)
          {
            case DIGITAL_HIGH: Phase = DIGITAL_LOW;  break;
            case DIGITAL_LOW:
              pinMode( TESTED, INPUT);
              digitalWrite( TESTED, LOW);        
              if( ++OutIndx >= portsNmb) { OutIndx = 0; }
              Phase = DIGITAL_HIGH;  
          }
          break;
        case 'q':
        case 'Q':
          Serial.println( " ");
          Serial.println( "Thanks for using the program!");
          Serial.println( " ");
          while(1) ;
      }
    }    
    pinMode( 13, INPUT);
    digitalWrite( 13, LOW);        // High impedance state of the pin
    
/******************************* Output and Input ********************/    
    pinMode( TESTED, OUTPUT);
    if( (Phase == DIGITAL_HIGH) || (Phase == RUN))
    {
      digitalWrite( TESTED, HIGH);
      InpIndx = OutIndx + 1;
      if( InpIndx >= portsNmb) InpIndx = 0;      
      inpHiLevel[OutIndx][0] = map( analogRead(6), 0, 1024, 0, 5000);
      inpHiLevel[OutIndx][1] = map( analogRead(7), 0, 1024, 0, 5000);
      Return[InpIndx][1] = digitalRead( READ);
    }

    if( (Phase == DIGITAL_LOW) || (Phase == RUN))
    {
      digitalWrite( TESTED, LOW);
      inpLoLevel[OutIndx][0] = map( analogRead(6), 0, 1024, 0, 5000);
      inpLoLevel[OutIndx][1] = map( analogRead(7), 0, 1024, 0, 5000);
      Return[InpIndx][0] = digitalRead( READ);
    }

    if( Phase == RUN)
    {
      pinMode( TESTED, INPUT);
      digitalWrite( TESTED, LOW);        
      if( ++OutIndx >= portsNmb) { OutIndx = 0; }
    }
    pinMode( 13, OUTPUT);  
    digitalWrite( 13, LOW);
    
/******************************* Print results of test ******/    
    switch( Phase)
    {
      case RUN:
        if( OutIndx == 0)
        {
          Serial.println( "Port    U6/U7 @ LOW    U6/U7 @ HIGH  inpPin  Pin(LOW/HIGH)");
          for( i = 0; i <= portsNmb-1; i++)
          {
            j = (i+1==portsNmb? 0:i+1);
            sprintf( s, " %02d     %04d / %04d     %04d / %04d    %02d       %d / %d",
            port[i], inpLoLevel[i][0], inpLoLevel[i][1], inpHiLevel[i][0], inpHiLevel[i][1],
            port[j], Return[j][0], Return[j][1]);
            Serial.print( s);  
            if( Return[j][1] && (!Return[j][0])) Serial.println( "    Port test OK!");
            else                                 Serial.println( "    Port test failed");
          }
          StopTime += (2*LONG_TICK);
        }
        break;
      case DIGITAL_HIGH:
        i = OutIndx;
        j = (i+1==portsNmb? 0:i+1);
        sprintf( s, "Port %02d HIGH    %04d / %04d    %02d       %d",
        port[i], inpHiLevel[i][0], inpHiLevel[i][1], port[j], Return[j][1]);
        Serial.print( s);  
        if( Return[j][1]) Serial.println( "    Port test OK!");
        else              Serial.println( "    Port test failed");
        break;
      case DIGITAL_LOW:
        i = OutIndx;
        j = (i+1==portsNmb? 0:i+1);
        sprintf( s, "Port %02d LOW     %04d / %04d    %02d       %d",
        port[i], inpLoLevel[i][0], inpLoLevel[i][1], port[j], Return[j][0]);
        Serial.print( s);  
        if( !Return[j][0]) Serial.println( "    Port test OK!");
        else               Serial.println( "    Port test failed");
        break;
      default: Serial.println( "Error in CASE");  
    }    // End of PRINT section
  }             // End of Timer1 handling
}                        // End of loop()
Logged

Phoenix, Arizona USA
Offline Offline
Faraday Member
**
Karma: 36
Posts: 5519
Where's the beer?
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmm - the idea is nifty; there might be refinements, but I can't think of any off the top of my head here (not really giving it much thought, though).

I can think of a couple of things - it would be neat to have a tester PCB as either a shield, or an off-board system connected by ribbon cables to the ports.

Also, it would be nice to have a similar device, but for testing bootloaded ATMega chips themselves, using a ZIF socket.

 smiley
Logged

I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

0
Offline Offline
Newbie
*
Karma: 0
Posts: 28
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Also, it would be nice to have a similar device, but for testing bootloaded ATMega chips themselves

I don't think so. You see, I'm not trying to test the chip, nor the whole variety of ATmega's functionality. My idea is rather to check soldering of the board, as the main source of problems.
Logged

Phoenix, Arizona USA
Offline Offline
Faraday Member
**
Karma: 36
Posts: 5519
Where's the beer?
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I don't think so. You see, I'm not trying to test the chip, nor the whole variety of ATmega's functionality. My idea is rather to check soldering of the board, as the main source of problems.

I am not positing that it would be useful for your usage, but for certain instances, it could be. For instance, I have some pre-bootloaded ATMegas that I bought from a vendor in China - for all I know they could be slugs (I haven't tested them yet). It would be nice to "run them thru their paces" so to speak, before, say, installing them into an RBBB, or standalone circuit.

If such a setup were combined with a ZIF programmer system, that would be a nice tool for the bench.

 smiley
Logged

I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

0
Offline Offline
Newbie
*
Karma: 0
Posts: 28
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I believe that the task of testing even the simplest IC is a big one. Not saying about a micro controller.
What kind of "slugs" do you mean? If we put away the check of chip, than only the program is to be tested. It can be done with READ-COMPARE operation. That's all, IMHO.
But maybe you know something I cannot understand.

I try to find whether my approach is well known here. Or, maybe it has some drawbacks. Or it may be useful but is in need of some modification.
These are my questions.
Logged

North Yorkshire, UK
Offline Offline
Faraday Member
**
Karma: 104
Posts: 5531
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I believe that the task of testing even the simplest IC is a big one. Not saying about a micro controller.
Well maybe if someone can get an arduino to arduino programmer working then you could have a board that loads a sketch on to it then that sketch runs and it checks all the outputs etc with a second chip (the one that loaded the sketch on perhaps) and reports any issues found.

Mowcius
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 28
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
and it checks all the outputs etc with a second chip

...and a special robot takes freshly tested board ant puts it in an appropriate box  :smiley

I'm trying to be practical. If Arduino starts and communicates with PC, we can load the test program and check something. I think that check of all Arduino i/o pins is a good test, not the best, but surely good.
If anything happens by the way a logical one and/or logical zero are being propagated from ATmega pin to Arduino pin and vice versa - we can find a reason and fix the problem.
If signals travel properly we can be sure that
- PWM will work,
- that all communication ports will work,
- that timers' outputs will generate wayforms,
- that all external interrupt sources will be caught.
The ATmega itself is beyond the suspicions, as Ceasar's wife smiley

I'm puzzled a little, dear fellows. No criticism, not even the links to the subject being discussed a lot... Can it be that nobody has the need to check Arduinos? I'm new here and cannot grasp the situation.
Logged

North Yorkshire, UK
Offline Offline
Faraday Member
**
Karma: 104
Posts: 5531
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oh I see promise in the idea but I have not myself had any issues with an arduino board that have not been that:
a - the chip doesn't work at all
b - the code doesn't quite work (so the duff pin was figured out from that)
c - not sure if there's a c...

I just think that maybe not many people have had issues like that.

Mowcius
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 28
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I see. Well, thanks to both of you, cr0sh and mowcius!
Logged

Phoenix, Arizona USA
Offline Offline
Faraday Member
**
Karma: 36
Posts: 5519
Where's the beer?
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

drvlas:

What I meant by "slugs" is that, back when I purchased my ATMegas, it was at a time (still? dunno, haven't checked) when ATMegas were difficult to come by in nearly any form (especially DIP). Mouser and Digikey had long lead times for their shipments to come in...

However, you could find several vendors on Ebay selling them; most of them were in China. In fact, if you checked various "global supplier" electronics sites, you found that you could get nearly any quantity you wanted from China.

Sparkfun ordered a bunch of chips (not sure if there were ATMegas or not, can't remember, too lazy to check) from a supplier in China - like 10,000+ pieces. The usual is to wire tranfer (Western Union) the check for the amount ($$$) to the supplier, and they ship the product. They ended up getting the product, but after testing the chip (both on a bench, and later by someone they know who can do hard-core stripdown reverse engineering) - they found they were shipped "slugs".

As in - there wasn't an actual piece of silicon in the chip package, just a "slug" of metal, not connected to anything (and even if it were, it wouldn't matter). They got burned for 10's of thousands of dollars, with no way to recover the money. The seller was long gone (as if you could recover it anyhow via the court system over there).

So - I don't know if maybe I got slugs, too. I only ordered a few (like 5 pcs), mainly to have a supply for future standalone projects. But because of the hype and such of people looking for ATMegas, I am sure there had to be at least one individual selling mismarked or bad chips of some sort to people on Ebay - you could easily make a lot of money doing that and split afterward; one .100 DIP looks like another, especially if you get the screenprint done right.

Everything looked OK on these chips as compared to the real one on my Arduino, but I won't really know until I can test them. I have a .100 28-pin ZIF socket waiting for building a test/programming rig, once I can get around to it.

 smiley
Logged

I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

North Yorkshire, UK
Offline Offline
Faraday Member
**
Karma: 104
Posts: 5531
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Sparkfun ordered a bunch of chips (not sure if there were ATMegas or not, can't remember, too lazy to check) from a supplier in China - like 10,000+ pieces. The usual is to wire tranfer (Western Union) the check for the amount ($$$) to the supplier, and they ship the product. They ended up getting the product, but after testing the chip (both on a bench, and later by someone they know who can do hard-core stripdown reverse engineering) - they found they were shipped "slugs".
Nope, they were/are
Quote
voltage regulators specifically designed to power high-performance Intel processors
 ;D
Not an ATmega then  smiley-wink
http://www.sparkfun.com/commerce/news.php?id=395

Mowcius
Logged

Pages: [1]   Go Up
Jump to: