MPU-9250 SPI in BASIC

Status
Not open for further replies.

Camerart

Member
Hi,
Firstly, I can only speak BASIC language, and I use Oshonsoft for programming, simulating and compiling. Unfortunately, this isn't used by many people which makes it challenging for me.

I am trying to get the MPU9250 comass module working using SPI. I have looked through the threads and found answers in ARDUINO, which I think I could pick through and convert to BASIC.

I wonder if there is anyone here that could help me write the compass section in BASIC please. I only need guidance:)

Perhaps to start with, point me to the best thread, that I could study first.

Cheers, Camerart.
 
1) Figure out how to talk to the SPI hardware. Configure the hardware for what you want to do.
2) Try to read the "who am i" register on the MPU-9250. If you get the expected value you can move on to trying writes.

If your version of BASIC doesn't have support for the SPI port, step 1 is going to be the hardest. You will have to consult the data sheets (and Teensy driver code) to figure out what values to write and where. It isn't excessively difficult, just tedious. I did it because I was using Forth and the MPU-9250 works quite well now.
 
I'm biased, but I think my MPU-9250 library is pretty good:
https://github.com/bolderflight/MPU9250

Once you can get the WHOAMI from the MPU-9250, look at the begin method of my library. It's pretty well commented, so it should make sense where I am starting to talk with the magnetometers. The basic steps are to:
1. Put the MPU-9250 into I2C master mode
2. Set the MPU-9250 I2C master clock
3. Put data in registers and command the MPU-9250 to send it over I2C to the magnetometers. You'll need to do this to setup the magnetometers.
4. Once setup is complete, command the MPU-9250 to request data from the magnetometers at a set rate (typically 100 Hz). From this point forward, you no longer need to work with the magnetometers, you just need to check the external data from the MPU-9250 at the specified rate to get your data.
 
1) Figure out how to talk to the SPI hardware. Configure the hardware for what you want to do.
2) Try to read the "who am i" register on the MPU-9250. If you get the expected value you can move on to trying writes.

If your version of BASIC doesn't have support for the SPI port, step 1 is going to be the hardest. You will have to consult the data sheets (and Teensy driver code) to figure out what values to write and where. It isn't excessively difficult, just tedious. I did it because I was using Forth and the MPU-9250 works quite well now.

Hi U,
My system supports SDI, and I've programmed other modules ok (i,e, BMP280 barometer)
I'll try 'Who am I'
Thanks C.
 
I'm biased, but I think my MPU-9250 library is pretty good:
https://github.com/bolderflight/MPU9250

Once you can get the WHOAMI from the MPU-9250, look at the begin method of my library. It's pretty well commented, so it should make sense where I am starting to talk with the magnetometers. The basic steps are to:
1. Put the MPU-9250 into I2C master mode
2. Set the MPU-9250 I2C master clock
3. Put data in registers and command the MPU-9250 to send it over I2C to the magnetometers. You'll need to do this to setup the magnetometers.
4. Once setup is complete, command the MPU-9250 to request data from the magnetometers at a set rate (typically 100 Hz). From this point forward, you no longer need to work with the magnetometers, you just need to check the external data from the MPU-9250 at the specified rate to get your data.

Hi B,
I've downloaded your ZIP file, and have Arduino, and need to know which are the minimum files I need for READing the XYZ Magnetometer registers?

Thanks,
C.
 
The files in src, the other files are API documentation, API examples, and sensor documentation.
 
The files in src, the other files are API documentation, API examples, and sensor documentation.

Hi B,
Thanks,

I had a quick scan and found reference to FIFO. When READing the XYZ Magnetometer Registers, is FIFO used or is each BYTE READ in turn? I think I have to use each BYTE in turn.

C.
 
Hi B,
Thanks,

I had a quick scan and found reference to FIFO. When READing the XYZ Magnetometer Registers, is FIFO used or is each BYTE READ in turn? I think I have to use each BYTE in turn.

C.

