MPU9250 woes

Recurrent H/W and software problems
Zim
Posts: 296
Joined: Mon Feb 08, 2021 9:15 pm
Has thanked: 277 times
Been thanked: 131 times

MPU9250 woes

Post by Zim »

Hi
I finally received the MPU9250. Took forever....

I am using the below sample, but keep getting "MPU9250 not found"
I ran the scan and got device at &H68. Tried that, no luck...
Do I have to add anything to this example or should it run out of the box?
Using "Annex32 CAN 1.47.2"
Please help! These magnetometers are driving me nuts.

Thanks in advance
Zim

Code: [Local Link Removed for Guests]

 I2C.Setup 21,22, 400000 '400000 set the I2C to max speed

if MPU9250.Setup(&H68) = 0 then print "MPU9250 not found" ': end
'if MPU9250.Setup(&H69) = 0 then print "MPU9250 not found" : end
Print "Temperature", MPU9250.TEMP ; "°C"

Dim vect(10) 'dimension the array

'read the values for all the axis

Ret =  MPU9250.VECTOR(vect())

'Print all the values

Print "ax "; vect(0), "ay "; vect(1), "az "; vect(2)

Print "gx "; vect(3), "gy "; vect(4), "az "; vect(5)

Print "mx "; vect(6), "my "; vect(7), "mz "; vect(8)
User avatar
cicciocb
Site Admin
Posts: 2195
Joined: Mon Feb 03, 2020 1:15 pm
Location: Toulouse
Has thanked: 470 times
Been thanked: 1461 times
Contact:

Re: MPU9250 woes

Post by cicciocb »

Are you sure that you received a MPU9250?
Maybe your device is an MPU6500 ?

Try using the example for the MPU6500 ....
Zim
Posts: 296
Joined: Mon Feb 08, 2021 9:15 pm
Has thanked: 277 times
Been thanked: 131 times

Re: MPU9250 woes

Post by Zim »

Hi cicciocb

I tried with the 6500 sketch. same result. scan shows log Found device at &H68.
Still says MPU6500 not found.
Should I try a different firmware?
Thanks
Zim
9250.jpg
esp32.jpg
You do not have the required permissions to view the files attached to this post.
User avatar
cicciocb
Site Admin
Posts: 2195
Joined: Mon Feb 03, 2020 1:15 pm
Location: Toulouse
Has thanked: 470 times
Been thanked: 1461 times
Contact:

Re: MPU9250 woes

Post by cicciocb »

have you tried to reverse SCL and SDA?
Zim
Posts: 296
Joined: Mon Feb 08, 2021 9:15 pm
Has thanked: 277 times
Been thanked: 131 times

Re: MPU9250 woes

Post by Zim »

Yes I have tried reversing them.... and a noble firmware
Zim
Posts: 296
Joined: Mon Feb 08, 2021 9:15 pm
Has thanked: 277 times
Been thanked: 131 times

Re: MPU9250 woes

Post by Zim »

cicciocb

It seems its a fake MPU9250. Apparently hard to find a real one. Would you consider implementing HMC5883L as it is cheap and easily available.
Fernando was helpful to read a HMC5883L, but the heading wasn't linear. It appears to be in zones.


Code: [Local Link Removed for Guests]

address = &H0D    ' Address of the device QMC5883
ioBuff.dim(0, 6)  ' To save the measurement result

i2c.setup 4, 5    ' SDA to GPIO4, SCL to GPIO5 (D2, D1 in wemos D1 mini)
' i2c.writeRegByte i2c_address, register, value
i2c.writeRegByte address, &H0B, 1
i2c.writeRegByte address, &H09, &B11000001 ' 64, 2 gauss, 10Hz, continuous

while 1
  i2c.read_ioBuff(0), address, &H00, 6

  x = ioBuff.read(0, 0) OR (ioBuff.read(0, 1) << 8)
  if x > 32768 then x = x - 65536

  y = ioBuff.read(0, 2) OR (ioBuff.read(0, 3) << 8) 
  if y > 32768 then y = y - 65536

  z = ioBuff.read(0, 4) OR (ioBuff.read(0, 5) << 8) 
  if z > 32768 then z = z - 65536

'  wlog "x="; x, "y="; y, "z=";z
  
  b1 = (atan2(y, x) * 180) / PI
  if b1 < 0 then b1 = 360 + b1

  b2 = (atan2(x, z) * 180) / PI
  if b2 < 0 then b2 = 360 + b2

  b3 = (atan2(z, y) * 180) / PI
  if b3 < 0 then b3 = 360 + b3

  wlog cint(b1), cint(b2), cint(b3)
  
  pause 5000
