BNO055 failure

edmunds

Senior Member
BNO055 I2C failure

Dear all,

I have now soldered the second unit and have not hurried to dip it in epoxy, so I have good access to all the pins. Still - no joy. It is likely, the first unit was also soldered just fine, there is some other problem.

I have it connected to the bus that works - writes and reads to eeprom with no problems. I have tried i2cslow and i2cfast and various setfreq parameters. I have also experimented with pull-up resistor values, despite, clearly, 4k7 should be fine for the application. I have nReset and nBoot pins high through 10k pull-ups as per data sheet. All the caps in their respective places, too. I have tested all the voltages are driven to the respective pins and do not show anything strange.

Out of no other ideas, I have tried reading not only CHIP_ID register at $00, but also other registers and the only thing I get is 255, i.e. device is not there and not saying anything.

I started reading about 'BNO055 not responding' on other forums, mainly adafruit, because they sell a breakout board for this. Some folks are having mysterious problems and one solution seems to be to increase the limit for pulse stretching. I do remember reading about such feature in PIC data sheet, so it does ring a bell. Before I venture into something very odd, has anyone encountered a device that would require looking into such intricate details of the protocol and has it ever helped anyone?

Will have to repair the logic analyser thing, I guess...


Thank you for your time,

Edmunds
 
Last edited:

edmunds

Senior Member
The code, just in case...

Code:
Symbol data_byte = b4

{'IMU registers
Symbol CHIP_ID = $0
}

