Need Help how to control 4 dc motors with 2 potentiometers atAdafruitMotorShield

Hi friends,

I am a mechatronic engineering 3rd class student at my university. I have decided to use arduino new for my tank project ;but I am a newbie. I am having trouble " to control 4 dc motors with 2 potentiometers ( 1 potentiometer will be for forward and backward feature; other potentiometer will be for turn right and left feature that I wanted to code that way ) at Adafruit Motor Shield " while coding or I didn't able to figure out what is the problem;because even the compiler doesn't give errors, the thing I want doesn't happen. Thus, I wanted to get the advices and helps from you friends. I am really stuck and it is really frustrating ;and there is noone at my university to ask too. Please help me friends, thanks.

The shield that I am using :



The code I have written at <AFMotor.h> ( V1 Adafruit motor shield library ) ( Firstly, I was trying here to control 1 dc motor with 1 potentiometer at adafruit motor shield for forward and backward feature. My 1 dc motor with 1 potentiometer try didn't work ;so I didn't add the " turn right and left feature " at this code example ;because I was stucked at the first place ) :

#include <AFMotor.h>

int potentiometerPin = 7; // analog pin used to connect the potentiometer
int potentiometerValue; // variable to read the value from the analog pin

AF_DCMotor left1stMotor(1); // 1. motor ( Left back motor )

// AF_DCMotor left2ndMotor(2); // 2. motor ( Left front motor )
// AF_DCMotor left3rdMotor(3); // 3. motor ( Right back motor )
// AF_DCMotor left4thMotor(4); // 4. motor ( Right front motor )

int i;

void setup()
{
Serial.begin(9600); // set up Serial library at 9600 bps

left1stMotor.setSpeed(200);
left1stMotor.run(RELEASE);

// left2ndMotor.setSpeed(200);
// left2ndMotor.run(RELEASE);

// left3rdMotor.setSpeed(200);
// left3rdMotor.run(RELEASE);

// left4thMotor.setSpeed(200);
// left4thMotor.run(RELEASE);

}

void loop()
{
potentiometerValue = analogRead(potentiometerPin); // reads the value of the potentiometer (value between 0 and 1023)
potentiometerValue = map(potentiometerValue, 0, 1023, 0, 255); // scale it to use it with the dc motor (value between 0 and 255)
potentiometerValue = potentiometerValue/4; // convert 0-1023 range to 0-255 range

Serial.print("tick");
left1stMotor.run(FORWARD);
//left2ndMotor.run(FORWARD);
//left3rdMotor.run(FORWARD);
//left4thMotor.run(FORWARD);

for (i=0; i<255; i++) {
if(potentiometerValue <= 127){
left1stMotor.setSpeed(i); // left1stMotor.setSpeed(254-(potentiometerValue*2))
delay(10);

// left2ndMotor.setSpeed(i);
// delay(10);
// left3rdMotor.setSpeed(i);
// delay(10);
// left4thMotor.setSpeed(i);
// delay(10);
}
}
Serial.print("tock");
left1stMotor.run(BACKWARD);
// left2ndMotor.run(BACKWARD);
// left3rdMotor.run(BACKWARD);
// left4thMotor.run(BACKWARD);

for (i=0; i<255; i++) {
if(potentiometerValue >= 127){
left1stMotor.setSpeed(i);
delay(10);

// left2ndMotor.setSpeed(i);
// delay(10);
// left3rdMotor.setSpeed(i);
// delay(10);
// left4thMotor.setSpeed(i);
// delay(10);
}

}

Serial.print("tech");
left1stMotor.run(RELEASE);
delay(1000);

// left2ndMotor.run(RELEASE);
// delay(1000);
// left3rdMotor.run(RELEASE);
// delay(1000);
// left4thMotor.run(RELEASE);
// delay(1000);
}

The code I have written at #include <Wire.h> ,#include <Adafruit_MotorShield.h> , #include "utility/Adafruit_PWMServoDriver.h" ( V2 Adafruit motor shield library )
( Firstly, I was trying here to control 1 dc motor with 1 potentiometer at adafruit motor shield for forward and backward feature. My 1 dc motor with 1 potentiometer try didn't work ;so I didn't add the " turn right and left feature " at this code example ;because I was stucked at the first place ) :

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"

