LPS22HB pressure sensor func crashes the programm after minutes (Nano BLE Sense)

Hi guys,

I lost several hours to solve this strange bug. The board I am using is Arduino Nano BLE Sense 33.

In short, I use sprintf to format some sensor readings before Serial.print() in loop(). At start, the programm works perfectly. However, after many iterations (maybe 500 runs?) of loop() the system hangs.

I tried also snprintf, snprintf_P, and even to make the char length way larger than needed, the program still crahes after running for several minutes.

Edit: After I checked the program carefully, I found It’s not sprintf, but pressure sensor reading func causing the crash. See #7.

The program crashes after several minutes at pressure sensor reading function.

#include <Arduino_LPS22HB.h>

in void loop: 
pressure = BARO.readPressure();

If I comment out the pressure sensor reading function, or simply replace this line with:

pressure = 5;

The program will not crash anymore. (At least for 20 minutes)

This is a similar problem stated in this post: https://forum.arduino.cc/index.php?topic=643883.0

Could you please help me?

Here is my code: simply read some sensor value, format them and print to serial port.

#include <Arduino_APDS9960.h>
#include <Arduino_LSM9DS1.h>
#include <Arduino_LPS22HB.h>
#include <Arduino_HTS221.h>
#include <PDM.h>


// Parameters for Microphone
#define MICROPHONE_BUFFER_SIZE_IN_WORDS (256U)
#define MICROPHONE_BUFFER_SIZE_IN_BYTES (MICROPHONE_BUFFER_SIZE_IN_WORDS * sizeof(int16_t))


/* MP34DT05 Microphone data buffer with a bit depth of 16. Also a variable for the RMS value */
int16_t microphoneBuffer[MICROPHONE_BUFFER_SIZE_IN_WORDS];
int16_t microphoneRMSValue;
// /* Used as a simple flag to know when microphone buffer is full and RMS value
//  * can be computed. */
bool microphoneBufferReadyFlag = false;

void Microphone_availablePDMDataCallback()
{
  // query the number of bytes available
  int bytesAvailable = PDM.available();

  if(bytesAvailable == MICROPHONE_BUFFER_SIZE_IN_BYTES)
  {
    PDM.read(microphoneBuffer, bytesAvailable);
    microphoneBufferReadyFlag = true;
  }
}

float Micophone_computeRMSValue()
{
  float rms = 0;
  // Square difference between each set of elements
  for (int i = 0; i < MICROPHONE_BUFFER_SIZE_IN_WORDS; i++) {
    rms += microphoneBuffer[i] * microphoneBuffer[i];
  }
  return sqrt((float)rms/MICROPHONE_BUFFER_SIZE_IN_WORDS);
}



void setup() {
  Serial.begin(9600);
  while (!Serial); // Wait for serial monitor to open

  if (!APDS.begin()) {
    Serial.println("Error initializing APDS9960 sensor.");
    while (true); // Stop forever
  }

  if (!IMU.begin()) {
    Serial.println("Failed to initialize IMU!");
    while (1);
  }

  if (!BARO.begin()) {
    Serial.println("Failed to initialize pressure sensor!");
    while (1);
  }

  if (!HTS.begin()) {
    Serial.println("Failed to initialize humidity temperature sensor!");
    while (1);
  }

    /* PDM setup for MP34DT05 microphone */
  /* configure the data receive callback to transfer data to local buffer */
  PDM.onReceive(Microphone_availablePDMDataCallback);
  /* Initialise single PDM channel with a 16KHz sample rate (only 16kHz or 44.1kHz available */
  if (!PDM.begin(1, 16000))
  {
    Serial.println("Failed to start PDM!");
    /* Hacky way of stopping program executation in event of failure. */
    while(1);
  }
  else
  {
    /* Gain values can be from 0 to 80 (around 38db). Check out nrf_pdm.h
     * from the nRF528x-mbedos core to confirm this. */
    /* This has to be done after PDM.begin() is called as begin() always
     *  sets the gain as the default PDM.h value (20).
     */
    PDM.setGain(50);
  }

}

int proximity = 0;
int r = 0, g = 0, b = 0;
unsigned long lastUpdate = 0;
float x1, y, z1, x2, y2, z2, x3, y3, z3, pressure, temperature, humidity, sound;
const int size = 50;
char event[size];

