myservo.attach ruining everything

I’m tired of slamming my head against this desk. I am going to go to the gym to cool down, but can still check for replys while im there. In the meantime, I wanted to see while I’m out if someone can give me the why and not the how. I can work on how to fix it, but I just don’t understand why it’s doing this. Here is the code:

#include "MotorDriver.h"
#include <Servo.h>


const int buttonPin1 = 2;
int buttonState1 = 0;
Servo myservo;

void setup()
{
	/*Configure the motor A to control the wheel at the left side.*/
	/*Configure the motor B to control the wheel at the right side.*/
	
        pinMode(buttonPin1, INPUT_PULLUP);
        myservo.attach(7);
        motordriver.init();
	motordriver.setSpeed(200,MOTORB);
	motordriver.setSpeed(200,MOTORA);
}

 
void loop()
{
	buttonState1 = digitalRead(buttonPin1);
        
        if (buttonState1 == LOW)
        {
        
        motordriver.goForward();
	delay(2000);
	motordriver.stop();
	delay(1000);
	motordriver.goBackward();
	delay(2000);
	motordriver.stop();
	delay(1000);
	motordriver.goLeft();
	delay(2000);
	motordriver.stop();
	delay(1000);
	motordriver.goRight();
	delay(2000);
	motordriver.stop();
	delay(1000);
        
	}
       



}

This was is going into a much larger code. But for now I am basically combining my servo code with a motor code. I only have one motor plugged into my shield as a test, and took out my servo positioning code. When executed, the motor should go forward, stop, go backwards, stop, go forward, stop, go backwards stop. If I take out myservo.attach(7) then I push the button and the motor turns and everyone celebrates. As soon as I put in the myservo code anywhere in void setup, the push button activates the shield, the indicator lights flash in order to say that the motor is going one direction stopping and then the other, but the motor itself does not move, or make any sounds. As soon as I take out the myservo code, it works fine again.

Like I said, I can fix the code with the how, but I first need to understand the why. Once the myservo code is read in arduino, does it stop else and only focus on the servo? and if so, why do the indicators still correspond with the button pushes?

My guess is that both libraries use Timer 1.

Thank you for your guesstimation. I am still new to libraries so I am not 100% what to look for. But here are the libraries, but I didn’t see any settings for timers, unless that’s a default value…

motordriver.h

#ifndef __MOTORDRIVER_H__
#define __MOTORDRIVER_H__
#include <Arduino.h>
/******Pins definitions*************/
#define MOTORSHIELD_IN1	8
#define MOTORSHIELD_IN2	11
#define MOTORSHIELD_IN3	12
#define MOTORSHIELD_IN4	13
#define SPEEDPIN_A		9
#define SPEEDPIN_B		10
/**************Motor ID**********************/
#define MOTORA 			0
#define MOTORB 			1

#define MOTOR_POSITION_LEFT  0
#define MOTOR_POSITION_RIGHT 1
#define MOTOR_CLOCKWISE      0
#define MOTOR_ANTICLOCKWISE  1

#define USE_DC_MOTOR		0

struct MotorStruct
{
	int8_t speed;
	uint8_t direction;
	uint8_t position;
};
/**Class for Motor Shield**/
class MotorDriver
{
	MotorStruct motorA;
	MotorStruct motorB;
public:
	void init();
	void configure(uint8_t position, uint8_t motorID);
	void setSpeed(int8_t speed, uint8_t motorID);
	void setDirection(uint8_t direction, uint8_t motorID);
	void rotate(uint8_t direction, uint8_t motor_position);
	void rotateWithID(uint8_t direction, uint8_t motorID);
	void goForward();
	void goBackward();
	void goLeft();
	void goRight();
	void stop();
	void stop(uint8_t motorID);
};
extern MotorDriver motordriver;

#endif

servo.h

Servo - Class for manipulating servo motors connected to Arduino pins.

    attach(pin )  - Attaches a servo motor to an i/o pin.
    attach(pin, min, max  ) - Attaches to a pin setting min and max values in microseconds
    default min is 544, max is 2400  
 
    write()     - Sets the servo angle in degrees.  (invalid angle that is valid as pulse in microseconds is treated as microseconds)
    writeMicroseconds() - Sets the servo pulse width in microseconds 
    read()      - Gets the last written servo pulse width as an angle between 0 and 180. 
    readMicroseconds()   - Gets the last written servo pulse width in microseconds. (was read_us() in first release)
    attached()  - Returns true if there is a servo attached. 
    detach()    - Stops an attached servos from pulsing its i/o pin. 
 */

