Introduction: Seed Motor Shield V2 Coding Tutorial

About: I work in industrial automation and spend any free time making.

In this Intructable we'll talk about a common problem in programming, the Top Down method of programming and learn how to control the Seeed Motor Shield V2.0 for the Arduino Uno. So lets jump right to it.

In manufacturing and in my side projects I encounter a common problem in all types of coding. Be it ladder logic, C++, or a Cognex Vision spreadsheet persons writing source code forget what source code is...
In programming with its jargon and syntax and languages it is easy to get caught up in "The Matrix" and start believing that you are writing code for machines to read.
Well its time to come out of the rabbit hole. Machines only understand binary; 1's and 0's. Unless you are Morpheus you are not writing code for machines you are writing code for people and for people to read. And just like a good essay, good code should never loose sight of its audience and should be easy to understand and pass on to others.
In this context just because your code works does not mean it is good code. (As a side note some code is intentionally vague but this another story.) This fact is one reason all programmers when picking up someone else's work will undoubtedly at some point say, "This is a mess i'll just have to re-write it." On the same line I've never heard anyone say ,"This code has too many comments and instructions."

Think of all the wasted man hours reinventing the wheel. Why? Because writing really good code means documenting and commenting and this means more key strokes on the front end, this takes more time so it doesn't get done.


For example Below I am going to present 2 simple Arduino code that controls a small robot. Both of the codes presented use the same hardware and perform the same action.

The hardware used will be:
- 2 DC motors in a small RC car body
- Arduino UNO
- Seeed Motor Shield and hook up wire

Both of these codes perform the same action. Which one would you rather get dropped in your lap?

Step 1: Seeed Motor Shield: Code 1

The first example code is below:

int lm1 = 8 ;

int lm2 = 11;

int lms = 9;

int rm1 = 12;

int rm2 = 13;

int rms = 10;

void setup()

{

pinMode(lm1,OUTPUT);

pinMode(lm2,OUTPUT);

pinMode(lms,OUTPUT);

pinMode(rm1,OUTPUT);

pinMode(rm2,OUTPUT);

pinMode(rms,OUTPUT);

}

void loop()

{

analogWrite(lms,255);

analogWrite(rms,255);

digitalWrite(lm2,LOW);

digitalWrite(rm2,LOW);

digitalWrite(lm1,HIGH);

digitalWrite(rm1,HIGH);

delay(5000);

digitalWrite(lms,LOW);

digitalWrite(rms,LOW);

delay(2000);

analogWrite(lms,200);

analogWrite(rms,200);

digitalWrite(lm1,LOW);

digitalWrite(rm1,LOW);

digitalWrite(lm2,HIGH);

digitalWrite(rm2,HIGH);

delay(5000);

}

If you stare at it for a while like one of those 3-d posters what is there does come out. But imagine you were given this and only this, no other documentation and had to make changes to it?

For now We'll just go to the next version of this code.

Step 2: Seeed Motor Shield Code 2

This is the second code example for controlling the Seeed Motor shield V2.0 with an Arduino Uno :
___________

//Code for Controling a Tumbler RC car

// with Arduino Uno and Seeed Motor Shield V2.0

// Chris 8/12/14

/*----Ardunio to Shield Pinout Controls-----

Are using a Seeed motor shield to drive 2 DC motors

Seeed motor shield uses Arduino pins 8->13

Pin 9 sets the enable and speed of shield outputs 1 & 2

Pin 10 sets the enable and speed of shield outputs 3 & 4

Pin 8 from Uno controls the state of shield output 1

Pin 11 from Uno controls the state of shield output 2

Pin 12 from Uno controls the state of shield output 3

Pin 13 from Uno controls the state of shiled output 4

*/

//--- Declared variables

int leftmotorForward = 8; // pin 8 --- left motor (+) green wire

int leftmotorBackward = 11; // pin 11 --- left motor (-) black wire

int leftmotorspeed = 9; // pin 9 --- left motor speed signal