init:
  pause 1000 'wait 1s for everybody to wake up

  hi2csetup i2cmaster, IMUAddress, i2cslow, i2cbyte

  hi2cin CHIP_ID,(data_byte)                                 'Check if IMU is responding
  if data_byte <> 127 then
    sertxd (#data_byte,"; IMU not found!",LF,CR)
  else
    sertxd (#data_byte,"; IMU found!",LF,CR)
  endif
Edmunds
 

BESQUEUT

Senior Member
The code, just in case...

Code:
Symbol data_byte = b4

{'IMU registers
Symbol CHIP_ID = $0
}

init:
  pause 1000 'wait 1s for everybody to wake up

  hi2csetup i2cmaster, IMUAddress, i2cslow, i2cbyte

  hi2cin CHIP_ID,(data_byte)                                 'Check if IMU is responding
  if data_byte <> 127 then
    sertxd (#data_byte,"; IMU not found!",LF,CR)
  else
    sertxd (#data_byte,"; IMU found!",LF,CR)
  endif
Edmunds
Please, publish whole code, not only extract...
 

sages

Member
If your analyser is a scope and can show an analog graph, have a look at that to ensure it isn't a voltage issue. The analyser and the device may have different logic thresholds.
 

westaust55

Moderator
Hi Edmunds,

Can you confirm what is the IMUAddress you are assigning for the BN055.
From the datasheet
- with pin COM 3 pulled high, the default I²C address of the BNO055 device is 0101001b (0x29).
- if COM3 is pulled low then the I²C address of the BNO055 device is 0101000b (0x28).
This is the 7-bit address and thus either needs to be shifted left 1 bit so $29 ==> $52.
If I am reading the data waveform correctly with the 9 clock pulses as 7 address, 1 R/W and 1 Ack bit then the 7-bit address on the scope appears like it may depending upon polarity be $24 (or $6B).
The $24 suggests you have entered either $28 or $29 without the 1 bit shift left.
 
Last edited:

hippy

Technical Support
Staff member
I would agree with Westaust55; you appear to have the Device Address wrong. It should be either -

%0101000 7-bit when COM3 low, which is %01010000 for PICAXE, $50
%0101001 7-bit when COM3 high, which is %01010010 for PICAXE, $52

Looking at the logic analyser you are using $28 or $29 which is why the ACK is not being issued and nothing else works.

As BESQUEST says, it helps if you publish all your code, not just extracts. Your SYMBOL definition for 'IMUAddress' is critical to your code and the issue you are having.

When writing test and proof of concept code it often helps to use the actual values in commands rather than use SYMBOL definitions.
 

hippy

Technical Support
Staff member
Try running this code ...

Code:
Pause 2000
SerTxd( "Started ...", CR, LF )

Do

  HI2cSetup i2cmaster, $50, i2cslow, i2cbyte
  HI2cIn $00, (b0)
  If b0 = $A0 Then
    SerTxd( "IMU found at $50", CR, LF )
  Else
    SerTxd( "IMU not found at $50 (", #b0, ")", CR, LF )
  End If

  Pause 1000

  HI2cSetup i2cmaster, $52, i2cslow, i2cbyte
  HI2cIn $00, (b0)
  If b0 = $A0 Then
    SerTxd( "IMU found at $52", CR, LF )
  Else
    SerTxd( "IMU not found at $52 (", #b0, ")", CR, LF )
  End If

  Pause 1000

Loop
Note that it is CR,LF rather than LF,CR, and the BNO055 CHIP_ID at register $00 is $A0 according to the datasheet, which is 160, not 127.
 
Last edited:

hippy

Technical Support
Staff member
I did a search for edmunds and says it uses port 0x28
It is either 0x28 or 0x29 depending on COM3 input level but that is when represented as a 7-bit I2C Device Address.

However the PICAXE uses 8-bit Device Addresses which would be $50 or $52, and what should be specified in the HI2CSETUP command.
 

edmunds

Senior Member
Guys,

1. Thank you.
2. I'm not at home, so I cannot test this right now, but the address has to be it.
3. Sorry for incomplete code - it was actually quite complete, but I deleted a lot of register definitions I thought were not needed and accidentally deleted the address definition, too.
4. @hippy, CHIP_ID is just a remainder of some previous stuff, since I print data_byte anyway, I did not bother to correct it. Could have been done better.
5. COM3 is low, so it is 0x28 as per data sheet. In my mind that is the same as $28, just different spelling. How do one knows, when to shift the bits and when not? I seem to remember this is not the first time I have come accross this, so I should learn it for good this time. The EEPROMs, FRAMs and magnetometers I just played with worked with what's in the data sheet without shifting anything anywhere. What is the secret keyword that enlightens the knowing and leaves the rest of us in the dark?
6. I have never quite know, if LF should be before CR or vice versa :). It seems to work either way. I was just thinking if LF stands for line feed and CR for carriage return or something similar, it should first go to the next line and then move to the leftmost cursor position. Or some sort of that logic. An old mechanical typewriter comes to mind. What is it then for real?


Thank you once again,

Edmunds
 

hippy

Technical Support
Staff member
One usually has to consult the datasheet as to whether a Device Address is 7-bit or otherwise. Looking at a diagram which shows bits sent for read or write usually reveals what it is. For example, as per attachment.

CR then LF order is mostly convention; return carriage to the left, move up a line. Some things will accept either but LF before CR can sometimes cause issues.
 

Attachments

edmunds

Senior Member
One usually has to consult the datasheet as to whether a Device Address is 7-bit or otherwise. Looking at a diagram which shows bits sent for read or write usually reveals what it is. For example, as per attachment.

CR then LF order is mostly convention; return carriage to the left, move up a line. Some things will accept either but LF before CR can sometimes cause issues.
@hippy, thank you, that picture now goes up to the wall :).
The device is now talking to me, but up to m16 i2cfast mode. At the moment no success with em64 and i2cxxxx_64. Will play with it for some more.

Edmunds
 

edmunds

Senior Member
Dear all,

An update for the night.

I have tested the device by reading several different registers checking this returns something useful. As noted above, it all works fine up to 16MHz clock speed setting. I only have 64MHz available on my AXE091 for 40x2, so to try 32MHz, I had to add 20x2. While at it, I tested the lower speed modes on 20x2 as well. Same behavior there, works alright up to 16MHz. Not working at 32 and 64MHz on 20x2 is different by the bus returning 81 [device address with R/W bit set] and not 255 as on 40x2 at 64MHz.

I have [again] played with pull-up resistors on the bus, but no success there. The logic analyzer picture below. I don't have much experience with analyzing I2C, but this seems like a strange pattern. Why is the clock stretched like that?

I2Cprintscreen2.JPG


Thank you for your time,

Edmunds
 

edmunds

Senior Member
According to this, it is possible to damage BNO055 if clock stretching is not supported by the host micro... What on Earth is clock stretching :). Time to find out.

Edmunds
 

AllyCat

Senior Member
Hi,

Clock stretching is used by I2C slaves if they are not "ready" to receive the data - they hold the SCL line low until they can read the SDA line. AFAIK it's really intended for "intelligent" slaves such as a another microcontroller, perhaps while it services an interrupt. Normally, a Slave has dedicated hardware to (immediately) support the I2C bus; I don't think PICaxe supports any clock-stretching, but maybe a "slow" mode would be good enough?

One of the (many) disadvantages of clock-stretching is that it can lock up the bus (or the master may think so) and I'm surprised that a dedicated Slave device needs to use it. Even more so if "incorrect" commands can brick it! It should be impossible for the normal Wired-OR (resistor pullups) lines to cause any hardware damage, so it sounds as if there might be some (hopefully rare) commands that can "reconfigure" or recalibrate it in some way.

Cheers, Alan.
 

edmunds

Senior Member
Further investigation shows I'm loosing the device after some 30-40 iterations of successful communication. Instead of the expected output, it returns either 0 or its own address until I reset picaxe. After some 5 such resets it does not help anymore, but power has to be cycled to reset both devices. Not looking good here.

Edmunds
 

edmunds

Senior Member
AFAIK it's really intended for "intelligent" slaves such as a another microcontroller, perhaps while it services an interrupt.
Alan, thank you for your input.

This likely falls exactly into the category of "intelligent" slaves. While it is called something else, it is a Cortex M0 processor that I'm talking to. It is quite possible to imagine, that the fusion functions the processor is doing differ in time they take depending on input magnitude of the four sensors it is trying to combine for results. Thus, it sounds exactly like the "clock stretching" intended application. I.e. the unit is trying to say 'wait, I'm still working on this number' if I ask for the next data set quickly. Sadly, slow mode is no remedy. Maybe if I pokesfr it to something even slower, it would work. It kind of has to accommodate for the slowest pulse possible. I understand 32bit micros can be fast, but that sounds like a ridiculously slow I2C bus. There are a lot of modes and settings to play with, so I might be able to get it to work this or that way, but the only proper way would be to cater for the "clock stretching" feature. Our most important data sheet actually talks about it quite a bit, but I cannot see there would be any settings available. I need to read it more carefully, however. Maybe fresh brain tomorrow will help.

Another totally different approach is the UART mode available. Never done any of that, but there is a first for everything, you know :).

Edmunds
 

hippy

Technical Support
Staff member
As AllyCat describes; clock stretching allows the I2C slave to delay the I2C master until it is ready. The PICAXE does not support clock stretching with the HI2C commands.

Because of the nature of the I2C bus it should not be possible to damage the bus, PICAXE or slave device but it may result in incorrect operation.
 

edmunds

Senior Member
Because of the nature of the I2C bus it should not be possible to damage the bus, PICAXE or slave device but it may result in incorrect operation.
Thanks, @hippy. Damaging the device physically is at least unlikely, but writing something strange to a register that is "reserved" could be allowed for. In the case of BNO055 it could "brick" the device unless firmware is re-flashed. In theory, at least.

Anyway, the goal is not to prove something can be bricked or not, but making it work :). When you say PICAXE does not support clock stretching does this mean the underlying PIC hardware does not support it or PICAXE interpreter does not have commands for it?


Thank you for your time,

Edmunds
 

edmunds

Senior Member
So.

I have educated myself on the details of I2C I was hopping I would never have to know. A bit like the old saying you should not know how sausages are made :). Ok, was not that bad, but it is somewhat mind-bending with all the various forms clock stretching can take.

