Go Down

Topic: Control toy chainable servo without datasheet (Read 473 times) previous topic - next topic

PAlex02

Feb 09, 2018, 11:04 pm Last Edit: Feb 09, 2018, 11:12 pm by PAlex02
Hi everyone,

I recently got a broken toy (Robot alpha 1s).
The main board is dead, but the 16 smart chainable servo motor are still good.

I am looking for a way to control them, but i haven't any documentation or datasheet (because it's a toy, and not an opensource one). The servo have no model number, but after some research, i have find them here : link
But the constructor didn't answer to my mails :/

have you any idea of how can i make them work ? (3 wire GND/Data/VIN and earch servo has an ID write on it).

Maybee somehow try to write / read on all the byte of the range in a big loop ?
May i use onewire to connect to it ? (already try but without succes).

Thanks ! (Sorry for any spelling mistakes, English is not my native language)

slipstick

That looks like a fairly standard hobby servo that can be driven with the Servo library. Try the example programs Sweep or Knob from the IDE.

Steve

PAlex02

Well not realy :/
Every servo has an unique ID write on it, and they are all plug on the same line, like a dynamixel.



PAlex02

#4
Feb 10, 2018, 11:30 am Last Edit: Feb 11, 2018, 12:54 am by PAlex02
Thank's ! it's the same constructor, if i am lucky, the commands will be similar :)

But i still dont realy know how to send this hexa value to the motor from an adruino code.

I have try pluging the data pin of one servo on the arduino TX, and write hexa on the serial port like that :


Code: [Select]

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

void loop() {

  //Head
  Serial.write(0xFA);
  Serial.write(0xAF);

  //Data
  Serial.write(0x0B); // Servo ID 11
  Serial.write(0x01); // Go to
  Serial.write(0x01); // Value
  Serial.write(0x0A);
  Serial.write(0x00);
  Serial.write(0x01);

  //Check & End
  Serial.write(0x18); 
  Serial.write(0xED);
 
  delay(3000);
}



But it didn't work. (and strangely it write text on the serial monitor, whereas RX is not plug).

How can i send this hexa commande, is it possible with an arduino or have i to use some kind of 3 wire TTL board ?

justone

The serial protocol for that is half duplex. Only one device ( servo or controller) can send data at a time.

You will have to manage 2 way communication over 1 line. You send a command and that command may require the servo to send data back to the controller all over just one wire.

The logic level for that servo may be 3.3V as mentioned at the end of that link.

You may want to put a 10K resistor inline on the data line for protection.

Without a controller sending data and reading the data(being able to sniff it) trying to figure out the protocol will be pretty hard to do.


PAlex02

#6
Feb 10, 2018, 11:43 pm Last Edit: Feb 11, 2018, 12:01 am by PAlex02
Okay ! So i need a 5v to 3.3v converter and a 10k resistor between RX and TX, this way ?




For the protocol itself, i have find this document :



It's the datasheet of the USB communication between a pc and the robot.
I know that this is not related to the servo protocol himself, but i have find out that it match perfectly with what the guy of your precedent link read (same hexa value at the same place).

That why i have good hope that it is the same, don't you think ?

MorganS

It seems from the web page that while it is half duplex, you don't actually need to read the acknowledgements coming from the servos.

My question on the code (other than "why isn't it in [ code ] tags?") is How did you calculate the checksum? The servo could be rejecting the invalid checksum.

The USB-to-Serial converter is always plugged into Serial on the UNO, Mega and most other Arduinos. You can send data to a device on the serial pins 0 and 1 and the Serial monitor will also see it. Where you run into trouble is when the device is sending and you also send something on the Serial monitor. That will usually destroy any data sent during that time, from both sources. You also can't see the device's responses on the Serial monitor.
"The problem is in the code you didn't post."

PAlex02

#8
Feb 11, 2018, 12:48 am Last Edit: Feb 11, 2018, 01:11 am by PAlex02
Sorry for the [ code ] tags, i can fix that.

For this one, i have done it by hand :
0x0B + 0x01 + 0x01 + 0x0A + 0x00 + 0x01
= 11    +  1        + 1        + 10       + 0        + 1
= 24 => convert to hexa => 0x18

But i have make multiple attempt with different value, maybe my calculation are wrong ?
And i dont know if Serial.write() is the correct way for send hexa on the serial port ?

You mean that it is suppose to work, even with only the TX wire, as i try ?

What surprised me, is that i got text on the serial monitor with only TX link to the servo (RX link to nothing).

MorganS

Yes, Serial.write(0xAA) is the correct way to write single bytes to the serial output.

I would not bother connecting to the Arduino RX unless you really need to see the servo's response. It may be useful during the debugging phase to use an Arduino with multiple hardware serial so you can send out on a dedicated port and also have a second port listening to what is said on that line.

Well, yes, you get Serial output on the Serial Monitor when you use Serial.write() and the Serial Monitor is connected. With a more advanced Arduino such as a Due or Teensy 3.x this won't happen. The USB serial is separate from the hardware serial. (Both of those are native 3.3V too.)
"The problem is in the code you didn't post."

PAlex02

#10
Feb 11, 2018, 11:29 am Last Edit: Feb 11, 2018, 02:19 pm by PAlex02
So maybee the only problem is that my arduino (Uno) TX is in 5v and the servo data is (maybee) in 3.3v.

I can have this 5v to 3.3v converter on monday : https://www.sparkfun.com/products/12009
I have already use it for i2c, but have no idea if it can do the job for serial at 115200 bps ?

Ok ! thank for the explanation, if i succeed to make them work, buy one of this board native in 3.3v would be a great idea :)

MorganS

Yes, that level converter should work. 115200 is slower than default I2C frequencies. You will still need the pullup resistor on the low-voltage side like I2C.
"The problem is in the code you didn't post."

PAlex02

#12
Feb 13, 2018, 01:08 am Last Edit: Feb 13, 2018, 01:16 am by PAlex02
It work perfectly, thanks a lot ! :)

here is the code :

Code: [Select]
#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

void setup() {
  Serial.begin(9600);
  mySerial.begin(115200);
  Serial.println("start");
}


void srv(char id, char mode, char val){
  int sum = id + mode + val;
  char zero = 0;
  while(sum > 255){
    sum -= 255;
  }
 
  //Head
  mySerial.write(0xFA);
  mySerial.write(0xAF);
  //Data
  mySerial.write(id);
  mySerial.write(mode);
  mySerial.write(val);
  mySerial.write(zero);
  mySerial.write(zero);
  mySerial.write(zero);
  //Check & End
  mySerial.write(sum);
  mySerial.write(0xED);
}


void srvFree(char id){
  srv(id, 2, 0);
}

void srvWrite(char id, char angle){
  srv(id, 1, angle);
}


void loop() {
 
  srvWrite(2, 0);
  delay(100);

  srvFree(2);
  delay(2000);
 
  srvWrite(2, 60);
  delay(100);
 
}



Go Up