#ifndef Servo_h
#define Servo_h

#include <inttypes.h>

/* 
 * Defines for 16 bit timers used with  Servo library 
 *
 * If _useTimerX is defined then TimerX is a 16 bit timer on the current board
 * timer16_Sequence_t enumerates the sequence that the timers should be allocated
 * _Nbr_16timers indicates how many 16 bit timers are available.
 */

// Architecture specific include
#if defined(ARDUINO_ARCH_AVR)
#include "avr/ServoTimers.h"
#elif defined(ARDUINO_ARCH_SAM)
#include "sam/ServoTimers.h"
#else
#error "This library only supports boards with an AVR or SAM processor."
#endif

#define Servo_VERSION           2     // software version of this library

#define MIN_PULSE_WIDTH       544     // the shortest pulse sent to a servo  
#define MAX_PULSE_WIDTH      2400     // the longest pulse sent to a servo 
#define DEFAULT_PULSE_WIDTH  1500     // default pulse width when servo is attached
#define REFRESH_INTERVAL    20000     // minumim time to refresh servos in microseconds 

#define SERVOS_PER_TIMER       12     // the maximum number of servos controlled by one timer 
#define MAX_SERVOS   (_Nbr_16timers  * SERVOS_PER_TIMER)

#define INVALID_SERVO         255     // flag indicating an invalid servo index

typedef struct  {
  uint8_t nbr        :6 ;             // a pin number from 0 to 63
  uint8_t isActive   :1 ;             // true if this channel is enabled, pin not pulsed if false 
} ServoPin_t   ;  

typedef struct {
  ServoPin_t Pin;
  volatile unsigned int ticks;
} servo_t;

class Servo
{
public:
  Servo();
  uint8_t attach(int pin);           // attach the given pin to the next free channel, sets pinMode, returns channel number or 0 if failure
  uint8_t attach(int pin, int min, int max); // as above but also sets min and max values for writes. 
  void detach();
  void write(int value);             // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds 
  void writeMicroseconds(int value); // Write pulse width in microseconds 
  int read();                        // returns current pulse width as an angle between 0 and 180 degrees
  int readMicroseconds();            // returns current pulse width in microseconds for this servo (was read_us() in first release)
  bool attached();                   // return true if this servo is attached, otherwise false 
private:
   uint8_t servoIndex;               // index into the channel data for this servo
   int8_t min;                       // minimum is this value times 4 added to MIN_PULSE_WIDTH    
   int8_t max;                       // maximum is this value times 4 added to MAX_PULSE_WIDTH   
};

#endif

resistorswtf: motordriver.h

While the header file is interesting it does not contribute to the discussion. The source file (dot-cpp) is the important part. A link is sufficient.

[quote author=Coding Badly date=1430790223 link=msg=2217983] While the header file is interesting it does not contribute to the discussion. The source file (dot-cpp) is the important part. A link is sufficient.

[/quote]

ahh, well, now I know the difference between a header and .cpp file. I looked for a link to the cpp but I directly downloaded the .zip from a wiki page resource so I guess I could link that if you wanted the file itself. As for the code inside the .cpp, it is this. I searched through it, but unless its abbr. I still don't see a timer setting:

#include "MotorDriver.h"

void MotorDriver::init()
{
    pinMode(MOTORSHIELD_IN1,OUTPUT);
    pinMode(MOTORSHIELD_IN2,OUTPUT);
    pinMode(MOTORSHIELD_IN3,OUTPUT);
    pinMode(MOTORSHIELD_IN4,OUTPUT);
    pinMode(SPEEDPIN_A,OUTPUT);
    pinMode(SPEEDPIN_B,OUTPUT);
    stop();
    /*Configure the motor A to control the wheel at the left side.*/
    configure(MOTOR_POSITION_LEFT,MOTORA);
    /*Configure the motor B to control the wheel at the right side.*/
    configure(MOTOR_POSITION_RIGHT,MOTORB);
    setSpeed(127,MOTORA);
    setSpeed(127,MOTORB);
    setDirection(MOTOR_ANTICLOCKWISE,MOTORA);
    setDirection(MOTOR_CLOCKWISE,MOTORB);
}
void MotorDriver::configure(uint8_t position, uint8_t motorID)
{
    if(motorID == MOTORA)motorA.position = position;
    else motorB.position = position;
}

