XYZrobot Smart Servo

Hello,

Currently I am trying to use an XYZrobot Smart Servo because it supposedly has full control and takes inputs unlike a continuous rotation servo which just turns on and off at various speeds for time. We need the precision and control. This servo comes from this website:

https://www.neweraai.com/us_en/product/edutainment-robot/robot-kits/smart-servo

and its library can be found here:

https://github.com/pololu/xyzrobot-servo-arduino

I have attempted to use the examples provided in the library and for the first example blink_all I am able to connect the servo to pin 10 and 11 and get the led to change colors. When it comes to the next example, changebaud, I go through the instructions and press y on the serial monitor and it pauses for a bit and then it has an error doing so. I cannot seem to change the ID on the other examples do not seem to do anything as well. I cannot find very much on this servo and from what I have seen some use a special shield and a different program? Any help would be greatly appreciated.

Thank you

Hi, Welcome to the forum.

Please read the first post in any forum entitled how to use this forum. http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code. It will be formatted in a scrolling window that makes it easier to read.

I have attempted to use the examples provided in the library and for the first example blink_all [u]I am able to connect the servo to pin 10 and 11[/u] and get the led to change colors.

What do you mean, you cannot physically connect the servo to the pins?

Please post the example code you are trying to run.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

A picture of your project and its connections will help.

How are you powering the project, in particular the servo?

You have connected 10 and 11 the right way round, they are rx and tx serial pins.

Thanks.. Tom... :)

So I can run the first example from the library:

// This sketch shows how to blink the LEDs on all of the smart
// servos attached to your board.
//
// Note that this sketch will leave your servo in a state where
// the LEDs are controlled by the serial interface instead of
// indicating the servo' status.  To get your servos back to
// normal after running this sketch, you will probably want to
// power cycle them.
//
// This sketch only writes data to the servos; it does not
// receive anything.

#include <XYZrobotServo.h>

// On boards with a hardware serial port available for use, use
// that port. For other boards, create a SoftwareSerial object
// using pin 10 to receive (RX) and pin 11 to transmit (TX).
#ifdef SERIAL_PORT_HARDWARE_OPEN
#define servoSerial SERIAL_PORT_HARDWARE_OPEN
#else
#include <SoftwareSerial.h>
SoftwareSerial servoSerial(10, 11);
#endif

// Define a servo object that uses the broadcast address, so
// commands that it sends will go to all the servos.
XYZrobotServo servo(servoSerial, 254);

void setup()
{
  // Turn on the serial port and set its baud rate.
  servoSerial.begin(115200);
}

void setAllLedsAtThisBaudRate(uint8_t color)
{
  delay(100);

  // Make all the LEDs be user-controlled.
  servo.writeAlarmLedPolicyRam(0b1111);

  // Turn on the specified LEDs.
  servo.writeLedControl(color);
}

void setAllLeds(uint8_t color)
{
  servoSerial.begin(9600);
  setAllLedsAtThisBaudRate(color);

  servoSerial.begin(19200);
  setAllLedsAtThisBaudRate(color);

  servoSerial.begin(57600);
  setAllLedsAtThisBaudRate(color);

  servoSerial.begin(115200);
  setAllLedsAtThisBaudRate(color);
}

void loop()
{
  delay(2500);

  // Try to make all the LEDs blue.
  setAllLeds(0b0010);

  delay(1000);

  // Try to make all the LEDs green.
  setAllLeds(0b0100);
}

This works with the current way I have set up and I am able to change all the colors of the led so I can somewhat connect it to my arduino mega. The way I have it set up looks like this:

When I run any example code from the XYZrobot like for instance these 2 codes:

// This example shows how to change the baud rate of a servo.
//
// To use this sketch:
//
// 1) Change the servoId, servoBaudOld, and servoBaudNew
//    parameters below.
// 2) Upload the sketch to your board.
// 3) Open the Serial Monitor and set its baud rate to 115200.
// 4) In the input box, type "y" and click "Send".

#include <XYZrobotServo.h>

// Change this to be the ID of the servo.
const uint8_t servoId = 1;

// Change this to be the baud rate that the servo currently uses.
// The options are 9600, 19200, 57600, or 115200.
const XYZrobotServoBaudRate servoBaudOld = XYZrobotServoBaudRate::B115200;

// Change this to be the baud rate that you want the servo to use.
const XYZrobotServoBaudRate servoBaudNew = XYZrobotServoBaudRate::B115200;

// On boards with a hardware serial port available for use, use
// that port. For other boards, create a SoftwareSerial object
// using pin 10 to receive (RX) and pin 11 to transmit (TX).
#ifdef SERIAL_PORT_HARDWARE_OPEN
#define servoSerial SERIAL_PORT_HARDWARE_OPEN
const bool usingSoftwareSerial = false;
#else
#include <SoftwareSerial.h>
SoftwareSerial servoSerial(10, 11);
const bool usingSoftwareSerial = true;
#endif

XYZrobotServo servo(servoSerial, servoId);

bool success;
char errorMessage[256];

void useOldBaudRate()
{
  servoSerial.begin(XYZrobotServoBaudRateToInt(servoBaudOld));
  delay(10);
}

void useNewBaudRate()
{
  servoSerial.begin(XYZrobotServoBaudRateToInt(servoBaudNew));
  delay(10);
}