Look through the begin method in the MPU9250 class. You likely are not using the FIFO, but are instructing the MPU9250 to gather 7 bytes of data from the magnetometers at the sample rate (likely 100 Hz):
https://github.com/bolderflight/MPU9250/blob/master/src/MPU9250.cpp#L157

That data will show up in the EXT_SENS_DATA_00 through EXT_SENS_DATA_06 registers and will automatically be updated at the sample rate. You can burst read those registers when reading from the MPU-9250 (i.e. read all 7 in a single transaction).
 
Look through the begin method in the MPU9250 class. You likely are not using the FIFO, but are instructing the MPU9250 to gather 7 bytes of data from the magnetometers at the sample rate (likely 100 Hz):
https://github.com/bolderflight/MPU9250/blob/master/src/MPU9250.cpp#L157

That data will show up in the EXT_SENS_DATA_00 through EXT_SENS_DATA_06 registers and will automatically be updated at the sample rate. You can burst read those registers when reading from the MPU-9250 (i.e. read all 7 in a single transaction).

Hi B,
Blimey!! I see why you're proud of it. To me it's a bit like reading hieroglyphics

I may be getting mixed up regarding the FIFO, I don't fully understand it, perhaps I don't need to?

I've just come across EXT_SENS_DATA_00 - 06, that I assume is a clever way of buffering the DATA. I had previously read that the Magnetometer section of the MPU-9250 is through I2C, I think I see why some of the program is in I2C and not SPI now. Regarding 'burst READ' I tried this previously in Oshonsoft, and couldn't get it to work (Perhaps poor programming) so I READ each BYTE separately in sequence.

I'm not such a good programmer (Still in BASIC since the 80s), and wonder if it's a bit too difficult for me, but I'll see if I can find out 'Who am I' first, and go from there
Thanks, C.
 
Hi,
Is this an error in the DATA sheet? If so, are there any others?
C
 

Attachments

  • Register error.jpg
    Register error.jpg
    46.9 KB · Views: 141
I may be getting mixed up regarding the FIFO, I don't fully understand it, perhaps I don't need to?

I've just come across EXT_SENS_DATA_00 - 06, that I assume is a clever way of buffering the DATA. I had previously read that the Magnetometer section of the MPU-9250 is through I2C, I think I see why some of the program is in I2C and not SPI now.
You have to configure the MPU-9250 to buffer data in a FIFO. Otherwise the data appears in the registers and waits to be read.

I don't know how this library handles it but I remember what I did. You can configure the MPU-9250 to periodically send commands over its I2C link to the magnetometer. I used a couple. The first commanded a read of the results and those were stored in those external data register locations. The second command told the magnetometer to begin a conversion. Assuming you have the timing right, the data will be waiting for you to read it.


Regarding 'burst READ' I tried this previously in Oshonsoft, and couldn't get it to work (Perhaps poor programming) so I READ each BYTE separately in sequence.
.
Very bad idea. The MPU-9250 could update the results in those registers part way through your reading them which could corrupt what you get. By reading all of them in a single transaction you prevent that.
 
There might exist different firmware releases for the MPU2950. So, it's not forcibly an error but just a different data sheet and f/w release. If I were you, I'd write code which reads and outputs all registers in a loop. Thus, you can see which address scheme applies.
 
You have to configure the MPU-9250 to buffer data in a FIFO. Otherwise the data appears in the registers and waits to be read.

I don't know how this library handles it but I remember what I did. You can configure the MPU-9250 to periodically send commands over its I2C link to the magnetometer. I used a couple. The first commanded a read of the results and those were stored in those external data register locations. The second command told the magnetometer to begin a conversion. Assuming you have the timing right, the data will be waiting for you to read it.



Very bad idea. The MPU-9250 could update the results in those registers part way through your reading them which could corrupt what you get. By reading all of them in a single transaction you prevent that.

Hi U,
Ok.
I relied on the READ being very fast, but did read about the errors if READ my way.
I'll try again using the FIFO.
C.
 
It is an error in the header file. Looking at the code, it doesn't use this definition. In any case, the data sheet is correct.

HI U,

I'm a bit confused! I'm an improving dyslexic.