Adafruit_MotorShield AFMS = Adafruit_MotorShield();

Adafruit_DCMotor *left1stMotor = AFMS.getMotor(1);
Adafruit_DCMotor *left2ndMotor = AFMS.getMotor(2);
Adafruit_DCMotor *left3rdMotor = AFMS.getMotor(3);
Adafruit_DCMotor *left4thMotor = AFMS.getMotor(4);

void setup() {
Serial.begin(9600); // set up Serial library at 9600 bps
Serial.println("Adafruit Motorshield v2 - DC Motor test!");

AFMS.begin(); // create with the default frequency 1.6KHz
//AFMS.begin(1000); // OR with a different frequency, say 1KHz

// Set the speed to start, from 0 (off) to 255 (max speed)
left1stMotor->setSpeed(150);
left1stMotor->run(FORWARD);
// turn on motor
left1stMotor->run(RELEASE);

left2ndMotor->setSpeed(150);
left2ndMotor->run(FORWARD);
// turn on motor
left2ndMotor->run(RELEASE);

left3rdMotor->setSpeed(150);
left3rdMotor->run(FORWARD);
// turn on motor
left3rdMotor->run(RELEASE);

left4thMotor->setSpeed(150);
left4thMotor->run(FORWARD);
// turn on motor
left4thMotor->run(RELEASE);

}

void loop(){

potentiometerValue = analogRead(potentiometerPin); // reads the value of the potentiometer (value between 0 and 1023)
potentiometerValue = map(potentiometerValue, 0, 1023, 0, 255); // scale it to use it with the dc motor (value between 0 and 255)
potentiometerValue = potentiometerValue/4; // convert 0-1023 range to 0-255 range

uint8_t i;

Serial.print("tick");

left1stMotor->run(FORWARD);

// left2ndMotor->run(FORWARD);
// left3rdMotor->run(FORWARD);
// left4thMotor->run(FORWARD);

for (i=0; i<255; i++) {
if(potentiometerValue <= 127){
left1stMotor->setSpeed(i);
delay(10);

// left2ndMotor->setSpeed(i);
// delay(10);
// left3rdMotor->setSpeed(i);
// delay(10);
// left4thMotor->setSpeed(i);
// delay(10);
}
}
Serial.print("tock");
left1stMotor->run(BACKWARD);
// left2ndMotor->run(BACKWARD);
// left3rdMotor->run(BACKWARD);
// left4thMotor->run(BACKWARD);

for (i=0; i<255; i++) {
if(potentiometerValue >= 127){
left1stMotor->setSpeed(i);
delay(10);

// left2ndMotor->setSpeed(i);
// delay(10);
// left3rdMotor->setSpeed(i);
// delay(10);
// left4thMotor->setSpeed(i);
// delay(10);
}

}

left1stMotor->run(RELEASE);
delay(1000);

// left2ndMotor->run(RELEASE);
// delay(1000);
// left3rdMotor->run(RELEASE);
// delay(1000);
// left4thMotor->run(RELEASE);
// delay(1000);
}

I want to learn that : " Can I supply power to arduino from arduino's normal power socket and from motor shield at the same time ;or power supply from motor shield is enough to supply the motors and arduino at the same time ;or power supply from arduino is enough to supply the motors and arduino at the same time ?

For the turn right and left feature with a potentiometer we should do like this : " while 2 left side motors stop working and only right side motors move forward for clockwise turn right rotation to turn right ( ;or right side motors move backward for non-clockwise turn left rotation ) ; or 2 motors at the left side move forward and 2 motors at the right side move backward ? there are many options and logics. Which one is bettter ?

Sorry for asking too much questions, it is my first time doing a solo project myself with arduino at coding.

My dc motors work between 9V-12V. Please someone help me please at coding by giving some examples that I wanted to do at my project coding. I want to learn and understand where I stucked and how to solve this problem. I look forward your replies to me, friends. Thank you very much.

