initCertStore() fail due to there's no CA certs file read

Hi all,
I’m now doing as follow of this guideline for esp8266: HiveMQ Cloud
When running the code, I’m successfully on wifi’s config and setDateTime() function also. But when it comes to CA certs read function, when running it I have an error: “No certs found” even when I have uploaded the certs.ar file to sketch directory.
I’m using window. Are there any solutions I can do to fix it ?
Thank you all for helping me.
Below is my code and the picture of my file location.

#include <math.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>  //mqtt protocol
#include "DHT.h"
#include <Adafruit_Sensor.h>
#include <Arduino_JSON.h>
#include <ESP8266WebServer.h>
#include <EEPROM.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_BME280.h>
#include <BH1750.h>  
#include <time.h>
#include <TZ.h>
#include <FS.h>
#include <LittleFS.h>
#include <CertStoreBearSSL.h>


#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

#define UV_PIN A0

#define OBSTACLE_PIN D0 

//#define DECIBLE_PIN A0

#define SCALE_DATA_PIN D4
#define SCALE_SCK_PIN D3

#define MSG_BUFFER_SIZE (500)
//config wifi  and mqtt server for esp8266
//  ******variable******
ESP8266WebServer server(80);
JSONVar data;
//WiFiClient espClient;
WiFiClientSecure espClient;
//PubSubClient client(espClient);  //use espClient for network communication
PubSubClient * client;  
unsigned long lastMsg = 0;
char msg[MSG_BUFFER_SIZE];

const char* mqtt_server = "900fd0b446d0454f8aaa8cb4c763a5c2.s1.eu.hivemq.cloud";  //mqtt broker
float humidity, temperature_C, temperature_F;
const float referenceVoltage = 3.3;   // ESP8266 ADC reference voltage (3.3V)
const float referenceSPL = 45.0;     // SPL of calibration sound source in dB
const int referenceADC = 512;        // ADC value recorded at reference SPL
const int numReadings = 10;          // Number of samples for averaging
double UV_index, sensor_value;  
double totalBee;
float weight;
double decible;

unsigned long x = 0, y = 0;
unsigned long dataArray[10];

int j = 0;

const int sampleWindow = 50;                              // Sample window width in mS (50 mS = 20Hz)
unsigned int sample;

unsigned long startMillis= millis();                   // Start of sample window
float peakToPeak = 0;                                  // peak-to-peak level

unsigned int signalMax = 0;                            //minimum value
unsigned int signalMin = 1024; 

// A single, global CertStore which can be used by all connections.
// Needs to stay live the entire time any of the WiFiClientBearSSLs
// are present.
BearSSL::CertStore certStore;


struct settings {
  char ssid[30];
  char password[30];
} user_wifi = {};

//  ******variable******

void web_handle() {
  server.on("/", handlePortal);
  server.begin();
}

/*set date time*/
void setDateTime() {
    // You can use your own timezone, but the exact time is not used at all.
    // Only the date is needed for validating the certificates.
    configTime(TZ_Europe_Berlin, "pool.ntp.org", "time.nist.gov");
  
    Serial.print("Waiting for NTP time sync: ");
    time_t now = time(nullptr);
    while (now < 8 * 3600 * 2) {
      delay(100);
      Serial.print(".");
      now = time(nullptr);
    }
    Serial.println();
  
    struct tm timeinfo;
    gmtime_r(&now, &timeinfo);
    Serial.printf("%s %s", tzname[0], asctime(&timeinfo));
  }
/*set date time*/