As far as I can deduct, MSSP module will support clock stretching when it is set in slave mode [i.e. when it needs it for itself, because it cannot keep up]. However, there is nothing to confirm it will when in master mode [i.e. not to cater for some other buddy not being able to keep up]. There is a possibility, it would support it if set to SMB mode, but details of this I have not found yet as well as I have not investigated if SMB bus is something that I2C device should work with. Just no more time for this now.

Now I need to think about how to proceed, because any route from here is either a lot of work, sub-optimal result or both.

Edmunds
 

edmunds

Senior Member
After a lot of experimentation, I have found a way of running this thing with some stability over I2C.

The simple to understand part is reducing processor speed for thousands of trouble free consecutive reads to m4 and to m2 for unlimited successful reads (or as long as I was prepared to wait for it to fail). The odd thing is neither standard slow, nor fast modes give stability at these clock speeds. The best I have achieved experimentally, is $C4 for SSP1ADD register value. I don't have good enough logic analyzer to figure out the details. Somehow, increasing to, say $6C gives only about 20 consecutive successful reads while anything below $2C will lock the bus entirely. There is also a clear correlation between swinging the device more aggressively and the bus locking up as opposed to quite stable operation when at standstill.

I have tried setting SDAHT bit in SSP1CON3 [to allow 300ns SDA hold time instead of default 100ns] and while doing this without disturbing the status bit and checking that it was actually correctly written was good learning, I did not get any improvements.