void tryToChangeBaud()
{
  success = false;
  errorMessage[0] = 0;

  // We can't reliably receive data at the old baud rate if we
  // are using software serial and the old baud rate is 115200.
  const bool canReceiveAtOldBaud = !(usingSoftwareSerial &&
    servoBaudOld == XYZrobotServoBaudRate::B115200);

  // Switch to the old baud rate.
  useOldBaudRate();

  // Make sure we can communicate with the servo using the old
  // baud rate.
  if (canReceiveAtOldBaud)
  {
    servo.readStatus();
    if (servo.getLastError())
    {
      sprintf_P(errorMessage,
        PSTR("Could not communicate with the servo: code %d."),
        servo.getLastError());
      return;
    }
  }

  // Set the ACK policy to its default so we can later read back
  // values from EEPROM.
  servo.writeAckPolicyRam(XYZrobotServoAckPolicy::OnlyReadAndStat);

  // Make sure there is not another servo using the new baud rate
  // and same ID, because then changing the baud rate would cause
  // a conflict and it could be hard to fix.
  useNewBaudRate();
  servo.readStatus();
  if (servo.getLastError() != (uint8_t)XYZrobotServoError::HeaderTimeout)
  {
    sprintf_P(errorMessage,
      PSTR("There was already a servo at the new baud rate: code %d."),
      servo.getLastError());
    return;
  }

  // Change the baud rate in EEPROM.  (It is not in RAM.)
  useOldBaudRate();
  servo.writeBaudRateEeprom(servoBaudNew);
  delay(20);

  // Make sure the baud rate in EEPROM is correct.
  if (canReceiveAtOldBaud)
  {
    XYZrobotServoBaudRate baudFromEeprom = servo.readBaudRateEeprom();
    if (servo.getLastError())
    {
      sprintf_P(errorMessage,
        PSTR("Failed to read baud rate from EEPROM: code %d"),
        servo.getLastError());
      return;
    }
    if (baudFromEeprom != servoBaudNew)
    {
      sprintf_P(errorMessage,
        PSTR("The baud rate in EEPROM is incorrect: %d"),
        (uint8_t)baudFromEeprom);
      return;
    }
  }

  // Restart the servo so it can use its new baud rate.
  servo.reboot();
  delay(2500);

  // Make sure the servo is responding at the new baud rate.
  useNewBaudRate();
  servo.readStatus();
  if (servo.getLastError())
  {
    sprintf_P(errorMessage,
      PSTR("The servo did not respond at its new baud rate: code %d"),
      servo.getLastError());
    return;
  }

  success = true;
}

// Prompt the user to send 'y' and wait until they do it.
void waitForUserInput()
{
  uint16_t lastPromptTime = 0;
  while (true)
  {
    if ((uint16_t)(millis() - lastPromptTime) >= 2000)
    {
      Serial.println(F("Send \"y\" to change the baud rate."));
      lastPromptTime = millis();
    }

    if (Serial.read() == 'y') { return; }
  }
}

void setup()
{
  Serial.begin(115200);

  servoSerial.setTimeout(20);

  // To receive data, a pull-up is needed on the RX line because
  // the servos do not pull the line high while idle.  If you are
  // using SoftwareSerial, the pull-up is probably enabled
  // already.  If you are using the hardware serial port on an
  // ATmega32U4-based board, we know the RX pin must be pin 0 so
  // we enable its pull-up here.  For other cases, you should add
  // code below to enable the pull-up on your board's RX line.
#if defined(SERIAL_PORT_HARDWARE_OPEN) && defined(__AVR_ATmega32U4__)
  pinMode(0, INPUT_PULLUP);
#endif

}

void loop()
{
  waitForUserInput();

  Serial.println(F("Trying to change the baud rate..."));

  tryToChangeBaud();

  if (success)
  {
    Serial.println(F("Successfully changed the servo's baud rate."));
    while (true) { }
  }
  else
  {
    Serial.print(F("Error: "));
    Serial.println(errorMessage);
  }
}
// This sketch shows how to move a servo back and forth between
// two different position.
//
// Positions are represented as numbers between 0 and 1023.  When
// you set a position, you can also specify the playtime, which
// is how long you want the movement to take, in units of 10 ms.
//
// This sketch only writes data to the servos; it does not
// receive anything.

#include <XYZrobotServo.h>

// On boards with a hardware serial port available for use, use
// that port. For other boards, create a SoftwareSerial object
// using pin 10 to receive (RX) and pin 11 to transmit (TX).
#ifdef SERIAL_PORT_HARDWARE_OPEN
#define servoSerial SERIAL_PORT_HARDWARE_OPEN
#else
#include <SoftwareSerial.h>
SoftwareSerial servoSerial(10, 11);
#endif

// Set up a servo object, specifying what serial port to use and
// what ID number to use.
//
// WARNING: Only change the ID number below to a servo that can
// rotate freely without damaging anything.
XYZrobotServo servo(servoSerial, 128);

const uint8_t playtime = 75;

void setup()
{
  // Turn on the serial port and set its baud rate.
  servoSerial.begin(115200);
}

void loop()
{
  delay(2500);
  servo.setPosition(475, playtime);
  delay(2500);
  servo.setPosition(525, playtime);
}

These the main code I am concerned about is the second one about setting position. All the example codes in the xyzrobot library do not do anything aside from the first one I posted above.

Hi, Thanks for the info. OPs image; |243x500 Have you got the gnd if the Mega connected to the gnd of the servo?

Tom... :)

Have the Red and block wired to a external 12v on a tamiya (red and black as well.)

Dino_flakes: Have the Red and block wired to a external 12v on a tamiya (red and black as well.)

But do you have [u]the negative of the servo power supply connected to the gnd[/u] of the Mega Board. You need a current return for the two signals you are communicating between the servo and the Mega. All I see in your picture are the two comms wires. Tom... :)