Looking at the register map again, with 'WHO AM I' I now see that I missed RESET VALUE, thinking that 71 is the register.

This could take a while:eek:

C.
 

Attachments

  • 117.jpg
    117.jpg
    112.8 KB · Views: 195
Hi B,
Blimey!! I see why you're proud of it. To me it's a bit like reading hieroglyphics

I may be getting mixed up regarding the FIFO, I don't fully understand it, perhaps I don't need to?

I've just come across EXT_SENS_DATA_00 - 06, that I assume is a clever way of buffering the DATA. I had previously read that the Magnetometer section of the MPU-9250 is through I2C, I think I see why some of the program is in I2C and not SPI now. Regarding 'burst READ' I tried this previously in Oshonsoft, and couldn't get it to work (Perhaps poor programming) so I READ each BYTE separately in sequence.

I'm not such a good programmer (Still in BASIC since the 80s), and wonder if it's a bit too difficult for me, but I'll see if I can find out 'Who am I' first, and go from there
Thanks, C.

You don't really need to understand the FIFO, it holds 512 bytes of data, if I remember correctly, and is accessible through three registers (0x72 and 0x73 give you the count of how much data is in the FIFO and 0x74 gives you R/W access to the FIFO buffer). What you are looking at with the EXT_SENS_DATA_XX is simply a bunch of registers set aside to hold external data, similar to how ACCEL_XOUT_H holds the high byte of the accelerometer output.

The MPU-9250 can act as I2C master to external devices. In fact, the MPU-9250 is really two sensors within the same package, a MPU-6050 gyro and accel and a AK8963C magnetometer. The AK8963C is on the MPU-9250 I2C bus, so we use the MPU-9250 registers for controlling its I2C bus to access the AK8963C and the data shows up in EXT_SENS_DATA registers.

You definitely need to do burst reads from the MPU-9250 registers to get valid data. The BME-280 supports burst reads as well and I'm assuming the BMP-280 was similar, so hopefully you have some experience with that.
 
HI U,

I'm a bit confused! I'm an improving dyslexic.

Looking at the register map again, with 'WHO AM I' I now see that I missed RESET VALUE, thinking that 71 is the register.

This could take a while:eek:

C.

0x75 is the register address, 0x71 is the expected value. For any register on the MPU-9250, except for the few listed, sending 0x00 will reset it to it's default value. The WHO_AM_I register is read only, so no point resetting it.
 
You don't really need to understand the FIFO, it holds 512 bytes of data, if I remember correctly, and is accessible through three registers (0x72 and 0x73 give you the count of how much data is in the FIFO and 0x74 gives you R/W access to the FIFO buffer). What you are looking at with the EXT_SENS_DATA_XX is simply a bunch of registers set aside to hold external data, similar to how ACCEL_XOUT_H holds the high byte of the accelerometer output.

The MPU-9250 can act as I2C master to external devices. In fact, the MPU-9250 is really two sensors within the same package, a MPU-6050 gyro and accel and a AK8963C magnetometer. The AK8963C is on the MPU-9250 I2C bus, so we use the MPU-9250 registers for controlling its I2C bus to access the AK8963C and the data shows up in EXT_SENS_DATA registers.

You definitely need to do burst reads from the MPU-9250 registers to get valid data. The BME-280 supports burst reads as well and I'm assuming the BMP-280 was similar, so hopefully you have some experience with that.

Hi B,
I now understand where I went wrong regarding the 'Who am I' register.

Even as a none Arduino speaker, I can see that your code is very comprehensive, but for me it may be too much. To start with I only need the Magnetometer readings. Would it be asking too much for you to strip out all lines apart from the minimum to READ the MAG readings or point me to a similar program that only does that please? If not that's ok.

With the BMP280, I READ it fast like this:

'For i = 0 To 2
'altmtr = 0 'CHIP SELECT BMP280 ON
'adr = 0xf7 + i
'SPISend adr
'SPIReceive data
'b(i) = data
'altmtr = 1 'CHIP SELECT BMP280 OFF
'Next i

