Closed napratin closed 8 years ago
Here is a link to a very ROUGH document on the I2C protocol between the BeagleBone and the DMCC. We really need to clean it up a bit before we release it, so we are putting it on a temporary google doc link: https://docs.google.com/document/d/1vNoH5H8ODUPpGeQgL33aTz3tzo64SsbbzK1ySuSa2As/edit?usp=sharing
Basically, the protocol goes like this: set parameters for Motor 1 or Motor 2 or both, then send the execute command (0xff
Feel free to comment here with any further questions, and we look forward to helping you out with the code so that we can merge it back into the main DMCC library. Please keep us posted on any of your projects with the DMCC (we would love to see some pictures!!)
Also, if you could share with us some of your benchmarking data and test code, we'd like to try to see where the bottleneck is as well.
Thanks!
Thanks a lot, @paulctan! This should definitely help us get moving in the right direction. We'll post back here if we have any questions.
I'll also clean up our benchmarking code to remove unnecessary dependencies and share with you.
Here are a few things we are juggling with right now:
ioctl
-like configuration; nor are we reading the /sys/bus/i2c/devices/<addr>/eeprom
file to perform any version checks - can the absence of these steps affect how the board gets initialized? (i.e. can we start issuing commands like PowerMotor1 directly after boot up?)@paulctan -- Many thanks for the I2C protocol document! I've spent a bit of time hacking at the work @napratin and @dfarrell07 began with our fork (http://github.com/NCSUhardware/DMCC_Library) of your library. I think we're in a good place from a performance perspective, as indicated by one of the Python test programs I included in our reimplementation:
# dmcc_motor_test
DMCC #1 @ 0x2d : Voltage = 8.302
DMCC #1 @ 0x2d:
100 reads in... 0.239 seconds (2.39 ms each).
100 sets in... 0.213 seconds (2.13 ms each).
So that's all good!
In the process of getting here, I converted (most of) the I2C protocol information you provided in the Google doc into a machine readable (YAML) description. This data file is processed by a generic I2C library (https://github.com/jschornick/i2c_device), allowing us to more easily poke at the various registers you expose. Most of the functional verification went as expected, but a few of the device registers don't behave as described.
Most importantly, reading the PowerMotor[12] values (0x02-0x05) in either PID mode always reports zero...
(from: https://github.com/NCSUhardware/DMCC_Library/blob/master/examples/dmcc_pid_test)
# dmcc_pid_test
DMCC #1 @ 0x2d : Voltage = 8.275
PID constants (pos): (0, 0, 0)
Setting to: (-5000, -200, -500)
PID constants (pos): (-5000, -200, -500)
Setting position target to 5000...
S:0, Pos: +000000, Vel: +000, Err: 0, Pow: 000.0, Cur: 0 mA
S:0, Pos: +000319, Vel: +143, Err: 0, Pow: 000.0, Cur: 182 mA
S:0, Pos: +000963, Vel: +285, Err: 0, Pow: 000.0, Cur: 101 mA
S:0, Pos: +001611, Vel: +289, Err: 0, Pow: 000.0, Cur: 95 mA
S:0, Pos: +002280, Vel: +291, Err: 0, Pow: 000.0, Cur: 91 mA
You'll also note that the status bits and PID error are also consistently zero. In each case, I'm writing Refresh (0x00) to Execute (0xff) before reading, which has the desired result when querying the other registers (such as the QEI position/velocity).
Can you help clarify why the status, power, and error aren't reporting as expected? Do you have some sample code of these features working in any language?
I don't think those bits/values were implemented in the released firmware. You should probably ignore them for now.
I'm glad you were able to get the performance numbers up. We'll spend sometime testing and re-integrating your code into the main branch when you guys are satisfied with it.
Updated I2C communication document can be found here -
https://docs.google.com/document/d/1vNoH5H8ODUPpGeQgL33aTz3tzo64SsbbzK1ySuSa2As/edit?usp=sharing
We ran some timing tests using the DMCC Python API, and the results show that each call is taking way too long for it to be usable (e.g., when setting 4 motors on one by one, we need that to happen pretty much instantaneously, but there's a clear delay per motor call). We understand that this is because the entire initialization routine occurs for each Python-to-C call.
Since we need an efficient Python interface to the DMCC capes, we tried to re-implement the library in native Python (see this fork). So far, we haven't been able to make much progress as the protocol between the Beaglebone and the cape is not easily discernible from the code.
@paulctan / @sarahttan: Could you please provide us with the I2C protocol that the cape uses to communicate (i.e. all the different commands along with parameters, byte order etc.)? Also, if there are any other necessary initialization steps, it would be great to know them as well. Needless to say, once we have a stable Python library we'll be glad to contribute it back. Thanks!