wend
User avatar
cicciocb
Site Admin
Posts: 2195
Joined: Mon Feb 03, 2020 1:15 pm
Location: Toulouse
Has thanked: 470 times
Been thanked: 1461 times
Contact:

Re: MPU9250 woes

Post by cicciocb »

As soon as I'll found a little bit of spare time I'll try to implement it.
I've just bought some of these modules
Zim
Posts: 296
Joined: Mon Feb 08, 2021 9:15 pm
Has thanked: 277 times
Been thanked: 131 times

Re: MPU9250 woes

Post by Zim »

cicciocb: re:

I think there is 2 similar ic's used on these modules.

HMC5883L and QMC5883L The following is most common. QMC5883L (thanks Fernando)
I believe both do the same job but use different addressing....



https://nettigo.pl/attachments/440

https://github.com/mprograms/QMC5883LCompass.

Thanks
Zim
Zim
Posts: 296
Joined: Mon Feb 08, 2021 9:15 pm
Has thanked: 277 times
Been thanked: 131 times

Re: MPU9250 woes

Post by Zim »

[Local Link Removed for Guests] wrote: [Local Link Removed for Guests]Sat Apr 15, 2023 5:08 pm As soon as I'll found a little bit of spare time I'll try to implement it.
I've just bought some of these modules
I just received some different modules. HW662 / AK8975
Would these be easier for you to integrate?
Thanks
Zim
HW662_Ak8975.jpg
You do not have the required permissions to view the files attached to this post.
User avatar
cicciocb
Site Admin
Posts: 2195
Joined: Mon Feb 03, 2020 1:15 pm
Location: Toulouse
Has thanked: 470 times
Been thanked: 1461 times
Contact:

Re: MPU9250 woes

Post by cicciocb »

Hi Zim,
I received the QMC5883L module and I played a little bit with it.

First of all I tried to use it directly in basic, without any library and, finally, I must say that it works not so bad.

You can find below a little sketch with my experimental code; basically the sensor must be calibrated trying to find the offset and the scale on each axis (mainly the X and Y for the heading purposes).

The code below simply do a "calibration" for a given time (In the example there are 200 iterations for the calibration = ~20 seconds).
The calibration consists into rotating the sensor slowly all around the horizontal plane; the program will take the min / max for each axis and will compute the required offset / scale.
After that the sensor will give the correct output in degrees.
Take care that the sensor is very sensitive to magnetic fields, ferromagnetic elements or electronic devices in proximity.

Try and let me know if it works for you and, eventually, I'll integrate this code inside Annex.

Code: [Local Link Removed for Guests]

I2C.SETUP 21, 22

address = &H0D    ' Address of the device QMC5883
ioBuff.dim(0, 6)  ' To save the measurement result

i2c.writeRegByte address, &H0A, &B10000000  ' SOFT_RST
pause 100
i2c.writeRegByte address, &H0B, 1 ' start
pause 100
'i2c.writeRegByte address, &H09, &B00000001 ' 512 samples, 2 gauss, 10Hz, continuous
i2c.writeRegByte address, &H09, &B00010001 ' 512 samples, 8 gauss, 10Hz, continuous

xmin = 1e10: xmax = -1e10
ymin = 1e10: ymax = -1e10
zmin = 1e10: zmax = -1e10

calib = 0
CYCLES_TO_CALIB = 200
while 1
  i2c.read_ioBuff(0), address, &H00, 6
  
  x = ioBuff.read(0, 0) OR (ioBuff.read(0, 1) << 8)
  if x > 32768 then x = x - 65536
  
  y = ioBuff.read(0, 2) OR (ioBuff.read(0, 3) << 8)
  if y > 32768 then y = y - 65536
  
  z = ioBuff.read(0, 4) OR (ioBuff.read(0, 5) << 8)
  if z > 32768 then z = z - 65536
  
  'wlog  "x="; x, "y="; y, "z=";z
  'wlog "xmin="; xmin, "xmax="; xmax, "ymin="; ymin, "ymax="; ymax
  
  if ((calib> 5) and (calib< CYCLES_TO_CALIB)) then
    if (x < xmin) xmin = x
    if (x > xmax) xmax = x+0.1
    if (y < ymin) ymin = y
    if (y > ymax) ymax = y+0.1
    if (z < zmin) zmin = z
    if (z > zmax) zmax = z+0.1    
  endif
  xoff = (xmax+xmin) / 2
  yoff = (ymax+ymin) / 2
  zoff = (zmax+zmin) / 2
  xdelta = (xmax-xmin)
  ydelta = (ymax-ymin)
  zdelta = (zmax-zmin)
  
  xscale = 1/xdelta
  yscale = 1/ydelta
  zscale = 1/zdelta
  
  x = (x-xoff) * xscale
  y = (y-yoff) * yscale
  z = (z-zoff) * zscale
  
  yaw = atan2(y, x) * 180 / PI
  if yaw < 0 then yaw = 360 + yaw 

  'you can eventually compute also the other axis
