I have seen that some code to read an imu is provided (seems to be from @rock) (https://github.com/Xilinx/PYNQ/blob/master/pynq/lib/pmod/pmod_grove_imu.py). I have a similar board from WaveShare which has the same MPU9250 and the BMP180. However, i do not have a Grove pmod adapter so I would like to directly use 2 pins of the PMOD (A or B, doesn’t matter) or the any of the arduino shield headers. So, where should I define the PINS I want to use in the code?
Moreover, I see that it also uses the .bin file. What is this for?
I am running everything directly on the pynq (via ssh) and I would like to run the python script but I haven’t succeed so far:
xilinx@pynq:~$ sudo python3.6
Python 2.7.15rc1 (default, Apr 15 2018, 21:51:34)
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from pynq.lib.pmod import pmod_grove_imu
And then? How should I call the functions? imu = pmod_grove_imu.Grove_IMU() ?
Thank you for your help.
That WaveShare board looks odd to me. By convention, Pmods have VCC, then Gnd aligned to the left, so it looks like you would need to insert this board upside down. Other than that, it seems it is pin compatible.
I2C needs pins with pull-up resistors. You can use the “G3” or “G4” pins in the base overlay as these are already set to have pull-up resistors. See here for more info: https://pynq.readthedocs.io/en/v2.6.1/pynq_libraries/grove.html
There is a software check to make sure you use these pins.
The Pmod is connected to a Microblaze. The real driver for the Pmod is running on the MicroBlaze. Think of the Python file as a wrapper. The bin is the MicroBlaze executable (pre-compiled).
I see the WaveShare has extra int and fsync pins though. I didn’t check what these are.
You included print into your measured time period, which will be slow. Also, reading it multiple times may not be the right thing to do; you are counting in the communication overhead each time. Logging might be the right thing to do, i.e., reading multiple values one time.
@rock As I am also doing this with ROS, there are NO prints and I still get the same sample rate. Even if I remove the print in the code I share I get the same number…Even if I read only one sensor, it takes ~ 140ms.
Then if reading multiple times may not be the right thing to do, how should I read only once all three at once still at 30 Hz? What do you mean by logging?
The reason why you have a long delay is that each read will incur a communication roundtrip overhead between Python, PS, and Microblaze. Logging is something we provide to deal with multiple values- basically just pushing back multiple values into the circular buffer and read them back all at once. e.g.
But the pmod pins are not connected to PS directly. Then you will have to rebuild a customized bitstream, which uses EMIO to connect your pmod pins to PS i2c pins - takes even longer time.
So, if I understood correctly, I should do those multiple I2C reads directly on the microblaze, store them in a circular buffer and directly read that buffer rather than the I2C?
How can I check if logging is a valid command? I should modify then this file (arduino_grove_imu.c), right?
Yes, you will need to add more cases to support logging. To recompile the arduino_grove_imu.bin you will need the microblaze BSP and Pynq-Z2 base.xsa file, and that is tedious. What I recommend is to use ipython microblaze, which allows you to program C code directly in jupyter cell.
The issue is that I cannot use jupyter, that is why I am directly ssh’ing into it. I already have a compiled image with the PS i2c pins routed to the pmods so the question would be, can I copy the pynq folder to use partial bitstream like in the dma example?
Yes, that is how I am doing it. The question was because I would still like to have the possibility to use partial bitstream for new hw components without having to re-compile everything. That is why I cited the DMA example.
This is needed if you want to add your kernel driver. But I think you should start with user-space first.
Suppose you connect it to PS I2C0, first I would check if PS I2C0 is already enabled in your PS configuration (in FSBL). If not you will need to enable that first - recompile the boot partition at least. Then the second step would be just reload the bitstream and do i2cdetect -y -r 0 to see if the new address is responsive.
@Rock the i2c is clear, I can see it with i2cdetect -y -r 0, can read and write the register. I am able to read at 30 Hz accl, gyro and mag. The question is if I can still use the pynq functionalities when I create a new bitstream like that dma example by just copying the pynq folder to my new image.
The pynq folder does not have to be touched. Sure you can replace that with some of your functionalities but I would just put all customized things outside so you have a separate package. When specifying the bitstream, just give the absolute path, e.g.:
from pynq import Overlay
ol = Overlay('/home/xilinx/i2c.bit')
And also, all pynq functionalities will be there if you want to use.
If you want to reuse the IMU driver code, maybe just copying out those methods out to your own driver.