void setup_wifi() {

  delay(10);
  EEPROM.begin(sizeof(struct settings));
  EEPROM.get(0, user_wifi);
  
  //config wifi station mode(join exists network)
  WiFi.mode(WIFI_STA);
  WiFi.begin(user_wifi.ssid, user_wifi.password);
  /**/
  byte tries = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    if (tries++ > 10) {
      WiFi.mode(WIFI_AP);
      WiFi.softAP("Setup Portal", "mrdiy.ca");
      break;
    }
    // randomSeed(micros()); //
    Serial.print(".");
  }
  web_handle();
  Serial.println("WiFi connected");
  Serial.print("IP HOST: ");
  Serial.println(WiFi.localIP());
  Serial.println(WiFi.gatewayIP());
  Serial.println(WiFi.subnetMask());
  Serial.println(WiFi.status());
}
/**/
void handlePortal() {
  if (server.method() == HTTP_POST) {

    strncpy(user_wifi.ssid, server.arg("ssid").c_str(), sizeof(user_wifi.ssid));
    strncpy(user_wifi.password, server.arg("password").c_str(), sizeof(user_wifi.password));
    user_wifi.ssid[server.arg("ssid").length()] = user_wifi.password[server.arg("password").length()] = '\0';
    EEPROM.put(0, user_wifi);
    EEPROM.commit();

    server.send(200, "text/html", "<!doctype html><html lang='en'><head><meta charset='utf-8'><meta name='viewport' content='width=device-width, initial-scale=1'><title>Wifi Setup</title><style>*,::after,::before{box-sizing:border-box;}body{margin:0;font-family:'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans','Liberation Sans';font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#f5f5f5;}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);border:1px solid #ced4da;}button{border:1px solid transparent;color:#fff;background-color:#007bff;border-color:#007bff;padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem;width:100%}.form-signin{width:100%;max-width:400px;padding:15px;margin:auto;}h1,p{text-align: center}</style> </head> <body><main class='form-signin'> <h1>Wifi Setup</h1> <br/> <p>Your settings have been saved successfully!<br />Please restart the device.</p></main></body></html>");
  } else {

    server.send(200, "text/html", "<!doctype html> <html lang='en'> <head> <meta charset='utf-8'> <meta name='viewport' content='width=device-width, initial-scale=1'> <title>Wifi Setup</title> <style> *, ::after, ::before { box-sizing: border-box; } body { margin: 0; font-family: 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', 'Liberation Sans'; font-size: 1rem; font-weight: 400; line-height: 1.5; color: #212529; background-color: #f5f5f5; } .form-control { display: block; width: 100%; height: calc(1.5em + .75rem + 2px); border: 1px solid #ced4da; } button { cursor: pointer; border: 1px solid transparent; color: #fff; background-color: #007bff; border-color: #007bff; padding: .5rem 1rem; font-size: 1.25rem; line-height: 1.5; border-radius: .3rem; width: 100% } .form-signin { width: 100%; max-width: 400px; padding: 15px; margin: auto; } h1 { text-align: center } </style> </head> <body> <main class='form-signin'> <form action='/' method='post'> <h1 class=''>Wifi Setup For BeeHive Equipment</h1><br /> <div class='form-floating'><label>Enter the Wifi's username:</label><input type='text' class='form-control' name='ssid'> </div> <div class='form-floating'><br /><label>Enter the Wifi's password</label><input type='password' class='form-control' name='password'></div><br /><br /><button type='submit'>Save Change</button> </form> </main> </body> </html>");
  }
}

void reconnect() {
  // Loop until we're reconnected
  while (!client->connected()) {
    Serial.print("Attempting MQTT connection...");
    String clientId = "ESP8266Client";
    clientId += String(random(0xffff), HEX);
    
    if (client->connect(clientId.c_str(), "tan_beehive", "Tan_beehive1")) {
      Serial.println("connected");
      //if esp can connect to server, then esp will subcribe the topic
      client->subscribe("device/temp");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client->state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}
//receive message sent from device to mqtt
void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // if message = 1 then react on esp
  if ((char)payload[0] == '1') {
    Serial.print("esp8266 receive message 1");
  }
}

void getTempHumid() {
  temperature_C = dht.readTemperature();

  temperature_F = dht.readTemperature(true);

  humidity = dht.readHumidity();



  // Check for error reading
  if (isnan(humidity) || isnan(temperature_C) || isnan(temperature_F)) {
    Serial.println(" DHT reading failed ");
    return;
  }


  Serial.print("Humidity: ");
  Serial.print(humidity);
  Serial.println("%");

  Serial.print("Temperature:");
  Serial.print(temperature_C);
  Serial.print(("°C ------- "));

  Serial.print(temperature_F);
  Serial.println("°F");
}

void getUV(){
  sensor_value = analogRead(UV_PIN); 
  float volts = sensor_value * 5.0 / 1024.0;
  UV_index = volts * 10;
  Serial.print ("Raw ADC data: ");
  Serial.print (sensor_value);
  Serial.print ("  UV Index: ");
  Serial.println (UV_index);
}

void getIR(){
  //read if there is obstacle
  Serial.print("obs \t");
  int obsDetect = digitalRead(OBSTACLE_PIN);
  if(obsDetect == 0){
    totalBee +=1;
    
  }
  Serial.println(totalBee);
}

void getWeight(){
 
 for (int j = 0; j < 10; j++)
  {
    digitalWrite(SCALE_SCK_PIN, LOW);//SCK is made LL
    while (digitalRead(SCALE_DATA_PIN) != LOW) //wait until Data Line goes LOW
      ;
    {
      for (int i = 0; i < 24; i++)  //read 24-bit data from HX711
      {
        clk();      //generate CLK pulse to get MSB-it at SCALE_DATA_PIN-pin
        bitWrite(x, 0, digitalRead(SCALE_DATA_PIN));
        x = x << 1;
      }
      clk();
      Serial.println(x, HEX);
      y = x;
      x = 0;
      delay(1000);
    }
    dataArray[j] = y;
  }

  Serial.println("===averaging process=========");
  unsigned long sum = 0;

  for (j = 0; j < 10; j++)
  {
    sum += dataArray[j];
  }
  Serial.print("Average Count = ");
  sum = sum / 10;
  //Serial.println(sum, DEC);
  float tare = 0.790;
  float W = (float)0.005331 * sum - 1146.176 - tare;
  W = (float)W / 1000.00; 
  Serial.println(W, 3);
  weight = W;
}


void clk(){
  digitalWrite(SCALE_SCK_PIN, HIGH);
  digitalWrite(SCALE_SCK_PIN, LOW);
  }

// void getDecible(){
//   while (millis() - startMillis < sampleWindow)
//    {
//       sample = analogRead(DECIBLE_PIN);                    //get reading from microphone
//       if (sample < 1024)                                  // toss out spurious readings
//       {
//          if (sample > signalMax)
//          {
//             signalMax = sample;                           // save just the max levels
//          }
//          else if (sample < signalMin)
//          {
//             signalMin = sample;                           // save just the min levels
//          }
//       }
//    }
 
//    peakToPeak = signalMax - signalMin;                    // max - min = peak-peak amplitude
//    int db = map(peakToPeak,20,900,49.5,90);             //calibrate for deciBels
 
//   Serial.print("Loudness: ");
//   Serial.print(db);
//   Serial.println("dB");
   
//   delay(200); 
// }



void dataPublishing(){
  //data format
  data["temperature"] = (double)temperature_C;
  data["humidity"] = (double)humidity;
  data["place"] = "Dong Nai";
  data["uv_value"] = sensor_value;
  data["uv_index"] = (int)UV_index;
  data["totalBee"] = totalBee; 
  //convert object to json string
  String jsonString = JSON.stringify(data);

  //publish sensor data to server via topic
  client->publish("beehive", jsonString.c_str(), true);

}

void pinDefine(){
  pinMode(OBSTACLE_PIN, INPUT);
  pinMode(UV_PIN, INPUT);
  pinMode(SCALE_DATA_PIN, INPUT); //data line  //Yellow cable
  pinMode(SCALE_SCK_PIN, OUTPUT);
  //pinMode (DECIBLE_PIN, INPUT);
 
}


void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinDefine();
  
  LittleFS.begin();
  setup_wifi();
  if(WiFi.status() == WL_CONNECTED){
    setDateTime();
  }else{
    Serial.println("fail");
  }
 
  if (!LittleFS.begin()) {
  Serial.println("Failed to mount LittleFS.");
  return;
  }
  int numCerts = certStore.initCertStore(LittleFS, PSTR("/certs.idx"), PSTR("/certs.ar"));
    Serial.printf("Number of CA certs read: %d\n", numCerts);
    if (numCerts == 0) {
        Serial.printf("No certs found.\n");
        Serial.printf("Did you run certs-from-mozilla.py and upload the LittleFS directory before running?\n");
        return; // Can't connect to anything w/o certs!
    }
  BearSSL::WiFiClientSecure *bear = new BearSSL::WiFiClientSecure();
  // Integrate the cert store with this connection
  bear->setCertStore(&certStore);

  client = new PubSubClient(*bear);

  client->setServer(mqtt_server, 8883);
  client->setCallback(callback);
  
   dht.begin();
}


