Openlog Qwiic and I2C sensors - random data loss

Hi all.

I have an Openlog Qwiic connected to an Adafruit BNO055 sensor and an Adafruit QT PY (a basic SAMD21 chip).

I can log data but I get random characters missing when I look at the log file.

By my own admission … I’m the worst coder and relatively new at this so any help / guidance much appreciated.

The attached code has been adapted from others sketches.

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>

#include "SparkFun_Qwiic_OpenLog_Arduino_Library.h"
OpenLog myLog; //Create instance

int ledPin = LED_BUILTIN; //Status LED connected to digital pin 13
  
Adafruit_BNO055 bno = Adafruit_BNO055(55);

void setup(void) 
{
  pinMode(ledPin, OUTPUT);

  Wire.begin(); //Initialize I2C
  myLog.begin(); //Open connection to OpenLog (no pun intended)
  
  Serial.begin(9600);
  Serial.println("Orientation Sensor Test"); Serial.println("");
  
  /* Initialise the sensor */
  if(!bno.begin())
  {
    /* There was a problem detecting the BNO055 ... check your connections */
    Serial.print("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!");
    while(1);
  }
  
  delay(1000);
    
  bno.setExtCrystalUse(true);
}

void loop(void) 
{
  /* Get a new sensor event */ 
  sensors_event_t event; 
  bno.getEvent(&event);
  
  /* Display the floating point data */
  Serial.print("X: ");
  Serial.print(event.orientation.x, 4);
  Serial.print("\tY: ");
  Serial.print(event.orientation.y, 4);
  Serial.print("\tZ: ");
  Serial.print(event.orientation.z, 4);
  Serial.println("");

  /* Log the floating point data */
  myLog.print("X: ");
  myLog.print(event.orientation.x, 4);
  myLog.print("\tY: ");
  myLog.print(event.orientation.y, 4);
  myLog.print("\tZ: ");
  myLog.print(event.orientation.z, 4);
  myLog.println("");
  
  myLog.syncFile();
  
  delay(100);
}

Check that either the BNO055 OR the OpenLog Qwicc have I2C pull-up resistors, not both. You can easily disable it on the QWICC Openlog.

For debugging :

Try to set delays between mylog.print() The library is sending 1 data-character at the time with each begintransmission() / write() / endtransmission(). Causing a bit of overhead on the line.

Else try to run Wire with different speed. Default is 100Khz. Try slower / faster.

Just for reference …. The sensor outputs the data to the serial monitor perfectly.

Please post some examples of data on the serial monitor, and those same data on the SD card, illustrating the differences that you observe.

Finally found the issue.

Its a processor conflict

The Openlog Qwiic does not like the SAMD21 processor.

It all works fine with my old UNO R3.

interesting… wonder why…

Yeah … not sure really.

Reading further it seems to have been spotted by a number of others. See the customer feedback on the spark fun product website.

There is also line of code in the openlog library that is supposed to address the conflict but it would seem not to be working properly.

Swapping processors / dev boards now.

Shame really - quite like the little samd21 boards

:slight_smile:

So … the story continues …

I can get a chain of sensors (adxl375, bno055, bmp390) all connected to the Qwiic OpenLog and then to an UNO r3.

It all works perfectly on the r3 - logs data, records it to the sd card - no losses of data issues whatsoever.

I need to add gps to the mix which then creates a sketch too large for the diminutive memory of the r3.

I have tried with the long list of other processors - Adafruit QT PY M0 (SAMD21), Adafruit QT PY (rp2040), SparkFun thing Plus Artemis (Apollo3 cortex M4), Adafruit ItsyBitsy M4 (SAMD51) - and nothing works properly

I still get random data loss when writing to the sd card.

If anyone (especially you SparkFun mods) has any suggestions for boards that actually work with the Qwiic OpenLog - please can you post them here.

Cheers

The Customer feedback about the QWICC Openlog on github, is around the I2C buffer. This will only impact reading speed, not writing. Writing is done unbuffered with every byte handling with a lot of overhead on the line.

I have just tested the code on a SAMD51 and can reproduce the problem and have a workaround / solution. The root cause seems to be that the Openlog module can not handle the speed of incoming data.

