Good day,
I am experimenting with the following setup.
1 Pololu motor dual_vnh5019_motor_driver_shield
1 Arduino Uno
2 DC geared motors 12V
1 servo SG92R 5V
1 ThumbJoystick
As seen in the picture I have a joystick using 5V from Arduino and Y/X using A0 and A1. Arduino and Pololu shield is powered by a 12 V power supply using the jumper and 2 dc motors connected to the shield.
I added a servo to the project and experimented different ways to build the circuit but in the end all resulted to the same situation where when using the joystick to turn the DC motors the servo turns as well. I did not even build a code yet to have the servo working.
I power up the servo independently from Arduino and I have no idea why the servo is acting up like this.
Anyone would have an idea on the reason why the servo is moving when I move the joystick? only the dc motors should be moving which they do by the way.
I noticed the servo doesn't move when I put joystick in the direction to have dc motors go backward.
#include "DualVNH5019MotorShield.h"
DualVNH5019MotorShield md;
void stopIfFault()
{
if (md.getM1Fault())
{
Serial.println("M1 fault");
while(1);
}
if (md.getM2Fault())
{
Serial.println("M2 fault");
while(1);
}
}
const int potpinY = A0;
const int potpinX = A1;
void setup()
{
Serial.begin (9600); //initialize serial communications
md.init(); //initiates default pololu shield pins
}
void loop()
{
int valY = analogRead(potpinY);
int valX = analogRead(potpinX);
valY = map(valY, 0, 1023, -255, 255);
valX = map(valX, 0, 1023, -255, 255);
Serial.println(valX);
if (valX >= 150)
{
md.setM1Speed(valX);
md.setM2Speed(valX);
stopIfFault();
}
else if (valX <= -150)
{
md.setM1Speed(valX);
md.setM2Speed(valX);
stopIfFault();
}
else if (valY <= -150)
{
md.setM1Speed(valY);
md.setM2Speed(-valY);
stopIfFault();
}
else if (valY >= 150)
{
md.setM1Speed(-valY);
md.setM2Speed(valY);
stopIfFault();
}
else {
md.setM1Speed(0);
md.setM2Speed(0);
}
}
Servo power negative/ground needs to be connected to Arduino GND.
Steve
Steve,
Thank You for the advice, I did change the ground of servo to Arduino ground pin.
I completed more of the code and is basically final, the idea is simply having both dc motors go forward/backward/left/right using the joystick and 2 buttons for a plow to go up/down.
I still observe the issue where when using the joystick both dc motors and servo turn.
I saw a topic mentioning about timer1 and libraries conflict but I don't believe this is the issue? Any guidance would be appreciated.
thank you
here is the final sketch I built
#include <DualVNH5019MotorShield.h>
#include <Servo.h>
DualVNH5019MotorShield md;
void stopIfFault()
{
if (md.getM1Fault())
{
Serial.println("M1 fault");
while (1);
}
if (md.getM2Fault())
{
Serial.println("M2 fault");
while (1);
}
}
Servo myservo; // create servo object to control a servo
int angle = 90; // initial angle for servo
int angleStep = 10;
#define LEFT A2 // pin A2 is connected to left button
#define RIGHT A3 // pin A3 is connected to right button
const int potpinY = A0;
const int potpinX = A1;
void setup()
{
Serial.begin (9600); //initialize serial communications
myservo.attach(3); // attaches the servo on pin 3 to the servo object
pinMode(LEFT, INPUT_PULLUP); // assign pin A2 ass input for Left button
pinMode(RIGHT, INPUT_PULLUP); // assing pin A3 as input for right button
myservo.write(angle);// send servo to the middle at 90 degrees
md.init(); //initiates default pololu shield pins
}
void loop()
{
int valY = analogRead(potpinY);
int valX = analogRead(potpinX);
valY = map(valY, 0, 1023, -255, 255);
valX = map(valX, 0, 1023, -255, 255);
if (valX >= 150)
{
md.setM1Speed(valX);
md.setM2Speed(valX);
stopIfFault();
}
else if (valX <= -150)
{
md.setM1Speed(valX);
md.setM2Speed(valX);
stopIfFault();
}
else if (valY <= -150)
{
md.setM1Speed(valY);
md.setM2Speed(-valY);
stopIfFault();
}
else if (valY >= 150)
{
md.setM1Speed(-valY);
md.setM2Speed(valY);
stopIfFault();
}
else {
md.setM1Speed(0);
md.setM2Speed(0);
}
while (digitalRead(RIGHT) == LOW) {
if (angle > 0 && angle <= 165) {
angle = angle - angleStep;
if (angle < 0) {
angle = 0;
} else {
myservo.write(angle); // move the servo to desired angle
Serial.print("Moved to: ");
Serial.print(angle); // print the angle
Serial.println(" degree");
}
}
delay(100); // waits for the servo to get there
}// while
while (digitalRead(LEFT) == LOW) {
if (angle >= 0 && angle <= 165) {
angle = angle + angleStep;
if (angle > 165) {
angle = 165;
} else {
myservo.write(angle); // move the servo to desired angle
Serial.print("Moved to: ");
Serial.print(angle); // print the angle
Serial.println(" degree");
}
}
delay(100); // waits for the servo to get there
}//
}