I'm only posting this, because it might be suitable for some applications and for future reference. For my application this slow operation won't work as only acquiring the data at these speeds require over 12ms when my target loop time for the entire thing is ~3ms.

While writing this, I figured I should look for some bus translator/buffer devices that could help by being in the middle. That is probably the only thing remaining to do in I2C side of things, time to look into UART option and how speedy I can make it.

Edmunds
 

edmunds

Senior Member
Dear all,

In case an application note says the following:
Code:
The BNO055 support UART interface with the following settings: 115200 bps, 8N1 (8 data
bits, no parity bit, one stop bit). The maximum length support for read and write is 128 Byte.
my only option is hserout/hserin commands and respective pins as baud rate in this case is not maximum possible (like of I2C), but the one to be delivered pronto, right?


Thank you for your time,

Edmunds
 

edmunds

Senior Member
Dear all,

To put some topping on the I2C problem, the app note on UART (will download a PDF file) of the device explains a response from the device will typically "take 1ms, but up to 4ms". Of, course, the I2C bus without clock stretching is long dead with that sort of delay.

I have re-soldered connections and written some code to test UART connection. The code is not complete and not intended to accomplish anything, just to start somewhere and see if something is happening at all. Which, of course it isn't. However, I can see something going on on hserout (RX on BNO055 side) pin as expected and something going on on hserin (TX on BNO055 side) just after on the scope. The interesting thing is that BNO055 is idling TX high and transmitting low. How is that even possible?

Code:
#picaxe 40x2
#no_data
#no_table



