Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 11:12 01 Aug 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : BNO055: The best position sensor BUT!!

     Page 1 of 2    
Author Message
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10310
Posted: 02:02pm 20 Jan 2018
Copy link to clipboard 
Print this post

The BNO055 is a nine axis position sensor like others on the market BUT it also has on-chip a 32-bit processor that does all the hard calculations for you, so you can read off the absolute orientation with no calcs needed on the Micromite.

Applications of the device are numerous:
Digital level
Tilt compensated compass
Attitude indicator
Pedometer

etc. etc.

I'll start by dealing with the BUT

You can buy it off Adafruit but it is expensive

You can also buy two versions from the usual ebay/Alieexpress suppliers. One version should be completely avoided. It cannot be configured for I2C operation. Picture at the bottom.

The one to buy is this one




but you will probably receive one looking like this (three out of three for me)




Note that the zero ohm resistor to the right of the picture is in a different place. As received it shorts out VCC to GND whereas it is supposed to link power from the incoming feed to the chip. The resistor is 0603 size and should be swapped with the capacitor above it. Not easy but very do-able. Note also that links S0 and S1 must be made (connect to - ) which puts the chip into I2C mode.
The vendors supply a 32KHz crystal which can be fitted to provide the BNO055's internal processor with a more accurate clock (by default uses internal RC) but I haven't got this to work on the PCBs supplied ( a simple I2C command is supposed to enable it) so it is probably best omitted. I suspect the load capacitors for the crystal are completely the wrong value.

After these changes are done using the chip is simplicity itself.

My main program is:

i2c open 100,1000
pause 500
id = readByte(CHIP_ID_ADDR)
if id <> BNO055_ID THEN
print "Chip not found"
else
PRINT "OK"
endif
writeByte(OPR_MODE_ADDR,&B1100) 'turn on fusion mode
writeByte(UNIT_SEL_ADDR,&B0) 'set output in degrees
pause 50
do
pause 500
readEUL
loop
end


The code to read the orientation (Euler angles) is:

sub readEUL
local a$
local float i,j,k
i2c write BNO055_ADDRESS,1,1,EULER_H_LSB_ADDR
pause 10
i2c read BNO055_ADDRESS,0,6,a$
i=intconv(left$(a$,2),1)/16
j=intconv(mid$(a$,3,2),1)/16
k=intconv(right$(a$,2),1)/16
print "Heading :".i," Roll: ",j," Pitch :",k
end sub


and there is one sneaky subroutine that loads the incoming bytes into an integer as a signed value

Function intconv(s$, p%) as integer
local integer l,k,j,i=len(s$)
k=peek(varaddr j)
for l=1 to i
poke byte k+l-1,asc(mid$(s$,l,1))
next l
if p% then
if (asc(mid$(s$,i,1)) and &H80) then
for l=i to 7
poke byte k+l,&HFF
next l
endif
endif
intconv=j
End Function


Assuming the wiring is correct the program will then report the absolute orientation of the sensor every half second

Wiring is:
VCC - 3.3V
GND - GND
ATX (also labelled TX-SDA) - Micromite I2C-DATA
LRX (also labelled RX-SCL) - Micromite I2C-CLOCK
I2C (also labelled COM3-I2c_SEL) - GND

The I2C pin selects the part address.

Full listing including all the address constants

Option explicit
option default NONE
CONST BNO055_ADDRESS_A = &H28 'connectI2C-SEL to GND
CONST BNO055_ADDRESS_B = &H29 'connectI2C-SEL to VCC
CONST BNO055_ID = &HA0
CONST PAGE_ID_ADDR = &H07

' PAGE0 REGISTER DEFINITION START
CONST CHIP_ID_ADDR = &H00
CONST ACCEL_REV_ID_ADDR = &H01
CONST MAG_REV_ID_ADDR = &H02
CONST GYRO_REV_ID_ADDR = &H03
CONST SW_REV_ID_LSB_ADDR = &H04
CONST SW_REV_ID_MSB_ADDR = &H05
CONST BL_REV_ID_ADDR = &H06

' Accel data register
CONST ACCEL_DATA_X_LSB_ADDR = &H08
CONST ACCEL_DATA_X_MSB_ADDR = &H09
CONST ACCEL_DATA_Y_LSB_ADDR = &H0A
CONST ACCEL_DATA_Y_MSB_ADDR = &H0B
CONST ACCEL_DATA_Z_LSB_ADDR = &H0C
CONST ACCEL_DATA_Z_MSB_ADDR = &H0D

' Mag data register
CONST MAG_DATA_X_LSB_ADDR= &H0E
CONST MAG_DATA_X_MSB_ADDR= &H0F
CONST MAG_DATA_Y_LSB_ADDR= &H10
CONST MAG_DATA_Y_MSB_ADDR= &H11
CONST MAG_DATA_Z_LSB_ADDR= &H12
CONST MAG_DATA_Z_MSB_ADDR= &H13

' Gyro data registers
CONST GYRO_DATA_X_LSB_ADDR = &H14
CONST GYRO_DATA_X_MSB_ADDR = &H15
CONST GYRO_DATA_Y_LSB_ADDR = &H16
CONST GYRO_DATA_Y_MSB_ADDR = &H17
CONST GYRO_DATA_Z_LSB_ADDR = &H18
CONST GYRO_DATA_Z_MSB_ADDR = &H19

' Euler data registers
CONST EULER_H_LSB_ADDR = &H1A
CONST EULER_H_MSB_ADDR = &H1B
CONST EULER_R_LSB_ADDR = &H1C
CONST EULER_R_MSB_ADDR = &H1D
CONST EULER_P_LSB_ADDR = &H1E
CONST EULER_P_MSB_ADDR = &H1F

' Quaternion data registers
CONST QUATERNION_DATA_W_LSB_ADDR = &H20
CONST QUATERNION_DATA_W_MSB_ADDR = &H21
CONST QUATERNION_DATA_X_LSB_ADDR = &H22
CONST QUATERNION_DATA_X_MSB_ADDR = &H23
CONST QUATERNION_DATA_Y_LSB_ADDR = &H24
CONST QUATERNION_DATA_Y_MSB_ADDR = &H25
CONST QUATERNION_DATA_Z_LSB_ADDR = &H26
CONST QUATERNION_DATA_Z_MSB_ADDR = &H27

