1

I bought Feetech SCS09 smart servos (also known as SCS009 or SCS0009).

Please note that these servos are not regular PWM servos, they are devices that communicate with board using Serial connection via device named TTLinker that converts UART to half duplex protocol. So the question is about the problem with serial communication only.

The seller provided me Arduino library to work with the servos.

The simplest testing sketch looks as this:

#include <SCServo.h>

SCServo SERVO;

void setup() {
  Serial2.begin(1000000);
  SERVO.pSerial = &Serial2;
  delay(500);
  SERVO.EnableTorque(1, 1);
  SERVO.EnableTorque(2, 1);
}

void loop() {
  SERVO.WritePos(1, 1023, 4000); // Servo ID:1, rotate to the position:0x2FF
  SERVO.WritePos(2, 1023, 1000); // Servo ID:2, rotate to the position:0x2FF
  delay(4000);
  SERVO.WritePos(1, 20, 3000); // Servo ID:1, rotate to the position:0x000
  SERVO.WritePos(2, 20, 1000); // Servo ID:1, rotate to the position:0x000
  delay(3000);
}

The code works perfectly on Arduino Mega and allows to independently control servos.

But with Due I have problems: not all commands can be performed. So if compile the code for Due only servo ID1 works, but ID2 do not work at all.

When I add delays between commands the servos started to work

    SERVO.WritePos(1, 1023, 4000); // Servo ID:1, rotate to the position:0x2FF
    delay(10);
    SERVO.WritePos(2, 1023, 1000); // Servo ID:2, rotate to the position:0x2FF
    delay(4000);
    SERVO.WritePos(1, 20, 3000); // Servo ID:1, rotate to the position:0x000
    delay(10);
    SERVO.WritePos(2, 20, 1000); // Servo ID:1, rotate to the position:0x000
    delay(3000);

When I set delays between 1 and 9 the both servos can work but sometimes skip commands. Servos can skip 1-4 actions and then start to work again. The less delay I set the more random skips I get.

So I think here is some specialities regarding Serial connection on Arduino Due. What It can be? Why delays help to make it working?

By the way I read that Arduino Due can have problems with 1000000 baud rate and I tried different, even significntly less baud rates (for example 38400) with Arduino Due: the result is the same.

I need to explain how WritePos function works in the library

int SCSProtocol::WritePos(u8 ID, u16 Position, u16 Time, u16 Speed)
{
    return writePos(ID, Position, Time, Speed, INST_WRITE);
}

int SCSProtocol::writePos(u8 ID, u16 Position, u16 Time, u16 Speed, u8 Fun)
{
    flushSCS();
    u8 buf[6];
    Host2SCS(buf+0, buf+1, Position);
    Host2SCS(buf+2, buf+3, Time);
    Host2SCS(buf+4, buf+5, Speed);
    writeBuf(ID, P_GOAL_POSITION_L, buf, 6, Fun);
    return Ack(ID);
}

void SCSProtocol::Host2SCS(u8 *DataL, u8* DataH, int Data)
{
    if(End){
        *DataL = (Data>>8);
        *DataH = (Data&0xff);
    }else{
        *DataH = (Data>>8);
        *DataL = (Data&0xff);
    }
}

int SCSProtocol::Ack(u8 ID)
{
    if(ID != 0xfe && Level){
        u8 buf[6];
        u8 Size = readSCS(buf, 6);
        if(Size!=6){
            return 0;
        }
    }
    return 1;
}

void SCSProtocol::writeBuf(u8 ID, u8 MemAddr, u8 *nDat, u8 nLen, u8 Fun)
{
    u8 msgLen = 2;
    u8 bBuf[6];
    u8 CheckSum = 0;
    bBuf[0] = 0xff;
    bBuf[1] = 0xff;
    bBuf[2] = ID;
    bBuf[4] = Fun;
    if(nDat){
        msgLen += nLen + 1;
        bBuf[3] = msgLen;
        bBuf[5] = MemAddr;
        writeSCS(bBuf, 6);

    }else{
        bBuf[3] = msgLen;
        writeSCS(bBuf, 5);
    }
    CheckSum = ID + msgLen + Fun + MemAddr;
    u8 i = 0;
    if(nDat){
        for(i=0; i<nLen; i++){
            CheckSum += nDat[i];
        }
    }
    writeSCS(nDat, nLen);
    writeSCS(~CheckSum);
}

int SCServo::readSCS(unsigned char *nDat, int nLen)
{
    int Size = 0;
    int ComData;
    unsigned long t_begin = millis();
    unsigned long t_user;
    while(1){
        ComData = pSerial->read();
        if(ComData!=-1){
            if(nDat){
                nDat[Size] = ComData;
            }
            Size++;
            t_begin = millis();
        }
        if(Size>=nLen){
            break;
        }
        t_user = millis() - t_begin;
        if(t_user>IOTimeOut){
            break;
        }
    }
    return Size;
}

int SCServo::writeSCS(unsigned char *nDat, int nLen)
{
    if(nDat==NULL){
        return 0;
    }
    return pSerial->write(nDat, nLen);
}

So the problem is somewhere here: Arduino Mega works good, but it seems like Arduino Due have no time for on of the operations.

You can see more info here:

Servo

TTLinker device

Arduino library

  • Please tell the name of the seller, give a link to your servo motors, give a link to the library that you use and to TTLinked. We would like to look into the hardware and library that you use, but then we have to know what you have. – Jot Jul 4 '17 at 5:12
  • I added links to my post, you can check, thanx – Sergey Kravchenko Jul 4 '17 at 8:37
  • This is a tough problem. The TTLinker uses 5V signals, and the Due uses 3.3V signals, so you do need indeed a level converter. Can the level converter do 5V to 5V ? to try the Mega board via the level converter ? Do you use a fast logic level converter ? or a weak slow open drain level converter for I2C ? The way you describe the problem is most likely a software problem. The Arduino Due uses 32-bits integers, and the Mega 16-bits. However, I can't find a problem with 32 versus 16 in the library. With a logic analyzer you can get more information and get a little closer to the problem. – Jot Jul 4 '17 at 10:51
  • I have no experience of the Due, but I have just noticed that Tx0 has a higher max output current (15mA) than Tx1 (3mA), could that be having an affect? – Code Gorilla Jul 4 '17 at 11:45
  • Jot, I use this level converter ali.onl/CdL based on TXS0108E, I will try it with Mega to figure out whether it is the converter problem or not – Sergey Kravchenko Jul 4 '17 at 13:25
0

I figured out that 250000 baud rate is the only choice for the Arduino Due with these servos. Less baud rates cause skips on Arduino Mega also, so this speed is not enough for fast data transfer.

Higher baud rates work good on Mega too but cause garbage on Due.

So let's summarize: these servos with TTLinker (TXS0108E) work good with Arduino Due at 250000 only and with Arduino Mega at 250000 and higher baud rates.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.