int rightmotorForward = 12; // pin 12 --- right motor (+) green wire

int rightmotorBackward = 13; // pin 13 --- right motor (-) black

int rightmotorspeed = 10; // pin 10 --- right motor speed signal

//--- Speeds and Timers

int Think = 2000; //Long delay time between steps

int Runtime = 5000; // How long Runtime actions will last

int Slow = 230; // slow speed (of 255 max)

int Fast = 255; // fast speed (of 255 max)

//------------------------------------------------------

void setup() //---6 Pins being used are outputs---
{

pinMode(leftmotorForward, OUTPUT);

pinMode(leftmotorBackward, OUTPUT);

pinMode(leftmotorspeed, OUTPUT);

pinMode(rightmotorForward, OUTPUT);

pinMode(rightmotorBackward, OUTPUT);

pinMode(rightmotorspeed, OUTPUT);

}

// ---Main Program Loop -----------------------------

void loop()

{

goForward();

delay(Runtime);

Stop();

delay(Think);

goBackward();

delay(Runtime);

}

//----- "Sub-rutine" Voids called by the main loop

void goForward()

{

analogWrite(leftmotorspeed,Fast); //Enable left motor by setting speed

analogWrite(rightmotorspeed,Fast); //Enable left motor by setting speed

digitalWrite(leftmotorBackward,LOW); // Drives LOW outputs down first to avoid damage

digitalWrite(rightmotorBackward,LOW);

digitalWrite(leftmotorForward,HIGH);

digitalWrite(rightmotorForward,HIGH);

}

void goBackward()

{

analogWrite(leftmotorspeed,Slow);

analogWrite(rightmotorspeed,Slow);

digitalWrite(leftmotorForward,LOW);

digitalWrite(rightmotorForward,LOW);

digitalWrite(leftmotorBackward,HIGH);

digitalWrite(rightmotorBackward,HIGH);

}

void Stop() // Sets speed pins to LOW disabling both motors

{

digitalWrite(leftmotorspeed,LOW);

digitalWrite(rightmotorspeed,LOW);

}


Step 3: When in Doubt Make a Note

Writing this Code 2 requires more keystrokes up front but the documentation is clear and even someone that is not familiar with programming could probably guess what is going on.

An added plus is having notes in the code. I often get pulled from projects for weeks at a time when I finally get back to it, it has all been translated into greek/ i've forgotten where I was and have to re-learn / never assume you will always remember your mind set when you write a program.

Modifying this 2nd code is easier too. Say you want to go forward and backward for 10 seconds you only have to change the int Runtime to 10000. The first code would require changing every delay() time line by line. In a large program this means mistakes will happen.

The last part of this Instructable I want to explore Top Down programming.....

Step 4: Top Down Method of Coding

An obstacle I still struggle with in learning to program is the over all approach of tutorials and how programming is normally presented.
I am by nature a mechanical / hardware guy and learning to code is just a necessity of my need to control the hardware etc. Therefore I tend to be Big Picture driven. I don't like to add things to code if I don't understand how it fits into my big picture. Entry level coding seems to always be presented in a bottom up approach that is completely backward from the way I think.
Lucky I recently was introduced to programming from the top down. This is the method in which Code 2 I presented above was developed.
For the Big Picture folks like me I'll show step by step how the 2nd Seeed Motor Shield Code from above was developed in the Top down Programming methodology.

In top down we are not going to be as concerned about details of the code at the on-set just write what you want the robot to do then go back and fill in the blanks. To start the robot needs to be able to go forward.. So start a Void loop and throw in a function like your commanding the robot.

Void loop()

{

goForward();

}

At this point this sketch will not do anything but generate some faults.

So now we start thinking about what actions we need to make this motion above happen.

1) We have to get power (+) to one side of both of the motors and (-) to the other side of both the motors.

2) To do this we need know what pins on the UNO control the Seeed Motor Shield

3)How to translate this into code