' Linear acceleration data registers
CONST LINEAR_ACCEL_DATA_X_LSB_ADDR = &H28
CONST LINEAR_ACCEL_DATA_X_MSB_ADDR = &H29
CONST LINEAR_ACCEL_DATA_Y_LSB_ADDR = &H2A
CONST LINEAR_ACCEL_DATA_Y_MSB_ADDR = &H2B
CONST LINEAR_ACCEL_DATA_Z_LSB_ADDR = &H2C
CONST LINEAR_ACCEL_DATA_Z_MSB_ADDR = &H2D

' Gravity data registers
CONST GRAVITY_DATA_X_LSB_ADDR = &H2E
CONST BNO055_GRAVITY_DATA_X_MSB_ADDR = &H2F
CONST GRAVITY_DATA_Y_LSB_ADDR = &H30
CONST GRAVITY_DATA_Y_MSB_ADDR = &H31
CONST GRAVITY_DATA_Z_LSB_ADDR = &H32
CONST GRAVITY_DATA_Z_MSB_ADDR = &H33

' Temperature data register
CONST TEMP_ADDR = &H34

' Status registers
CONST CALIB_STAT_ADDR = &H35
CONST SELFTEST_RESULT_ADDR = &H36
CONST INTR_STAT_ADDR = &H37

CONST SYS_CLK_STAT_ADDR = &H38
CONST SYS_STAT_ADDR= &H39
CONST SYS_ERR_ADDR = &H3A

' Unit selection register
CONST UNIT_SEL_ADDR= &H3B
CONST DATA_SELECT_ADDR = &H3C

' Mode registers
CONST OPR_MODE_ADDR= &H3D
CONST PWR_MODE_ADDR= &H3E

CONST SYS_TRIGGER_ADDR = &H3F
CONST TEMP_SOURCE_ADDR = &H40

' Axis remap registers
CONST AXIS_MAP_CONFIG_ADDR = &H41
CONST AXIS_MAP_SIGN_ADDR = &H42

' SIC registers
CONST SIC_MATRIX_0_LSB_ADDR = &H43
CONST SIC_MATRIX_0_MSB_ADDR = &H44
CONST SIC_MATRIX_1_LSB_ADDR = &H45
CONST SIC_MATRIX_1_MSB_ADDR = &H46
CONST SIC_MATRIX_2_LSB_ADDR = &H47
CONST SIC_MATRIX_2_MSB_ADDR = &H48
CONST SIC_MATRIX_3_LSB_ADDR = &H49
CONST SIC_MATRIX_3_MSB_ADDR = &H4A
CONST SIC_MATRIX_4_LSB_ADDR = &H4B
CONST SIC_MATRIX_4_MSB_ADDR = &H4C
CONST BNO055_SIC_MATRIX_5_LSB_ADDR = &H4D
CONST SIC_MATRIX_5_MSB_ADDR = &H4E
CONST SIC_MATRIX_6_LSB_ADDR = &H4F
CONST SIC_MATRIX_6_MSB_ADDR = &H50
CONST SIC_MATRIX_7_LSB_ADDR = &H51
CONST SIC_MATRIX_7_MSB_ADDR = &H52
CONST SIC_MATRIX_8_LSB_ADDR = &H53
CONST SIC_MATRIX_8_MSB_ADDR = &H54

' Accelerometer Offset registers
CONST ACCEL_OFFSET_X_LSB_ADDR = &H55
CONST ACCEL_OFFSET_X_MSB_ADDR = &H56
CONST ACCEL_OFFSET_Y_LSB_ADDR = &H57
CONST ACCEL_OFFSET_Y_MSB_ADDR = &H58
CONST ACCEL_OFFSET_Z_LSB_ADDR = &H59
CONST ACCEL_OFFSET_Z_MSB_ADDR = &H5A

' Magnetometer Offset registers
CONST MAG_OFFSET_X_LSB_ADDR = &H5B
CONST MAG_OFFSET_X_MSB_ADDR = &H5C
CONST MAG_OFFSET_Y_LSB_ADDR = &H5D
CONST MAG_OFFSET_Y_MSB_ADDR = &H5E
CONST MAG_OFFSET_Z_LSB_ADDR = &H5F
CONST MAG_OFFSET_Z_MSB_ADDR = &H60

' Gyroscope Offset register s
CONST GYRO_OFFSET_X_LSB_ADDR = &H61
CONST GYRO_OFFSET_X_MSB_ADDR = &H62
CONST GYRO_OFFSET_Y_LSB_ADDR = &H63
CONST GYRO_OFFSET_Y_MSB_ADDR = &H64
CONST GYRO_OFFSET_Z_LSB_ADDR = &H65
CONST GYRO_OFFSET_Z_MSB_ADDR = &H66

' Radius registers
CONST ACCEL_RADIUS_LSB_ADDR = &H67
CONST ACCEL_RADIUS_MSB_ADDR = &H68
CONST MAG_RADIUS_LSB_ADDR = &H69
CONST MAG_RADIUS_MSB_ADDR = &H6A
' Power Mode Settings
CONST POWER_MODE_NORMAL = &H00
CONST POWER_MODE_LOWPOWER = &H01
CONST POWER_MODE_SUSPEND = &H02
' Operation mode settings
CONST OPERATION_MODE_CONFIG = &H00
CONST OPERATION_MODE_ACCONLY = &H01
CONST OPERATION_MODE_MAGONLY = &H02
CONST OPERATION_MODE_GYRONLY = &H03
CONST OPERATION_MODE_ACCMAG = &H04
CONST OPERATION_MODE_ACCGYRO = &H05
CONST OPERATION_MODE_MAGGYRO = &H06
CONST OPERATION_MODE_AMG = &H07
CONST OPERATION_MODE_IMUPLUS = &H08
CONST OPERATION_MODE_COMPASS = &H09
CONST OPERATION_MODE_M4G = &H0A
CONST OPERATION_MODE_NDOF_FMC_OFF = &H0B
CONST OPERATION_MODE_NDOF = &H0C
CONST REMAP_CONFIG_P0 = &H21
CONST REMAP_CONFIG_P1 = &H24 ' default
CONST REMAP_CONFIG_P2 = &H24
CONST REMAP_CONFIG_P3 = &H21
CONST REMAP_CONFIG_P4 = &H24
CONST REMAP_CONFIG_P5 = &H21
CONST REMAP_CONFIG_P6 = &H21
CONST REMAP_CONFIG_P7 = &H24
CONST REMAP_SIGN_P0 = &H04
CONST REMAP_SIGN_P1 = &H00 ' default
CONST REMAP_SIGN_P2 = &H06
CONST REMAP_SIGN_P3 = &H02
CONST REMAP_SIGN_P4 = &H03
CONST REMAP_SIGN_P5 = &H01
CONST REMAP_SIGN_P6 = &H07
CONST REMAP_SIGN_P7 = &H05
DIM INTEGER id
DIM INTEGER BNO055_ADDRESS = BNO055_ADDRESS_A
'
i2c open 100,1000
pause 500
id = readByte(CHIP_ID_ADDR)
if id <> BNO055_ID THEN
print "Chip not found"
else
PRINT "OK"
endif
writeByte(OPR_MODE_ADDR,&B1100) 'turn on fusion mode
writeByte(UNIT_SEL_ADDR,&B0) 'set output in degrees
pause 50
do
pause 500
readEUL
loop
end

