A sketch to test newly assembled boards. Open the Serial Monitor at 115200 baud to get a walkthrough as you test.
#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
Servo myservo; // create servo object to control a servo
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("");
Serial.println("");
Serial.println("Begin diagnostic");
}
void loop() {
testDigitalIn("Switch", SWITCH);
testDigitalIn("Button", BUTTON);
testDigitalOut("LED", LED);
testDigitalOut("Red", RGB_RED);
testDigitalOut("Green", RGB_GREEN);
testDigitalOut("Blue", RGB_BLUE);
testAnalogOut("Piezo", PIEZO);
testDigitalOut("Relay", RELAY);
testServo();
testAnalogIn("Light Sensor", PHOTOCELL);
testAnalogIn("Hall Sensor", HALL);
testAnalogIn("Thermistor", THERMISTOR);
testAnalogIn("Potentiometer", POT);
testRotary();
}
void testDigitalOut(String name, int pin) {
Serial.println("Testing: " + name);
digitalWrite(pin, HIGH);
delay(800);
digitalWrite(pin, LOW);
delay(200);
}
void testAnalogOut(String name, int pin) {
Serial.println("Testing: " + name);
analogWrite(pin, 128);
delay(800);
digitalWrite(pin, LOW);
delay(200);
}
void testServo() {
myservo.attach(SERVO);
delay(100);
Serial.println("Testing: Servo");
myservo.write(45);
delay(700);
myservo.write(135);
delay(700);
myservo.detach();
}
void testDigitalIn(String name, int pin) {
int startValue = digitalRead(pin);
int newValue = startValue;
Serial.println("Testing: " + name + ". Change value to continue...");
while (startValue == newValue) {
newValue = digitalRead(pin);
delay(40);
}
analogWrite(PIEZO, 128);
delay(100);
digitalWrite(PIEZO, LOW);
delay(200);
}
void testAnalogIn(String name, int pin) {
int startValue = analogRead(pin);
int delta = 0;
Serial.println("Testing: " + name + ". Change value to continue...");
while (delta < 20) {
delta = abs(startValue - analogRead(pin));
delay(40);
}
analogWrite(PIEZO, 128);
delay(100);
digitalWrite(PIEZO, LOW);
}
void testRotary() {
Serial.println("Testing: Rotary Encoder. Change value to continue...");
int8_t startData = 0;
while (abs(startData) < 12) {
startData += read_encoder();
}
analogWrite(PIEZO, 128);
delay(100);
digitalWrite(PIEZO, LOW);
}
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 )]);
}
Alternative Diagnostics. 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