and it appears to work ok. I can tell which of my stairs I'm on.

But if I can master the FIFO method, it is what's suggested.

C.
 
To start with I only need the Magnetometer readings. Would it be asking too much for you to strip out all lines apart from the minimum to READ the MAG readings or point me to a similar program that only does that please?

Reading the magnetometer is about the hardest thing to do. Start with something simpler.

Configure the accel and gyro. Set the sample rate and such. Then get data. Which brings up the point of how do you know when data is available? Are you going to use the interrupt output pin or poll for it? I have seen some that set them for a higher sample rate than required and then just read the data when they want it. A bad approach in my book.

Once you have that done you can work on configuring the slave control registers to handle the magnetometer.
 
Reading the magnetometer is about the hardest thing to do. Start with something simpler.

Configure the accel and gyro. Set the sample rate and such. Then get data. Which brings up the point of how do you know when data is available? Are you going to use the interrupt output pin or poll for it? I have seen some that set them for a higher sample rate than required and then just read the data when they want it. A bad approach in my book.

Once you have that done you can work on configuring the slave control registers to handle the magnetometer.

Hi U,

So far I've got 3 or 4 different compass modules, that I've failed to be able to program for various reasons, one being Oshonsoft limitations. I first ordered the MPU9250s in April but they failed to arrive twice, and after another re-order, I got these a couple of weeks ago.

I only need the compass, but I chose these modules as they are modern, use SPI and eventually I may need the ACCEL and GYRO which is on the same board. Unfortunately they use I2C for the compass, I've no idea why?

I'll keep trying with this module, especially if the CODE is simplified. Then if no progress I'll look for another type.

Cheers, C.
 
I only need the compass,

Then why did you buy the MPU-9250? The magnetometer is a third party chip grafted onto the accel/gyro. (Hence the I2C.) Worse, the magnetometer is horrible. Not quite as bad as the one in the MPU-9150 but still bad with high noise and limited dynamic range. Sure they have that fancy 14 bit ADC but how many bits are used in normal operation? (Compare the 0.6uT/LSB sensitivity to the Earth's field strength.)
 
Then why did you buy the MPU-9250? The magnetometer is a third party chip grafted onto the accel/gyro. (Hence the I2C.) Worse, the magnetometer is horrible. Not quite as bad as the one in the MPU-9150 but still bad with high noise and limited dynamic range. Sure they have that fancy 14 bit ADC but how many bits are used in normal operation? (Compare the 0.6uT/LSB sensitivity to the Earth's field strength.)

Hi U,

Why did I buy it? I thought it may be future proof, as mentioned, also lack of knowledge.

Can you suggest another one? SPI, and not to pricey.

C.
 
Can you suggest another one? SPI, and not to pricey.

I have always liked the Honeywell parts but they seem to have scaled back their offerings while I wasn't looking. The HMC5843 had ~1600 counts/uT but was I2C for example.I couldn't find any similar parts in production during my limited search.
 
I have always liked the Honeywell parts but they seem to have scaled back their offerings while I wasn't looking. The HMC5843 had ~1600 counts/uT but was I2C for example.I couldn't find any similar parts in production during my limited search.

Hi U,

I have tried HMC5983, with no success, but just found this:
http://flightcontroller.blogspot.com/2014/08/communicating-with-hmc5983-magnetometer.html
I haven't properly read it yet, though. I just tried a couple of links from the page, but got errors. It may have been Oshonsoft restrictions, that didn't allow success?

So at the moment the best bet is B's code for a while.
C.
 
I have always liked the Honeywell parts but they seem to have scaled back their offerings while I wasn't looking. The HMC5843 had ~1600 counts/uT but was I2C for example.I couldn't find any similar parts in production during my limited search.
Hi U,

I have found the LSM303C which appears to have direct SPI control, I've ordered a couple. I'll see how I get on with them before carrying on with the excellent CODE that's been posted.

I have found it a bit too difficult to use both SPI and I2C in the same program.

Thanks to all that contributed.

C.
 
Status
Not open for further replies.
Back
Top