void MotorDriver::setSpeed(int8_t speed, uint8_t motorID)
{
    if(motorID == MOTORA) motorA.speed = speed;
    else if(motorID == MOTORB) motorB.speed = speed;
}
void MotorDriver::setDirection(uint8_t direction, uint8_t motorID)
{
    if(motorID == MOTORA)motorA.direction= direction;
    else if(motorID == MOTORB)motorB.direction = direction;
}
/**********************************************************************/
/*Function: Get the motor rotate                                     */
/*Parameter:-uint8_t direction,Clockwise or anticlockwise;            */
/*          -uint8_t motor_position,MOTOR_POSITION_LEFT or           */
/*          MOTOR_POSITION_RIGHT;                                      */
/*Return:   void                                                       */
void MotorDriver::rotate(uint8_t direction, uint8_t motor_position)
{
    if(motor_position == motorA.position)
    {
        rotateWithID(direction,MOTORA);
    }
    if(motor_position == motorB.position)
    {
        rotateWithID(direction,MOTORB);
    }
}
/**********************************************************************/
/*Function: Get the motor rotate                                     */
/*Parameter:-uint8_t direction,Clockwise or anticlockwise;            */
/*          -uint8_t motor_position,MOTORA or MOTORB                 */
/*Return:   void                                                       */
void MotorDriver::rotateWithID(uint8_t direction, uint8_t motorID)
{
    uint8_t in1_level,in2_level;
    if(MOTOR_CLOCKWISE == direction)
    {
        in1_level = LOW;
        in2_level = HIGH;
    }
    else 
    {
        in1_level = HIGH;
        in2_level = LOW;
    }
    if(motorID == MOTORA)
    {
        analogWrite(SPEEDPIN_A,motorA.speed);
        digitalWrite(MOTORSHIELD_IN1,in1_level);
      digitalWrite(MOTORSHIELD_IN2,in2_level);
    }
    else if(motorID == MOTORB)
    {
        analogWrite(SPEEDPIN_B,motorB.speed);
        digitalWrite(MOTORSHIELD_IN3,in1_level);
      digitalWrite(MOTORSHIELD_IN4,in2_level);
    }
}

void MotorDriver::goForward()
{
    rotate(MOTOR_ANTICLOCKWISE,MOTOR_POSITION_LEFT);
    rotate(MOTOR_CLOCKWISE,MOTOR_POSITION_RIGHT);
}
void MotorDriver::goBackward()
{
    rotate(MOTOR_ANTICLOCKWISE,MOTOR_POSITION_RIGHT);
    rotate(MOTOR_CLOCKWISE,MOTOR_POSITION_LEFT);
}
void MotorDriver::goLeft()
{
    rotate(MOTOR_CLOCKWISE,MOTOR_POSITION_RIGHT);
    rotate(MOTOR_CLOCKWISE,MOTOR_POSITION_LEFT);
}
void MotorDriver::goRight()
{
    rotate(MOTOR_ANTICLOCKWISE,MOTOR_POSITION_RIGHT);
    rotate(MOTOR_ANTICLOCKWISE,MOTOR_POSITION_LEFT);
}

/*************************************************************/
void MotorDriver::stop()
{
    /*Unenble the pin, to stop the motor. */
    digitalWrite(SPEEDPIN_A,LOW);
    digitalWrite(SPEEDPIN_B,LOW);
}

Link to the .ZIP file containing the motor driver:

http://www.seeedstudio.com/wiki/File:MotorDriver20121210.zip

#define SPEEDPIN_A		9
#define SPEEDPIN_B		10
analogWrite(SPEEDPIN_A,motorA.speed);
analogWrite(SPEEDPIN_B,motorB.speed);

Pin 9 is Output Compare Timer 1 Channel A. Pin 10 is Output Compare Timer 1 Channel B. Servo takes over Timer 1. After that pulse width modulation on pins 9 and 10 will no longer work.

Try using a servo library designed to work on timer 2…
https://www.google.com/search?q=servo+timer+2

[quote author=Coding Badly link=msg=2218030 date=1430795306]

#define SPEEDPIN_A      9
#define SPEEDPIN_B      10
analogWrite(SPEEDPIN_A,motorA.speed);
analogWrite(SPEEDPIN_B,motorB.speed);

Pin 9 is Output Compare Timer 1 Channel A. Pin 10 is Output Compare Timer 1 Channel B. Servo takes over Timer 1. After that pulse width modulation on pins 9 and 10 will no longer work.

Try using a servo library designed to work on timer 2... https://www.google.com/search?q=servo+timer+2

[/quote]

Thank you for your help through all of this. I just saw this this morning so I will have to verify this afternoon. Although I thought it would have been funnier if you had posted a LMGTFY instead of just the google link. I do have one question. It is good to know that that is the issue, but I am still confused how it takes over timer 1 from the code that was posted. Is this because both the programs default to timer 1? or am I overlooking something that is assigning it? If they just default, wouldn't that make all programs that use #include conflict unless they were specified on a different timer?

Is this because both the programs default to timer 1?

PWM uses timers - one timer per pair of pins. The Servo library needs a timer, too. The various timers have different resolutions, so they are not entirely interchangeable. The Servo library is designed to use timer 1. That makes it unavailable for PWM use.

If they just default, wouldn't that make all programs that use #include conflict unless they were specified on a different timer?

If they #include the Servo header file, actually create an instance of the class, attach the instance to a pin AND try to do PWM on pins 9 or 10, yes.

PaulS: AND try to do PWM on pins 9 or 10, yes.

This is where I found the mistake. The motor shield I am using uses pins 8-12 to function. Per the Servo library, 9-10 are disabled for PWM functionality on my UNO. So when I get home I will change the speed pins in the library from 9 & 10 to two different ones. Logically, this should solve everything. Thanks again.

If the motor shield is stacked on the Arduino, as is normally the case with shields, then you will need to hack the shield hardware as well as changing the library to use different pins.

Does the servo code work properly if you don't use the motor code?

If so why not try the servoTimer2 library

Trying would be quicker than trying to figure out what is in the other libraries.

...R

UKHeliBob: If the motor shield is stacked on the Arduino, as is normally the case with shields, then you will need to hack the shield hardware as well as changing the library to use different pins.

NOOOOOOOOOO, that was my fear. I was hoping the logic would push the pins to output and everything would be happy go lucky. I was hoping I wouldn't have to resort to physical changes. Thank you though, its an inconvenience, but shouldn't be too terrible.

And yes Robin2, I was looking into the Timer2 since that was the first thing mentioned, but I am a very visual learner and timers are just blowing my mind at the moment when trying to read and understand them. The changing output pins just seemed like a quick fix...until Bob ruined it :P

Robin2: Does the servo code work properly if you don't use the motor code?

If so why not try the servoTimer2 library

Trying would be quicker than trying to figure out what is in the other libraries.

...R

My apologies for the double post. Robin2, yes the code works if I don't use the motor code. Hell, the servo code works even if I do use the motor code. Its just the motor code that wont work if I myserver.attach().

A question about the library that you linked, it does state:

Note that analogWrite of PWM on pins 3 and 11 is disabled when the first servo is attached

will I run into the same issue that I currently have because my shield still needs to utilize 8-12, or does it being on a separate timer negate what is happening on timer1 with the motor?

Are you using analogWrite() on pins 3 and 11 ? I presume that is controlled by Timer2 which the library uses.

I guess if you are not using analogWrite() on those pins you will be OK.

...R

Robin2: Are you using analogWrite() on pins 3 and 11 ? I presume that is controlled by Timer2 which the library uses.

I guess if you are not using analogWrite() on those pins you will be OK.

...R

Yea, I am going to go with this idea. I was going to say disregard the 3, 11 thing but didn't want to triple post, and I thought the thread was dying. I looked into the library and only 11 would be affected, and it is just used as an indicator light. I could care less if it indicates, as long as the motor is moving :D.

Hello,

I have experienced the same problem. I am working on a project for my middle school Arduino class to build a small robot that uses two DC motors and one Servo. However I have run into the same problem with the fact that servo.h disables pwm and pins 9-10. I have been searching for days and days for a solution/work around but have not found one. Have tried to use the ServoTimer2.h library but it does not work with the latest version of the IDE. Seeedstudio documentation does not give any solutions. And after reading through this thread, it seems like everyone is thinking along the same line with certain work arounds but to no avail. Does anyone know of another shield that will allow two DC motors and on servo to work simultaneously or at least won't cancel each other out due to the servo.h issue turning off pwm on pins 9-10? I need a solution in the next 2 weeks so I can order enough motor shields for my students for this robotics project. I will continue searching and working on a solution as well and will contribute if I find one. Thanks for all the current information that everyone has tried.

chonito: Have tried to use the ServoTimer2.h library but it does not work with the latest version of the IDE

Simple solution to that. Use an older version of the IDE. I am using 1.5.6

There is no problem having several versions on a PC. They are just Java programs.

...R