sub writeByte(reg%,value%)
i2c write BNO055_ADDRESS,0,2,reg%,value%
end sub
'
function readByte(reg%) as integer
i2c write BNO055_ADDRESS,1,1,reg%
pause 100
i2c read BNO055_ADDRESS,0,1,readByte

end function

sub readEUL
local a$
local float i,j,k
i2c write BNO055_ADDRESS,1,1,EULER_H_LSB_ADDR
pause 10
i2c read BNO055_ADDRESS,0,6,a$
i=intconv(left$(a$,2),1)/16
j=intconv(mid$(a$,3,2),1)/16
k=intconv(right$(a$,2),1)/16
print "Heading :".i," Roll: ",j," Pitch :",k
end sub

sub readQUAT
local a$
local float qw,qx,qy,qz,s=1<<14
i2c write BNO055_ADDRESS,1,1,QUATERNION_DATA_W_LSB_ADDR
pause 10
i2c read BNO055_ADDRESS,0,8,a$
qw=intconv(left$(a$,2),1)/s
qx=intconv(mid$(a$,3,2),1)/s
qy=intconv(mid$(a$,5,2),1)/s
qz=intconv(right$(a$,2),1)/s
print qw," ",qx," ",qy," ",qz

end sub

Function intconv(s$, p%) as integer
local integer l,k,j,i=len(s$)
k=peek(varaddr j)
for l=1 to i
poke byte k+l-1,asc(mid$(s$,l,1))
next l
if p% then
if (asc(mid$(s$,i,1)) and &H80) then
for l=i to 7
poke byte k+l,&HFF
next l
endif
endif
intconv=j
End Function













Edited by matherp 2018-01-22
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1993
Posted: 12:19am 21 Jan 2018
Copy link to clipboard 
Print this post

Looks good Peter, I have tried to get your previous compass to work using the Navigation PCB and GY-91 but had trouble with the calibration. The calibration routine ran and I substituted the values into the code but the compass was not accurate. Any chance of some compass code for this module, it is a bit beyond me.
Paul.
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10310
Posted: 10:05am 21 Jan 2018
Copy link to clipboard 
Print this post

  Quote   Any chance of some compass code for this module, it is a bit beyond me.


That is the beauty of this device - there is almost no code to write as it does it all for you. Just put it into "COMPASS" mode, waggle it about until it says it is calibrated (which it does automatically) and start reading the heading.

Code example attached below, but remember you are unlikely to see any sort of linear change in heading on the electronics bench. You should see repeat-ability in fixed orientations and of course the change should be monotonic but don't expect south to be 180 degrees from north unless you are in a electrically very quiet environment.

Note calibration continues after you get the flag and values will change until fully settled down.

Option explicit
option default NONE
CONST BNO055_ADDRESS_A = &H28 'connectI2C-SEL to GND
CONST BNO055_ADDRESS_B = &H29 'connectI2C-SEL to VCC
CONST BNO055_ID = &HA0
CONST PAGE_ID_ADDR = &H07

' PAGE0 REGISTER DEFINITION START
CONST CHIP_ID_ADDR = &H00
CONST ACCEL_REV_ID_ADDR = &H01
CONST MAG_REV_ID_ADDR = &H02
CONST GYRO_REV_ID_ADDR = &H03
CONST SW_REV_ID_LSB_ADDR = &H04
CONST SW_REV_ID_MSB_ADDR = &H05
CONST BL_REV_ID_ADDR = &H06

' Accel data register
CONST ACCEL_DATA_X_LSB_ADDR = &H08
CONST ACCEL_DATA_X_MSB_ADDR = &H09
CONST ACCEL_DATA_Y_LSB_ADDR = &H0A
CONST ACCEL_DATA_Y_MSB_ADDR = &H0B
CONST ACCEL_DATA_Z_LSB_ADDR = &H0C
CONST ACCEL_DATA_Z_MSB_ADDR = &H0D

' Mag data register
CONST MAG_DATA_X_LSB_ADDR= &H0E
CONST MAG_DATA_X_MSB_ADDR= &H0F
CONST MAG_DATA_Y_LSB_ADDR= &H10
CONST MAG_DATA_Y_MSB_ADDR= &H11
CONST MAG_DATA_Z_LSB_ADDR= &H12
CONST MAG_DATA_Z_MSB_ADDR= &H13

' Gyro data registers
CONST GYRO_DATA_X_LSB_ADDR = &H14
CONST GYRO_DATA_X_MSB_ADDR = &H15
CONST GYRO_DATA_Y_LSB_ADDR = &H16
CONST GYRO_DATA_Y_MSB_ADDR = &H17
CONST GYRO_DATA_Z_LSB_ADDR = &H18
CONST GYRO_DATA_Z_MSB_ADDR = &H19

' Euler data registers
CONST EULER_H_LSB_ADDR = &H1A
CONST EULER_H_MSB_ADDR = &H1B
CONST EULER_R_LSB_ADDR = &H1C
CONST EULER_R_MSB_ADDR = &H1D
CONST EULER_P_LSB_ADDR = &H1E
CONST EULER_P_MSB_ADDR = &H1F

