I am using Arduino for an IoT class (40 students). I have set up a test program to check all sensors and actuators used in the class (we need to recycle for next semester). However, I would also like to check the Arduino's themselves (and also NodeMCU´s) in case some of the units have been broken. I have an idea of testing input/output of each pin to make sure its working - using LEDs and buttons, but if anyone has some ideas to improve testing, it would be great to hear from you.

  • Thank you all for your valuable input. Unfortunately, I have to do the testing myself since students are working from home (Covid-19). So each student receives a package with all components and does the labs under online supervision. That is why testing is important. I had the same class last summer with good results, but with brand new components. May 13 at 19:55

Testing microcomputers is a very complicated task. In your case I would suggest writing some programs to do exactly what you are saying. Then let the students do the testing. When the class starts you have to teach them the basics, this will check the computers etc and also the test equipment on there benches. At the end of testing they will have knowledge of the basics they will need to continue with the class. You can also have the students do this at the end of the semester to get a head start on any problems.


A complete test would obviously be something fairly complex, and would probably require building some sort of rig. You can, however, perform a minimal test that checks for common failure modes, without connecting any extra hardware.

I assume the pin I/O stages are the easiest thing to break. You can then check that, when you read a pin that is set to OUTPUT, you get the value that the pin is supposed to be outputting. You can leverage the stray capacitances of floating pins to test them as inputs: the capacitance should make the pin “remember” its previous output value for some time, and that time should be really short if the internal pull-up is enabled.

The following program tests pins 2–13 and A0–A5 of an Uno. It checks that:

  1. a pin set to OUPUT LOW reads LOW
  2. a pin set to OUPUT HIGH reads HIGH
  3. a pin switched from OUPUT HIGH to INPUT reads HIGH
  4. a pin switched from OUPUT LOW to INPUT reads LOW
  5. a pin switched from OUPUT LOW to INPUT_PULLUP reads LOW, then switches to HIGH less than a microsecond later

Pins 0 and 1 are not tested, as they are connected to the serial port. On the other hand, if you can upload a sketch, you know those pins work at least as RX/TX.

Note that the program uses direct port access, as the Arduino functions for accessing the pins are too slow for this kind of tests. If all works, the program prints “All tests passed.”. Otherwise specific error messages are printed, followed by “Some tests failed.”

#include <avr/cpufunc.h>
#include <util/delay.h>

int failures = 0;

static void log_failure(char port_name, const char * reason)
    Serial.print("FAIL: Port ");
    Serial.print(", read ");

static inline __attribute__((always_inline))
void test_port(const char port_name, uint8_t mask,
    volatile uint8_t *pin, volatile uint8_t *ddr, volatile uint8_t *port)
    *port = 0;
    *ddr = mask;   // OUTPUT LOW
    if ((*pin & mask) != 0)
        log_failure(port_name, "OUTPUT LOW");
    *port = mask;  // OUTPUT HIGH
    if ((*pin & mask) != mask)
        log_failure(port_name, "OUTPUT HIGH");
    *ddr = 0;      // INPUT_PULLUP
    *port = 0;     // INPUT -> HIGH
    if ((*pin & mask) != mask)
        log_failure(port_name, "INPUT HIGH");
    *ddr = mask;   // OUTPUT LOW
    *ddr = 0;      // INPUT -> LOW
    if ((*pin & mask) != 0)
        log_failure(port_name, "INPUT LOW");
    *port = mask;  // INPUT_PULLUP
    uint8_t r1 = *pin;
    uint8_t r2 = *pin;
    if ((r1 & mask) != 0 || (r2 & mask) != mask)
        log_failure(port_name, "INPUT_PULLUP");

void setup()
    TIMSK0 &= ~_BV(TOIE0);  // disable timer interrupt

    test_port('B', 0x3f, &PINB, &DDRB, &PORTB);  // PB0..PB5
    test_port('C', 0x3f, &PINC, &DDRC, &PORTC);  // PC0..PC5
    test_port('D', 0xfc, &PIND, &DDRD, &PORTD);  // PD2..PD7

    if (failures == 0)
        Serial.println("All tests passed.");
        Serial.println("Some tests failed.");

void loop(){}

As an extension, analog inputs could be tested in a manner similar to test 5: if the analog sampling is done at the right time, you can get a reading that is somewhere mid-range.


I'd add a second Arduino to supply a HIGH and LOW signal to the Arduino being tested (to test the INPUT), and to verify that the tested Arduino can output HIGH and LOW. Testing inputs, outputs, and being able to upload you test sketch will catch the most common problems.

Testing the regulator would be my next thing, but that also depends on whether you're previous course was using the regulator.


When I make a new (Uno-like) board, I test for shorts and opens with sketch that blinks each pin in sequence. @Gerben's suggestion to test the inputs as well makes a lot of sense for your application. Plus the basic ability to power up (working barrel-connector input & voltage regulator, working USB connector and USB communication) would another test I'd make. I'd probably boards that have a socketed chip for my future purchases (if you're not already).


There are a number of open issues which need to be addressed in order to narrow the scope of this project to a manageable and reasonable effort. For instance:

  1. Which Arduino (board and processor) are you using? Does the board power off a regulated USB 5 volt source? Or does it use a regulator which needs testing?
  2. How many GPIO pins are there? Will they be used to drive, sense or both?
  3. Are there any Analog pins? Do they need to be tested over a range or just a select voltage?
  4. Are there any PWM outputs which need to be tested?

To simplify testing we might make some assumptions. For example:

  1. If the GPIO aspect of a pin works any PWM feature for that pin may be assumed functional.
  2. If a given voltage at a Analog Input pin results in a reasonable analog to digital conversion then all other reasonable voltages will result in the expected analog to digital conversion.

For testing many UUTs (Units Under Test), it is almost always better to build a fixture. This might be simple cables connected to another (carefully controlled) Arduino all the way to a bed-of-nails In Circuit Tester (ICT).

The "Make a Pogo Pin Test Jig" project at Adafruit addresses many of these concerns at a level that may be suitable to implement at the college level.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.