Board Diagnostics

A sketch to test newly assembled boards.  Runs through all the functionality one by one.

#include <Servo.h> 

/* Rotary encoder read example */
#define ENCODER_A 14
#define ENCODER_B 15
#define ENCODER_PORT PINC
#define SWITCH 13
#define BUTTON 12
#define RGB_RED 11
#define RGB_GREEN 10
#define RGB_BLUE 9
#define LED 6
#define SERVO 5
#define PIEZO 3
#define RELAY 2
#define POT 2
#define HALL 3
#define THERMISTOR 4
#define PHOTOCELL 5

/* 
CodeShield Diagnostic V0.2 Dave Carpenter 
Designed to test all inputs and outputs
Any components not working or disconnected will not stall the diagnostic.
Current step can be skipped by pressing the button or wait until the step 
is completed.

Set a serial monitor at 115200 baud to see diagnostics of the current step.
Switch controls whether piezo will beep and whether servo will move.
All outputs are affected by each test:
 LED1's brightness
 LED2's colour
 PIEZO's tone
 SERVO's angle
 RELAY's state

Tests adjust all of the outputs depending on the input:
1) Waveform: no input test of outputs
2) Thermistor: hold THERM component to change outputs by temperature
3) Hall effect: bring a magnet near HALL component to change outputs by field
4) Photocell: cover or illuminate PHOTO to change outputs by light
5) Potentiometer: turn POT handle to vary outputs continuously
6) Encoder: turn ENC handle to step outputs up and down in steps

BUTTON is used to skip to the next test before it is finished
SWITCH will turn off the piezo and servo so you can hear the relay changing state

**** TO FIX: encoder skips many steps
   Piezo is "phasing" instead of changing tone
   Servo being on also seems to mangle the colours on LED2, perhaps too much drain on the usb power?
*/

static boolean showValues = false; //set to true to see the input values
   // on the serial output

Servo myservo;  // create servo object to control a servo 
static uint8_t counter = 1;      //this variable will be changed by encoder input
int switchState = LOW;
int lastRotValue;
int testState = -1;
int testCount = -1;
static int testValue;
int rawValue;
String testInfo[] = {
 "Waveform: no input test of outputs", 
 "Thermistor: hold THERM component to change outputs by temperature",
 "Hall effect: bring a magnet near HALL component to change outputs by field",
 "Photocell: cover or illuminate PHOTO to change outputs by light",
 "Potentiometer: turn POT handle to vary outputs continuously",
 "Encoder: turn ENC handle to step outputs up and down in steps"
};

void setup()
{
 /* Setup encoder pins as inputs */
 pinMode(ENCODER_A, INPUT);
 digitalWrite(ENCODER_A, HIGH);
 pinMode(ENCODER_B, INPUT);
 digitalWrite(ENCODER_B, HIGH);
 pinMode(SWITCH, INPUT);
 pinMode(BUTTON, INPUT);
 pinMode(RGB_RED, OUTPUT);
 pinMode(RGB_BLUE, OUTPUT);
 pinMode(RGB_GREEN, OUTPUT);
 pinMode(LED, OUTPUT);
 pinMode(PIEZO, OUTPUT);
 pinMode(RELAY, OUTPUT);

 Serial.begin (115200);
 Serial.println("Begin diagnostic");
}

