Correct, i just tested this and the query do not work.
However the feature itself does. It’s more of a debug thing.
I will probably remove this from my test list… Maybe should be removed from the Wiki page:
Edit: might also want to remove it from your header file:
@kurte
I’d say the best in this case would be to simply send all queries for a specific servo ID back to back (no waiting) and then wait on the responses. The LSS have a large internal buffer for this purpose and can easily absorb the data and then respond to it when able. @cmackenzie probably has more details on this as he’s done quite a bit of work on making his queries as fast as possible!
The delay (and its jitter) from \r of a query to the start of a * depends on where the LSS is in its cycle while it receives the commands. This delay should be minimal since the LSS firmware scheduling was modified to have staggered tasks (i.e.: aside from taking care of input, only 1 major task [internal sensors for voltage/temp/current processing, control code, etc.] should happen on any main loop; the encoder I think happens every 2 ms if I remember correctly).
I think what you are getting here in your data is the measure of a full main loop of the LSS. The very thing the LSS does is check for valid inputs (commands sent with # to \r already buffered). If there are none then the input is not processed until the next loop (which is probably around ~1ms). I am definitely interested in testing this again… though I think I have some posts somewhere on the forum about this…
I’ve also seen those before with a Salaea logic analyzer watching a LSS bus. It drove me mad for hours as to why it was happening… and then I realized that my log in the LSS Config matching those readings didn’t have any errors reported for those values (and instead had the right value reported). Effectively, my logic analyzer was seeing a frame error (due to the high sampling rate) that is probably only a very minor electrical noise (maybe on the line, the internal buffer or something else) that was not detectable by the RX on my USB<>UART / the software. But I certainly could see it in the trace (like you have above):
Maybe reduce your sampling speed to 4 or 8 times the baud rate instead and you’ll get still a very accurate picture of the signal without details that may lead to erroneous conclusions.
Of course, this is separate from obtaining wrong packets completely. On that front, more testing would be needed (just received some stuff, so I can probably get started on that soon!) and I’m certainly curious too.
Well, you literally have all of those traces above in your posts, so we can see what the exact baud rate is (in those transmissions). The specs for the STM32 part used most likely have the exact value (@cbenson ?).
Of course, the crystal inside that is driving those clock probably varies a bit (specs of ±PPM would be great to have) and temperature probably has an impact too. All of those combines most likely give us a range/% of ±error from 250kBaud that we are likely to get. I don’t have all of the details required to calculate this theoretical value at this time though, but it is probably quite low on each section (< 0.5%), but of course all of this accumulates!
edit: forgot to add this great link about this earlier!
According to your numbers above:
Optimal/perfect 250 kBaud is 25 kBytes/s > 40 µs/byte (or character)
query: 196 µs for 5 characters (#1QV\r); so about 39.2 µs/byte
response (part 1): 152 µs for 4 characters (#1QV; so roughly 38 µs/byte
response (part 2): 232 µs for 6 characters (11936\r); so just about 38.6_ µs/byte
We can say that in this test your output is at about 25510.2041 bytes/s or ~255102 Baud, roughly 102.04% of the target speed of 250000.
Similarly, the LSS is also running a bit faster, going at 26315.7895 bytes/s or ~ 263157 Baud (105.26 % of target) to 25862.06897 bytes/s or ~258620 Baud (103.45 % of target). From what I remember, a total disparity (or error) of baud rate of < 5% is typically manageable by most interfaces. With your Teensy at 102% and the LSS at 103.5-105% the total baud rate difference should be acceptable. Though I have seen UART interface that only tolerate 0.5% or even far less!
I’ll definitely want to run some tests on my own LSS to see what I’m getting baud rate wise.
From what I can remember, the LSS does not do any processing/reading of values when queries. The ADC stuff is DMA-driven and writes directly from peripheral to buffers. There’s a scheduled task for processing that is done periodically to update the values (and check safety limits, etc.) and those updated values may be what is used to feed queries, though it is possible the averaging is done in real-time (instead of using previous value) when queried from those buffers, explaining the small gap between first and second part of some query replies?
I think that was added a while back, at first for debugging but maybe it didn’t make it to the current recommended version (368.16.14)?
Check out 368.29.18, I believe that one definitely has it. And by its comment, probably 368.29.16 does too!
Also @kurte, which LSS (hardware release) are you using and which firmware version are they running (maybe this was already detailed somewhere… ) for these tests?
Thanks @scharette -
I am not sure exactly which version of firmware I am running. It shows QF as 368
Yes I have run into this at times, but again I just ran the same test program again and did my query all of a servo function manually 3 times and on 2 of the three servos, the QN error failed, both to my program and likewise under the logic analyzer.
Ran it again with 4 servos, turned on Analog reading as well… Again 2 out of 4 servos failed the QN…
You can see a dip in the area in the analog as well.
And again the program showed error condition:
Cmd: 9 4
Servo 4 values
Q - 1 t:827
QO - 0 t:829
QAR - 1800 t:1061
QP - 1664 t:941
QD - 148 t:900
QWD - 0 t:891
QWR - 0 t:898
QS - 0 t:809
QSD - 360 t:981
QSR - 60 t:942
QLED - 0 t:1016
QG - 1 t:890
QID - 4 t:944
QB - -12144 t:1420
QFD - DIS t:1648
QMS - LSS-ST1 t:1851
QN - (null) failed(2) t:101051
QF - 368 t:980
QV - 12045 t:1198
QT - 342 t:1015
QC - 0 t:886
QA - 0 failed(2) t:99901
QAS - 0 t:895
QAH - 4 t:887
QAA - 100 t:996
QAD - 100 t:1015
QEM - 1 t:915
QLB - 0 failed(2) t:99270
It is interestingly consistent that it often hits this in the exact query… Wonder if maybe something in the servo firmware that mucks quickly with the IO pin or ???
I will hack up a version of this test, remove the QLB and see if it changes… Note: My quick and dirty version for 3 values: Position, voltage and Temp and very little difference… Bu will try again.
Thanks again
Try #[id]QF3\r
That is super interesting! The consistency is weird though.
Unless anything change in the serial code since then (seems like it didn’t) and if I remember correctly, the “header” and “footer” of replies are all pre-compiled and “ready to go” and called from some specific functions, so they are all consistent throughout.
The only part that would change in replies is the forming of the “data part”… But all of this is output through functions that are standard throughout the firmware (i.e.: any other query that outputs a similar type of data should have the same issue).
Well, I’ve received one LSS but still waiting on adapter board , power supply and such, so I’ll check as soon as I receive those on my end and see if I get the same behaviour.
I assume you get this on more than one LSS, right?
It is possible the version of the firmware you are running is doing only one reply per “main loop” instead of responding to all queued up commands all at once. Again, once I have my LSS here I’ll see if there are some old .lss.bin I have somewhere that do this reply part differently.
If you are already running on 368.29.14 try out the .16 version (under experimental) and see if that has any different behaviours.
It returns 68…
Hmm…
Well, you can read about the expected output here.
In theory, if you send QF (no value) or QF0, it returns the major firmware version number, in this case 368.
If you send QF1, it returns the minor version (29 for the recommended).
If you send QF2, it returns the revision (14 for the recommended).
If you send QF3, it returns all of them, such as 368.29.14.
It is weird yours is not. Maybe flash on it the current recommend then. Are you doing these tests on a newer LSS or one from the old beta batch from before?
Looking forward to participate on the testings. Just got a mail from UPS about a package from Robotshop on the way!
Sort of interesting… I had a bug in my dump all registers that added a trailing 0 character to all query functions…
Did not appear to impact much… Still get fails often on serial number…
Add QF1, QF2, QF3 - Fails 1 and 2…
Servo 4 values
Q - 1 t:656
QO - 0 t:758
QAR - 1800 t:1037
QP - 1664 t:918
QD - 148 t:829
QWD - 0 t:868
QWR - 0 t:882
QS - 0 t:790
QSD - 360 t:948
QSR - 60 t:911
QLED - 0 t:958
QG - 1 t:786
QID - 4 t:929
QB - -12144 t:1382
QFD - DIS t:1742
QMS - LSS-ST1 t:1106
QN - (null) failed(2) t:100911
QF - 368 t:852
QV - 12064 t:1115
QT - 363 t:976
QC - 0 t:851
QA - 0 failed(2) t:99186
QAS - 0 t:856
QAH - 4 t:843
QAA - 100 t:918
QAD - 100 t:1003
QEM - 1 t:879
QF1 - (null) failed(4) t:846
QF2 - (null) failed(4) t:809
QF3 - 68.29.14 t:1228
Note: I ask for #4QF1 and the response says *4QF2 so fails
Dito I ask for QF2 and it responds with QF1
But QF3 does give me the whole string:
From your picture above, it seems they all work as expected!
It might be important to clarify that replies to queries only include the letters of a command (it’s identifier), not its parameters (ex: 0, 1, 2, 3 for the QF command).
Yep this is the thing I sort of missed… As Communication Protocol document shows:
Query Commands
Query commands request information from the servo. They are received via the Rx pin of the servo, and the servo’s reply is sent via the servo’s Tx pin. Using separate lines for Tx and Rx is called “full duplex”. Query commands are also similar to action and configuration commands and must use the following format:
- Start with a number sign # (Unicode Character: U+0023)
- Servo ID number as an integer
- Query command (one to four letters, no spaces, capital or lower case)
- End with a carriage return \r or Unicode Character (U+000D)
So I will update my test code to know about not to pass these through as I called off to:
genericWrite(id, “QP2”) and likewise for genericRead_Blocking_s16 (or _str)
@zenta - It will be great when you can join in as well…
Quick update: I tried a read all of the Qwerry commands, two ways. One simply output one and wait, output the next…
And a second way where I try to output as many commands as I can to the device and wait for all of the data to come back
And so far it looks more or less the same timing:
So next up may be to see about updated firmware.
Wondering out laud. With the Serial # query. Wondering if the processor has to do anything strange to get this value. Example with some Teensy boards, I think we have to lower the processor speed temporarily in order to read that area of storage…
Again just wondering out laud.
Sure seems like that current firmware is only responding to one query per cycle (~1/ms).
Can you try with 368.29.16 or .18 and check if the results are any different?
@cmackenzie what firmware version (QF3) are you using currently? If you pack your queries, do you get large gaps too?
If you are only querying session values than they are read from RAM, so nothing weird there. If you specifically request “EEPROM” value, then reading will done from FLASH virtual EEPROM which may potentially be slower, but that does not seem to be the case here.
It really does seem like the main loop is only responding to 1 query/command per loop (which is ~1 ms).
Again, nothing I can test until I can the adapter board & power supply…
Quick update, I updated servos 1-6 to 368.29.18 and I am not seeing any differences in data:
Cmd: 9 10
Servo 10 values
Q(-1) - 1 t:755
QO(-1) - 0 t:865
QAR(-1) - 1800 t:1073
QP(-1) - 1661 t:955
QD(-1) - 145 t:922
QWD(-1) - 0 t:928
QWR(-1) - 0 t:941
QS(-1) - 0 t:850
QSD(-1) - 360 t:1010
QSR(-1) - 60 t:975
QLED(-1) - 0 t:1045
QG(-1) - 1 t:868
QID(-1) - 10 t:1051
QB(-1) - -12144 t:1524
QFD(-1) - DIS t:1712
QMS(-1) - LSS-ST1 t:1184
QN(-1) - 141520944450444303 t:2274
QF(-1) - 368 t:968
QV(-1) - 12049 t:1194
QT(-1) - 363 t:1074
QC(-1) - 0 t:989
QAS(-1) - 0 t:1007
QAH(-1) - 4 t:970
QAA(-1) - 100 t:1044
QAD(-1) - 100 t:1064
QEM(-1) - 1 t:917
QF(1) - 29 t:988
QF(2) - 14 t:990
QF(3) - 368.29.14 t:1287
Total Time: 31549
0 - All Servos off
1 - All Servos center
2 - Set Servo position [<Servo>] <Position> [<Time>]
3 - Set Servo Angle
4 - Get Servo Positions
5 - Find All Servos
9 - Print Servo Values
9 - Print Servo Values fill tx
b - Baud <new baud>
t - Toggle track Servos
h - hold [<sn>]
f - free [<sn>]
m - move all servos
r - Reboot [<sn>]
:
Cmd: 8 10
Servo 10 values
Q(-1) - 1
QO(-1) - 0
QAR(-1) - 1800
QP(-1) - 1661
QD(-1) - 145
QWD(-1) - 0
QWR(-1) - 0
QS(-1) - 0
QSD(-1) - 360
QSR(-1) - 60
QLED(-1) - 0
QG(-1) - 1
QID(-1) - 10
QB(-1) - 250000
QFD(-1) - DIS
QMS(-1) - LSS-ST1
QN(-1) - 141520944450444303
QF(-1) - 368
QV(-1) - 12039
QT(-1) - 364
QC(-1) - 0
QAS(-1) - 0
QAH(-1) - 4
QAA(-1) - 100
QAD(-1) - 100
QEM(-1) - 1
QF(1) - 29
QF(2) - 14
QF(3) - 368.29.14
Total Time: 30058
0 - All Servos off
1 - All Servos center
2 - Set Servo position [<Servo>] <Position> [<Time>]
3 - Set Servo Angle
4 - Get Servo Positions
5 - Find All Servos
9 - Print Servo Values
9 - Print Servo Values fill tx
b - Baud <new baud>
t - Toggle track Servos
h - hold [<sn>]
f - free [<sn>]
m - move all servos
r - Reboot [<sn>]
Probably it for tonight
I am using 368.29.18. I am getting a lot of communication failures too. 30% of my transactions to be exact on all 3 buses. I remember I was getting about 3% or so a few months ago, I dont exactly recall. 3% is not ideal but acceptable when I am running at 30Hz update rate it’s not noticeable. Two things changed since though. (1) I had to reinstall the OS on the RPi and I might have previously optimized the serial ports better and (2) I upgraded to 368.29.18 a few months ago.
I’ll be watching this thread keenly.
What were you running before?
That seems ridiculously high…