Introduction: Demo and Code Walkthrough for an Arduino/Easy Driver Animation Control Board

About: Unfortunately the owner of this site has passed away however it has not been closed to allow other users to hopefully benefit from some of the projects.

The Animation Control Board (PCB) is a spin off from my project to create an N-Scale Drawbridge that is functional and driven by an Arduino paired with an Easy Driver. The PCB is introduced in another Instructable on that topic located here.

The PCB that I created for the drawbridge is, as I stated in the previous Instructable, designed to be generic and applicable to other projects. The earlier instructable describes the hardware side of the PCB. This one covers the software but with a generic hardware example that will be described by the next step.

The PCB is for sale on eBay here. The PCB measures 100x70mm and can be mounted on the shown 3D Print which is available here.

Step 1: Demo and Code Walkthrough Hardware

The hardware for the Demo and Code Walkthrough is based on the following (from top left and moving clockwise around the photo):

  • LED attached to the LED1-D5 connector (connected to Nano pin D5 with a resistor on the ground lead and initialized as OUTPUT).
  • Push Button attached to the D6 connector (connected to Nano pin D6 initialized as INPUT-PULLUP).
  • Stepper Motor (5V) attached to the Stepper Motor header (connected to Easy Driver pins 1A, 1B, 2A, and 2B).
  • Current Sensor (ACS712) attached to the A2-D16 connector (connected to Nano pin A2).
  • Relay attached to the A1-D15 connector (connected to Nano pin A1 initialized as a digital pin 15 for OUTPUT).
  • Servo attached to the A0-D14 connector.

Step 2: Functionality Presented by the Demo

The functionality presented by the demo covers a variety of what can be done with the Animation Control Board and the Arduino Nano and Easy Driver mounted on the PCB:

  • Connecting to an LED
  • Using a push button
  • Driving a stepper motor
  • Controlling a relay
  • Driving a servo.
  • Getting input from an analog device.

Step 3: Output From the Demo Sketch

Below is the output from the demo sketch. When the sketch is run it will expect the push button to be pressed to invoke each of four tests. When the push button is pressed the LED will be illuminated with a string of fast flashes followed by slow flashes that will tell you what test is being run followed by another string of fast flashes. This accomplishes the goals of demonstrating the push button and the LED!

Started - Each button press starts a new test!
**********************************************
Button pressed 1
**********************************************
**********************************************
Stepper Motor Test
**********************************************
Test complete
**********************************************
Button pressed 2
**********************************************
**********************************************
Current Reading Test
**********************************************
**Activating Motor
Baseline: 47
Loaded: 9
Load: 38
**Deactivating Motor
Test complete
**********************************************
Button pressed 3
**********************************************
**********************************************
Servo Test
**********************************************
Test complete
**********************************************
Button pressed 4
**********************************************
**********************************************
Relay Test 
**********************************************
Test complete

Step 4: Setting Up the Nano Pins

The entire sketch is here with this step but the remainder of the instructable will present it in pieces with a dialog as to purpose. First starting with all the pin assignments as shown below (note that naming follows what is printed on the PCB):

/* ************************************************************************
 Pin Definitions
************************************************************************ */
const int     LED_D2 =    2;        // 5v LED on Pin D2
const int     LED_D3 =    3;        // 5v LED on Pin D3
const int     LED_D4 =    4;        // 5v LED on Pin D4
const int     LED_D5 =    5;        // 5v LED on Pin D5
const int     PIN_D6 =    6;        // Pin D6
const int     PIN_D7 =    7;        // Pin D7
const int     PIN_D8 =    8;        // Pin D8
const int     SLEEP =     9;        // Sleep pin on Easy Driver
const int     DIR =       10;       // Direction pin on Easy Driver
const int     STEP =      11;       // Step pin on Easy Driver
const int     MS1 =       12;       // Config pin 1 on Easy Driver 
const int     MS2 =       13;       // Config pin 2 on Easy Driver
const int     PIN_A0 =    0;        // Pin A0
const int     PIN_D14 =   14;       // Pin A0 as D14
const int     PIN_A1 =    1;        // Pin A1
const int     PIN_D15 =   15;       // Pin A1 as D15
const int     PIN_A2 =    2;        // Pin A2
const int     PIN_D16 =   16;       // Pin A2 as D16</p>

Attachments

Step 5: Code for Push Button

Setup for the push button entails declaring its pin as INPUT_PULLUP which is needed unless you have connected your own pull up resistor:

    //
    // Setup for the Push Button
    //
    pinMode(PIN_D6, INPUT_PULLUP);

A push of the button results in the pin being drawn down into a LOW state which is then detected here. The sketch uses the flashLED function (described next) to signal what test is being run. The appropriate test, depending on whether this was the first, second, third, or fourth press, is then run via the switch construct.

void loop() {
   if (digitalRead (PIN_D6) == LOW) {
        test++;
        flashLED(LED_D5, 5, 50, 50);
        flashLED(LED_D5, test + 1, 350, 350);
        flashLED(LED_D5, 5, 50, 50);
        
        Serial.println("**********************************************");
        Serial.print("Button pressed ");
        Serial.println(test);
        Serial.println("**********************************************");
        testComplete = false;
    }
    if (testComplete == false) {
        testComplete = true;
        switch (test) {
            case 1:
                stepperMotorTest();
                Serial.println("Test complete");
                break;
            case 2:
                relayTest();
                Serial.println("Test complete");
                break;
            case 3:
                currentReadingTest();
                Serial.println("Test complete");
                break;
            case 4:
                servoTest();
                Serial.println("Test complete");
                test = 0;
                break;
        }
    }
}

Step 6: Code for LED

Setup for the LED is just to declare its pin as output.

    //
    // Setup for the LED
    //
    pinMode(LED_D5, OUTPUT);</p>

