Debug coding with rtc and sd card

Hi,
I tried to understand what happening in my code but I don't understand the issue.
I use several sensors on my arduino pro micro (4 dht22, rtc, sd card, frequency meter, weight sensor). And i try to understand the error in my script step by step.
My code just the setup :

#include <SPI.h>
#include <SD.h>
#include <RTClib.h>

#include <Wire.h>
#include <AHTxx.h>
#include "DHT.h"
#include "arduinoFFT.h"



/*
   MASSE
*/
#include <HX711_ADC.h>
#if defined(ESP8266)|| defined(ESP32) || defined(AVR)
#include <EEPROM.h>
#endif


//pins:
const int HX711_dout = 8; //mcu > HX711 dout pin
const int HX711_sck = 7; //mcu > HX711 sck pin

//HX711 constructor:
HX711_ADC LoadCell(HX711_dout, HX711_sck);

const int calVal_eepromAdress = 0;
unsigned long t = 0;
// ############################################

const int chipSelect = 4;



File myFile;

RTC_DS1307 rtc;

//TEMP EXT
#define brocheDHText 6    // La ligne de communication du DHT22 sera donc branchée sur la pin D6 de l'Arduino
#define brocheDHT_posA 9
#define brocheDHT_posB 10
#define brocheDHT_posC 19

#define typeDeDHT DHT22             // Ici, le type de DHT utilisé est un DHT22 (que vous pouvez changer en DHT11, DHT21, ou autre, le cas échéant)

DHT dht_ext(brocheDHText, typeDeDHT);
DHT dht_intA(brocheDHT_posA, typeDeDHT);
DHT dht_intB(brocheDHT_posB, typeDeDHT);
DHT dht_intC(brocheDHT_posC, typeDeDHT);

//capteur son
arduinoFFT FFT = arduinoFFT(); /* Create FFT object */

#define CHANNEL A0
const uint16_t samples = 128; //This value MUST ALWAYS be a power of 2
const double samplingFrequency = 1212; //Hz, must be less than 10000 due to ADC

unsigned int sampling_period_us;
unsigned long microseconds;

double vReal[samples];
double vImag[samples];

#define SCL_INDEX 0x00
#define SCL_TIME 0x01
#define SCL_FREQUENCY 0x02
#define SCL_PLOT 0x03