I have connected my logic analyzer (Saleae-8) to the I2C bus and clearly see that at a certain moment the Openlog is sending a NACK on an address write request. From that moment sending of the current buffer is aborted and data is lost. As I do a println() of the buffer, the println() routine will now send a new buffer with “\r\n” which is handled correctly by the Openlog.

The I2C speed is set to 100Khz, which I see on the logic analyzer as well. Also monitoring the 3V3 power on an analog line of the logic analyzer at the same time does not show a drop or spike in power.

I implemented a display of the result returned by the mylog.println() which provides the number of bytes sent. The error is happening at random moments. Using exactly the same input buffer it fails at positions: 70, 76, 121, 11, 17, 26 or 43.

After comparing the OpenLog I2C traffic with a UNO-R3 to the I2C traffic with the SAMD51, it showed that the time after completing the sending a byte and start sending the next byte is 44us on an UNO-R3, where is it 15us with the SAMD51. The processor is much faster and this time delay looks to be on the critical boundary.

The quick solution is by a small change in SparkFun_Qwiic_OpenLog_Arduino_Library.cpp.

In the function write(), around line 303, add at the beginning:```
delayMicroseconds(30);


size_t OpenLog::write(uint8_t character)
{
delayMicroseconds(30);
_i2cPort->beginTransmission(_deviceAddress);
_i2cPort->write(registerMap.writeFile); // Send the byte that corresponds to writing a file
_i2cPort->write(character);


I could not get it to fail after that, but if still failing try a larger value than 30. Look forward hearing your experience.

P.s.

If you want to apply the larger read buffer as indicated on [https://github.com/sparkfun/SparkFun_Qw ... y/issues/6](https://github.com/sparkfun/SparkFun_Qwiic_OpenLog_Arduino_Library/issues/6) for the Adafruit QT PY M0, you should use __SAMD21E18A__ instead of __SAMD21G18A__

paulvha:
The Customer feedback about the QWICC Openlog on github, is around the I2C buffer. This will only impact reading speed, not writing. Writing is done unbuffered with every byte handling with a lot of overhead on the line.

I have just tested the code on a SAMD51 and can reproduce the problem and have a workaround / solution. The root cause seems to be that the Openlog module can not handle the speed of incoming data.

I have connected my logic analyzer (Saleae-8) to the I2C bus and clearly see that at a certain moment the Openlog is sending a NACK on an address write request. From that moment sending of the current buffer is aborted and data is lost. As I do a println() of the buffer, the println() routine will now send a new buffer with “\r\n” which is handled correctly by the Openlog.

The I2C speed is set to 100Khz, which I see on the logic analyzer as well. Also monitoring the 3V3 power on an analog line of the logic analyzer at the same time does not show a drop or spike in power.

I implemented a display of the result returned by the mylog.println() which provides the number of bytes sent. The error is happening at random moments. Using exactly the same input buffer it fails at positions: 70, 76, 121, 11, 17, 26 or 43.

After comparing the OpenLog I2C traffic with a UNO-R3 to the I2C traffic with the SAMD51, it showed that the time after completing the sending a byte and start sending the next byte is 44us on an UNO-R3, where is it 15us with the SAMD51. The processor is much faster and this time delay looks to be on the critical boundary.

The quick solution is by a small change in SparkFun_Qwiic_OpenLog_Arduino_Library.cpp.

In the function write(), around line 303, add at the beginning:```
delayMicroseconds(30);





size_t OpenLog::write(uint8_t character)
{
delayMicroseconds(30);
_i2cPort->beginTransmission(_deviceAddress);
_i2cPort->write(registerMap.writeFile); // Send the byte that corresponds to writing a file
_i2cPort->write(character);




I could not get it to fail after that, but if still failing try a larger value than 30. Look forward hearing your experience.



P.s.

If you want to apply the larger read buffer as indicated on [https://github.com/sparkfun/SparkFun_Qw ... y/issues/6](https://github.com/sparkfun/SparkFun_Qwiic_OpenLog_Arduino_Library/issues/6) for the Adafruit QT PY M0, you should use __SAMD21E18A__ instead of __SAMD21G18A__

Thanks Paul.

That’s looking good so far.

More testing to do and will keep you informed.

Will this become a permanent addition to the Qwiic openlog lib ??

Good to hear. Once you also have tested successfully, I will make a github issue report. It is down to Sparkfun to decide whether to update the source code