void loop() {

  // check if a gesture reading is available
  if (APDS.gestureAvailable()) {
    int gesture = APDS.readGesture();
    lastUpdate = millis();
    switch (gesture) {
      case GESTURE_UP:
        snprintf_P(event, size, PSTR("UP[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, 1);
        Serial.println(event);
        break;

      case GESTURE_DOWN:
        snprintf_P(event, size, PSTR("DOWN[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, 1);
        Serial.println(event);
        break;

      case GESTURE_LEFT:
        snprintf_P(event, size, PSTR("LEFT[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, 1);
        Serial.println(event);
        break;

      case GESTURE_RIGHT:
        snprintf_P(event, size, PSTR("RIGHT[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, 1);
        Serial.println(event);
        break;

      default:
        // ignore
        break;
    }
    delay(1000);
  }

  // Check if a proximity reading is available.
  if (APDS.proximityAvailable()) {
    proximity = APDS.readProximity();
  }

  // check if a color reading is available
  if (APDS.colorAvailable()) {
    APDS.readColor(r, g, b);
  }

  if(IMU.accelerationAvailable()){
      IMU.readAcceleration(x1, y, z1);
  }

  if (IMU.gyroscopeAvailable()) {
    IMU.readGyroscope(x2, y2, z2);
  }

  if (IMU.magneticFieldAvailable()) {
    IMU.readMagneticField(x3, y3, z3);
  }

  if(microphoneBufferReadyFlag)
  {
    sound = Micophone_computeRMSValue();
    microphoneBufferReadyFlag = false;
  }

  pressure = BARO.readPressure();
  temperature = HTS.readTemperature();
  humidity    = HTS.readHumidity();
 
  // Print updates every 200ms
  if (millis() - lastUpdate > 200) {
    lastUpdate = millis();

    snprintf_P(event, size, PSTR("proximity[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, proximity);
    Serial.println(event);

    snprintf_P(event, size, PSTR("pressure[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, (int)pressure);
    Serial.println(event);

    snprintf_P(event, size, PSTR("temperature[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, (int)temperature);
    Serial.println(event);

    snprintf_P(event, size, PSTR("humidity[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, (int)humidity);
    Serial.println(event);

    snprintf_P(event, size, PSTR("RMS_Sound[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, (int)sound);
    Serial.println(event);
    Serial.println();

    Serial.print("rgb=");
    Serial.print(r);
    Serial.print(",");
    Serial.print(g);
    Serial.print(",");
    Serial.println(b);

    Serial.print("Vibration=");
    Serial.print(x1);
    Serial.print(",");
    Serial.print(y);
    Serial.print(",");
    Serial.println(z1);

    Serial.print("Gyroscope=");
    Serial.print(x2);
    Serial.print(",");
    Serial.print(y2);
    Serial.print(",");
    Serial.println(z2);

    Serial.print("MagneticField=");
    Serial.print(x3);
    Serial.print(",");
    Serial.print(y3);
    Serial.print(",");
    Serial.println(z3);

    Serial.println();
    Serial.println();
  }
}

Thanks in advance. :wink:

Welcome,

First, sprintf doesn't work with floats, unless enabled by adding compiler flags, which I won't detail here (you can search this forum, it has been asked many times)

But even then, you use wrong format for your values. Floats should be formatted with %f, and unsigned long should be formatted with %lu . See this page : printf - C++ Reference

To convert float to string, you can use dtostrf

Hi guix,

Thanks for your answer. After I changed the sprintf with the correct specifier, the program still crashes after several minutes. I have literaly no clue about what happend inside the board. ;-(

The updated code is here:

snprintf_P(event, size, PSTR("proximity[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, proximity);
Serial.println(event);

snprintf_P(event, size, PSTR("pressure[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, (int)pressure);
Serial.println(event);

snprintf_P(event, size, PSTR("temperature[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, (int)temperature);
Serial.println(event);

snprintf_P(event, size, PSTR("humidity[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, (int)humidity);
Serial.println(event);

Thanks!

Are you sure the crash is caused by those snprintf_P ?

Try this loop :

void loop() {

  // Check if a proximity reading is available.
  /*if (APDS.proximityAvailable()) {
    proximity = APDS.readProximity();
  }*/
  proximity = 123;

  // check if a color reading is available
  /*if (APDS.colorAvailable()) {
    APDS.readColor(r, g, b);
  }*/
  r = 12;
  g = 34;
  b = 56;

  /*if(IMU.accelerationAvailable()){
      IMU.readAcceleration(x1, y, z1);
  }*/
  x1 = 1;
  y = 2;
  z1 = 3;

  /*if (IMU.gyroscopeAvailable()) {
    IMU.readGyroscope(x2, y2, z2);
  }*/
  x2 = 4;
  y2 = 5;
  z2 = 6;

  /*if (IMU.magneticFieldAvailable()) {
    IMU.readMagneticField(x3, y3, z3);
  }*/
  x3 = 7;
  y3 = 8;
  z3 = 9;

  pressure = 20; //BARO.readPressure();
  temperature = 21; //HTS.readTemperature();
  humidity    = 22; //HTS.readHumidity();
  
  // Print updates every 200ms
  if (millis() - lastUpdate > 200) {
    lastUpdate = millis();

    snprintf_P(event, size, PSTR("proximity[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, proximity);
    Serial.println(event);

    snprintf_P(event, size, PSTR("pressure[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, (int)pressure);
    Serial.println(event);

    snprintf_P(event, size, PSTR("temperature[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, (int)temperature);
    Serial.println(event);

    snprintf_P(event, size, PSTR("humidity[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, (int)humidity);
    Serial.println(event);

    Serial.println();

    Serial.print("rgb=");
    Serial.print(r);
    Serial.print(",");
    Serial.print(g);
    Serial.print(",");
    Serial.println(b);

    Serial.print("Vibration=");
    Serial.print(x1);
    Serial.print(",");
    Serial.print(y);
    Serial.print(",");
    Serial.println(z1);

    Serial.print("Gyroscope=");
    Serial.print(x2);
    Serial.print(",");
    Serial.print(y2);
    Serial.print(",");
    Serial.println(z2);

    Serial.print("MagneticField=");
    Serial.print(x3);
    Serial.print(",");
    Serial.print(y3);
    Serial.print(",");
    Serial.println(z3);

    Serial.println();
  }
}

Hi guix,

My apologies. Somehow, after I upload the code again, the program works like a charm. :slight_smile: :slight_smile: :slight_smile:
No, at the time I’m writing the post, the program crashes… >:( this time it holds much longer.

I don’t know what causes the problem. Looks like there are much randomness there. I will try your method again.

Here is my whole code snippet:

#include <Arduino_APDS9960.h>
#include <Arduino_LSM9DS1.h>
#include <Arduino_LPS22HB.h>
#include <Arduino_HTS221.h>
#include <PDM.h>


// Parameters for Microphone 
#define MICROPHONE_BUFFER_SIZE_IN_WORDS (256U)
#define MICROPHONE_BUFFER_SIZE_IN_BYTES (MICROPHONE_BUFFER_SIZE_IN_WORDS * sizeof(int16_t))


/* MP34DT05 Microphone data buffer with a bit depth of 16. Also a variable for the RMS value */
int16_t microphoneBuffer[MICROPHONE_BUFFER_SIZE_IN_WORDS];
int16_t microphoneRMSValue;
// /* Used as a simple flag to know when microphone buffer is full and RMS value
//  * can be computed. */
bool microphoneBufferReadyFlag = false;

void Microphone_availablePDMDataCallback()
{
  // query the number of bytes available
  int bytesAvailable = PDM.available();

  if(bytesAvailable == MICROPHONE_BUFFER_SIZE_IN_BYTES)
  {
    PDM.read(microphoneBuffer, bytesAvailable);
    microphoneBufferReadyFlag = true;
  }
}

float Micophone_computeRMSValue()
{
  float rms = 0;
  // Square difference between each set of elements
  for (int i = 0; i < MICROPHONE_BUFFER_SIZE_IN_WORDS; i++) {
    rms += microphoneBuffer[i] * microphoneBuffer[i];
  }
  return sqrt((float)rms/MICROPHONE_BUFFER_SIZE_IN_WORDS);
}



void setup() {
  Serial.begin(9600);
  while (!Serial); // Wait for serial monitor to open

  if (!APDS.begin()) {
    Serial.println("Error initializing APDS9960 sensor.");
    while (true); // Stop forever
  }

  if (!IMU.begin()) {
    Serial.println("Failed to initialize IMU!");
    while (1);
  }

  if (!BARO.begin()) {
    Serial.println("Failed to initialize pressure sensor!");
    while (1);
  }

  if (!HTS.begin()) {
    Serial.println("Failed to initialize humidity temperature sensor!");
    while (1);
  }

    /* PDM setup for MP34DT05 microphone */
  /* configure the data receive callback to transfer data to local buffer */
  PDM.onReceive(Microphone_availablePDMDataCallback);
  /* Initialise single PDM channel with a 16KHz sample rate (only 16kHz or 44.1kHz available */
  if (!PDM.begin(1, 16000))
  {
    Serial.println("Failed to start PDM!");
    /* Hacky way of stopping program executation in event of failure. */
    while(1);
  }
  else
  {
    /* Gain values can be from 0 to 80 (around 38db). Check out nrf_pdm.h
     * from the nRF528x-mbedos core to confirm this. */
    /* This has to be done after PDM.begin() is called as begin() always
     *  sets the gain as the default PDM.h value (20).
     */
    PDM.setGain(50);
  }

}

int proximity = 0;
int r = 0, g = 0, b = 0;
unsigned long lastUpdate = 0;
float x1, y, z1, x2, y2, z2, x3, y3, z3, pressure, temperature, humidity, sound;
const int size = 50;
char event[size];

void loop() {

  // check if a gesture reading is available
  if (APDS.gestureAvailable()) {
    int gesture = APDS.readGesture();
    lastUpdate = millis();
    switch (gesture) {
      case GESTURE_UP:
        snprintf_P(event, size, PSTR("UP[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, 1);
        Serial.println(event);
        break;

      case GESTURE_DOWN:
        snprintf_P(event, size, PSTR("DOWN[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, 1);
        Serial.println(event);
        break;

      case GESTURE_LEFT:
        snprintf_P(event, size, PSTR("LEFT[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, 1);
        Serial.println(event);
        break;

      case GESTURE_RIGHT:
        snprintf_P(event, size, PSTR("RIGHT[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, 1);
        Serial.println(event);
        break;

      default:
        // ignore
        break;
    }
    delay(1000);
  }

  // Check if a proximity reading is available.
  if (APDS.proximityAvailable()) {
    proximity = APDS.readProximity();
  }

  // check if a color reading is available
  if (APDS.colorAvailable()) {
    APDS.readColor(r, g, b);
  }

  if(IMU.accelerationAvailable()){
      IMU.readAcceleration(x1, y, z1);
  }

  if (IMU.gyroscopeAvailable()) {
    IMU.readGyroscope(x2, y2, z2);
  }

  if (IMU.magneticFieldAvailable()) {
    IMU.readMagneticField(x3, y3, z3);
  }

  if(microphoneBufferReadyFlag)
  {
    sound = Micophone_computeRMSValue();
    microphoneBufferReadyFlag = false;
  }

  pressure = BARO.readPressure();
  temperature = HTS.readTemperature();
  humidity    = HTS.readHumidity();
  
  // Print updates every 200ms
  if (millis() - lastUpdate > 200) {
    lastUpdate = millis();

    snprintf_P(event, size, PSTR("proximity[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, proximity);
    Serial.println(event);

    snprintf_P(event, size, PSTR("pressure[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, (int)pressure);
    Serial.println(event);

    snprintf_P(event, size, PSTR("temperature[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, (int)temperature);
    Serial.println(event);

    snprintf_P(event, size, PSTR("humidity[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, (int)humidity);
    Serial.println(event);

    snprintf_P(event, size, PSTR("RMS_Sound[%013lu,%013lu](%i)$"), lastUpdate, lastUpdate, (int)sound);
    Serial.println(event);
    Serial.println();

    Serial.print("rgb=");
    Serial.print(r);
    Serial.print(",");
    Serial.print(g);
    Serial.print(",");
    Serial.println(b);

    Serial.print("Vibration=");
    Serial.print(x1);
    Serial.print(",");
    Serial.print(y);
    Serial.print(",");
    Serial.println(z1);

    Serial.print("Gyroscope=");
    Serial.print(x2);
    Serial.print(",");
    Serial.print(y2);
    Serial.print(",");
    Serial.println(z2);

    Serial.print("MagneticField=");
    Serial.print(x3);
    Serial.print(",");
    Serial.print(y3);
    Serial.print(",");
    Serial.println(z3);

    Serial.println();
    Serial.println();
  }
}

The only format you are really using is “%013lu”.

If you don’t need the string as one piece (which is very rarely so) you could just convert the
unsigned long number to your strange format.

void setup() {
  Serial.begin(250000);
  Serial.println(strangeFormat(1234567890UL));
}

char* strangeFormat(uint32_t unsignedNum) {
  static char buf[14];
  for (byte i=0; i<13; i++) {
    buf[12-i] = '0' + unsignedNum % 10;
    unsignedNum /= 10;
  }
  return buf;
}

void loop() {}
0001234567890

The most common reason for programs crashing is writing past the end of an array, or writing using an invalid pointer. Both can cause either very consistent, or very random crashes. Are you sure you're not doing one of the other? If you're thinking sprintf itself is at fault (i.e. - a bug in sprintf), I can virtually guarantee that is NOT the case.

Hi Guys,

Thanks for the answers. You are right. It’s not sprintf causing the crash. What I’m sure is that I neither use invalid pointer nor did I write past the end of an array. As you can see the code, I am using Arduino Library to read the sensor data and format them (Prepare to be pushed into another program).

I just test the program again. The program crashes after several minutes at pressure sensor reading function.

#include <Arduino_LPS22HB.h>
pressure = BARO.readPressure();

If I comment out the pressure sensor reading function, or simply replace this line with:

pressure = 5;

The program will not crash anymore. (At least after several minutes)

This is a similar problem stated in this post: https://forum.arduino.cc/index.php?topic=643883.0

Do you know how can I solve this?

Thanks in advance. :o

You haven't provided any description of what "crashes" means.

I'd start instrumenting inside the readPressure() function with Serial.print() statements to get a more precise indication of where it's "crashing".

gfvalvo:
You haven't provided any description of what "crashes" means.

I'd start instrumenting inside the readPressure() function with Serial.print() statements to get a more precise indication of where it's "crashing".

Hi Gfvalvo,
I checked the code like this:

Serial.println("test1");
pressure = BARO.readPressure();
Serial.println(pressure);
Serial.println("test2");

After several minutes, the program hangs after the serial port outputs "test1". No output anymore. No error shows.

That library looks pretty standard, it just reads and writes over I²C. One obvious place where it could go wrong is this while loop:

Try adding some print statements to see if that's the place where your code gets stuck. You could use the built-in RGB LED to easily check this without print statements:

  // trigger one shot
  digitalWrite(LEDR, HIGH);
  i2cWrite(LPS22HB_CTRL2_REG, 0x01);

  // wait for ONE_SHOT bit to be cleared by the hardware
  while ((i2cRead(LPS22HB_CTRL2_REG) & 0x01) != 0) {
    yield();
  }
  digitalWrite(LEDR, LOW);

(Don't forget a pinMode in your setup.)

The Arduino Nano 33 BLE runs ARM mbed os. When an error occurs, a message will be printed to the Serial1 port at 115,200 baud. Try connecting a USB-to-Serial adapter to the TX pin of the Arduino and see what it tells you.

Otherwise, the SWD pins are accessible at the bottom, so you can hook it up to a debugger using OpenOCD (e.g. PlatformIO makes this more accessible) so you can see where it goes wrong.

Pieter

Your conclusion that the crash occurs in readPressure() is not necessarily correct. Unless you follow each Serial.print() with a Serial.flush(), the Serial output tells you NOTHING about where the crash actually occurs. Serial is VERY slow....

That while loop that PieterP pointed out looks convincing though.

RayLivingston:
Your conclusion that the crash occurs in readPressure() is not necessarily correct. Unless you follow each Serial.print() with a Serial.flush(), the Serial output tells you NOTHING about where the crash actually occurs. Serial is VERY slow....

Let me have another try with Serial.flush(). I tested the code on the board for several times by powering on/off, each time the program frezees in a few minutes after output "test1" in Serial port. And I do have two Nano sense ble boards, both report same problem.

Update: the program freezes right after output "test1" in serial port, even if I add Serial.flush() after every Serial.print()

So add some prints to the library around that while loop and see if that's where it hangs.

PieterP:
That library looks pretty standard, it just reads and writes over I²C. One obvious place where it could go wrong is this while loop:
Arduino_LPS22HB/BARO.cpp at d3d6bacb12cd4e8519494e3a440a1f7c29e9cfc3 · arduino-libraries/Arduino_LPS22HB · GitHub
Try adding some print statements to see if that's the place where your code gets stuck. You could use the built-in RGB LED to easily check this without print statements:

  // trigger one shot

digitalWrite(LEDR, HIGH);
  i2cWrite(LPS22HB_CTRL2_REG, 0x01);

// wait for ONE_SHOT bit to be cleared by the hardware
  while ((i2cRead(LPS22HB_CTRL2_REG) & 0x01) != 0) {
    yield();
  }
  digitalWrite(LEDR, LOW);



(Don't forget a pinMode in your setup.)

The Arduino Nano 33 BLE runs ARM mbed os. When an error occurs, a message will be printed to the Serial1 port at 115,200 baud. Try connecting a USB-to-Serial adapter to the TX pin of the Arduino and see what it tells you. 

Otherwise, the SWD pins are accessible at the bottom, so you can hook it up to a debugger using OpenOCD (e.g. PlatformIO makes this more accessible) so you can see where it goes wrong.

Pieter

wildbill:
So add some prints to the library around that while loop and see if that's where it hangs.

wildbill:
That while loop that PieterP pointed out looks convincing though.

You are right. The code hangs in the while loop. ;-( What can I do to make it right. I'm a newbie in the Arduino world.

arhyrhy123:
What can I do to make it right.

Time to dig deeper. Which condition is causing i2cRead() to return a bad value?

int LPS22HBClass::i2cRead(uint8_t reg)
{
  _wire->beginTransmission(LPS22HB_ADDRESS);
  _wire->write(reg);
  if (_wire->endTransmission(false) != 0) {
    return -1;
  }

  if (_wire->requestFrom(LPS22HB_ADDRESS, 1) != 1) {
    return -1;
  }
  
  return _wire->read();
}

I would chase it down the rabbit hole that gfvalvo suggested.

You may prefer other options. A few days ago, there was a thread about timing issues with analogRead on the new Nano and I learned that it runs some mult-tasking system under the covers. There was some suspicion that some other task was using CPU during the read.

I wonder if that’s happening here too. It might be interesting to see what happens if you comment out the yield in the loop. I’d also make the loop restrict itself to a small number of attempts and return afterwards whether it got a pressure or not. Experiments will tell you how many attempts are needed.

gfvalvo:
Time to dig deeper. Which condition is causing i2cRead() to return a bad value?

int LPS22HBClass::i2cRead(uint8_t reg)

{
 _wire->beginTransmission(LPS22HB_ADDRESS);
 _wire->write(reg);
 if (_wire->endTransmission(false) != 0) {
   return -1;
 }

if (_wire->requestFrom(LPS22HB_ADDRESS, 1) != 1) {
   return -1;
 }
 
 return _wire->read();
}

wildbill:
I would chase it down the rabbit hole that gfvalvo suggested.

You may prefer other options. A few days ago, there was a thread about timing issues with analogRead on the new Nano and I learned that it runs some mult-tasking system under the covers. There was some suspicion that some other task was using CPU during the read.

I wonder if that’s happening here too. It might be interesting to see what happens if you comment out the yield in the loop. I’d also make the loop restrict itself to a small number of attempts and return afterwards whether it got a pressure or not. Experiments will tell you how many attempts are needed.

Hey guys, I just checked the program again by adding some Serial.print in the code, like this:

int LPS22HBClass::i2cRead(uint8_t reg)
{
  _wire->beginTransmission(LPS22HB_ADDRESS);
  _wire->write(reg);
  if (_wire->endTransmission(false) != 0) {
    Serial.println("first condition");
    return -1;
  }

  if (_wire->requestFrom(LPS22HB_ADDRESS, 1) != 1) {
    Serial.println("second condition");
    return -1;
  }
  Serial.println("End of function");
  return _wire->read();
}

I ran the program several times, every time the program hangs, “second condition” is first output for once and followed by endless “first condition”. What should I do from here? :wink:

Try printing the return value of endTransmission(): Arduino - WireEndTransmission