I am currently working on a 1-DOF, direct drive haptic pedal. For the position and velocity measurement I am using encoder and a gyroscope of MPU6050.
Since the launchpad has quadrature encoder interface, reading position is done by one memory reading, there is no interrupt for it. To be able to read the gyroscope, I am using data-ready interrupt of MPU6050.
A little problem about MPU6050 is that even though I program the sensor to give 1Khz(1ms period) data, its period is around 750us (not too problematic for the case)
The pedal will be used in masters thesis which aims analyzing human behaviour on juggling, so I need to be able to read position, velocity and time stamps of this measurements at 1Khz(Human motor system bandwidth), periodically.
I am currently using USB-UART converter of the board for this with buffer (I am using uartstdio library of TI with 230400 baudrate) and when an interrupt occurs I set a flag and the flag is cleared inside main function when the values are sent to computer. I am currently taking these measurements offline and analyze them in Matlab to design a Kalman filter.
After taking some measurements, I realized that some measurements are missed and period is 2 or 3 times (1500-2100us) of the mean (750us). So the UART cannot send the data in time.
My question is that how can I achive the data rate I want, is it possible using UART? I have considered sending bytes, not human readable numbers, but I am not sure to use uartprintf inside the ISR of gyro interrupt. Do you have any suggestions or is there a common way to do it?
Thanks in advance :)
I believe the MPU6050 is I2C, so when the MPU6050 data ready interrupt occurs, you then read the data using I2C but you haven't said what speed you are running the I2C bus at.
Also you haven't said how much data you are reading from the Gyro at each interrupt. Is it just 6-Bytes for XYZ data? More? If they are in continuous register locations, then you can use I2C burst-read mode to setup the initial register address and then read all the registers. This will improve the throughput of the I2C bus.
Here are my general opinions, having used the MPU 6050 recently.
1. You need to run the UART faster than the I2C bus, otherwise you have no chance of ever keeping up.
2. Never call anything at all from an ISR. Collect data into a buffer, and set a flag, let the main loop do the grunt work.
3.Use multiple buffers, aka a FIFO, and work through them in the main loop sending them out the UART. This way the I2C can be filling up one buffer, while the UART is transmitting the other. I see no reason why you shouldn't be able to use interrupt-driven I2C and interrupt-driven UART at the same time.
5. If you run out of buffers, send a special packet over the UART that signals a reading has been dropped.
4. Send binary over the UART to minimize processing time on the embedded processor. Let the desktop PC do the hard work.
You've just hit the point at which you have to stop pretending that the Cortex M4 on your board is a PC and get into the nuts and bolts of how it works !
There will be a way of sending data directly to the usb peripheral without using printf but unless the TI code is open source it may be hard to find.
Another route would be to use a UART on the processor and an external FTDI cable which translates the USB on a PC to logic level UART interface. This might seem odd if the board has USB already but it is usually much easier to talk to the UART on a chip than to USB.
Finally, and this is a bodge that might work, why not encode your data into an ascii printable form - if you use hex you can transmit 3 x 16 bit numbers in 12 characters, adding two to separate the data bursts means you'll need 14 characters per ms which is only about half the capacity of your link. printf will probably waste much less time if you print reasonable length strings (perhaps 32 ms worth at a time). printf can be very slow when it has to do lots of conversion and formatting.
You don't need a time stamp - the receiver can easily count data bursts.
How many bytes are sent once in every 750uS. When I calculate looks you can send only 17 bytes maximum at 230400 baud rate over UART (Within 750uS). Again we need to consider the function call overhead.
I read only GyroZ value, 2 bytes of data and i2c works at 400Khz speed, to clear the interrupt flag of MPU6050(on the chip not in MCU), I also read interrupt status byte in the IC. I preffered uartstdio because it is interrupt driven and buffered, I did not have to handle buffer etc. I am not using interrupt driven I2C just because I read small amount of data here.
When printed in ASCII format, it takes around 150 characters for each line and increases with the time stamp size.
For this I will try byte streaming, with delimiters. Dou you have any information how byte streams can be read in Matlab? Or should i look for python or c++ to read the data?