{'Outputs
Symbol IMU_TX = C.1
}
{'Inputs
Symbol IMU_RX = C.2
}
{'Byte variables
Symbol octant = b0                'Octant of heading angle, bit7 to bit0
Symbol vehicle_state = b1         'Vehicle state, bit15 to bit8
Symbol op_mode = b2               'Vehicle operation mode, bit23 to bit16

Symbol data_byte = b4

Symbol H_L_byte = b55          'w27
Symbol H_H_byte = b54
}
{'Word variables (system)
Symbol Counter = s_w0             'Just a counter, 16-bit big
Symbol Temp = s_w1                'Just a temporary storage variable, 16-bit big
}
{'Word variables
Symbol H_word = w27               'heading output

}
{'IMU registers, Page 0
Symbol CHIP_ID = $00
Symbol ACC_ID = $01
Symbol MAG_ID = $02
Symbol GYR_ID = $03
Symbol SW_REV_ID_LSB = $04
Symbol SW_REV_ID_MSB = $05
Symbol BL_REV_ID = $06
Symbol PAGE_ID = $07
Symbol ACC_DATA_X_LSB = $08
Symbol ACC_DATA_X_MSB = $09
Symbol ACC_DATA_Y_LSB = $0A
Symbol ACC_DATA_Y_MSB = $0B
Symbol ACC_DATA_Z_LSB = $0C
Symbol ACC_DATA_Z_MSB = $0D
Symbol MAG_DATA_X_LSB = $0E
Symbol MAG_DATA_X_MSB = $0F
Symbol MAG_DATA_Y_LSB = $10
Symbol MAG_DATA_Y_MSB = $11
Symbol MAG_DATA_Z_LSB = $12
Symbol MAG_DATA_Z_MSB = $13
Symbol GYR_DATA_X_LSB = $14
Symbol GYR_DATA_X_MSB = $16
Symbol GYR_DATA_Y_LSB = $16
Symbol GYR_DATA_Y_MSB = $17
Symbol GYR_DATA_Z_LSB = $18
Symbol GYR_DATA_Z_MSB = $19
Symbol EUL_DATA_X_LSB = $1A
Symbol EUL_DATA_X_MSB = $1B
Symbol EUL_DATA_Y_LSB = $1C
Symbol EUL_DATA_Y_MSB = $1D
Symbol EUL_DATA_Z_LSB = $1E
Symbol EUL_DATA_Z_MSB = $1F
Symbol QUA_DATA_W_LSB = $20
Symbol QUA_DATA_W_MSB = $21
Symbol QUA_DATA_X_LSB = $22
Symbol QUA_DATA_X_MSB = $23
Symbol QUA_DATA_Y_LSB = $24
Symbol QUA_DATA_Y_MSB = $25
Symbol QUA_DATA_Z_LSB = $26
Symbol QUA_DATA_Z_MSB = $27
Symbol LIA_DATA_X_LSB = $28
Symbol LIA_DATA_X_MSB = $29
Symbol LIA_DATA_Y_LSB = $2A
Symbol LIA_DATA_Y_MSB = $2B
Symbol LIA_DATA_Z_LSB = $2C
Symbol LIA_DATA_Z_MSB = $2D
Symbol GRV_DATA_X_LSB = $2E
Symbol GRV_DATA_X_MSB = $2F
Symbol GRV_DATA_Y_LSB = $30
Symbol GRV_DATA_Y_MSB = $31
Symbol GRV_DATA_Z_LSB = $32
Symbol GRV_DATA_Z_MSB = $33
Symbol TEMP_DATA = $34
Symbol CALIB_STAT = $35
Symbol ST_RESULT = $36
Symbol INT_STA = $37
Symbol SYS_CLK_STATUS = $38
Symbol SYS_STATUS = $39
Symbol SYS_ERR = $3A
Symbol UNIT_SEL = $3B
Symbol OPR_MODE = $3D
Symbol PWR_MODE = $3E
Symbol SYS_TRIGGER = $3F
Symbol TEMP_SOURCE = $40
Symbol AXIS_MAP_CONFIG = $41
Symbol AXIS_MAP_SIGN = $42
Symbol ACC_OFFSET_X_LSB = $55
Symbol ACC_OFFSET_X_MSB = $56
Symbol ACC_OFFSET_Y_LSB = $57
Symbol ACC_OFFSET_Y_MSB = $58
Symbol ACC_OFFSET_Z_LSB = $59
Symbol ACC_OFFSET_Z_MSB = $5A
Symbol MAG_OFFSET_X_LSB = $5B
Symbol MAG_OFFSET_X_MSB = $5C
Symbol MAG_OFFSET_Y_LSB = $5D
Symbol MAG_OFFSET_Y_MSB = $5E
Symbol MAG_OFFSET_Z_LSB = $5F
Symbol MAG_OFFSET_Z_MSB = $60
Symbol GYR_OFFSET_X_LSB = $61
Symbol GYR_OFFSET_X_MSB = $62
Symbol GYR_OFFSET_Y_LSB = $63
Symbol GYR_OFFSET_Y_MSB = $64
Symbol GYR_OFFSET_Z_LSB = $65
Symbol GYR_OFFSET_Z_MSB = $66
Symbol ACC_RADIUS_LSB = $67
Symbol ACC_RADIUS_MSB = $68
Symbol MAG_RADIUS_LSB = $69
Symbol MAG_RADIUS_MSB = $6A
}
{'IMU registers, Page 1
Symbol ACC_CONFIG = $08
Symbol MAG_CONFIG = $09
Symbol GYR_CONFIG_0 = $0A
Symbol GYR_CONFIG_1 = $0B
Symbol ACC_SLEEP_CONFIG = $0C
Symbol GYR_SLEEP_CONFIG = $0D
Symbol INT_MSK = $0F
Symbol INT_EN = $10
Symbol ACC_AM_THRES = $11
Symbol ACC_INT_SETTINGS = $12
Symbol ACC_HG_DURATION = $13
Symbol ACC_HG_THRES = $14
Symbol ACC_NM_THRES = $15
Symbol ACC_NM_SET = $16
Symbol GYR_INT_SETTING = $17
Symbol GYR_HR_X_SET = $18
Symbol GYR_DUR_X = $19
Symbol GYR_HR_Y_SET = $1A
Symbol GYR_DUR_Y = $1B
Symbol GYR_HR_Z_SET = $1C
Symbol GYR_DUR_Z = $1D
Symbol GRY_AM_THRES = $1E
Symbol GYR_AM_SET = $1F
}
{'IMU parameters
Symbol SEL_PAGE_0 = $00
Symbol SEL_PAGE_1 = $01
Symbol CONFIGMODE = $00
Symbol ACCONLY = $01
Symbol MAGONLY = $02
Symbol GYRONLY = $03
Symbol ACCMAG = $04
Symbol ACCGYRO = $05
Symbol MAGGYRO = $06
Symbol AMG = $07
Symbol IMU = $08
Symbol COMPASS = $09
Symbol M4G = $0A
Symbol NDOF_FMC_OFF = $0B
Symbol NDOF = $0C
Symbol U_WRITE = $00
Symbol U_READ = $01
Symbol U_NULL = $00
Symbol U_BYTE = $01
Symbol U_WORD = $02
Symbol U_START = $AA
}