Start thinking about your hardware and go to the next step...

Step 5: Top Down Cont...

Looking on the Seeed website I found the information that was noted in the sketch of the 2nd Code presented earlier. And I determinded what motor leads on the robot chassis if given the (+) voltage yielded the 2 directions.

Determine what you want to call each motor / leftmotor / rightmotor /motor1 / motor 2. And the control signals going to the leads of the motors.

"Codey" short hand is nice but I'm never consistent at what my ' codenames' are and end up with a hot mess. So I've adopted just naming things what I would naturally call then. (That is what source code is for right?) Then even though it is more key strokes the name tags are more intuitive the writing becomes more fluid and less mistakes are likely.

I chose to use leftmotor / rightmotor. The motor signals are names referencing the wire lead getting the (+) signal and what direction this will send the robot.

So what the Arduino needs to know at the beginning of the Sketch is what actions are linked to what pins. So at the top of the sketch after the notes we define stuff.

int leftmotorForward = 8;

int leftmotorBackward = 11;

int leftmotorSpeed = 9;

int rightmotorForward = 12;

int rightmotorBackward = 13;

int rightmotorspeed = 10;

Now the Arduino needs us to set the pin modes for the Pins above that we said we wanted to use....

All of the pins being used here will be outputs so...

void setup()
{

pinMode(leftmotorForward, OUTPUT);

pinMode(leftmotorBackward, OUTPUT);

pinMode(leftmotorspeed, OUTPUT);

pinMode(rightmotorForward, OUTPUT);

pinMode(rightmotorBackward, OUTPUT);

pinMode(rightmotorspeed, OUTPUT);

}

Step 6: Finishing the Sketch....

At this point our sketch looks like this...

int leftmotorForward = 8;

int leftmotorBackward = 11;

int leftmotorSpeed = 9;

int rightmotorForward = 12;

int rightmotorBackward = 13;

int rightmotorspeed = 10;

void setup()

{

pinMode(leftmotorForward, OUTPUT);

pinMode(leftmotorBackward, OUTPUT);

pinMode(leftmotorspeed, OUTPUT);

pinMode(rightmotorForward, OUTPUT);

pinMode(rightmotorBackward, OUTPUT);

pinMode(rightmotorspeed, OUTPUT);

}

void loop()
{

goForward();

}

We are almost finished. The only thing at this point we are missing is that we have not defined what the goForward() is suppose to do. If you tried to run the sketch at his point the verify step would probably say something to that effect.

So to go forward we have to put power (+) (drive this pin HIGH) to the left & right motor leads that will take the robot forward and sink (-) (or drive LOW if you like that term better.) the other 2 motor leads. We already worked out what the hardware connections had to be before naming the declared pins so to go forward the ___Forward pins must go HIGH the ___Backward pins need to go LOW.

The Seeed Motor Shield also needs to know what speed we want to go in a value of 0 (off) to 255 (max).

So create the goForward() loop;

void goForward()
{

analogWrite(leftmotorspeed,255);

analogWrite(rightmotorspeed,255);

digitalWrite(leftmotorBackward,LOW);

digitalWrite(rightmotorBackward,LOW);

digitalWrite(leftmotorForward,HIGH);

digitalWrite(rightmotorForward,HIGH);

}

At this point you should be able to run this sketch. But note that in the goForward() defined above the speed is 255 not Fast like the original Code 2 presented.

The timers and speeds in the Code 2 are optional but defining any conditions in the start that you may want to tune or adjust allow you to change them in the declarations without having to hunt everywhere in the code.

Step 7: Continue the Sketch...

Continue building on the sketch by adding functions for every motion you want.

Step 8: Closing Notes

I hope this helps anyone needing to control a Seeed V2 motor shield. Any improvement ideas are welcome as I mentioned earlier I am only a programmer by necessity.
For general coding methodology learning MIT has some great lecture videos available on YouTube and ITunes U. Just search for Intro to Programming Methodology.