working with mpu9250 sparkfun board
iseries
Posts: 1,492
in Propeller 1
I have been working with this board and have converted the sparkfun code over to the propeller.
What have just noticed is that the propeller chip is way slower than the STM32L4 chip that I am testing with.
Both chips say they are running at 80 Mhz and I used a test program where I capture the program counter and then pause for 1 second and subtract it to get the count.
Propeller:
Arduino code:
In both cases they return 1,000,000 which is expected.
When I hook them up to the mpu9250 and read 6 continues registers they take vastly different amounts of time to do it.
The Propeller takes 5,330 microseconds and the STM32L4 takes only 857 microseconds.
Why is the i2c protocol so much slower on the propeller?
Mike
What have just noticed is that the propeller chip is way slower than the STM32L4 chip that I am testing with.
Both chips say they are running at 80 Mhz and I used a test program where I capture the program counter and then pause for 1 second and subtract it to get the count.
Propeller:
int I = CNT; pause(1000); I = CNT - I; I = I / 80; // microseconds
Arduino code:
int I = micros(); delay(1000); I = micros() - I;
In both cases they return 1,000,000 which is expected.
When I hook them up to the mpu9250 and read 6 continues registers they take vastly different amounts of time to do it.
The Propeller takes 5,330 microseconds and the STM32L4 takes only 857 microseconds.
Why is the i2c protocol so much slower on the propeller?
Mike
Comments
Jim
internal code: Arduino read bytes Mike
Mike
http://forums.parallax.com/discussion/158294/simple-ide-i2c-bus-speed-how-to-change
Mike II
The short answer is that the STM32 is a much more powerful chip than the Prop. If you were doing the I2C read in native PASM you'd probably bet getting the same speed because of limitations of I2C itself.
I think I can also get away without using floating point numbers as well.
But the propeller is not close to fast enough to even read the registers let along do the simple calculations so that I can update the angle every 10 milliseconds.
I switched to the LMM memory module and got the read speed down to 1058 milliseconds from the initial 5316. A five fold increase in speed that just might make it fast enough to do the work....
I have played a little bit with the assemble code and that does make a difference in some cases. It would be nice if the compiler output some of the assembly code so that one code see what its doing and possible rework the code to something faster.
C code was invented to help developer write assemble code for phone systems at bell labs back in the day. I would hate to think it doesn't do that anymore.
Also I find it very difficult to write COG assembly routines as there doesn't seem to be a function to create a COG program. I guess the only way is to use SPIN.
Mike
https://github.com/parallaxinc/Flight-Controller
It's not simple code, but if you use the 8 cores on the Prop to do the work in parallel it's capable of doing a lot.
I just got my head around quaternions and still have a head ache.
While the code you have there is great, I believe that the point of understanding it has gone by the wayside.
It takes too many side tracks from just plain functions and just loses some of the straight forwardness of the application.
I believe a self balancing robot maybe more straight forward than that and lead the way to better understanding of the math that makes it all work.
Mike
PropGCC's fcache is a reserved 64-word (256-byte) section of cog RAM that can be used to execute user code at a high speed, without reading individual instructions or byte codes out of HUB RAM. Any code that is tagged as fcache in the source will, when invoked, be copied into cog RAM prior to execution, and then invoked directly from cog RAM. You end up with a small execution delay (often looks like a hiccup) to load the code into the cog, but then a VERY HIGH performance gain once the execution begins. This scheme is ideal for serial communication like UART, I2C, and SPI, and it is exactly what both PropWare and libpropeller use.
Using PropWare's I2C object isn't hard, either. Here's an example that writes a string to the Propeller's EEPROM and then reads it back and displays it on the standard serial bus (this example requires an EEPROM larger than 32kB)
The "#include <simpletools.h>" is only there because "EEPROM_ADDR" is defined there. The rest of the above code is all PropWare. If you want to give this a go for yourself and try it with your MPU-9250, check out PropWare's download/installation instructions here.
Here's the code you'd want (untested) to replace your call to the Simple library's I2C functions:
Documentation for PropWare::I2C can be found here.
Aside from the EEPROM, I don't have many I2C devices around so I can't actually test the speed of this for you. If you're willing to give it a shot, I'm very curious to hear what your results are in both CMM and LMM.
I agree with you - I had to do a lot of things to make it fit, and make it fast enough, that sacrifice readability. That said, the approach of having PASM drivers and C or Spin main code is a common practice on the Prop. The cogs on the Prop were largely intended to replace the peripherals you find on other chips. Instead of having 2 UARTs and a couple I2C or SPI engines on pre-set pins in an Atmel or STM chip, you implement them in PASM (or use code others have already written) and run them in a cog. This allows the parts that need to be fast to be fast, and still lets you have some flexibility with the way things are processed.
In the Sensors driver from the Elev8 code, I read a gyro, accelerometer, magnetometer, and barometer, compensate for temperature drift in the gyro readings, turn the barometer pressure reading into an altitude estimate, and send out values for a string of WS2812 LEDs. You could get away with much less - just reading the data from the IMU, and setting the Y-rotation in a variable for another cog to use, and that would be pretty simple to write in C.
On my Sideway project, I have a cog that reads the sensors, and one that runs the math (like on the Elev8), one to read the controller, one to run the motors (the Servo32 object from the Obex), and one to run the main loop and balance code. Splitting things into tasks like this means that they all run in parallel with each other, and all run quite fast. It started like this: