Hard fault using Wire.h Library with Arduino Nicla Sens ME

Hello together,

I am currently building a battery powered microcontroller to record room data (temperature, air pressure, humidity, CO2, VOC, light intensity). For this I use as a base an Arduino Nicla Sens Me which I have additionally equipped with a RTC (RTC DS1307), a Microcard SD Reader (DEBO MicroSD2), a light sensor (DEBO Light Sens4) and a battery controller. The whole setup is powered by a Lithium Polymer battery with 3,7 V. Individually I can read out the sensors without any problems and read out the RTC, so I don't assume a hardware failure. However, if I try to read out all sensor values via a program and write them to the SD card, the light sensor and the BME of the Nicla in particular give me a headache. If I try to start the Wire library, I get a hard fault of the Arduino with the error code 0x80FF013D. If I start only the wire library for the I²C connection for the light sensor or the BSEC library for the BME sensor, the Arduino Nicla works fine. The program code is attached :slight_smile:

Does anyone vllt have an idea what the problem could be? Thanks a lot!

#include "Nicla_System.h"
#include "Arduino_BHY2.h"
#include "ArduinoBLE.h"
#include <SPI.h>
#include <SD.h>
#include "RTClib.h"
#include <Wire.h>
#include <BH1750_WE.h>
#define BH1750_ADDRESS 0x23

RTC_DS1307 rtc;
BH1750_WE myBH1750 = BH1750_WE(BH1750_ADDRESS);

#define Seconds() (millis()/1000)
File myFile;

Sensor pressure(SENSOR_ID_BARO);
Sensor temperature(SENSOR_ID_TEMP);
Sensor humidity(SENSOR_ID_HUM);
Sensor gas(SENSOR_ID_GAS);
SensorBSEC bsec(uint8_t(171));

void setup() {
  nicla::begin();
  nicla::leds.begin();

  BHY2.begin();
  bsec.begin();
  pressure.begin();
  temperature.begin();
  humidity.begin();
  gas.begin();
  

  // Open serial communications and wait for port to open:
  Serial.begin(9600);

  //Wire.begin();
  //myBH1750.init();

  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.print("Initializing SD card...");

  if (!SD.begin(6)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open("test.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println(String("time") + ";" + String("pressure") + ";" + String("temperature") + ";" + String("humidity") + ";" + String("gas") + ";" + String("CO2") + ";" + String("VOC"));
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }

#ifndef ESP8266
  while (!Serial); // wait for serial port to connect. Needed for native USB
#endif

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    while (1) delay(10);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running, let's set the time!");
    // When time needs to be set on a new device, or after a power loss, the
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }

  // When time needs to be re-set on a previously configured device, the
  // following line sets the RTC to the date & time this sketch was compiled
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  // This line sets the RTC with an explicit date & time, for example to set
  // January 21, 2014 at 3am you would call:
  // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}

void loop() {
  static auto lastCheck = millis();
  BHY2.update();
  DateTime now = rtc.now();

  // Check sensor values every second
  if (millis() - lastCheck >= 1000) {
    lastCheck = millis();

    unsigned co2 = bsec.co2_eq();
    float b_voc_eq = bsec.b_voc_eq();

    SD.begin(6);
    // open the file. note that only one file can be open at a time,
    // so you have to close this one before opening another.
    myFile = SD.open("test.txt", FILE_WRITE);

    // if the file opened okay, write to it:
    if (myFile) {
      Serial.print("Writing to test.txt...");
      myFile.println(String(now.year()) + "/" + String(now.month()) + "/" + String(now.day()) + " " + String(now.hour()) + ":" + String(now.minute()) + ":" + String(now.second()) + ";"  + String(Seconds()) + ";" + pressure.value() + ";" + temperature.value() + ";" + humidity.value() + ";" + gas.value() + ";" + String(co2) + ";" + String(b_voc_eq));
      delay(100);
      // close the file:
      myFile.close();
      Serial.println("done.");
    } else {
      // if the file didn't open, print an error:
      Serial.println("error opening test.txt");
    }

    nicla::leds.setColor(green);
    delay(1000);
    nicla::leds.setColor(off);
    delay(1000);
  }
}

I (for one) would like to see this fault posted in your Post #1 (image or text).

@xfpd Thank you very much for your answer.

Of course, here is the complete error message

16:04:35.080 -> ++ MbedOS Fault Handler ++
16:04:35.080 ->
16:04:35.080 -> FaultType: HardFault
16:04:35.080 ->
16:04:35.080 -> Context:
16:04:35.080 -> R 0: 00000000
16:04:35.080 -> R 1: 40001548
16:04:35.080 -> R 2: 00000000
16:04:35.080 -> R 3: 4000ED7C
16:04:35.080 -> R 4: 65747361
16:04:35.080 -> R 5: 0000D834
16:04:35.080 -> R 6: 20000500
16:04:35.080 -> R 7: 20000A94
16:04:35.080 -> R 8: 00000060
16:04:35.080 -> R 9: 00000000
16:04:35.080 -> R 10: 00000000
16:04:35.080 -> R 11: 00000000
16:04:35.080 -> R 12: 50532072
16:04:35.080 -> SP : 20004400
16:04:35.080 -> LR : 20000A9C
16:04:35.080 -> PC : 0005216C
16:04:35.080 -> xPSR : 210B0000
16:04:35.080 -> PSP : 20004398
16:04:35.080 -> MSP : 2000FFC0
16:04:35.080 -> CPUID: 410FC241
16:04:35.080 -> HFSR : 40000000
16:04:35.080 -> MMFSR: 00000000
16:04:35.080 -> BFSR : 00000004
16:04:35.080 -> UFSR : 00000000
16:04:35.080 -> DFSR : 00000000
16:04:35.080 -> AFSR : 00000000
16:04:35.080 -> Mode : Thread
16:04:35.080 -> Priv : Privileged
16:04:35.080 -> Stack: PSP
16:04:35.080 ->
16:04:35.080 -> -- MbedOS Fault Handler --
16:04:35.080 ->
16:04:35.080 ->
16:04:35.080 ->
16:04:35.080 -> ++ MbedOS Error Info ++
16:04:35.080 -> Error Status: 0x80FF013D Code: 317 Module: 255
16:04:35.080 -> Error Message: Fault exception
16:04:35.080 -> Location: 0x5216C
16:04:35.080 -> Error Value: 0x2000982C
16:04:35.080 -> Current Thread: main Id: 0x200038E0 Entry: 0x1E5C3 StackSize: 0xC00 StackMem: 0x20003928 SP: 0x20004400
16:04:35.080 -> For more info, visit: mbedos-error
16:04:35.080 -> -- MbedOS Error Info --

The error has a line entry for "CPUID 410FC241" and a search for "vendor cpuid 0x410FC241" refer to an ARM control register... I wonder if that is on the Nicla Sens ME and what is running MbedOS... because the error is "system out of memory."

@xfpd thanks for your reply,

I was able to identify the error more precisely and could at least fix the hard fault of the Nicla. The problem was, that I have initalized the SD card in the loop again, this has led to the Hard Fault. I can now read out all sensor data and at least display them in the seriell monitor. But I can not open the SD card in the loop or write to it. In the setup of the program I write successfully a header in a .txt on the SD card and close the file again... I think somehow the interfaces are getting in each other's way. But I have no idea how to fix this.

May I ask: What are the results if you put the "readfrom/writeto" in a loop in the setup? I do not know, but suspect void loop() might do things too quickly (if you can break it in void setup() - that's a clue). Also, is the size of the SD card 2GB for FAT16, 4GB for FAT32 (is it full)?