LSS-4DOF Robotic Arm - Unable to Communicate via Standard ASCII Serial (Linux User)

Hello,

I recently purchased an assembled LSS-4DOF Robotic Arm from Lynxmotion (via RobotShop). According to the product description, the unit was manufacturing tested.

I am working from a Linux (Ubuntu 22.04) system and attempting to communicate directly with the arm via standard serial ASCII commands over /dev/ttyUSB0 (using 115200 baud).
I have verified:

  • USB detection and device enumeration (ttyUSB0 present).
  • Correct Linux serial drivers (ch341 loaded).
  • External servo power is connected and stable.
  • Serial connection opens successfully using picocom or screen.

When sending standard ASCII queries (e.g., #254Q + Enter), the device responds only with unreadable characters (garbage data).
I have clinically tested different baud rates (9600, 57600, 250000) with no success.
Only at 115200 baud do I receive any characters — but they are not valid responses.

I do not have access to Windows, and therefore cannot use the FlowArm software.

My goals:

  • Confirm if the unit is stuck in a special mode (e.g., FlowArm protocol, bootloader).
  • Understand if there is a way to reset the LSS servos or LSS Adapter back to standard LSS ASCII command mode.
  • Proceed with direct ASCII control from Linux or Raspberry Pi.

Any help or official guidance would be greatly appreciated.

Thank you!

Jasmine

Hi Jasmine,

Welcome to our RobotShop / Lynxmotion community
!!

Looking in your order you got the “Assembled” version of the 4DoF arm which, indeed, should have been tested.

However sending a “#254” command address all servos as the same time and they will also try to answer all at the same time which gives you unreadable characters.

Try to talk to One servo at a time based on the IDs on the wiki.
Ex: #1Q

All the best,

2 Likes

Hi dialfonzo,
Of course, silly me! Yes, it’s all working now.
Thank you so much.
Jasmine

1 Like

Hi Jasmine,

There is a trick if you want to query or address multiple servo at once by creating Groups.
If that’s something you want to do.

Thanks for contacting the RobotShop / Lynxmotion support center.

Here’s a clear explanation of Group Commands and Slots based on LSS Firmware v370 and the LSS Communication Protocol:


:small_blue_diamond: Group Commands

Group commands allow multiple servos to receive and respond to a single serial command without bus contention.

:white_check_mark: Why use Group Commands?

  • Efficient communication
  • Avoids response collisions
  • Speeds up multi-servo queries or updates

:white_check_mark: Example (Using Direct IDs):

#0QD#5QD#10QD\r
  • Asks servos with IDs 0, 5, and 10 to send back their positions.
  • They’ll all try to reply at once (can cause collisions unless managed).

To combine position + current in a single line:

#0QD0QC0#5QD0QC0\r
  • 0 after each command separates them properly.
  • Servo 0 and 5 each report position (QD) and current (QC).

:small_blue_diamond: Auto Baud Rate (ABR)

Lets servos automatically detect the baud rate on power-up.

  • Enable once:
#254ABR1\r
  • Enable, and re-enable after 30s inactivity:
#254ABR2,30\r

:warning: ABR is not compatible with LSS Config software currently.


:small_blue_diamond: Delayed Query Response

Used to scan the full bus without response collisions.

#254QID120\r
  • Sends a global query for servo IDs.
  • Each servo waits: 200ÎŒs + ID * 120ÎŒs before replying.
  • Helps prevent collision when querying all IDs.

:warning: #254QID with no parameter risks conflict (kept for backward compatibility).


:small_blue_diamond: Slots System

Slots allow you to assign a logical index (slot) to each servo for safe group communication.

:white_check_mark: Why use Slots?

  • Prevents bus collisions during group queries
  • Useful when servo IDs are not sequential

:hammer_and_wrench: Setup Example:

Let’s say your servos have IDs: 0, 5, and 10.
You want them to be Slot 0, 1, and 2, respectively.

#254SLOTCOUNT3\r   // Defines 3 slots total
#5SLOT1\r          // ID 5 → Slot 1
#10SLOT2\r         // ID 10 → Slot 2

(ID 0 defaults to Slot 0 so it doesn’t need to be set)

:white_check_mark: Group Query by Slot:

#254QD\r
  • Queries all slots for position (QD)
  • Responses are auto-delayed based on slot order
#254QD0QC0\r
  • Queries all slots for position + current

:mag: Summary: ID vs Slot

Feature ID-based Slot-based
Setup Effort Low (default) Needs manual config
Collision Risk High None (delayed)
Sequential Needed? Yes No
Reconfig on Power-Up? No (slots reset) Yes (set at each power-up)

Would you like a diagram showing slot setup vs ID communication?

2 Likes

Hi dialfonzo,

Thank you so much for suggesting that, I didn’t know the group commands and slots, super helpful, lots for me to learn.
All servos talking to me nicely, (except the ID returns nothing), but as I was trying to figure out the positioning calibration on servo1 (the base that turn the round table), it yanked the cable out or the cable got caught. Sorry, beginners error, despite I was being very careful, not triggered happy. As it was stuck, red light flashing, I powered off and had to gently moved the base (connected to the servo) to untangle the cable and base. That resulted in now that, the servo 1 when I query its QP, gave me -2500 or 2500 after each stop irrespective where it stopped. It does not know where it is. I managed to figure out to start it at 0, then 90, 180, 270, 360, clockwise and anticlockwise. Then it moved completely fine but it still lost its own positioning to report back. My goal is to programme all 5 of them in the future, so I need reliable understanding on the max, min ranges of it etc. Anyway, I had a good search on the Lynxmotion wiki (sorry I am not very good in finding things there), I think the best solution is to install a VM with Windows, then try to configure it using the LSS configure software, and hopefully reset the servo 1 mapping back to how it was (not sure if I can or not). As there are 5 of them, I think I need that configuration software if I am stuck again. That’s where I got to now.

A long answer to your question, I would love the diagram showing slot setup vs ID comms, but I am still at baby 0 step. Hopefully remove the -2500 and 2500 positioning that would be a nice start. :slight_smile:

Let’s break it down in sections
 :slight_smile:

You had an issue where the base moved and got caught.
The red flashing is over-torque protection and should just recover by a reset or you cand send a “LIMP / #1L” command.

When you query QP on the base 1 servo, it gives you either -2500 or 2500.
The QP was made for some backward compatibility with RC Servo code, you should use QD to get the real position. If the motor move and stop it’s position encoder work so it’s software related. Maybe you found a bug for the QP which is almost never used.

Understanding on the Max and Min range
What do you mean by that ?

Explain what you try to achieve and maybe I can help out.
You might want to change the Origin Offset (essentially the zero) as well as Angular Range.

Let me know
!!

2 Likes

Thank you so much! Yes, you are right, I did not realise red flashing was the over torque protection, good to know it’s there. I did change the offset to 0, it was not too bad at -8. The QD command makes more sense now, reporting accurately every tme.
The min and max value is because I am still trying to orientate myself the degree, which way it sweeps, just learning about the virtual angular angle now. So, I want to make sure when I hooked up all the servos (full 4DoF), I won’t accidentally send an overshot command to one of the servo and damage it. So, to establish what is the max and min for each servo (I might be wrong, just in my simple head for now), when I code it up later, I will make sure all commands must be within that safe range zone for each servo. For example, I don’t need servo 1 to be 4800 sweep anyway, I think the min max range would be around -45degree to + 45 degree, so the cable won’t yank out again. The speed is currently set at 60. I will look to slow it down a bit. So, my immediate goal is just to get the min max range like this for each servo working within a safe range. Nothing fancy just yet. :stuck_out_tongue:
Btw, I did manage to install VM Window and got the LSS configuration software running on my Linux. Definitely not without a fight though, as it is Windows. :sweat_smile:

Can I please ask the LIMP / #1L function? Does it disable the servo’s torque? Once it’s disabled, can it be enabled again? Also, for the soft RESET, back to default values. What are the default values?

Thanks again for your time and advice.

1 Like

If you manually move the servos, you can do an M ove in Degrees (relative) command which is going to move From the current position.
That way you can move just a little and understand which way it’s turning.

If the rotation is not intuitive you can change it as well with G yre Direction

The L imp function will indeed disable the servo making it free turning. Any new commands will get it back moving or you can also use a H alt & Hold command.

Reset will not default the servo, just a soft reset / reboot.

You can do a Default Configuration but it requires a Confirm Changes right after and be prepare to assign the ID back as it’s clearing everything.

You might want to explore the * Command List table on the wiki.

:slight_smile:

2 Likes

Thank you for the super tips again, I will definitely try as you suggested. I have been actually looking at the command list table, some are a bit cryptic for me. More for me to explore. Thank you for your time, making my first post on this community so welcomed. :smile:

1 Like

Another important thing would be to limit the speed and/or use Time commands.

EX: #1MD900T2000
That would result in a movement of 90.0degrees and will be done in 2s total.

2 Likes

Thank you again, that is very helpful. :+1:

I am new here, I bound to have more questions later. Can I continue here or do I need to start a new topic? Please advice. It will all be obsessively about this 4DoF arm :laughing: I am very happy to put a new seperate topic though. Basically, I am exploring LSS commands at the moment. Then I will write a few scripts to automate it for me, so I can save some fingers pressing the cutecom! Once I got further, I would like to get my Raspberry Pi 5 to talk to it, then add a few other bits as it gets more exciting :crossed_fingers:. That’s the general direction.

The best is to continue here so I will be notified if you make a reply.
It’s also useful for anyone with the same project / questions etc


:slight_smile:

2 Likes

I have tested commands like H, RW, G, MD, T, all the them worked as expected, except this one:
MD+T e.g., your example EX: #1MD900T2000
This does not work, it moves MD (relative to its current position), but it does not slow down. (i.e., the same as #1MD900). However, I tried
#1D900T2000 and #1D-900T2000 both work as expected. But, this only moves to the position (not relative) of course. Is there something I need to fix?

I regularly check the #1QD and #1Q, after I have done a few moves, sometimes, it return *1Q6, or *1Q8, but mostly *1Q6. And the position *1QD is always a bit off (e.g., it started off *1QD0, then after a few moves, it becomes *1QD4, this is for the 0 degree position, I use that as a reference). These behaviours are normal, right? Do I need to do CO configure the offset after a few moves? &/or every time I power it on? As I have *1Q6, do I need to do #1CO-6 in order to get this back to 0 offset?

I have not screwed the base down firmly onto something yet, I have it sat on a fairly think silicon mat, it is sitting stable but will move slightly after a few moves/a spin. :smile:

Just tested it and your are right, the T modifier do not seems to be effective over MD.
That’s a bug but also not something most people use (MD).

The #1Q will return the status of the servo so 6 is pretty normal, holding.
If you have a status 8 it’s stuck probably on over current / over torque. È

When sending a #D900 you want the servo to go at 90.0deg and the servo with “try” to reach it with it’s internal PID system.
Things will impact the end position like the mechanics and it could sag a bit as well so having a little difference is normal.

If your position was “0” and you get *QD0 or *QD4 you are 0.4deg away from zero which is not bad depending on the mechanics.
Just moving the servo by hand will give you greater differences, I think. No need to adjust the Origin Offset.

The origin offset is required because the sensor in the servo is capable of reading 360° continuously (i.e., multiturn).

This means the servo itself doesn’t have a predefined “zero” point — it simply reports its current position based on its internal reading. You could technically use the default CO0 (current origin at 0) and accept the current mechanical position as your reference, coding your application accordingly. However, in most cases, it’s much easier and cleaner to set a mechanical zero that makes sense for your setup and apply an origin offset to align the servo’s internal reading with that position.

This simplifies calibration, repeatability, and application logic.

2 Likes

Hi, it’s me again. :sweat_smile:

I have done some testings on 5 servos, they all move independently and nicely as I expected. e.g.,
1D450T2500#5D00T2500#3D287T2500#2D-600T2500
I then wanted to focus on just 1 servo, my goal is to stream some command down (could be an array) depending on image processor module that processed video/images. I have done a separate interrupt (#254H or just hard stop) in case things go south, all working fine. But first, I wanted to stream a short command down first like this:
#5D00T2500#5D-270T2500
I notice that, the gripper was already in open state (i.e., at -270), this command got ignored. However, with the gripper stays open, I send this command down
#5D-270T2500#5D00T2500, this time the gripper did shut as I expected.
I have done similar testing to other servos, they all behaving the same.
This tells me, (please do correct me if I am wrong), the execution to the command is state-dependent. I have even gave it a waiting time, before I sent down the command, still did not work. I then executed multiple commands and change it mid way (i.e., before it even finished its last command), it did respond to the latest command without delay (which is very nice!) but it has to be the opposite of its current physical state. If the command happens to be the same as its current physical state, otherwise it just got completely missed/ignored, and any trailing commands were also ignored.
Also, I notice in this batch command mode, the command at the tail end overrides the command at the front
if the commands are for the same servo.

Is my understanding correct? Sorry, it may sound trivial, but I was never intended to use it to manually send command down one by one :sweat_smile:. I was hoping to stream commands down depending on the images processed. So, does it mean I need to check its current physical state at any one point in time? or I just keep sending command message one at a time? then any trailing won’t get missed. Or is there a better way to do this? Hope this makes sense. I don’t mind coding any workaround, just want to avoid unnecessarily work due to my lack of understanding. Many thanks for your kind help again. :nerd_face:

I’m not 100% certain I understand.
But if you send two commands on the same line, for the same servo, the last one will be the one used.

That’s how servos work usually, it’s not a pool of moves that’s sent and processed internally.
You have to send your moves yourself, but you don’t necessary need to look for the position if not needed.

2 Likes

Thank you - sorry I did not ask my question clear. Because the commands I will send down, will be automatically generate and sending/streaming down to the arm live. Your answer helped me to confirm how I should build the commands send module.
Separately, I have found some good info online in terms of the physical dimensions of the arm for each link (servo to servo), torque and other specs. Do you happen to know whether there are any mass/weight of each link? The reason I am asking this, I am intending to build a small physic model of this arm to simulate all possible positions. I have found one servo is around 74g on the RobotShop website. Do you know if each joint (the long rod bit :stuck_out_tongue:) what materials they are made of? If not, it’s okay.

1 Like

No worries, I was just uncertain of what you were asking. Glad my answer helped
 lol
:slight_smile:

If you want you can download the CAD file on the product page HERE.

  1. Servos
  2. All brackets are made of Aluminum as well as the Tube Clamp
  3. Tubes are made of Carbon Fiber

image

1 Like