'  pitch = (atan2(-x, sqr(y*y + z*z))) * 180 / PI
'  if pitch < 0 then pitch = 360 + pitch 
  
'  roll = (atan2(y, sqr(x*x + z*z))) * 180 / PI
'  if roll < 0 then roll = 360 + roll 
  
  wlog cint(yaw);"°",  "Calibrated:";calib>CYCLES_TO_CALIB

  calib = calib + 1

  pause 100
wend

end
This is another example I did with an M5 atom matrix.
The led indicates the always NORTH position.
VID_20230430_213307.mp4

Code: [Local Link Removed for Guests]

SDA = 26
SCL = 32
I2C.SETUP SDA, SCL 'Pins as shown
neo.setup 27, 25 ' set the RGB strip
neo.strip 0,24, 0 ' clear the strip

address = &H0D    ' Address of the device QMC5883
ioBuff.dim(0, 6)  ' To save the measurement result

i2c.writeRegByte address, &H0A, &B10000000  ' SOFT_RST
pause 100
i2c.writeRegByte address, &H0B, 1 ' start
pause 100
'i2c.writeRegByte address, &H09, &B00000001 ' 512 samples, 2 gauss, 10Hz, continuous
i2c.writeRegByte address, &H09, &B00010001 ' 512 samples, 8 gauss, 10Hz, continuous

xmin = 1e10: xmax = -1e10
ymin = 1e10: ymax = -1e10
zmin = 1e10: zmax = -1e10

calib = 0
CYCLES_TO_CALIB = 200
while 1
  i2c.read_ioBuff(0), address, &H00, 6
  
  x = ioBuff.read(0, 0) OR (ioBuff.read(0, 1) << 8)
  if x > 32768 then x = x - 65536
  
  y = ioBuff.read(0, 2) OR (ioBuff.read(0, 3) << 8)
  if y > 32768 then y = y - 65536
  
  z = ioBuff.read(0, 4) OR (ioBuff.read(0, 5) << 8)
  if z > 32768 then z = z - 65536
  
  'wlog  "x="; x, "y="; y, "z=";z
  'print "xmin="; xmin, "xmax="; xmax, "ymin="; ymin, "ymax="; ymax
  
  if ((calib> 5) and (calib< CYCLES_TO_CALIB)) then
    if (x < xmin) xmin = x
    if (x > xmax) xmax = x+0.1
    if (y < ymin) ymin = y
    if (y > ymax) ymax = y+0.1
    if (z < zmin) zmin = z
    if (z > zmax) zmax = z+0.1    
  endif
  xoff = (xmax+xmin) / 2
  yoff = (ymax+ymin) / 2
  zoff = (zmax+zmin) / 2
  xdelta = (xmax-xmin)
  ydelta = (ymax-ymin)
  zdelta = (zmax-zmin)
'  avg_delta = (xdelta+ydelta+zdelta)/3
'  xscale = avg_delta/xdelta
'  yscale = avg_delta/ydelta
'  zscale = avg_delta/zdelta
  
  xscale = 1/xdelta
  yscale = 1/ydelta
  zscale = 1/zdelta
  
  x = (x-xoff) * xscale
  y = (y-yoff) * yscale
  z = (z-zoff) * zscale
  
  yaw = atan2(y, x) * 180 / PI
  if yaw < 0 then yaw = 360 + yaw 
  
  pitch = (atan2(-x, sqr(y*y + z*z))) * 180 / PI
  if pitch < 0 then pitch = 360 + pitch 
  
  roll = (atan2(y, sqr(x*x + z*z))) * 180 / PI
  if roll < 0 then roll = 360 + roll 
  
  'wlog "x="; x, "y="; y, "z=";z, 
  'wlog cint(b1);"°", cint(b2), cint(b3), calib>CYCLES_TO_CALIB 
  if (calib and 1) then 
    wlog cint(yaw);"°", pitch, roll, calib>CYCLES_TO_CALIB 
  endif
  calib = calib + 1

  pause 100
  px = cos(-yaw/180*PI)*3 + 2
  py = sin(-yaw/180*PI)*3 + 2
  draw_pixel px, py, 255
wend

end

sub draw_pixel x, y, col
  if x < 0 then x = 0 else if x > 4 then x = 4
  if y < 0 then y = 0 else if y > 4 then y = 4
  neo.strip 0, 24, 0, 1 'clear all the strip without refreshing
  neo.pixel cint(x) + cint(y)*5, col
end sub
You do not have the required permissions to view the files attached to this post.
Post Reply