' Quaternion data registers
CONST QUATERNION_DATA_W_LSB_ADDR = &H20
CONST QUATERNION_DATA_W_MSB_ADDR = &H21
CONST QUATERNION_DATA_X_LSB_ADDR = &H22
CONST QUATERNION_DATA_X_MSB_ADDR = &H23
CONST QUATERNION_DATA_Y_LSB_ADDR = &H24
CONST QUATERNION_DATA_Y_MSB_ADDR = &H25
CONST QUATERNION_DATA_Z_LSB_ADDR = &H26
CONST QUATERNION_DATA_Z_MSB_ADDR = &H27

' Linear acceleration data registers
CONST LINEAR_ACCEL_DATA_X_LSB_ADDR = &H28
CONST LINEAR_ACCEL_DATA_X_MSB_ADDR = &H29
CONST LINEAR_ACCEL_DATA_Y_LSB_ADDR = &H2A
CONST LINEAR_ACCEL_DATA_Y_MSB_ADDR = &H2B
CONST LINEAR_ACCEL_DATA_Z_LSB_ADDR = &H2C
CONST LINEAR_ACCEL_DATA_Z_MSB_ADDR = &H2D

' Gravity data registers
CONST GRAVITY_DATA_X_LSB_ADDR = &H2E
CONST BNO055_GRAVITY_DATA_X_MSB_ADDR = &H2F
CONST GRAVITY_DATA_Y_LSB_ADDR = &H30
CONST GRAVITY_DATA_Y_MSB_ADDR = &H31
CONST GRAVITY_DATA_Z_LSB_ADDR = &H32
CONST GRAVITY_DATA_Z_MSB_ADDR = &H33

' Temperature data register
CONST TEMP_ADDR = &H34

' Status registers
CONST CALIB_STAT_ADDR = &H35
CONST SELFTEST_RESULT_ADDR = &H36
CONST INTR_STAT_ADDR = &H37

CONST SYS_CLK_STAT_ADDR = &H38
CONST SYS_STAT_ADDR= &H39
CONST SYS_ERR_ADDR = &H3A

' Unit selection register
CONST UNIT_SEL_ADDR= &H3B
CONST DATA_SELECT_ADDR = &H3C

' Mode registers
CONST OPR_MODE_ADDR= &H3D
CONST PWR_MODE_ADDR= &H3E

CONST SYS_TRIGGER_ADDR = &H3F
CONST TEMP_SOURCE_ADDR = &H40

' Axis remap registers
CONST AXIS_MAP_CONFIG_ADDR = &H41
CONST AXIS_MAP_SIGN_ADDR = &H42

' SIC registers
CONST SIC_MATRIX_0_LSB_ADDR = &H43
CONST SIC_MATRIX_0_MSB_ADDR = &H44
CONST SIC_MATRIX_1_LSB_ADDR = &H45
CONST SIC_MATRIX_1_MSB_ADDR = &H46
CONST SIC_MATRIX_2_LSB_ADDR = &H47
CONST SIC_MATRIX_2_MSB_ADDR = &H48
CONST SIC_MATRIX_3_LSB_ADDR = &H49
CONST SIC_MATRIX_3_MSB_ADDR = &H4A
CONST SIC_MATRIX_4_LSB_ADDR = &H4B
CONST SIC_MATRIX_4_MSB_ADDR = &H4C
CONST BNO055_SIC_MATRIX_5_LSB_ADDR = &H4D
CONST SIC_MATRIX_5_MSB_ADDR = &H4E
CONST SIC_MATRIX_6_LSB_ADDR = &H4F
CONST SIC_MATRIX_6_MSB_ADDR = &H50
CONST SIC_MATRIX_7_LSB_ADDR = &H51
CONST SIC_MATRIX_7_MSB_ADDR = &H52
CONST SIC_MATRIX_8_LSB_ADDR = &H53
CONST SIC_MATRIX_8_MSB_ADDR = &H54

' Accelerometer Offset registers
CONST ACCEL_OFFSET_X_LSB_ADDR = &H55
CONST ACCEL_OFFSET_X_MSB_ADDR = &H56
CONST ACCEL_OFFSET_Y_LSB_ADDR = &H57
CONST ACCEL_OFFSET_Y_MSB_ADDR = &H58
CONST ACCEL_OFFSET_Z_LSB_ADDR = &H59
CONST ACCEL_OFFSET_Z_MSB_ADDR = &H5A

' Magnetometer Offset registers
CONST MAG_OFFSET_X_LSB_ADDR = &H5B
CONST MAG_OFFSET_X_MSB_ADDR = &H5C
CONST MAG_OFFSET_Y_LSB_ADDR = &H5D
CONST MAG_OFFSET_Y_MSB_ADDR = &H5E
CONST MAG_OFFSET_Z_LSB_ADDR = &H5F
CONST MAG_OFFSET_Z_MSB_ADDR = &H60

' Gyroscope Offset register s
CONST GYRO_OFFSET_X_LSB_ADDR = &H61
CONST GYRO_OFFSET_X_MSB_ADDR = &H62
CONST GYRO_OFFSET_Y_LSB_ADDR = &H63
CONST GYRO_OFFSET_Y_MSB_ADDR = &H64
CONST GYRO_OFFSET_Z_LSB_ADDR = &H65
CONST GYRO_OFFSET_Z_MSB_ADDR = &H66