There are a lot of things that you can signal with an LED so I like to have a single routine that can do a number of different flashes. This one is called with the pin on which the LED is connected, the number of flashes, the duration of the on part of the flash and the duration of the off part of the flash. The previous page shows three calls to this routine.

void flashLED(int pin, int iterations, int onDuration, int offDuration) {
    while (iterations-- > 1) {
        digitalWrite(LED_D5, HIGH);
        delay(onDuration);
        digitalWrite(LED_D5, LOW);
        delay(offDuration);
    }
    delay(250);
}

Step 7: Code for Stepper Motor

The stepper motor is manipulated by talking to the Easy Driver using five outputs. MS1 and MS2 are used to configure the micro steps. If both are LOW then there will be no micro stepping and if both are high then a full eight micro steps will be done for each full step. STEP and DIR are the standard movement calls for a stepper driver. If SLEEP is low the stepper driver will idle the motor (otherwise it would be powered at all times). Note that jumpers need to be on J1 and J2 for MS1 and MS2 to be connected to the Nano.

    //
    // Setup for the Stepper Motor
    //
    pinMode(MS1, OUTPUT);
    pinMode(MS2, OUTPUT);
    pinMode(STEP, OUTPUT);
    pinMode(DIR, OUTPUT);
    pinMode(SLEEP, OUTPUT);</p>

There are libraries that can be used to control the stepper but the below code works for my purposes. The first thing that I do is a wakeup. I then set direction and tell the driver that I do not want micro steps. I then move 200 steps, which is half a rotation on my test servo by writing a HIGH then LOW wave form of 650 micro seconds.

I then switch directions, tell the driver that I want a full eight micro steps, and do 1600 micro steps but with the wave form being much shorter at 80 microseconds. The motor will have returned to its starting position at which point I tell things to go back to sleep.

void stepperMotorTest() {
    digitalWrite(SLEEP, HIGH);
    Serial.println("**********************************************");
    Serial.println("Stepper Motor Test");
    Serial.println("**********************************************");

    // First a full rotation of full steps
    digitalWrite(DIR, HIGH);
    digitalWrite(MS1, LOW);     // Both LOW for no micro steps
    digitalWrite(MS2, LOW);     // Both HIGH for 8 micro steps
    int steps1 = 200;</p><p>    while (steps1-- > 0) {
        digitalWrite(STEP, HIGH); 
        delayMicroseconds(650);
        digitalWrite(STEP, LOW);
        delayMicroseconds(650);
    }
    delay(2000);
    // Next an eighth rotation in the other direction of micro steps
    digitalWrite(DIR, LOW);
    digitalWrite(MS1, HIGH);     // Both LOW for no micro steps
    digitalWrite(MS2, HIGH);     // Both HIGH for 8 micro steps
    int steps2 = 1600;</p><p>    while (steps2-- > 0) {
        digitalWrite(STEP, HIGH); 
        delayMicroseconds(80); 
        digitalWrite(STEP, LOW);
        delayMicroseconds(80);
    }
    digitalWrite(SLEEP, LOW);
}

Step 8: Code for the Relay Test

Setup for the relay test is simply to declare the pin on which the relay sits to be OUTPUT. What is interesting about this code snippet is the amount of difficulty that you will have finding a pin on the Nano that is labeled D15. What many folks do not know is that analog pins A0 to A7 can be declared as digital pins D14 to D21.

Setting the pin the relay is on LOW will trigger the relay and returning it to high will release it back to the default state. In the case of the test only one side of the relay circuit is used and that side starts an electric motor that runs for five seconds. The relay has two sides so you could have a default action and the triggered action. On the bridge this is used for the two LEDs in a signal.

void relayTest() {
    Serial.println("**********************************************");
    Serial.println("Relay Test ");
    Serial.println("**********************************************");
    digitalWrite(PIN_D15, LOW);
    delay(5000);
    digitalWrite(PIN_D15, HIGH);
}

Step 9: Code for Current Test

Just to review the physical connections for this test... I am using a little DC motor to create a current draw. It is connected through the relay

There is no setup for the current test as an analog input needs no introduction. I have never actually used one of these devices so am not sure that I am interpreting the results correctly, that I have it connected correctly, or how to convert the reading into an amperage! What I am sure about is that the example of reading an analog value is valid based on the change in readings when the motor fires up!

void currentReadingTest() {
    Serial.println("**********************************************");
    Serial.println("Current Reading Test");
    Serial.println("**********************************************");
    int iteration = 5000;
    long baseline = 0;
    while (iteration-- > 0) {
        baseline = baseline + analogRead(PIN_A2);
    }
    baseline = baseline / 5000;
    Serial.println("**Activating Motor");
    digitalWrite(PIN_D15, LOW);
    iteration = 5000;
    long loaded = 0;
    while (iteration-- > 0) {
        loaded = loaded + analogRead(PIN_A2);
    }
    loaded = loaded / 5000;
    Serial.print("Baseline: ");
    Serial.println(baseline);
    Serial.print("Loaded: ");
    Serial.println(loaded);
    Serial.print("Load: ");
    Serial.println(baseline - loaded);
    Serial.println("**Deactivating Motor");
    digitalWrite(PIN_D15, HIGH);
}

Step 10: Code for the Servo Test

Setup for the servo consists of including the right library and then instantiating a copy of that library for our servo.
// Needed for the Servo Test
#include Servo
Servo servo1;<br>
Telling the servo to move is easy...just do a write from the servo library for the position that you want for the servo.
void servoTest() {
    Serial.println("**********************************************");
    Serial.println("Servo Test");
    Serial.println("**********************************************");
    servo1.attach(14);
    servo1.write(50);
    delay(1000);
    servo1.write(100);
    delay(1000);
    servo1.detach();
}