ASCII commands makes ODrive unreachable


#1

Hi all,
I try to connect the output of a simulator software to ODrive.
My setting is a 3.5 board with the latest devel branch. Connected is a KEDA motor with mounted AMT102.

The startup sequence is running fine and the motor resposes to the commands through a serial connection.
Everything looks good till this point.

This is the UI of the simulator software:

As you can see, the software sends a initial positioning command, waits for 1 second and starts to send positions every 50ms.
ODrive sets the motor to the initial position and after getting some of the commands, it stops responding.
hex(odrive0.axis0.error) shows nothing, the software hangs.

If you want to test this, use HTerm, it’s a pretty terminal programm for serial connections.
Make a file with just one command like: p 0 32000 0 0 (+CR)
In Hterm you can send this file coninuously.

grafik

As shorter the delay between the repetitions, as earlier ODrive hangs.

I don’t know how to debug the code with VS Code, setting stop points…
Maybe somebody can tell me what I can try to get this running.

Thanks / Zennix


Simulator rig with ODrive
Reset needed between two UART transmission
Serial Timeout Issue
#2

Hi,

I clicked a little app together to get a better test. You need dot net 4.6.1 to run it.
https://drive.google.com/open?id=1kKuIi_Zo5Npc25uD6jVV-5sX5PyVmX6X

grafik

you can send your commands in defined intervalls and repetitions.

greetings / Zennix


#3

Hi all,
after some more digging I found, that remarking the following block in ascii_protocoll.cpp solves the problem.

else if (cmd[0] == 'w') { // write property
        char name[MAX_LINE_LENGTH];
        char value[MAX_LINE_LENGTH];
        int numscan = sscanf(cmd, "w %" TO_STR(MAX_LINE_LENGTH) "s %" TO_STR(MAX_LINE_LENGTH) "s", name, value);
        if (numscan < 1) {
            respond(response_channel, use_checksum, "invalid command format");
        } else {
            Endpoint* endpoint = application_endpoints_->get_by_name(name, sizeof(name));
            if (!endpoint) {
                respond(response_channel, use_checksum, "invalid property");
            } else {
                bool success = endpoint->set_string(value, sizeof(value));
                if (!success)
                    respond(response_channel, use_checksum, "not implemented");
            }
        }

I know, that block shouldn’t be used, without sending a “w”. But that’s what I found. After remarking it, I was able to send thousands of commands with a distance of 10ms. I’m not really confirm in programming ST32, maybe somebody can tell me why that happens. Maybe the If else is to long and the serial receive interrupt fires before the routine is finished.

Greetings / Zennix


#4

Hi Zennix,

I think I may have the same problem as you do (explained here).
So I was wondering what you mean by “remarking” the block of code ? Did you suppress the “else if” so that this block is always called even when you don’t send “w”?
So I guess that if this is what you do, it means that you can only write property, but you can’t read anymore.

Thank you for your work!


#5

Hi CFluck,

looks like, we have the same problem. I commented out the hole block shown in my post, so everything is used but ‘w’.
I couldn’t test if removeing other unused parts of the function will fix it too.

Greetings Zennix


#6

Hi Zennix,

Thank you for answering!
did you also try to read out some parameters ? or did you just send position commands ?


#7

Hi CFluck,

sorry, no. My use case only sends position commands.

Greetings / Zennix


#8

@Zennix I have made a github issue for this bug. Can you please keep your test probram available at that google drive link, and we will use it when we get to addressing this issue.

Thanks.


#9

Hi,
sure, I will keep it available.

Greetings / Zennix