Asked

Lewansol Servos Reporting Inaccurate Degrees In Auto Position Movement

We are using Lewansol servo skill in conjunction with Auto Position skill. We have connected the LX-16A servo on serial UART 1 connected to the EZ-B v4 controller on pins 5 and 6. When we go to "get and set all positions", it sends an incorrect number back for the current degrees that the servo has been set. When the servo is at 1 degree, 90 degrees or 180 degrees, it reports back a degree number that is very close. But when the servo is moved to any degree between 1 and 90 or 90 and 180, the number retrieved from the servo is incorrect by many degrees. Why are the degrees reported back incorrect?


Related Hardware EZ-B v4

ARC Pro

Upgrade to ARC Pro

Take control of your robot's destiny by subscribing to Synthiam ARC Pro, and watch it evolve into a versatile and responsive machine.

PRO
Synthiam
#9   — Edited

I updated the robot skill to v28, which includes testing. But I need you to do me a favor for further testing because I do not have a servo to use...

  1. Update to the latest robot skill version 28

  2. Run this JavaScript again

for (var i = 0; i < 180; i+=10) {

  Servo.setPosition(v1, i);

  sleep(1000)
  
  var resp = Servo.getPositionRealtime(v1);
  
  print("ARC: " + i + " Servo: " + resp);
}
  1. In the robot skill. Click in the LOG text area and press CTRL-A to select all text. 

    User-inserted image

  2. Now press CTRL-C to copy all text to the clipboard

  3. Paste the text into a message here please

#10   — Edited

DJ,

Here is the text from the robot skill,

Connected Events
UART 1 @ 115200bps
UART 1 @ 115200bps
Reading position from V1
UART 1 @ 115200bps
V1: 1 ret: 85,85,1,3,28,223,85,85,1,5,28,122,0,99
Reading position from V1
UART 1 @ 115200bps
V1: 10 ret: 85,85,1,3,28,223,85,85,1,5,28,123,0,98
Reading position from V1
UART 1 @ 115200bps
V1: 20 ret: 85,85,1,3,28,223,85,85,1,5,28,123,0,98
Reading position from V1
UART 1 @ 115200bps
V1: 30 ret: 85,85,1,3,28,223,85,85,1,5,28,162,0,59
Reading position from V1
UART 1 @ 115200bps
V1: 40 ret: 85,85,1,3,28,223,85,85,1,5,28,220,0,1
Reading position from V1
UART 1 @ 115200bps
V1: 50 ret: 85,85,1,3,28,223,85,85,1,5,28,19,1,201
Reading position from V1
UART 1 @ 115200bps
V1: 60 ret: 85,85,1,3,28,223,85,85,1,5,28,75,1,145
Reading position from V1
UART 1 @ 115200bps
V1: 70 ret: 85,85,1,3,28,223,85,85,1,5,28,133,1,87
Reading position from V1
UART 1 @ 115200bps
V1: 80 ret: 85,85,1,3,28,223,85,85,1,5,28,187,1,33
Reading position from V1
UART 1 @ 115200bps
V1: 90 ret: 85,85,1,3,28,223,85,85,1,5,28,243,1,233
Reading position from V1
UART 1 @ 115200bps
V1: 100 ret: 85,85,1,3,28,223,85,85,1,5,28,44,2,175
Reading position from V1
UART 1 @ 115200bps
V1: 110 ret: 85,85,1,3,28,223,85,85,1,5,28,99,2,120
Reading position from V1
UART 1 @ 115200bps
V1: 120 ret: 85,85,1,3,28,223,85,85,1,5,28,154,2,65
Reading position from V1
UART 1 @ 115200bps
V1: 130 ret: 85,85,1,3,28,223,85,85,1,5,28,210,2,9
Reading position from V1
UART 1 @ 115200bps
V1: 140 ret: 85,85,1,3,28,223,85,85,1,5,28,12,3,206
Reading position from V1
UART 1 @ 115200bps
V1: 150 ret: 85,85,1,3,28,223,85,85,1,5,28,66,3,152
Reading position from V1
UART 1 @ 115200bps
V1: 160 ret: 85,85,1,3,28,223,85,85,1,5,28,107,3,111
Reading position from V1
V1: 170 ret: 85,85,1,3,28,223,85,85,1,5,28,108,3,110