{'Init:
init:
  hsersetup B115200_8, %00111
}
{'Main:
main:
  do
  	hserout 0,(U_START,U_WRITE,SEL_PAGE_0,U_BYTE,U_NULL)    'Select page 0
    pause 100
    get 0, data_byte
    sertxd(#data_byte)
    get 1, data_byte
    sertxd(",",#data_byte,CR,LF)
    hserptr = 0
    hserout 0,(U_START,U_WRITE,OPR_MODE,U_BYTE,NDOF)        'Set operation mode to NDOF
    pause 100
    get 0, data_byte
    sertxd(#data_byte)
    get 1, data_byte
    sertxd(",",#data_byte,CR,LF)
    hserptr = 0
    pause 1000 'some delay for the loop
  loop
}

{'UART Error
	UART_Error:
  Select case data_byte
  case $03
    sertxd("WRITE FAIL",CR,LF)
  case $04
    sertxd("REGMAP INVALID ADDRESS",CR,LF)
  case $05
    sertxd("REGMAP WRITE DISABLED",CR,LF)
  case $06
    sertxd("WRONG START BYTE",CR,LF)
  case $07
    sertxd("BUS OVER RUN ERROR",CR,LF)
  case $08
    sertxd("MAX LENGTH ERROR",CR,LF)
  case $09
    sertxd("MIN LENGTH ERROR",CR,LF)
  case $0A
    sertxd("RECEIVE CHARACTER TIMOUT",CR,LF)
  endselect
return
}
Thank you for your input,

Edmunds
 
Last edited:

edmunds

Senior Member
Never mind, I'm actually getting something back. Not sure I like it, but that is another issue :).

Edmunds
 

edmunds

Senior Member
Ok, so spent a little more time on it. I'm now getting two bytes - 132 and 62 back (decimal). This does not make any sense according to the datasheet, but it is clearly what this thing is sending unless I'm doing something very wrong with the code above. I have checked the third byte as well, but it is always zero and this can be repeated any number of times with exactly these values, so it is not just some random noise or some part of the response. Any ideas?


Thank you all,

Edmunds
 

hippy

Technical Support
Staff member
No idea what's going on but, as I think may have been said earlier in this thread, start as simple as possible, don't include values defined by SYMBOL use actual values in the HSEROUT commands, and don't include anything more than is needed.

Code:
#Picaxe 40X2
HSerSetup B115200_8, %111
Pause 1000
SerTxd( "Starting...", CR,LF )
Do
  HSerOut 0, ( $AA, ? ? ? )
  Pause 1000
  Do While ptr <> hSerPtr
    SerTxd( "Got ", #@ptrInc, CR, LF )
  Loop
  SerTxd( "---", CR, LF )
Loop
Start by reading the ID register as I recall you were doing with I2C. Don't worry about whether that will or won't work, whether page registers need to be set or not; at this stage you are only interested in getting the command right and seeing a response which matches what it should be.

The reason for using actual values in the code rather than SYMBOL defined values is that it adds time having to look through the code to see what values those symbols have, makes it harder for people who haven't used the BNO055 to help and say 'that looks right' or not.
 

AllyCat

Senior Member
Hi,

The interesting thing is that BNO055 is idling TX high and transmitting low. How is that even possible?
I haven't looked at the BNO055 data sheet, but that is very much the normal (for a "TTL" interface). It's PICaxe that is rather unusual in receiving/transmitting the (buffered/inverted) RS232 polarity directly on the chip pins.

However, HSEROUT/IN is rather device-specific and I haven't looked at the configuration parameters for an X2. You're not sending/receiving the wrong serial polarity are you?

Cheers, Alan.
 

edmunds

Senior Member
@hippy, thanks. Modified the read command in your code to HSerOut 0, ( $AA, $01, $00, $01 ) and got exactly the same thing back - 132 and 62. I would expect either $BB or 187 decimal and data or $EE or 238 decimal and error code. 132 and 62 does not make any sense, as I said above.

Symbols are way easier for me, because I don't have to look every last register or command up in the data sheet every time, but I will try to behave in future and post raw commands instead :)

Edmunds
 

edmunds

Senior Member
You're not sending/receiving the wrong serial polarity are you?
Dear Alan,

I might be doing exactly that along with hundred other things wrong as I have not touched serial asynchronous communication with the notable exception of sertxd up until now. The data sheet of the device says 115200 bps, 8N1 (8 data bits, no parity bit, one stop bit).

I have 1 for N polarity in hsersetup. Could that be wrong?

Edmunds
 

edmunds

Senior Member
Well, ok for the fun of it I did turn the polarity around. Now I get 238 and 7 for the first time and 187,1 and 160 all the consecutive times. Investigating what that could be.

Edmunds
 

edmunds

Senior Member
238 is the expected error code and 7 means "BUS_OVER_RUN_ERROR" which is explained as "The BNO055 was not able to clear the receive buffer in time for the next send data, this can happen, since UART is an asynchronous protocol. Resend the command."

I'm not sure why this happens, but consecutive 187 ($BB) means a decent response and 1 is decent length of the response and 160 is the expected value of CHIP_ID register.

Edmunds
 

edmunds

Senior Member
From online reference on hserout:

Polarity

When bit1 is 0, the serial output polarity is 'True' which is same as a 'Txxx' baud rate in the 'serout' command. In this state the pin idles high and pulses low. This is the state normally used with a MAX232 type inverter for computer connection.

When bit1 is 1, the serial output polarity is 'Inverted' which is same as a 'Nxxx' baud rate in the 'serout' command. In this state the pin idles low and pulses high. This is the state normally used with third party devices (e.g. an AXE033 serial LCD) or director 'resistor' connection to a PC.

On some parts the hardware serial input polarity is always true, it cannot be inverted (ie bit 2 serial input inversion only applies to X2 parts). This is a limitation of the internal microcontroller structure. Therefore a MAX232 type inverter is required for computer connections.


Is that the other way around then or is it I don't understand something? What?

Edmunds
 

hippy

Technical Support
Staff member
The command looks right to me, but I wasn't sure what the final $01 byte should be; is that the length of the packet sent or the length of the data expected back ? The datasheet I have doesn't say what 'length' means.

I agree you should be getting $BB (187) back, and more than two bytes of data.

As to why you are not getting that it could be any number of things. Maybe the chip needs power-cycling, maybe it's not wired correctly for serial operation, it might be wired wrongly to the PICAXE or perhaps pull-ups/pull-downs are interfering, perhaps there are errors in the datasheet.

Others seem to have had difficulty in getting UART mode to work but others say they have achieved that.

As one can't tell what's going on just by looking at the results the next step would be to show that the BNO055 is wired correctly and to put a logic analyser or scope on the serial pins to see exactly what is being sent and received.

Another option is to find or create a USB-to-TTL-UART adapter and see if you can communicate with it and get expected responses using a terminal emulator.
 

hippy

Technical Support
Staff member
Is that the other way around then or is it I don't understand something? What?
Yes the HSEROUT polarity ( and what I copied ) is wrong for TTL-UART polarity; should be -

HSEROUT B115200_8, %001

Added : After a fair amount of crossed-posts it seems this was the error and it's now working as expected.

One reason for the first 'bad command' error can be that the PICAXE starts with its pin low or floating, where the BNO055 expects it to be idling high. This may corrupt the first command sent or confuse the receiver.

It is good practice to start comms by reading an ID if one is available or executing a 'do nothing' command, repeating that until the expected result is returned, at which point the device should be ready to accept further commands sent.
 

AllyCat

Senior Member
Hi,

From online reference on hserout:
'Nxxx' ... In this state the pin idles low and pulses high. This is the state normally used with third party devices (e.g. an AXE033 serial LCD) or direct 'resistor' connection to a PC.
IMHO that is the "confusing" part. An AXE033 is hardly a "third party" product (it's a PICaxe! ) and the majority of third party ics (e.g. Arduin* , presumably your BNO055, and even the base PIC M2 chips! ) use "TTL" polarity signals on the assumption that they will be connecting to a similar TTL device or to a MAX232 (inverter).

Cheers, Alan.
 
Last edited:

edmunds

Senior Member
From a practical perspective, when one knows there can always be something strange about polarity it takes seconds just to try one and the other :)

As for the actual device, I can now read everything I wanted in m8 mode, but not yet in em64. Generally, either this device or the protocol in general requires re-try on error, because what did not work on the first attempt might very well work on the second or third. That is very different from I2C. But I'm getting there. Will report back when I stabilise it enough to see if it can do what I need.


Thank you for your inputs,

Edmunds
 

hippy

Technical Support
Staff member
IMHO that is the "confusing" part. An AXE033 is hardly a "third party" product (it's a PICaxe! )
I am not entirely sure what that phrasing may have originally been intended to convey but I have updated the on-line command description to clarify the descriptions of the two modes.
 

edmunds

Senior Member
Ok, so my main problem now seems to be locating the correct byte(-s) of information. Is it ok to reset hserptr to zero to get it to write into location 0 again? Or is it done in some other way? I don't want to count from the start of communication through 1024 byte scratchpad to look for the byte I'm interested in ...

If I would use hserin instead of scratchpad to put data right into variables, how would I make sure hserin is done fast enough after hserout to request the needed data? How long will the device be happy to wait for me to 'prepare' the hserin command?

Edmunds
 
Top