That's a very complicated sketch, and too much to debug in one go. Start with the basics: Can you make each motor run forwards and backwards at the speed you want? Can you read the value of a potentiometer? You should expect to write test sketches to do each of these things in isolation and get all the different parts of your project working in isolation before you start trying to integrate them.

Is there any possibility to give/write to me a simple code that is about how to how to control 1 dc motor with a 1 potentiometer with adafruit motor shield or any other motor shield which I can use for my 4 dc motors that can be control from a motor shield ? thanks.

It looks like you were very close with the firs program you posted. Here it is in code tags and without the commented lines which only serve to confuse. I have also reformatted it to make it easier to read.

#include <AFMotor.h>

int potentiometerPin = 7; // analog pin used to connect the potentiometer
int potentiometerValue; // variable to read the value from the analog pin 


AF_DCMotor left1stMotor(1); // 1. motor ( Left back motor )

int i;

void setup() 
{ 
  Serial.begin(9600); // set up Serial library at 9600 bps
  left1stMotor.setSpeed(200);
  left1stMotor.run(RELEASE);
} 

void loop() 
{ 
  potentiometerValue = analogRead(potentiometerPin); // reads the value of the potentiometer (value between 0 and 1023) 
  potentiometerValue = map(potentiometerValue, 0, 1023, 0, 255);  //use this line or the next line but not both 
  potentiometerValue = potentiometerValue/4;

  Serial.print("tick");
  left1stMotor.run(FORWARD);

  for (i=0; i<255; i++) 
  {
    if(potentiometerValue <= 127)
    {
      left1stMotor.setSpeed(i);
      delay(10);
    }
  }
  Serial.print("tock");
  left1stMotor.run(BACKWARD);

  for (i=0; i<255; i++) 
  {
    if(potentiometerValue >= 127)
    {
      left1stMotor.setSpeed(i);
      delay(10);
    }
  }

  Serial.print("tech");
  left1stMotor.run(RELEASE);
  delay(1000);
}

Note my comment about using one line or the other but not both. The first line maps the 0 to 1023 value to 0 to 255 then the second line divides the answer by 4. Will the result ever be greater than 127 ?

What does the 1 in this line do ?
AF_DCMotor left1stMotor(1);Does it mean that you are using digital pin 1 ? If so then it will conflict with Serial.print() and vice versa.

My given 2 examples seems similar ;but one is <AFMotor.h> ( V1 Adafruit motor shield library ) v1 coding a little different that the V2 version of Adafruit motor shield library. I gave both ;because both of them don't work while I rotate the potentiometer.

I put your reformatted version of my code, it still doesn't work. I don't know where I do wrong really.I have written somewhere missing at my coding or written wrongly , I cannot able to understand. There is no problem with my potentiometer because I can rotate the servo motor with it from that adafruit motor shield ;and I was written a simple movement code for dc motor solo and it works too. However, when I put a potentiometer it doesn't work at all :-(.

I have checked google about how to fix this issue or is there any examples ;but there is nothing really. There are only " dc motor + encoder " or " stepper motor + encoder/potentiometer " examples ;but there is no " dc motor + potentiometer " example for adafruit motor shield. Thus, I cannot figure out where I miss or where I do wrong. I don't have an encoder or stepper motor in my inventory ;so would you/anyone help me please to solve this issue ?