' Radius registers
CONST ACCEL_RADIUS_LSB_ADDR = &H67
CONST ACCEL_RADIUS_MSB_ADDR = &H68
CONST MAG_RADIUS_LSB_ADDR = &H69
CONST MAG_RADIUS_MSB_ADDR = &H6A
' Power Mode Settings
CONST POWER_MODE_NORMAL = &H00
CONST POWER_MODE_LOWPOWER = &H01
CONST POWER_MODE_SUSPEND = &H02
' Operation mode settings
CONST OPERATION_MODE_CONFIG = &H00
CONST OPERATION_MODE_ACCONLY = &H01
CONST OPERATION_MODE_MAGONLY = &H02
CONST OPERATION_MODE_GYRONLY = &H03
CONST OPERATION_MODE_ACCMAG = &H04
CONST OPERATION_MODE_ACCGYRO = &H05
CONST OPERATION_MODE_MAGGYRO = &H06
CONST OPERATION_MODE_AMG = &H07
CONST OPERATION_MODE_IMUPLUS = &H08
CONST OPERATION_MODE_COMPASS = &H09
CONST OPERATION_MODE_M4G = &H0A
CONST OPERATION_MODE_NDOF_FMC_OFF = &H0B
CONST OPERATION_MODE_NDOF = &H0C
CONST REMAP_CONFIG_P0 = &H21
CONST REMAP_CONFIG_P1 = &H24 ' default
CONST REMAP_CONFIG_P2 = &H24
CONST REMAP_CONFIG_P3 = &H21
CONST REMAP_CONFIG_P4 = &H24
CONST REMAP_CONFIG_P5 = &H21
CONST REMAP_CONFIG_P6 = &H21
CONST REMAP_CONFIG_P7 = &H24
CONST REMAP_SIGN_P0 = &H04
CONST REMAP_SIGN_P1 = &H00 ' default
CONST REMAP_SIGN_P2 = &H06
CONST REMAP_SIGN_P3 = &H02
CONST REMAP_SIGN_P4 = &H03
CONST REMAP_SIGN_P5 = &H01
CONST REMAP_SIGN_P6 = &H07
CONST REMAP_SIGN_P7 = &H05
'
DIM INTEGER id
DIM INTEGER BNO055_ADDRESS = BNO055_ADDRESS_A
'
i2c open 100,1000
resetBNO
setMode(OPERATION_MODE_CONFIG)
pause 50
writeByte(UNIT_SEL_ADDR,&B0) 'set output in degrees
setMode(OPERATION_MODE_COMPASS) 'turn on fusion mode compass
pause 50
Print "Move in figures of 8 until calibrated"
do
pause 500
readEUL
loop
end
'
sub resetBNO 'reset the sensor
writeByte(SYS_TRIGGER_ADDR, &H20)
timer=0
do
pause 10
loop until readByte(CHIP_ID_ADDR)=BNO055_ID or timer>4000
if timer> 4000 then
print "BNO055 not found"
end
ENDIF
pause 50
end sub
'
sub setMode(value%) 'set to a specific operation mode (see values above)
writeByte(OPR_MODE_ADDR,value%)
timer=0
do
pause 10
loop until readByte(CHIP_ID_ADDR)=BNO055_ID or timer>4000
if timer> 4000 then
print "BNO055 not found"
end
ENDIF
pause 50
end sub
'
sub writeByte(reg%,value%) 'write a single register
i2c write BNO055_ADDRESS,0,2,reg%,value%
end sub
'
function readByte(reg%) as integer 'read a single register
i2c write BNO055_ADDRESS,1,1,reg%
pause 100
i2c read BNO055_ADDRESS,0,1,readByte
end function

sub readEUL 'read in the Euler angles
local a$
local float i,j,k
i2c write BNO055_ADDRESS,1,1,EULER_H_LSB_ADDR
pause 10
i2c read BNO055_ADDRESS,0,6,a$
i=intconv(left$(a$,2),1)/16
j=intconv(mid$(a$,3,2),1)/16
k=intconv(right$(a$,2),1)/16
if(readByte(CALIB_STAT_ADDR) AND &HC0 = &HC0) then print "Heading :",i
' print "Heading :",i," Roll: ",j," Pitch :",k, " Calibration :",bin$(readByte(CALIB_STAT_ADDR))
end sub

sub readQUAT 'read in the quaternions
local a$
local float qw,qx,qy,qz,s=1<<14
i2c write BNO055_ADDRESS,1,1,QUATERNION_DATA_W_LSB_ADDR
pause 10
i2c read BNO055_ADDRESS,0,8,a$
qw=intconv(left$(a$,2),1)/s
qx=intconv(mid$(a$,3,2),1)/s
qy=intconv(mid$(a$,5,2),1)/s
qz=intconv(right$(a$,2),1)/s
print qw," ",qx," ",qy," ",qz
end sub

Function intconv(s$, p%) as integer 'convert values to signed integers
local integer l,k,j,i=len(s$)
k=peek(varaddr j)
for l=1 to i
poke byte k+l-1,asc(mid$(s$,l,1))
next l
if p% then
if (asc(mid$(s$,i,1)) and &H80) then
for l=i to 7
poke byte k+l,&HFF
next l
endif
endif
intconv=j
End Function
Edited by matherp 2018-01-22
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1993
Posted: 08:47pm 21 Jan 2018
Copy link to clipboard 
Print this post

Thanks Peter
Paul.
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1993
Posted: 03:33am 11 Feb 2018
Copy link to clipboard 
Print this post

@ Matherp,
Sorry to trouble you.
I have got the device working and it seems to read accurately, however there is a problem.
I uncommented the line
  Quote  ' print "Heading :",i," Roll: ",j," Pitch :",k, " Calibration :",bin$(readByte(CALIB_STAT_ADDR))

so I could see the values on the screen. The calibration value is zero for the first eleven prints and then changes to 100. I assume this means it is calibrated.
The heading seems to read OK but after about 40 seconds I get an error on line
273
  Quote  Function intconv(s$, p%) as integer 'convert values to signed integers

Not Enough Memory.

Paul.

Edit. The code seems to be stuck in this loop
do
pause 500
readEUL
loop
end


Edit. After having another look I think it is meant to keep looping to
print out the heading.Edited by palcal 2018-02-12
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10310
Posted: 07:51am 11 Feb 2018
Copy link to clipboard 
Print this post

  Quote  Not Enough Memory.


You shouldn't be seeing that. What MM are you running on? If Pic-cromite or MMX please try a standard MM or MM+ and post the results. Also, please try it with just the bin$ clause removed
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1993
Posted: 08:37am 11 Feb 2018
Copy link to clipboard 
Print this post

Running on a 28 pin Micromite Backpack.
Will remove the bin$ line soon.
Paul.Edited by palcal 2018-02-12
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2170
Posted: 08:37am 11 Feb 2018
Copy link to clipboard 
Print this post

any use? Pure bit/maths solution and fast

http://www.fruitoftheshed.com/MMBasic.Sign-Extend-an-Integer.ashx?HL=sign,extend Edited by CaptainBoing 2018-02-12
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10310
Posted: 08:41am 11 Feb 2018
Copy link to clipboard 
Print this post

  Quote  Running on a 28 pin Micromite Backpack.
Will remove the bin$ line soon.
Paul.


I've sent an email to Geoff linking this thread as that shouldn't be happening and suggests a memory leak of some sort
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1993
Posted: 09:05am 11 Feb 2018
Copy link to clipboard 
Print this post

I commented the line
' print "Heading :",i," Roll: ",j," Pitch :",k, " Calibration :",bin$(readByte(CALIB_STAT_ADDR))

