I am trying to use multiple ODrives to control a cable robot. The four boards will be fed by a Quanser QPIDe Data Acquisition Device. The Quanser can only give out simple analog outputs. So, my question is multi-faceted.
is it even possible to control both motors of an Odrive with only analog inputs? if so, in what control mode?
how would you test such a system? would it be okay if I just attached a basic circuit (with variable resistance) to the analog input pins and then tested the system using differing resistances? or do I need something that can input a variable voltage?
I donāt know enough about the ODrive to know where to begin, so I am asking here before I start trying to edit firmware (which I assume is necessary to get a system like this working).
Yes that is perfectly possible. The best way is to make some changes to the firmware in Communication, add a make_protocol_function() or make_protocol_property(). From what I understand it is also possible to use the odrv0.config.gpio#_pwm_mapping() functions, but I donāt have experience using them.
You can read the GPIO values from your PC, using stock firmware, and write a control loop in python to test your control solution without modifying the firmware. Should work just fine. Just call odrv0.get_adc_voltage(#).
Lastly; be careful you donāt accidentaly fry any of your GPIO ports. Remember they are 0 - 3.2V (4096 bits). I think they are 5V tolerant, not sure, but the readout will not increase above 3.2V.
Thanks so much for your help. I, however, have no idea what you are talking about with your response to the first part of the question. I donāt know what it means to āadd a make_protocol_function() or make_protocol_property()ā.
After reading your comment @Riewert, this is what I was able to do:
But I guess I shouldnāt have done that before I knew how the functions worked. Nothing seems to have broken, but I canāt control the motor with the voltage input through GPIO3. Right now I just have the ability to vary the voltage input to GPIO3 between 3.3 and 0 volts. But changing the input does literally nothing other than change what I get when I run odrv0.get_adc_voltage(3).
I was able to write a python script that reads the value input to GPIO3 and control the motors through that. This, however, requires that I have a computer connected to each ODrive and have the script running in the background. This makes my processing very slow. The robot I am building needs to input information from the payload to the Quanser, have the computer compute the changes needed and then have the Quanser send commands to the ODrives. This is made significantly slower and more difficult if the output has to go from the computer to the Quanser and then back to the computer to be decoded.
I have tried to read through the firmware documentation but I donāt have nearly enough experience to understand what is going on in there. Any help as to what changes I have to do and where would be amazing. Thank you so much for any assistance you can provide.
No problem, I understand what you are going through.
I have no idea how odrv0.config.gpio3_analog_mapping.endpoint works, but from what your saying, maybe try making a mapping for gpio2 and gpio4. I noticed that the numbering of the GPIOs is not always consistent. I donāt know of anybody who has actually used the mapping functionsā¦ @Wetmelon Also, googleing led me to: https://flipsky.net/blogs/vesc-tool/how-to-use-fsodrive-base-on-odrive-3-14
It seems like the analog_mapping function is not working for me and doesnāt seem super well documented. So I doubt I will ever get it properly working. So, editing the firmware it is.
A slight issue, however, is that I donāt know how to compile the firmware (I actually donāt even know what that really means). I tried to go through the setup guide for windows on the documentation page here. But I donāt know if I downloaded the right materials in the right places because I donāt know how to use them in the first place.
I was able to download the firmware master and I can edit the code. But I am having issues with flashing the experimental firmware to the board. Whenever Iāve tried to flash the new code I bricked the board and had to completely reflash the master from here. Essentially I am asking if I have to compile the whole master (with my updates) into a single .hex file and then flash that? or if it is possible to flash a single .cpp file as an update to the old firmware? I canāt seem to find an answer online because I donāt know really anything about embedded systems.
Once again, thank you so much for all the help you have already given. You probably donāt know how much of godsend this is.
Yes, you need to compile the whole .hex file (even for the smallest changes). The easiest way to do that for me was through Visual Studio Code. How far are you getting with the compilation? Be sure to create a copy of tup.config for you board based on the tup.config.default file.
Also, how are you tranfering your code to the Odrive? Have you tried using the DFU mode over USB, by running odrivetool dfu custom_firmware.hex from the folder where the .hex file is? That works quite reliably for me.
I am currently in the process of working out how to compile the firmware in VSCode. But I ran into an issue that I canāt seem to surpass. I made a post about it here.
I think I correctly copied over the tup.config.default file and made it into a tup.config file correctly.
For flashing the firmware I was trying to use odrivetool dfu (file path) but that resulted in me bricking the board. The tool erased the old firmware and then crashed immediately afterward, resulting in a board with nothing on it. That meant that I couldnāt even run odrivetool dfu to put the firmware back on the board. So, I used the Upgrading firmware with a different DFU tool instructions to restore the firmware. I am more confident in my ability to flash the firmware than to edit it.
The main holdup right now is simply getting the firmware to compile into a flashable hex file. Which I am, slowly, making progress on.
Hi all.
Has there been any update to the analogue input use case since this thread in 2019?
I normally wouldnāt use an analogue input, but for my eBike conversion, it makes sense.
I have a Hall effect thumb throttle connected to GPIO5 (PC4 on the STM32). Is there any easy way to read that and map it to axis1.controller.input_current, or will I need to hack the firmware?
This sets the analog pin up to command between 0 and 10 amps. In my case I had to increase āminā a bit to account for some offset in the thumb throttle.
However, I am using GPIO5, which doesnāt exist. To add it, I simply had to edit Firmware/odrive_interface.yaml (this seems to be a rather nice new feature in the Devel branch, but it has a couple of extra Python dependencies on build)
Well, I can confirm that ODrive works in an e-bike setting.
Thereās a bit of noise induced onto the analogue input when the motor is running faster than a certain speed, and that can cause it to run indefinitely until I stop it with the manual brake.
I could probably fix that with a resistor to GND, since this is a Hall effect throttle, it can probably source enough current for a 10k pulldown without affecting its output value.
Oddly, putting it in INPUT_MODE_TORQUE_RAMP seems to make the problem worse.
Also, Iāve somehow managed to blow one of the 20A automotive fuses that I put in line with the motor phases, even though I have set the analogue mapping max to 10 (which produces a demand of 8A when at full throttle due to the offset/scaling of the throttle). Not sure how that could happen, unless the current controller is marginally stable, which wouldnāt surprise me. meas_l is 65400 (uH?) and Iām currently running from 19V.
I didnāt trip the 10A breaker which I fitted to the input to be on the safe side.
However, Iād now like to have a digital input control whether the bike applies forward or reverse thrust. This will be connected to the rear brake lever.
Iāll need to hack the firmware anyway, because I want that reverse thrust only to apply when the bike is moving above a certain positive speed. I donāt want a reverse gear! Also, Iād like it only to go into reverse āmodeā when the throttle is zero, so I donāt get any sudden changes. (same applies to going forwards again)
But, not sure how best to define a digital input. Not sure that itās possible in the odrive_interface.yaml file. Iād like it to map to any boolean or real-valued property in the same way the analogue input does.
Iām surprised youāre doing this directly. Iād be inclined to wire everything to a Teensy or similar and then send CAN torque commands to the ODrive.
Iām surprised, too!
But then it really is just another thing to go wrong. I have access to the source code of this wonderful open-source motor controller, so why not?