void setup() {

  Serial.begin(115200);
#ifndef ESP8266
  while (!Serial); // wait for serial port to connect. Needed for native USB
#endif
  sampling_period_us = round(1000000 * (1.0 / samplingFrequency));

delay(1000);
  if (! rtc.begin()) {
    Serial.println(F("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));
  }
    Serial.println("ok");

  dht_ext.begin();
  dht_intA.begin();
  dht_intB.begin();
  dht_intC.begin();

  //rtc.adjust(DateTime(2023, 5, 8, 22, 06, 0));

  //Serial.println(F("initialization done."));
  myFile = SD.open("data.txt", FILE_WRITE);
  if (myFile) {
    Serial.println(F("File opened ok"));
    myFile.println("Date,Time,Temperature_ruche_A (ºC),Humidity_ruche_A (%),Temperature_ruche_B (ºC),Humidity_ruche_B (%),Temperature_ruche_C (ºC),Humidity_ruche_C (%),Temperature_ext,Humidity_ext, Poids (kg), Frequence (Hz)");
    myFile.close();
//
  } else {
    // if the file didn't open, print an error:
    Serial.println(F("error opening data.txt"));
  }

  //rtc.adjust(DateTime(2023, 3, 8, 21, 33, 0));

}

And the message in the serial monitor :ok error opening data.txt
I dont understand why the SD file was not open.

Thank you for your help.

Check your wiring?
Try using the SD card module by its self with a library example?
Check if the sd card was correctly inserted?

Thank you for your answer. I have a pcb and the circuit is correct. I used an exemple for sd card read and write and it works.

Then does ALL the circuit consume a lot of power?
Need more amperage?

You miss the
SD.begin(SD_PIN); // part?

-jim lee

I have the SD.begin in my loop because if i remove the sd card i can detect it. But i did the SD.begin in my setup and obtain this :

okDate,Time,Temperature_ruche_A (ºC),Humidity_ruche_A (%),Temperature_ruche_B (ºC),Humidity_ruche_B (%),Temperature_ruche_C (ºC),Humidity_ruche_C (%),Temperature_ext,Humidity_ext, Poids (kg), Frequence (Hz),OKA⸮⸮a9 ⸮⸮g⸮⸮⸮⸮⸮⸮!⸮⸮⸮3⸮PE@⸮>
@⸮>	 ⸮>⸮⸮>Q⸮c
kKc
revevK⸮⸮⸮⸮! ⸮⸮⸮	d⸮⸮4T⸮⸮	c
⸮
⸮⸮⸮
⸮ ⸮⸮⸮
⸮

I will try with my 9ah external battery. Can i add the power with my external battery on 'raw' pin and connect the arduino usb to my computer simultaneously to have the serial monitor ?

I don't think that works like that.

Maybe first try it without your auto detection trick?

-jim lee

Yes i did. Just with the setup part and empty loop. I obtained the message above in the serial monitor.
Here is my full code :

#include <SPI.h>
#include <SD.h>
#include <RTClib.h>

#include <Wire.h>
#include <AHTxx.h>
#include "DHT.h"
#include "arduinoFFT.h"



/*
   MASSE
*/
#include <HX711_ADC.h>
#if defined(ESP8266)|| defined(ESP32) || defined(AVR)
#include <EEPROM.h>
#endif


//pins:
const int HX711_dout = 8; //mcu > HX711 dout pin
const int HX711_sck = 7; //mcu > HX711 sck pin

//HX711 constructor:
HX711_ADC LoadCell(HX711_dout, HX711_sck);

const int calVal_eepromAdress = 0;
unsigned long t = 0;
// ############################################

const int chipSelect = 4;



File myFile;

RTC_DS1307 rtc;

//TEMP EXT
#define brocheDHText 6    // La ligne de communication du DHT22 sera donc branchée sur la pin D6 de l'Arduino
#define brocheDHT_posA 9
#define brocheDHT_posB 10
#define brocheDHT_posC 19

#define typeDeDHT DHT22             // Ici, le type de DHT utilisé est un DHT22 (que vous pouvez changer en DHT11, DHT21, ou autre, le cas échéant)

DHT dht_ext(brocheDHText, typeDeDHT);
DHT dht_intA(brocheDHT_posA, typeDeDHT);
DHT dht_intB(brocheDHT_posB, typeDeDHT);
DHT dht_intC(brocheDHT_posC, typeDeDHT);

//capteur son
arduinoFFT FFT = arduinoFFT(); /* Create FFT object */

#define CHANNEL A0
const uint16_t samples = 128; //This value MUST ALWAYS be a power of 2
const double samplingFrequency = 1212; //Hz, must be less than 10000 due to ADC

unsigned int sampling_period_us;
unsigned long microseconds;

double vReal[samples];
double vImag[samples];

#define SCL_INDEX 0x00
#define SCL_TIME 0x01
#define SCL_FREQUENCY 0x02
#define SCL_PLOT 0x03

void setup() {

  Serial.begin(115200);
#ifndef ESP8266
  while (!Serial); // wait for serial port to connect. Needed for native USB
#endif
  sampling_period_us = round(1000000 * (1.0 / samplingFrequency));

delay(1000);
  if (! rtc.begin()) {
    Serial.println(F("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));
  }
    Serial.println("ok");

  dht_ext.begin();
  dht_intA.begin();
  dht_intB.begin();
  dht_intC.begin();

  //rtc.adjust(DateTime(2023, 5, 8, 22, 06, 0));
  SD.begin()
  //Serial.println(F("initialization done."));
  myFile = SD.open("data.txt", FILE_WRITE);
  if (myFile) {
    Serial.println(F("File opened ok"));
    myFile.println("Date,Time,Temperature_ruche_A (ºC),Humidity_ruche_A (%),Temperature_ruche_B (ºC),Humidity_ruche_B (%),Temperature_ruche_C (ºC),Humidity_ruche_C (%),Temperature_ext,Humidity_ext, Poids (kg), Frequence (Hz)");
    myFile.close();
//
  } else {
    // if the file didn't open, print an error:
    Serial.println(F("error opening data.txt"));
  }

  //rtc.adjust(DateTime(2023, 3, 8, 21, 33, 0));

}
/* rtc
*******************************************************************************************
*/
void loggingTime() {
  DateTime now = rtc.now();
  myFile = SD.open("data.txt", FILE_WRITE);
  if (myFile) {
    myFile.print(now.year(), DEC);
    myFile.print('/');
    myFile.print(now.month(), DEC);
    myFile.print('/');
    myFile.print(now.day(), DEC);
    myFile.print(',');
    myFile.print(now.hour(), DEC);
    myFile.print(':');
    myFile.print(now.minute(), DEC);
    myFile.print(':');
    myFile.print(now.second(), DEC);
    myFile.print(",");
  }
  myFile.close();
  delay(1000);
}

/*temp
****************************************************************************************************
*/
void loggingTemperature() {

  float hum = dht_ext.readHumidity();
  float temp = dht_ext.readTemperature();

  float hum_A = dht_intA.readHumidity();
  float temp_A = dht_intA.readTemperature();


  float hum_B = dht_intB.readHumidity();
  float temp_B = dht_intB.readTemperature();


  float hum_C = dht_intC.readHumidity();
  float temp_C = dht_intC.readTemperature();


  myFile = SD.open("data.txt", FILE_WRITE);
  if (myFile) {
    myFile.print(temp_A);
    myFile.print(",");
    myFile.print(hum_A);
    myFile.print(",");
    myFile.print(temp_B);
    myFile.print(",");
    myFile.print(hum_B);
    myFile.print(",");
    myFile.print(temp_C);
    myFile.print(",");
    myFile.print(hum_C);
    myFile.print(",");
    myFile.print(temp);
    myFile.print(",");
    myFile.print(hum);
    myFile.print(",");
  }
  myFile.close();
}

/*MASSE
************************************************************
*/


void calibrate() {
  Serial.println(F("***"));
  Serial.println(F("Start calibration:"));
  Serial.println(F("Place the load cell an a level stable surface."));
  Serial.println(F("Remove any load applied to the load cell."));
  Serial.println(F("Send 't' from serial monitor to set the tare offset."));

  boolean _resume = false;
  while (_resume == false) {
    LoadCell.update();
    if (Serial.available() > 0) {
      if (Serial.available() > 0) {
        char inByte = Serial.read();
        if (inByte == 't') LoadCell.tareNoDelay();
      }
    }
    if (LoadCell.getTareStatus() == true) {
      Serial.println(F("Tare complete"));
      _resume = true;
    }
  }

  Serial.println(F("Now, place your known mass on the loadcell."));
  Serial.println(F("Then send the weight of this mass (i.e. 100.0) from serial monitor."));

  float known_mass = 0;
  _resume = false;
  while (_resume == false) {
    LoadCell.update();
    if (Serial.available() > 0) {
      known_mass = Serial.parseFloat();
      if (known_mass != 0) {
        Serial.print(F("Known mass is: "));
        Serial.println(known_mass);
        _resume = true;
      }
    }
  }

  LoadCell.refreshDataSet(); //refresh the dataset to be sure that the known mass is measured correct
  float newCalibrationValue = LoadCell.getNewCalibration(known_mass); //get the new calibration value

  Serial.print(F("New calibration value has been set to: "));
  Serial.print(newCalibrationValue);
  Serial.println(F(", use this as calibration value (calFactor) in your project sketch."));
  Serial.print(F("Save this value to EEPROM adress "));
  Serial.print(calVal_eepromAdress);
  Serial.println("? y/n");

  _resume = false;
  while (_resume == false) {
    if (Serial.available() > 0) {
      char inByte = Serial.read();
      if (inByte == 'y') {
#if defined(ESP8266)|| defined(ESP32)
        EEPROM.begin(512);
#endif
        EEPROM.put(calVal_eepromAdress, newCalibrationValue);
#if defined(ESP8266)|| defined(ESP32)
        EEPROM.commit();
#endif
        EEPROM.get(calVal_eepromAdress, newCalibrationValue);
        Serial.print(F("Value "));
        Serial.print(newCalibrationValue);
        Serial.print(F(" saved to EEPROM address: "));
        Serial.println(calVal_eepromAdress);
        _resume = true;

      }
      else if (inByte == 'n') {
        Serial.println(F("Value not saved to EEPROM"));
        _resume = true;
      }
    }
  }

  Serial.println("End calibration");
  Serial.println(F("***"));
  Serial.println(F("To re-calibrate, send 'r' from serial monitor."));
  Serial.println(F("For manual edit of the calibration value, send 'c' from serial monitor."));
  Serial.println(F("***"));
}

void changeSavedCalFactor() {
  float oldCalibrationValue = LoadCell.getCalFactor();
  boolean _resume = false;
  Serial.println(F("***"));
  Serial.print(F("Current value is: "));
  Serial.println(oldCalibrationValue);
  Serial.println(F("Now, send the new value from serial monitor, i.e. 696.0"));
  float newCalibrationValue;
  while (_resume == false) {
    if (Serial.available() > 0) {
      newCalibrationValue = Serial.parseFloat();
      if (newCalibrationValue != 0) {
        Serial.print(F("New calibration value is: "));
        Serial.println(newCalibrationValue);
        LoadCell.setCalFactor(newCalibrationValue);
        _resume = true;
      }
    }
  }
  _resume = false;
  Serial.print(F("Save this value to EEPROM adress "));
  Serial.print(calVal_eepromAdress);
  Serial.println("? y/n");
  while (_resume == false) {
    if (Serial.available() > 0) {
      char inByte = Serial.read();
      if (inByte == 'y') {
#if defined(ESP8266)|| defined(ESP32)
        EEPROM.begin(512);
#endif
        EEPROM.put(calVal_eepromAdress, newCalibrationValue);
#if defined(ESP8266)|| defined(ESP32)
        EEPROM.commit();
#endif
        EEPROM.get(calVal_eepromAdress, newCalibrationValue);
        Serial.print(F("Value "));
        Serial.print(newCalibrationValue);
        Serial.print(F(" saved to EEPROM address: "));
        Serial.println(calVal_eepromAdress);
        _resume = true;
      }
      else if (inByte == 'n') {
        Serial.println(F("Value not saved to EEPROM"));
        _resume = true;
      }
    }
  }
  Serial.println(F("End change calibration value"));
  Serial.println("***");
}
void PrintVector(double *vData, uint16_t bufferSize, uint8_t scaleType)
{
  for (uint16_t i = 0; i < bufferSize; i++)
  {
    double abscissa;
    /* Print abscissa value */
    switch (scaleType)
    {
      case SCL_INDEX:
        abscissa = (i * 1.0);
        break;
      case SCL_TIME:
        abscissa = ((i * 1.0) / samplingFrequency);
        break;
      case SCL_FREQUENCY:
        abscissa = ((i * 1.0 * samplingFrequency) / samples);
        break;
    }

  }
}

/*loop
*******************************************************************************************
*/

void frequency() {
  microseconds = micros();
  for (int i = 0; i < samples; i++)
  {
    vReal[i] = analogRead(CHANNEL);
    vImag[i] = 0;
    while (micros() - microseconds < sampling_period_us) {
      //empty loop
    }
    microseconds += sampling_period_us;
  }
  /* Print the results of the sampling according to time */
  PrintVector(vReal, samples, SCL_TIME);

  FFT.Windowing(vReal, samples, FFT_WIN_TYP_HAMMING, FFT_FORWARD);  /* Weigh data */
  PrintVector(vReal, samples, SCL_TIME);

  FFT.Compute(vReal, vImag, samples, FFT_FORWARD); /* Compute FFT */
  PrintVector(vReal, samples, SCL_INDEX);
  PrintVector(vImag, samples, SCL_INDEX);

  FFT.ComplexToMagnitude(vReal, vImag, samples); /* Compute magnitudes */

  double x = FFT.MajorPeak(vReal, samples, samplingFrequency);
  Serial.println(x, 6);

    myFile = SD.open("data.txt", FILE_WRITE);
    if (myFile) {
      myFile.print(x, 6);
      myFile.println(",");
    }
    myFile.close();
}

void loop() {
  if (!SD.begin(chipSelect)) {
    Serial.println(F("initialization failed!"));
    return;
  }
  loggingTime();
  //loggingTemperature();
  frequency();
  Serial.println("OK");
  /*SAMPLING*/

  //LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

  delay(1000);

}

Is the SD card reader mounted on a display or something?

-jim lee

I send you a picture of my circuit

Vin pin?
Battery voltage?

I think you can do that with serial.

Raw pin on arduino pro micro. I use a 12v 9ah Lead battery with solar panel.

I find the issue but i can't explain this.
I use 3 functions in my loop ( loggingTime(); loggingTemperature(); and frequency(); )
But the issue appears when i use the frequency function with the other.

void PrintVector(double *vData, uint16_t bufferSize, uint8_t scaleType)
{
  for (uint16_t i = 0; i < bufferSize; i++)
  {
    double abscissa;
    /* Print abscissa value */
    switch (scaleType)
    {
      case SCL_INDEX:
        abscissa = (i * 1.0);
        break;
      case SCL_TIME:
        abscissa = ((i * 1.0) / samplingFrequency);
        break;
      case SCL_FREQUENCY:
        abscissa = ((i * 1.0 * samplingFrequency) / samples);
        break;
    }

  }
}

/*loop
*******************************************************************************************
*/

void frequency() {
  microseconds = micros();
  for (int i = 0; i < samples; i++)
  {
    vReal[i] = analogRead(CHANNEL);
    vImag[i] = 0;
    while (micros() - microseconds < sampling_period_us) {
      //empty loop
    }
    microseconds += sampling_period_us;
  }
  /* Print the results of the sampling according to time */
  PrintVector(vReal, samples, SCL_TIME);

  FFT.Windowing(vReal, samples, FFT_WIN_TYP_HAMMING, FFT_FORWARD);  /* Weigh data */
  PrintVector(vReal, samples, SCL_TIME);

  FFT.Compute(vReal, vImag, samples, FFT_FORWARD); /* Compute FFT */
  PrintVector(vReal, samples, SCL_INDEX);
  PrintVector(vImag, samples, SCL_INDEX);

  FFT.ComplexToMagnitude(vReal, vImag, samples); /* Compute magnitudes */

  double x = FFT.MajorPeak(vReal, samples, samplingFrequency);
  Serial.println(x, 6);
  SD.begin(chipSelect);
    myFile = SD.open(nameSD, FILE_WRITE);
    if (myFile) {
      myFile.print(x, 6);
      myFile.println(",");
    }
    myFile.close();
}

When i use the frequency function in an other script it works...

Oh, That must be the the external Power input for the Arduino.
Sorry, I have no experience with Pro micro.

Wow!
So 9 hours at one amp?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.