But it makes no difference.
The line above that is....
if(readByte(CALIB_STAT_ADDR) AND &HC0 = &HC0) then print "Heading :",i

but it does not print the "Heading"
all I get when I run the code is...
  Quote  "Move in figures of 8 until calibrated"

and about 30 seconds later the "Not enough menory" error.
Paul.
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3292
Posted: 01:37pm 11 Feb 2018
Copy link to clipboard 
Print this post

There are a lot of things that can cause out of memory errors but it is unlikely to be a memory leak due to the way that memory is cleaned up after each command is executed.

It is not feasible to reverse engineer this program, can you distil this into a short program (<10 lines) that demonstrates the fault?
Geoff Graham - http://geoffg.net
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1993
Posted: 09:42pm 11 Feb 2018
Copy link to clipboard 
Print this post

Ok I found the problem, in the loop
do
pause 500
readEUL
loop


I added these lines
Text 175,60, " HEADING ",CM, 1, 3,RGB(blue),RGB(cyan)
Text 110,150, Heading$,CM, 1, 3,RGB(blue),RGB(cyan)
Text 240,155, "Degrees",CM,1,2,RGB(Blue),RGB(Cyan)

So it would print to the TFT screen and that causes the problem.WHY?
Paul.

Edit. I also added a line to the 'Sub EUL'
Heading$ = Str$(i,3)

Edited by palcal 2018-02-13
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 05:57am 12 Feb 2018
Copy link to clipboard 
Print this post

Paul,
I finally got the courage up enough to re-solder the chips on my board.
I wasn't able to create any memory problems on a 28 pin 'mite with LCD attached.

This code has the LCD print statements you added as well as a MEMORY command which outputs to the console.
OPTION EXPLICIT
OPTION DEFAULT NONE
CONST BNO055_ADDRESS_A = &H28 'connectI2C-SEL to GND
CONST BNO055_ADDRESS_B = &H29 'connectI2C-SEL to VCC
CONST BNO055_ID = &HA0
CONST PAGE_ID_ADDR = &H07

' PAGE0 REGISTER DEFINITION START
CONST CHIP_ID_ADDR = &H00
CONST ACCEL_REV_ID_ADDR = &H01
CONST MAG_REV_ID_ADDR = &H02
CONST GYRO_REV_ID_ADDR = &H03
CONST SW_REV_ID_LSB_ADDR = &H04
CONST SW_REV_ID_MSB_ADDR = &H05
CONST BL_REV_ID_ADDR = &H06

' Accel data register
CONST ACCEL_DATA_X_LSB_ADDR = &H08
CONST ACCEL_DATA_X_MSB_ADDR = &H09
CONST ACCEL_DATA_Y_LSB_ADDR = &H0A
CONST ACCEL_DATA_Y_MSB_ADDR = &H0B
CONST ACCEL_DATA_Z_LSB_ADDR = &H0C
CONST ACCEL_DATA_Z_MSB_ADDR = &H0D

' Mag data register
CONST MAG_DATA_X_LSB_ADDR= &H0E
CONST MAG_DATA_X_MSB_ADDR= &H0F
CONST MAG_DATA_Y_LSB_ADDR= &H10
CONST MAG_DATA_Y_MSB_ADDR= &H11
CONST MAG_DATA_Z_LSB_ADDR= &H12
CONST MAG_DATA_Z_MSB_ADDR= &H13

' Gyro data registers
CONST GYRO_DATA_X_LSB_ADDR = &H14
CONST GYRO_DATA_X_MSB_ADDR = &H15
CONST GYRO_DATA_Y_LSB_ADDR = &H16
CONST GYRO_DATA_Y_MSB_ADDR = &H17
CONST GYRO_DATA_Z_LSB_ADDR = &H18
CONST GYRO_DATA_Z_MSB_ADDR = &H19

' Euler data registers
CONST EULER_H_LSB_ADDR = &H1A
CONST EULER_H_MSB_ADDR = &H1B
CONST EULER_R_LSB_ADDR = &H1C
CONST EULER_R_MSB_ADDR = &H1D
CONST EULER_P_LSB_ADDR = &H1E
CONST EULER_P_MSB_ADDR = &H1F

' Quaternion data registers
CONST QUATERNION_DATA_W_LSB_ADDR = &H20
CONST QUATERNION_DATA_W_MSB_ADDR = &H21
CONST QUATERNION_DATA_X_LSB_ADDR = &H22
CONST QUATERNION_DATA_X_MSB_ADDR = &H23
CONST QUATERNION_DATA_Y_LSB_ADDR = &H24
CONST QUATERNION_DATA_Y_MSB_ADDR = &H25
CONST QUATERNION_DATA_Z_LSB_ADDR = &H26
CONST QUATERNION_DATA_Z_MSB_ADDR = &H27

' Linear acceleration data registers
CONST LINEAR_ACCEL_DATA_X_LSB_ADDR = &H28
CONST LINEAR_ACCEL_DATA_X_MSB_ADDR = &H29
CONST LINEAR_ACCEL_DATA_Y_LSB_ADDR = &H2A
CONST LINEAR_ACCEL_DATA_Y_MSB_ADDR = &H2B
CONST LINEAR_ACCEL_DATA_Z_LSB_ADDR = &H2C
CONST LINEAR_ACCEL_DATA_Z_MSB_ADDR = &H2D

' Gravity data registers
CONST GRAVITY_DATA_X_LSB_ADDR = &H2E
CONST BNO055_GRAVITY_DATA_X_MSB_ADDR = &H2F
CONST GRAVITY_DATA_Y_LSB_ADDR = &H30
CONST GRAVITY_DATA_Y_MSB_ADDR = &H31
CONST GRAVITY_DATA_Z_LSB_ADDR = &H32
CONST GRAVITY_DATA_Z_MSB_ADDR = &H33

' Temperature data register
CONST TEMP_ADDR = &H34

' Status registers
CONST CALIB_STAT_ADDR = &H35
CONST SELFTEST_RESULT_ADDR = &H36
CONST INTR_STAT_ADDR = &H37

CONST SYS_CLK_STAT_ADDR = &H38
CONST SYS_STAT_ADDR= &H39
CONST SYS_ERR_ADDR = &H3A

' Unit selection register
CONST UNIT_SEL_ADDR= &H3B
CONST DATA_SELECT_ADDR = &H3C