I just tried a test using only the below code and everything works fine when running the portion for the servo excluding the motors.
Seem like a wiring problem or my code.
#include <Servo.h>
Servo myservo; // create servo object to control a servo
int angle =90; // initial angle for servo
int angleStep =10;
#define LEFT A2 // pin 12 is connected to left button
#define RIGHT A3 // pin 2 is connected to right button
void setup() {
Serial.begin(9600); // setup serial
myservo.attach(3); // attaches the servo on pin 9 to the servo object
pinMode(LEFT,INPUT_PULLUP); // assign pin A2 ass input for Left button
pinMode(RIGHT,INPUT_PULLUP);// assing pin A3 as input for right button
myservo.write(angle);// send servo to the middle at 90 degrees
Serial.println("Robojax Servo Button ");
}
void loop() {
while(digitalRead(RIGHT) == LOW){
if (angle > 0 && angle <= 165) {
angle = angle - angleStep;
if(angle < 0){
angle = 0;
}else{
myservo.write(angle); // move the servo to desired angle
Serial.print("Moved to: ");
Serial.print(angle); // print the angle
Serial.println(" degree");
}
}
delay(100); // waits for the servo to get there
}// while
while(digitalRead(LEFT) == LOW){
if (angle >= 0 && angle <= 165) {
angle = angle + angleStep;
if(angle >165){
angle =165;
}else{
myservo.write(angle); // move the servo to desired angle
Serial.print("Moved to: ");
Serial.print(angle); // print the angle
Serial.println(" degree");
}
}
delay(100); // waits for the servo to get there
}//
}
Looking at the code that motorshield driver does seem to grab Timer1 and so probably messes with the servo library use of it.
As an experiment you could try replacing Servo.h with ServoTimer2.h. You'll need to change the writes because ServoTimer2 uses milliseconds not degrees so 0 to 180 becomes roughly 600 to 2400.
Steve
Steve,
thank you, I made the change to library ServoTimer2.
I do see improvement but I observe strange behavior still that I am trying to fix. There seem to be interference when using the joystick.
question#1 can I make the servo go faster?
question#2 can the noise problem when using the joystick and servo moving be caused by my circuit being incorrect?
I will change my code and use digital pins instead of the analog pins for the buttons
#include <ServoTimer2.h>
#include <DualVNH5019MotorShield.h>
//#include <Servo.h>
DualVNH5019MotorShield md;
void stopIfFault()
{
if (md.getM1Fault())
{
Serial.println("M1 fault");
while (1);
}
if (md.getM2Fault())
{
Serial.println("M2 fault");
while (1);
}
}
ServoTimer2 myservo; // create servo object to control a servo
int angle = 1000; // initial angle for servo
#define LEFT A2 // pin 12 is connected to left button
#define RIGHT A3 // pin 2 is connected to right button
const int potpinY = A0;
const int potpinX = A1;
void setup()
{
Serial.begin (9600); //initialize serial communications
myservo.attach(3); // attaches the servo on pin 3 to the servo object
pinMode(LEFT, INPUT_PULLUP); // assign pin 5 ass input for Left button
pinMode(RIGHT, INPUT_PULLUP); // assing pin 11 as input for right button
myservo.write(angle);// send servo to the middle at 90 degrees
md.init(); //initiates default pololu shield pins
}
void loop()
{
int valY = analogRead(potpinY);
int valX = analogRead(potpinX);
valY = map(valY, 0, 1023, -255, 255);
valX = map(valX, 0, 1023, -255, 255);
if (valX >= 150)
{
md.setM1Speed(valX);
md.setM2Speed(valX);
stopIfFault();
}
else if (valX <= -150)
{
md.setM1Speed(valX);
md.setM2Speed(valX);
stopIfFault();
}
else if (valY <= -150)
{
md.setM1Speed(valY);
md.setM2Speed(-valY);
stopIfFault();
}
else if (valY >= 150)
{
md.setM1Speed(-valY);
md.setM2Speed(valY);
stopIfFault();
}
else {
md.setM1Speed(0);
md.setM2Speed(0);
}
while (digitalRead(LEFT) == LOW && angle < 2400) {
angle++;
myservo.write(angle);
delay(10);
}
while (digitalRead(RIGHT) == LOW && angle > 600) {
angle--;
myservo.write(angle);
delay(10);
}
}
I think I found the reason.
the below link points to an example using servo with pololu shield.
I will attempt to understand it and apply to my existing sketch......... :o
ServoTimer2 already uses T2 instead of T1...but there's no harm trying. And the analog pins are digital pins anyway when you use digitalRead on them.
But looking at your video there's something very wrong with your servo. An SG92R should not be able to rotate more than 180 degrees and yours is doing full circles. Is it a genuine TowerPro? Can you try a different one?
You can get the servo to go faster by reducing the delay(10). If you want full speed don't move the servo 1 step at a time, just write the end position directly. Or instead of angle++ add 5 or 10 to angle every time.
Steve