Updating Arduino library

Hi, are there plans in place to update the Arduino library? I’ve started adding functions to make it so I don’t have to type out the whole serial string (more like the Python library). Seems like most of the things that appear in the reference are able to be read / written so it seems like a worthy cause to go ahead and write a complete wrapper for Arduino.

I’m happy to contribute if there is an official effort to this end.

1 Like

We can always use more fleshed out examples and functionality in the library. Maybe it makes sense to make an autogenerator from the odrive-interface.yaml? We already generate the enums and so-on, maybe automatically generating a UART/ASCII library makes sense.

2 Likes

Hi, I’m planning to start working on this soon. Can you point me in the direction of an existing autogenerator of the type you mentioned if you know of one, just to get me started?

I suppose doing variations of this could work:

with open('odrive-interface.yaml', 'r') as f:
    doc = yaml.load(f)

# Make CamelCase names for functions
def convert(word):
    return ''.join(x.capitalize() or '_' for x in word.split('_'))

type = None

# Parsing candidates for writeable attributes
for attribute in interface['interfaces']['ODrive']['attributes']:
    try:
        type = interface['interfaces']['ODrive']['attributes'][attribute]['type']
        if type in 'bool float32 uint8 uint32 uint64 int8 int32 int64':
            print(f'void ODriveArduino::{convert(attribute)}({type} {attribute}){{\n\tserial_ << "w {attribute} " << {attribute} << "\\n";\n}}')
    except:
        pass

^ This prints:

void ODriveArduino::IbusReportFilterK(float32 ibus_report_filter_k){
	serial_ << "w ibus_report_filter_k " << ibus_report_filter_k << "\n";
}
void ODriveArduino::TaskTimersArmed(bool task_timers_armed){
	serial_ << "w task_timers_armed " << task_timers_armed << "\n";
}

This is probably a super naive approach, but let me know what you think :slight_smile:

Hi, I have made a simple Odrive library for Arduino (using ASCII protocol) that does not hang while waiting for the Arduino response. It uses callbacks to activate some code when the response is received by the Arduino. @abrown, you can use it as a base for your high level wrapper if you want.

You can find it here: (GitHub - bvtvusn/OdriveLink: This Arduino Library communicates with the Odrive BLDC motor controller. The communication supports checksums. The advantage of this library is that it does not hang if the Odrive does not respond to a command. Instead the callback will just not be called.)

@Wetmelon Is there a need for a library like mine?

1 Like

I guess, but it looks like it makes a stack? It doesn’t seem to know whether the ODrive is returning data out of order.

It is true that the library does not check if the order of the responses is correct. (It uses a queue.) But I guess there is no way it can find out?

So far, my Odrive has responded in the correct order. Does this problem happen often?

When using the library, I use a response timeout time that is less than my main Arduino loop interval. This way, the library “synchronize” each loop, because all waiting callbacks from the previous loop will be too old and are therefore ignored.

Any updates on this? I’m deep into the process of deciding which Arduino library to run with. I went first with clement/ODriveArduino simply because it was available in the PlatformIO registry. It looks like it was intended to be much richer that the official library but so far has only transcribed the official library and introduced some critical and some non-critical bugs.

I was intending on contributing fixes back, but would prefer to combine efforts rather than fragment them. I’m particularly interested in your callback feature, since the official’s blocking calls could be problematic for me. On the other hand, I’d like the library I use to be in a registry, rather than require a zip download, for ease of project maintenance.

I see there’s also a native protocol library effort underway (but early stage?). If the ASCII protocol is lacking some important features (are errors readable?) and the native protocol suits machine-driven UART use (eg. recovers well from missed bytes), then I suppose that’s a contender too.

What are others using for field-ready Arduino comms?

It would be possible to add this library to a registry, but I haven’t seen anyone interested until now.
In my own projects, I might go over to using CAN-bus, because I have had some EMI problems.

Yeah, surely we can’t be the only two driving an ODrive from an Arduino!

I’d prefer CAN myself, but project constraints don’t include a CAN driver. So mitigating UART EMI will do for now. Tolerating bit errors seems like a worthwhile feature of a UART protocol anyway…

So I guess I agree, if there’s not a big call for this, perhaps we can all just do our own thing. But I have to imagine that there’s a bunch of people dropping off early when they can’t find a working library in the Arduino registry and don’t have the desire/ability to import one.

Hi guys,

I like and use the ODrive and I have my own sketches that make things work with Arduino (more or less), and I have plans to invest time into organizing a nice library – eventually. But I have a lot of projects I’m working on, and I tend to prioritize my projects based on the open-sourcedness of the tool that I’m developing for.

I actually agree with the rationale behind ODrive going closed, but in the case that they have high quality devs being paid to be familiar with the ins and outs of the controller and write good software for it, and they seem to be doing well business-wise, I think I’ll make do with my chicken scratch code and contribute with my wallet by buying gear and hope that they prioritize making a full fledged Arduino library eventually.

What’s missing? It needs to get added to the Arduino library registry?

I think you answered this question yourself in your first reply to this thread. Only a fraction of the functionality from odrive-interface.yaml is represented by dedicated functions in the Arduino library.

The result is a lack of consistency in how commands / requests are sent, for instance:

In the example sketch we have motor position being read like this:

Serial << odrive.GetPosition(motor) << '\t';

and then bus voltage being read like this:

odrive_serial << "r vbus_voltage\n";

hraftery, I like the idea, but the implementation seems to use a stack, rather than a queue and I can’t understand how this works if there is more than a single outstanding response when processInputs is called. The RemoveFirst method pops the top of the stack, which is the most recent request pushed. Thus, the newest is always on top and I would think that if responses are roughly queued by the controller, this will get out of sync as soon as two requests are outstanding.

Yeah definitely an opportunity to do it right, with specified behaviour, instead of formalising something untested. I no longer have a project on the books related to this, so have no burning motivation, but more than happy to contribute.