' Mode registers
CONST OPR_MODE_ADDR= &H3D
CONST PWR_MODE_ADDR= &H3E

CONST SYS_TRIGGER_ADDR = &H3F
CONST TEMP_SOURCE_ADDR = &H40

' Axis remap registers
CONST AXIS_MAP_CONFIG_ADDR = &H41
CONST AXIS_MAP_SIGN_ADDR = &H42

' SIC registers
CONST SIC_MATRIX_0_LSB_ADDR = &H43
CONST SIC_MATRIX_0_MSB_ADDR = &H44
CONST SIC_MATRIX_1_LSB_ADDR = &H45
CONST SIC_MATRIX_1_MSB_ADDR = &H46
CONST SIC_MATRIX_2_LSB_ADDR = &H47
CONST SIC_MATRIX_2_MSB_ADDR = &H48
CONST SIC_MATRIX_3_LSB_ADDR = &H49
CONST SIC_MATRIX_3_MSB_ADDR = &H4A
CONST SIC_MATRIX_4_LSB_ADDR = &H4B
CONST SIC_MATRIX_4_MSB_ADDR = &H4C
CONST BNO055_SIC_MATRIX_5_LSB_ADDR = &H4D
CONST SIC_MATRIX_5_MSB_ADDR = &H4E
CONST SIC_MATRIX_6_LSB_ADDR = &H4F
CONST SIC_MATRIX_6_MSB_ADDR = &H50
CONST SIC_MATRIX_7_LSB_ADDR = &H51
CONST SIC_MATRIX_7_MSB_ADDR = &H52
CONST SIC_MATRIX_8_LSB_ADDR = &H53
CONST SIC_MATRIX_8_MSB_ADDR = &H54

' Accelerometer Offset registers
CONST ACCEL_OFFSET_X_LSB_ADDR = &H55
CONST ACCEL_OFFSET_X_MSB_ADDR = &H56
CONST ACCEL_OFFSET_Y_LSB_ADDR = &H57
CONST ACCEL_OFFSET_Y_MSB_ADDR = &H58
CONST ACCEL_OFFSET_Z_LSB_ADDR = &H59
CONST ACCEL_OFFSET_Z_MSB_ADDR = &H5A

' Magnetometer Offset registers
CONST MAG_OFFSET_X_LSB_ADDR = &H5B
CONST MAG_OFFSET_X_MSB_ADDR = &H5C
CONST MAG_OFFSET_Y_LSB_ADDR = &H5D
CONST MAG_OFFSET_Y_MSB_ADDR = &H5E
CONST MAG_OFFSET_Z_LSB_ADDR = &H5F
CONST MAG_OFFSET_Z_MSB_ADDR = &H60

' Gyroscope Offset register s
CONST GYRO_OFFSET_X_LSB_ADDR = &H61
CONST GYRO_OFFSET_X_MSB_ADDR = &H62
CONST GYRO_OFFSET_Y_LSB_ADDR = &H63
CONST GYRO_OFFSET_Y_MSB_ADDR = &H64
CONST GYRO_OFFSET_Z_LSB_ADDR = &H65
CONST GYRO_OFFSET_Z_MSB_ADDR = &H66

' Radius registers
CONST ACCEL_RADIUS_LSB_ADDR = &H67
CONST ACCEL_RADIUS_MSB_ADDR = &H68
CONST MAG_RADIUS_LSB_ADDR = &H69
CONST MAG_RADIUS_MSB_ADDR = &H6A
' Power Mode Settings
CONST POWER_MODE_NORMAL = &H00
CONST POWER_MODE_LOWPOWER = &H01
CONST POWER_MODE_SUSPEND = &H02
' Operation mode settings
CONST OPERATION_MODE_CONFIG = &H00
CONST OPERATION_MODE_ACCONLY = &H01
CONST OPERATION_MODE_MAGONLY = &H02
CONST OPERATION_MODE_GYRONLY = &H03
CONST OPERATION_MODE_ACCMAG = &H04
CONST OPERATION_MODE_ACCGYRO = &H05
CONST OPERATION_MODE_MAGGYRO = &H06
CONST OPERATION_MODE_AMG = &H07
CONST OPERATION_MODE_IMUPLUS = &H08
CONST OPERATION_MODE_COMPASS = &H09
CONST OPERATION_MODE_M4G = &H0A
CONST OPERATION_MODE_NDOF_FMC_OFF = &H0B
CONST OPERATION_MODE_NDOF = &H0C
CONST REMAP_CONFIG_P0 = &H21
CONST REMAP_CONFIG_P1 = &H24 ' default
CONST REMAP_CONFIG_P2 = &H24
CONST REMAP_CONFIG_P3 = &H21
CONST REMAP_CONFIG_P4 = &H24
CONST REMAP_CONFIG_P5 = &H21
CONST REMAP_CONFIG_P6 = &H21
CONST REMAP_CONFIG_P7 = &H24
CONST REMAP_SIGN_P0 = &H04
CONST REMAP_SIGN_P1 = &H00 ' default
CONST REMAP_SIGN_P2 = &H06
CONST REMAP_SIGN_P3 = &H02
CONST REMAP_SIGN_P4 = &H03
CONST REMAP_SIGN_P5 = &H01
CONST REMAP_SIGN_P6 = &H07
CONST REMAP_SIGN_P7 = &H05
'
DIM INTEGER id
DIM INTEGER BNO055_ADDRESS = BNO055_ADDRESS_A
DIM Heading$
'
I2C OPEN 100,1000
resetBNO
setMode(OPERATION_MODE_CONFIG)
PAUSE 50
writeByte(UNIT_SEL_ADDR,&B0) 'set output in degrees
setMode(OPERATION_MODE_COMPASS) 'turn on fusion mode compass
PAUSE 50
PRINT "Move in figures of 8 until calibrated"
CLS
DO
PAUSE 500
readEUL
TEXT 175,60, " HEADING ",CM, 1, 3,RGB(BLUE),RGB(CYAN)
TEXT 110,150, Heading$,CM, 1, 3,RGB(BLUE),RGB(CYAN)
TEXT 240,155, "Degrees",CM,1,2,RGB(BLUE),RGB(CYAN)
PRINT CHR$(27)+"[2J"+CHR$(27)+"[1;1H ",Heading$
MEMORY
LOOP
END
'
SUB resetBNO 'reset the sensor
writeByte(SYS_TRIGGER_ADDR, &H20)
TIMER=0
DO
PAUSE 10
LOOP UNTIL readByte(CHIP_ID_ADDR)=BNO055_ID OR TIMER>4000
IF TIMER> 4000 THEN
PRINT "BNO055 not found"
END
ENDIF
PAUSE 50
END SUB
'
SUB setMode(value%) 'set to a specific operation mode (see values above)
writeByte(OPR_MODE_ADDR,value%)
TIMER=0
DO
PAUSE 10
LOOP UNTIL readByte(CHIP_ID_ADDR)=BNO055_ID OR TIMER>4000
IF TIMER> 4000 THEN
PRINT "BNO055 not found"
END
ENDIF
PAUSE 50
END SUB
'
SUB writeByte(reg%,value%) 'write a single register
I2C WRITE BNO055_ADDRESS,0,2,reg%,value%
END SUB
'
FUNCTION readByte(reg%) AS INTEGER 'read a single register
I2C WRITE BNO055_ADDRESS,1,1,reg%
PAUSE 100
I2C READ BNO055_ADDRESS,0,1,readByte
END FUNCTION