void loop() {

 testCount = (testCount + 1) % 256;
 if(!testCount) { 
     testState = (testState + 1) % 6;
     Serial.println("Test "+String(testState)+": " + testInfo[testState]);
    if(showValues) {
       delay(1500); //pause or you can't read it when values fly past
     }

     testValue = 0; //set a default, e.g. for encoder step
 }
 switch (testState) {
   case 0: // waveform (no input) test
     rawValue = testCount;
     testValue = rawValue;
     break;
   case 1: // thermistor test
     rawValue = analogRead(THERMISTOR);
     testValue = constrain(map(rawValue, 500, 600, 0, 255),0,255);
     break;
   case 2: // hall effect
     rawValue = analogRead(HALL);
     testValue = constrain(map(rawValue,400,600,0,255),0,255);
     break;
   case 3: // photocell 
     rawValue = analogRead(PHOTOCELL);
     testValue = constrain(map(rawValue,400,800,0,255),0,255);
     break;
   case 4: // pot
     rawValue = analogRead(POT);
     testValue = constrain(map(rawValue,150,600,0,255),0,255);
     break;
   case 5: // encoder
     //step up or down by steps of 16 based on encoder
     rawValue = read_encoder();
     testValue = testValue + rawValue*16; 
     break;
 }

 if(showValues) {
   Serial.println("Raw: " + String(rawValue) + 
     " Test: " + String(testValue) +
     " Button: " + String(digitalRead(BUTTON)==HIGH) +
     " Switch: " + String(digitalRead(SWITCH)==HIGH)
   );
 }

 //LED 1 brightness is testValue
 analogWrite(LED, (testValue)%256);

 //LED 2 testValue is transformed to a colour spectrum of red, yellow, green,
 // cyan, blue, magenta, red 
 analogWrite(RGB_RED, (testValue<85)*(85-testValue)*3 + (testValue>=170)*(testValue%85)*3 + (testValue==255)*255);
 analogWrite(RGB_GREEN, (testValue<85)*(testValue)*3 + (testValue>=85 && testValue<170)*(85-(testValue%85))*3);
 analogWrite(RGB_BLUE, (testValue>=170 && testValue<255)*(85-(testValue%85))*3 + (testValue>=85 && testValue<170)*(testValue%85)*3);

 //Relay state is testValue low or high; should be able to hear clicking
 digitalWrite(RELAY, (testValue<128));

 //Piezo is 
 analogWrite(PIEZO, testValue*digitalRead(SWITCH)); // don't make a tone if switch is off

 //Servo angle mapped to testValue if switch is on
 if (digitalRead(SWITCH) == HIGH) {
   myservo.attach(SERVO);
   myservo.write(map(testValue, 0, 255, 0, 179));    
 } else {
   myservo.detach();
 } 

 while(digitalRead(BUTTON)==HIGH) {
   testCount=255; //start next test
 } //put this in a while so we don't skip five tests for one "press"

 delay(50);
}

/* returns change in encoder state (-1,0,1) */
int8_t read_encoder()
{
 static int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
 static uint8_t old_AB = 0;
 /**/
 old_AB <<= 2;                   //remember previous state
 old_AB |= ( ENCODER_PORT & 0x03 );  //add current state
 return ( enc_states[( old_AB & 0x0f )]);
}
									

2 comments. Leave a Reply

  1. Geff Waite

    Dave:
    I purchased a codeshield at the recent Central Ontario Radio Amateur Ham Fest. It went together well with the only problem in the last few steps when the long pins on the headers could not be pushed all the way down on my Uno so the codeshield sits half an inch up from the Arduino. Oh well!

    My main question to you is that when I ran the Board Doagnostics, things happen but seemingly in a completely random fashon. Now I know that I should go thru your script, line by line, and find out what each command does and I will, I promise!! But for now can you tell me with a simple list what is suppose to happen and for how long, just so that I know if the codeshield was assembled correctly.

    Any suggestions would be appreciated.

    Geff

    • Verdi Rodrigues Diamond

      Hi Geff!

      I’m glad you came out and saw us. We came last year and were delighted with the turnout.

      The pin headers are designed to make the shield stick up a little bit so that the button does not short out against the large USB connector beneath it. We had to do this to fit as many components on the board as we did. We’ve heard that some people have also tried putting a piece of electrical tape on the top of the USB connector to make our board sit closer to the Arduino.

      I’m glad you’re interested in taking apart the code piece by piece. While we don’t have a list of all of the commands the Arduino supports, I highly suggest you check out their learning and reference pages respectively. They’ll explain everything to you step by step going into as much detail as you need.

      Keep having fun!
      Verdi

Leave a Reply

Your email is never published nor shared.

You may use these HTML tags and attributes:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>