This the text from the script,

Start
ARC: 0 Servo: 180
ARC: 10 Servo: 180
ARC: 20 Servo: 180
ARC: 30 Servo: 180
ARC: 40 Servo: 180
ARC: 50 Servo: 180
ARC: 60 Servo: 180
ARC: 70 Servo: 180
ARC: 80 Servo: 180
ARC: 90 Servo: 180
ARC: 100 Servo: 180
ARC: 110 Servo: 180
ARC: 120 Servo: 180
ARC: 130 Servo: 180
ARC: 140 Servo: 180
ARC: 150 Servo: 180
ARC: 160 Servo: 180
ARC: 170 Servo: 180
Done (00:00:22.0461169)

The servo responded in 10 degree movements. But in Auto Position the "Get and Set All Positions" is always returning 180 degrees.

#11  

Thank you for providing the information that DJ had requested. This will help us verify the details of the received packet for the servo. We will be looking at it today and have an update shortly.

#12   — Edited

A new version (version 29) has been posted for you to use, which should correct the issue.

I will explain what is happening so you can see how it works.

  1. If you were to review the datasheet, you would notice a send packet is 7 bytes to request a position, and the return packet is 7 bytes with the response. The UART's TX and RX are connected because the servos use a single wire for bi-directional communication. This means that any data transmitted on the TX from the EZB is received on the RX of the EZB. That is to be expected and is accounted for.

  2. By reviewing each packet, you can see the first 7 bytes and the last 7 bytes. The product datasheet poorly documented the last 7 bytes containing the response. The datasheet defines response indexes 2 and 3 as holding the low and high bytes of the integer. This is incorrect, as most of the LewanSoul datasheet was translated from Chinese and is incorrect. The actual indexes containing the low and high bytes are 11 & 12.

  3. Now, if you were by chance using a TTL/USB Debug Board (which you're not), you would only get 7 bytes in the response packet. The TTL/USB debug board prevents the transmitted packets from returning to the RX buffer. That is why there is a checkbox for it in the configuration screen.

Let's look at a complete packet...

V1: 70 ret: 85,85,1,3,28,223,85,85,1,5,28,133,1,87
  • v1 is in position 70.
  • that means we should have a response from the servo of a position scaled from 1-180 to 0-1000 and relative to position 70
  • I highlighted the 2 bytes that hold the Low and High bytes of the signed 16-bit integer

The two bytes are 133 (low) and 1 (high). If we were to convert those to bytes into a 16-bit integer, we'd get 389

How did we get that?

Well, a 16-bit integer is 2 x 8 bytes.

00000000 00000001 = the value 1
00000000 00000010 = the value 2
00000000 00000011 = the value 3
... and so on
00000001 00000000 = the value 256
00000001 00000001 = the value 257
00000001 00000010 = the value 258

So we have to combine the two bytes and create a single integer; this is done with a simple function such as...

    int word(byte low, byte high) {

      return (int)low + (int)high * 256;
    }

The issue you were experiencing was that the incorrect index positions of the response array were being parsed and converted into the integer. This was due to LewanSoul having an incorrect datasheet.

#13  

DJ,

I tested version 29 and it returns the correct degrees except from 0 to 20 and 170 to 180. It appears to limit to 23 and 157. This is far better and more usable than before. Thank you for spending the time on this.

Start ARC: 0 Servo: 23 ARC: 10 Servo: 23 ARC: 20 Servo: 23 ARC: 30 Servo: 29 ARC: 40 Servo: 40 ARC: 50 Servo: 50 ARC: 60 Servo: 60 ARC: 70 Servo: 70 ARC: 80 Servo: 80 ARC: 90 Servo: 90 ARC: 100 Servo: 100 ARC: 110 Servo: 110 ARC: 120 Servo: 120 ARC: 130 Servo: 130 ARC: 140 Servo: 140 ARC: 150 Servo: 150 ARC: 160 Servo: 157 ARC: 170 Servo: 157 Done (00:00:22.0590857)

PRO
Synthiam
#14  

No need to thank me. Thank Synthiam support for doing the work to fix it. From reviewing the fix, it seems the servo must not be accurate in that range. There’s nothing which can be done to further improve the resolution at the lower end.

by reviewing the log you provided, it shows the servo as returning the same value for the first 20 positions.