SUB readEUL 'read in the Euler angles
LOCAL a$
LOCAL FLOAT i,j,k
I2C WRITE BNO055_ADDRESS,1,1,EULER_H_LSB_ADDR
PAUSE 10
I2C READ BNO055_ADDRESS,0,6,a$
i=intconv(LEFT$(a$,2),1)/16
j=intconv(MID$(a$,3,2),1)/16
k=intconv(RIGHT$(a$,2),1)/16
IF(readByte(CALIB_STAT_ADDR) AND &HC0 = &HC0) THEN PRINT "Heading :",i
' print "Heading :",i," Roll: ",j," Pitch :",k, " Calibration :",bin$(readByte(CALIB_STAT_ADDR))
Heading$ = STR$(i,3,1)
END SUB

SUB readQUAT 'read in the quaternions
LOCAL a$
LOCAL FLOAT qw,qx,qy,qz,s=1<<14
I2C WRITE BNO055_ADDRESS,1,1,QUATERNION_DATA_W_LSB_ADDR
PAUSE 10
I2C READ BNO055_ADDRESS,0,8,a$
qw=intconv(LEFT$(a$,2),1)/s
qx=intconv(MID$(a$,3,2),1)/s
qy=intconv(MID$(a$,5,2),1)/s
qz=intconv(RIGHT$(a$,2),1)/s
PRINT qw," ",qx," ",qy," ",qz
END SUB

FUNCTION intconv(s$, p%) AS INTEGER 'convert values to signed integers
LOCAL INTEGER l,k,j,i=LEN(s$)
k=PEEK(VARADDR j)
FOR l=1 TO i
POKE BYTE k+l-1,ASC(MID$(s$,l,1))
NEXT l
IF p% THEN
IF (ASC(MID$(s$,i,1)) AND &H80) THEN
FOR l=i TO 7
POKE BYTE k+l,&HFF
NEXT l
ENDIF
ENDIF
intconv=j
END FUNCTION


I don't have my device on long enough leads to get a good idea about it's abilities.

I was able to confirm that my days of soldering those micro chips are over.
I am waiting on an appointment with a neurologist to confirm my GP's diagnosis. "It's 'Essential Tremor', something that happens to the elderly". I'm not that bloody old!
Unfortunately, the drugs that help it will not help my Asthma so I am stuck with it.

Jim
VK7JH
MMedit
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1993
Posted: 07:10am 12 Feb 2018
Copy link to clipboard 
Print this post

Well I don't know what is happening. The backpack was previously used for another project with no problems. With my code it runs for about 30 seconds before the error. I have checked it at intervals and I see the free RAM slowly dropping until the error when I have 3K free.
The error appears at this line
FUNCTION intconv(s$, p%) AS INTEGER 'convert values to signed integers

so it must run out of memory in the 'SUB readEUL".
As soon as I comment out the TEXT lines that print to the screen it runs OK.
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2170
Posted: 07:23am 12 Feb 2018
Copy link to clipboard 
Print this post

time for a re-flash - get the MM to a known state

I have had really weird behaviour - inexplicable oddness with no rhyme or reason... Flash it and it's all OK. Might not fix it in your case but like I said... known state - it's one thing you can rule out.

Two specific examples are a local variable that simply wasn't being recognised and another was a FOR-NEXT loop that wouldn't count backwards...

Try that - nothing to lose.Edited by CaptainBoing 2018-02-13
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1993
Posted: 08:30am 12 Feb 2018
Copy link to clipboard 
Print this post

@ CaptainBoing
Good suggestion will do first thing in the morning.
Paul.

"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1993
Posted: 09:12pm 12 Feb 2018
Copy link to clipboard 
Print this post

@ CaptainBoing
Thanks all, re flashing did the trick, something for me to remember when
odd things happen.
Paul.
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2170
Posted: 09:25pm 12 Feb 2018
Copy link to clipboard 
Print this post

glad you got it sorted.
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10310
Posted: 06:28pm 16 Feb 2018
Copy link to clipboard 
Print this post




If you have a BNO055 up and working
and you have a 100 or 144 pin Micromite eXtreme
and you have a 4.3" SSD1963
and you have uploaded the latest firmware.
Then you can play with my Attitude indicator code.

Set up the display using the new buffered driver OPTION LCDPANEL SSD1963_4_16_buff, L, RDpin

and run the code.

The code tests the internal sensor fusion algorithm in the BNO055 and compares it with the open source sensor fusion that I have included in the Micromite firmware. There is no comparison to my mind; the open source firmware running in double precision on the PIC32MZ is much much better and it allows you to tune the sensitivity of the fusion algorithm to optimise for your specific application (see the appendix in the Micromite eXtreme manual) .

You can choose the fusion algorithm in the demo program using the constant "FUSION"
0 = BNO055 internal
1 = Micromite eXtreme Mahony
2 = Micromite eXtreme Madgwick

Update rate on the display is about 18 frames per second

2018-02-17_042145_BNO055-AI.zip


Edited by matherp 2018-02-18
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1993
Posted: 12:57am 17 Feb 2018
Copy link to clipboard 
Print this post

Thanks for that Peter will try it out when I get a spare minute. At the moment my daughter is here with a whip watching me shovel 5 metres of hardwood chip out of the trailer.
Paul.
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
     Page 1 of 2    
Print this page
The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025