void loop() {
  while (WiFi.status() != WL_CONNECTED) { // Chờ cho đến khi kết nối thành công
        Serial.print(".");
        delay(500);
        server.handleClient(); // Xử lý yêu cầu HTTP nếu cần
    }
  delay(2000);
  if (!client->connected()) {
    reconnect();
   }
   client->loop();
  //Wait a few seconds between measurements.
  delay(2000);
  getUV();
  getTempHumid();
  dataPublishing();
  getIR();
  //getSound();
  delay(2000);
}



Hi @duybao, welcome to the HiveMQ Community. It’s great to have you here, and we’re glad you’re exploring MQTT and HiveMQ.

It seems like you are having trouble with the ESP8266 finding the certificates file even though you’ve uploaded it. It is unknown which board and version of ESP8266 core you are using.

Based on the error message “No certs found,” there’s likely an issue with how the certificates file was uploaded or the file path. Let me suggest troubleshooting steps:

  • Make sure the certs.ar file is placed in a folder named data within the sketch directory, not directly in the sketch directory itself.
  • Confirm that the LittleFS upload tool completed successfully. You should see “LittleFS Image Uploaded” in the Arduino IDE after uploading.
  • Ensure both certs.ar and certs.idx files are present in the data folder. The code looks for both files.
  • Make sure LittleFS.begin() is successful. The customer could add error checking:
if (!LittleFS.begin()) {
  Serial.println("Failed to initialize LittleFS");
  return;
}
  • Check that the paths in certStore.initCertStore(LittleFS, PSTR("/certs.idx"), PSTR("/certs.ar")) match the actual filenames.
  • Verify that an appropriate flash size is selected in Tools > Flash Size. If the files are too large for the selected flash size, this could cause issues.
  • Add code to check what files are actually present on the filesystem:
  void listFiles() {
    Dir dir = LittleFS.openDir("/");
    while (dir.next()) {
      Serial.print("Found file: ");
      Serial.println(dir.fileName());
    }
  }

Then call this in setup() before trying to initialize the certificate store.

  • Sometimes a full restart of the Arduino IDE can help resolve issues with tools like the LittleFS uploader.

I hope it helps,
Best,
Dasha from The HiveMQ Team