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

With ARC Pro, your robot is not just a machine; it's your creative partner in the journey of technological exploration.

PRO
Synthiam
#1  

Looking at the robot skill code, it seems the resolution of the lewansoul is between 1 and 1000. Can you confirm this is correct? Is there a manual for your product or datasheet that defines the number of servo positions?

      getServoResponse.Position = (int)EZ_B.Functions.RemapScalar(BitConverter.ToInt16(ret, 11), 1, 1000, Servo.SERVO_MIN, Servo.SERVO_MAX);

I would have expected it to be between 0 and 1024.

PRO
Synthiam
#2   — Edited

Also, something interesting is the COM and EZB Uart functions seem to differ in the robot skill. One reverses the response before parsing the uint16. I'm not sure why they did that - but I can have a new version built for you once you let me know about the resolution from the datasheet. Is it betwen 0-1000? or 1-1000? etc...

Once we get that answer, i can look at the reverse and see what's up. I might have to update it a few times until we get it right because we don't have that servo.

EZB UART

      getServoResponse.Position = (int)EZ_B.Functions.RemapScalar(BitConverter.ToInt16(ret.Reverse().ToArray(), 0), 1, 1000, Servo.SERVO_MIN, Servo.SERVO_MAX);

Serial COM

      getServoResponse.Position = (int)EZ_B.Functions.RemapScalar(BitConverter.ToInt16(ret, 11), 1, 1000, Servo.SERVO_MIN, Servo.SERVO_MAX);
PRO
Canada
#3  

It appears there might be a discrepancy in how the servo's position resolution is being interpreted within the LewanSoul servo skill for the EZ-B v4 controller. The resolution of the LewanSoul LX-16A servo is indeed crucial for accurately mapping the servo's reported position to the expected degree range (0-180 degrees for standard servos).

The code snippets you've provided suggest that the servo's position is being remapped from a range of 1-1000 to the standard servo degree range. This remapping is essential for converting the servo's internal position representation to a more understandable degree format. However, the exact resolution range (whether it's 0-1000, 1-1000, or 0-1024) needs to be confirmed against the LewanSoul LX-16A servo's datasheet or manual.

The difference in handling the byte order (ret.Reverse().ToArray()) between the EZB UART and Serial COM methods is intriguing. This could be related to the endianness of the data received from the servo. Endianness refers to the order of bytes in a multi-byte value; different systems may use different byte orders, leading to discrepancies if not handled correctly.

To address the issue of inaccurate degree reporting:

  1. Confirm the Servo's Resolution: Check the LewanSoul LX-16A servo's datasheet or manual to confirm the exact resolution range it uses. This information is crucial for accurately mapping the servo's position.

  2. Adjust the Remapping Range: Once the correct resolution range is confirmed, adjust the remapping range in the code accordingly. This adjustment will ensure that the servo's position is accurately converted to degrees.

  3. Review Byte Order Handling: Investigate why the byte order reversal is applied in the EZB UART method but not in the Serial COM method. It might be necessary to standardize the approach based on the servo's communication protocol specifications.

  4. Iterative Testing: As mentioned, iterative updates and testing may be required to fine-tune the remapping and byte order handling until the reported degrees accurately reflect the servo's position.

If you don't have access to the LewanSoul LX-16A servo's datasheet or if the issue persists after making the adjustments, consider reaching out to LewanSoul's support for more detailed technical specifications or assistance. Additionally, the Synthiam community and support team can be valuable resources for troubleshooting and obtaining further guidance.


I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.
PRO
Synthiam
#5  

Okay, can you give me the output of this JavaScript code...

(I'm using v1 port, but you'll need to change it to your port if it's not v1)

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

  Servo.setPosition(v1, i);

  sleep(1000)
  
  var resp = Servo.getPositionRealtime(v1);
  
  print("ARC: " + i + " Servo: " + resp);
}

The output should look like this...

Start
> ARC: 0 Servo:1
> ARC: 10 Servo:10
> ARC: 20 Servo:20
> ARC: 30 Servo:30
> 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
Done (00:00:17.2250414)
PRO
Synthiam
#6   — Edited

Hey there - when you get a chance, can you give me the output of my above example? I want to make sure we fix this up.

To add context to the request. The list of positions will help me understand if it's a rounding/scaling error or if the bits need to be flipped. I'm not certain why they're flipped in one of the conditions in the robot skill - so I'm not sure which one is correct. Seeing the list of positions from that query will help us fix it.

#7   — Edited

DJ, This is the output from the the script that I received.

Start
ARC: 0 Servo: 18
ARC: 10 Servo: 18
ARC: 20 Servo: 18
ARC: 30 Servo: 11
ARC: 40 Servo: 1
ARC: 50 Servo: 82
ARC: 60 Servo: 72
ARC: 70 Servo: 62
ARC: 80 Servo: 52
ARC: 90 Servo: 88
ARC: 100 Servo: 124
ARC: 110 Servo: 113
ARC: 120 Servo: 104
ARC: 130 Servo: 93
ARC: 140 Servo: 175
ARC: 150 Servo: 165
ARC: 160 Servo: 157
ARC: 170 Servo: 157
Done (00:00:21.9617503)

The servo moved to different positions but as you can see they did not report back correctly.

PRO
Synthiam
#8  

Ah perfect! Thank you. That leads me to believe it might be the reverse bits. Let me run a test and get a new build out.

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.