Please give me some tips/clues ;or a small example of coding for this issue. I am trying for hours how to solve this issue but I cannot fix it. Friends, I am really stuck at my tank project now ( at " dc motor + pot " coding at adafruit v1 or v2 motor shield " ). Please help me, I look forward your replies to me here, thank you very much.

Not :
AF_DCMotor left1stMotor(1);
I was assigned " left1stMotor " as my left bottom motor at my tank project. There will be 4 motors at body.

Will the result ever be greater than 127 ?
I have 1K potentiomter ( but I will get 10K one soon ) ;so with this "potentiometerValue = potentiometerValue/4; " I wanted to make smaller the value for less pot rotation with my fingers.

//use this line or the next line but not both , what do you mean by " next line " ? it is the bottom line that is under the " potentiometerValue = map(potentiometerValue, 0, 1023, 0, 255); " ,right ? thanks.

AF_DCMotor left1stMotor(1);
I was assigned " left1stMotor " as my left bottom motor at my tank project. There will be 4 motors at body.

That does not explain what the 1 refers to.

Will the result ever be greater than 127 ?
I have 1K potentiomter ( but I will get 10K one soon ) ;so with this "potentiometerValue = potentiometerValue/4; " I wanted to make smaller the value for less pot rotation with my fingers.

If it is wired correctly it will not matter if the potentiometer is 1K or 10K, the value returned by analogRead() will still be between 0 and 1023. How is the potentiometer wired ?

//use this line or the next line but not both , what do you mean by " next line " ? it is the bottom line that is under the " potentiometerValue = map(potentiometerValue, 0, 1023, 0, 255); " ,right ? thanks.

The map function turns a range of values between 0 and 1023 into a range of values between 0 and 255. This effectively divides the original value by 4. Then your next line divides the value by 4 again so the maximum value will now be 64 and can never be greater than 127.

More generally, have you tried printing the value of any of the variables in your program to see if is doing what you expect ? Printing potentiometerValue just before you test it to see whether it is greater/less than 127 would be interesting.

that " 1 " representing the M1 ( motor 1 ) on the adafruit motor shield.

Some informations about adafruit motor shield ( this one is for version 2 motor shield ) :

class Adafruit_MotorShield;
The Adafruit_MotorShield class represents a motor shield and must be instantiated before any DCMotors or StepperMotors can be used. You will need to declare one Adafruit_MotorShield for each shield in your system.

Adafruit_MotorShield(uint8_t addr = 0x60);
The constructor takes one optional parameter to specify the i2c address of the shield. The default address of the constructor (0x60) matches the default address of the boards as shipped. If you have more than one shield in your system, each shield must have a unique address.

void begin(uint16_t freq = 1600);
begin() must be called in setup() to initialize the shield. An optional frequency parameter can be used to specify something other than the default maximum: 1.6KHz PWM frequency.

Adafruit_DCMotor *getMotor(uint8_t n);
This function returns one of 4 pre-defined DC motor objects controlled by the shield. The parameter specifies the associated motor channel: 1-4.

Adafruit_StepperMotor *getStepper(uint16_t steps, uint8_t n);
This function returns one of 2 pre-defined stepper motor objects controlled by the shield.
The first parameter specifies the number of steps per revolution.
The second parameter specifies the associated stepper channel: 1-2.

void setPWM(uint8_t pin, uint16_t val);
void setPin(uint8_t pin, boolean val);
These are low-level functions to control pins on the on-board PWM driver chip. These functions are intended for internal use only.

Connecting DC Motors
To connect a motor, simply solder two wires to the terminals and then connect them to either the M1, M2, M3, or M4. Then follow these steps in your sketch
Include the required libraries
Make sure you #include the required libraries
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"
Create the Adafruit_MotorShield object
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Create the DC motor object
Request the Stepper motor from the Adafruit_MotorShield:
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);
with getMotor(port#). Port# is which port it is connected to. If you're using M1 its 1, M2 use 2, M3 use 3 and M4 use 4

Connect to the Controller
In your setup() function, call 'begin()" on the Adafruit_MotorShield object:

AFMS.begin();
Set default speed
Set the speed of the motor using setSpeed(speed) where the speed ranges from 0 (stopped) to 255 (full speed). You can set the speed whenever you want.
myMotor->setSpeed(100);
Run the motor
To run the motor, call run(direction) where direction is FORWARD, BACKWARD or RELEASE. Of course, the Arduino doesn't actually know if the motor is 'forward' or 'backward', so if you want to change which way it thinks is forward, simply swap the two wires from the motor to the shield.
myMotor->run(FORWARD);

Some informations about adafruit motor shield ( this one is for version 1 motor shield ) :

To connect a motor, simply solder two wires to the terminals and then connect them to either the M1, M2, M3, or M4. Then follow these steps in your sketch

Make sure you #include <AFMotor.h>
Create the AF_DCMotor object with AF_DCMotor(motor#, frequency), to setup the motor H-bridge and latches. The constructor takes two arguments.
The first is which port the motor is connected to, 1, 2, 3 or 4.
frequency is how fast the speed controlling signal is.
For motors 1 and 2 you can choose MOTOR12_64KHZ, MOTOR12_8KHZ, MOTOR12_2KHZ, orMOTOR12_1KHZ. A high speed like 64KHz wont be audible but a low speed like 1KHz will use less power. Motors 3 & 4 are only possible to run at 1KHz and will ignore any setting given
Then you can set the speed of the motor using setSpeed(speed) where the speed ranges from 0 (stopped) to 255 (full speed). You can set the speed whenever you want.
To run the motor, call run(direction) where direction is FORWARD, BACKWARD or RELEASE. Of course, the Arduino doesn't actually know if the motor is 'forward' or 'backward', so if you want to change which way it thinks is forward, simply swap the two wires from the motor to the shield.

Copy Code

#include <AFMotor.h>

AF_DCMotor motor(2, MOTOR12_64KHZ); // create motor #2, 64KHz pwm

void setup() {
Serial.begin(9600); // set up Serial library at 9600 bps
Serial.println("Motor test!");
motor.setSpeed(200); // set the speed to 200/255
}

void loop() {
Serial.print("tick");
motor.run(FORWARD); // turn it on going forward
delay(1000);

Serial.print("tock");
motor.run(BACKWARD); // the other way
delay(1000);
Serial.print("tack");
motor.run(RELEASE); // stopped
delay(1000);
}

AF_DCMotor motorname(portnum, freq)

This is the constructor for a DC motor. Call this constructor once for each motor in your sketch. Each motor instance must have a different name as in the example below.

Parameters:

port num - selects which channel (1-4) of the motor controller the motor will be connected to
freq - selects the PWM frequency. If no frequency is specified, 1KHz is used by default.

Frequencies for channel 1 & 2 are:

MOTOR12_64KHZ
MOTOR12_8KHZ
MOTOR12_2KHZ
MOTOR12_1KHZ

Frequencies for channel 3 & 4 are:

MOTOR34_64KHZ
MOTOR34_8KHZ
MOTOR34_1KHZ

Example:
Copy Code

AF_DCMotor motor4(4); // define motor on channel 4 with 1KHz default PWM
AF_DCMotor left_motor(1, MOTOR12_64KHZ); // define motor on channel 1 with 64KHz PWM

adafruit_products_DC_Motor_Ports.gif
Note: Higher frequencies will produce less audible hum in operation, but may result in lower torque with some motors.
setSpeed(speed)

Sets the speed of the motor.

Parameters:

speed- Valid values for 'speed' are between 0 and 255 with 0 being off and 255 as full throttle.

Example:
Note: DC Motor response is not typically linear, and so the actual RPM will not necessarily be proportional to the programmed speed.
run(cmd)

Sets the run-mode of the motor.

Parameters:

cmd - the desired run mode for the motor

Valid values for cmd are:

FORWARD - run forward (actual direction of rotation will depend on motor wiring)
BACKWARD - run backwards (rotation will be in the opposite direction from FORWARD)
RELEASE - Stop the motor. This removes power from the motor and is equivalent to setSpeed(0). The motor shield does not implement dynamic breaking, so the motor may take some time to spin down

Example:
Copy Code

motor.run(FORWARD);
delay(1000); // run forward for 1 second
motor.run(RELEASE);
delay(100); // 'coast' for 1/10 second
motor.run(BACKWARDS); // run in reverse

From this link you can see the adafruit Version 1 ( V1 ) motor shield's .h and .cpp documents ( Please check ) :

From this link you can see the adafruit Version 1 ( V2 ) motor shield's .h and .cpp documents ( Please check ) :

Sorry if my comment is so long, for 2 days I am searching non-stop really. I give everything related with adafruit motorshield version 1 and 2, the basics of this motor shield.

UKHeliBob, Would you write for me a simple adafruit motor shield ( V1 or V2 ) coding for the control the speed and direction of 1 dc motor with 1 potentiometer please ? I want to see where I do wrong. I hope that you / anyone would help me to fix this issue, thank you very much.