Create a data logger recording data from two linear potentiometers and a matric potential sensor for soil (Teros 21 Gen 2)

Hi everyone!
I'm a newbie with Arduino, the first time I'm trying to program something...
What I am trying to do, is to create a data logger that can record the values received by some sensors. I’d like to connect two linear potentiometers and a soil potential sensor to arduino. I am using Arduino UNO, to which I have connected a logging and RTC shield. The sensors seem to be working, but I can’t get the soil sensor values on the SD card. Opening the serial monitor, I see a first line where the values of the ground sensor (sensor number, potential and temperature) are correctly read. For example, what appears is "0-3.5+20.1". From the next lines, they appear similar to this "5/2/2023,17:25:5, ,0.0000000000,14.5161294937", which should be: date, time, value of the soil sensor (which does not appear), value of the potentiometer 1 (correct), value of the potentiometer 2 (correct). Practically, I see the value of the soil sensor only at the beginning, and it is not written correctly with others. I have tried in various ways to edit my sketch... Can anyone suggest me where I am going wrong?
I paste here my sketch:

#include <Wire.h> 
#include "RTClib.h"  
#include <SDI12.h> 
#include <SPI.h> 
#include <SD.h> 

#define SERIAL_BAUD 9600 
#define DATA_PIN 2         
#define POWER_PIN 7     

RTC_DS1307 RTC;
SDI12 mySDI12(DATA_PIN);


String myCommand = "0R0!";  


const int chipSelect = 10; 

 
void setup() {

   pinMode(7, OUTPUT); 
   
  
   Serial.begin(SERIAL_BAUD);
   
   
 
  Wire.begin(); 
  RTC.begin();
  
  mySDI12.begin();
 
  
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running");}
   

  
  DateTime now = RTC.now();
  DateTime compiled = DateTime(__DATE__, __TIME__);
  if (now.unixtime() < compiled.unixtime()) {
    Serial.println("RTC is older than compile time! Updating");
    RTC.adjust(DateTime(__DATE__, __TIME__));}
 
  Serial.println("Setup complete.");


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

 
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    
  }
  Serial.println("card initialized.");




  
  if (POWER_PIN > 0) {
    Serial.println("Powering up sensors...");
    pinMode(POWER_PIN, OUTPUT);
    digitalWrite(POWER_PIN, HIGH);
    delay(200);
  }
 
}


 

 
void loop() {
  // Get the current time
  DateTime now = RTC.now();
   
  mySDI12.sendCommand(myCommand);
  delay(300);  // wait a while for a response
  while (mySDI12.available()) 
  {  // write the response to the screen
    Serial.write(mySDI12.read());
  }
   


int val1; 
int val2;



  digitalWrite(7, HIGH); 
  

  val1=analogRead(0);     
float length1 = val1 * (25/1023.0); 
  val2=analogRead(1);     
float length2 = val2 * (25/1023.0); 
     

  
  Serial.print(now.day(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC); 
  Serial.print('/');
  Serial.print(now.year(), DEC);
  Serial.print(',');
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.print(',');
 Serial.write(mySDI12.read());
    Serial.print(',');
   Serial.print(length1*1,DEC);
  Serial.print(','); 
  Serial.println(length2*1,DEC);
  

  digitalWrite(7, LOW); 
 
   delay(10000);

 
 File dataFile = SD.open("datalog.txt", FILE_WRITE); 
 
  // if the file is available, write to it:
  if (dataFile) { 
    // store data every 15 minute
  if (now.minute()== 0  || now.minute()== 15 || now.minute()== 30 || now.minute()== 45) 
  { 
  dataFile.print(now.day(), DEC);
  dataFile.print('/');
  dataFile.print(now.month(), DEC); 
  dataFile.print('/');
  dataFile.print(now.year(), DEC);
  dataFile.print(',');
  dataFile.print(now.hour(), DEC);
  dataFile.print(':');
  dataFile.print(now.minute(), DEC);
  dataFile.print(':');
  dataFile.print(now.second(), DEC);
  dataFile.print(',');
  dataFile.print(mySDI12.read());
  dataFile.print(',');
  dataFile.print(length1,DEC);
  dataFile.print(','); 
  dataFile.println(length2,DEC); 
  dataFile.close();
  }
  else {
    dataFile.close();
  }
  
 }
  
  else {
    Serial.println("error opening datalog.txt");
  } 
  } 

The "power" wires are on the digital pin 7, the digital communication of the soil sensor is on the digital pin 2, the analog data from linear potentiometers are on analog pin A0 and A1, the ground of all sensors on GND.

The manual for the soil sensor is at this link [http://library.metergroup.com/Manuals/20854_TEROS21_Gen2_Manual_Web.pdf]
(http://library.metergroup.com/Manuals/20854_TEROS21_Gen2_Manual_Web.pdf)

Thank you in advance for any help!

can you upload a copy of the serial monitor text output and a copy of the file contents on the SD?

Sure! Here is the copy of the serial monitor:

Setup complete.
Initializing SD card...card initialized.
Powering up sensors...
0-2.2+19.0
5/2/2023,22:53:40,⸮,0.0000000000,24.3890533447
5/2/2023,22:53:51,⸮,0.0000000000,10.8993158340
5/2/2023,22:54:1,⸮,0.0000000000,10.8748779296
5/2/2023,22:54:11,⸮,0.0000000000,10.8748779296

And so on... On the sd card:

4/2/2023,18:30:7,25.0000000000,0.0000000000
4/2/2023,18:30:18,25.0000000000,0.0000000000
4/2/2023,18:30:28,25.0000000000,0.0000000000
4/2/2023,18:30:38,25.0000000000,0.0000000000
4/2/2023,18:30:48,25.0000000000,0.0000000000
4/2/2023,18:30:58,25.0000000000,0.0000000000
4/2/2023,18:45:8,25.0000000000,0.0000000000
4/2/2023,18:45:18,25.0000000000,0.0000000000
4/2/2023,18:45:28,25.0000000000,0.0000000000
4/2/2023,18:45:38,25.0000000000,0.0000000000
4/2/2023,18:45:48,25.0000000000,0.0000000000
4/2/2023,18:45:58,25.0000000000,0.0000000000
4/2/2023,19:0:6,-1,0.8797654151,0.8064516067
4/2/2023,19:0:17,-1,0.8797654151,0.8553275108
4/2/2023,19:0:27,-1,0.9042033195,0.8308896064
4/2/2023,19:0:37,-1,0.8797654151,0.8308896064
4/2/2023,19:0:48,-1,0.8797654151,0.8064516067
4/2/2023,19:0:58,-1,0.8797654151,0.8064516067
4/2/2023,19:15:7,-1,0.8308896064,0.7575757980
4/2/2023,19:15:18,-1,0.8308896064,0.7820137023
4/2/2023,19:15:28,-1,0.8308896064,0.7575757980
4/2/2023,19:15:38,-1,0.8308896064,0.7820137023
4/2/2023,19:15:49,-1,0.8308896064,0.7820137023
4/2/2023,19:15:59,-1,0.8308896064,0.7820137023
4/2/2023,19:30:8,-1,0.8308896064,0.7575757980
4/2/2023,19:30:19,-1,0.8308896064,0.7820137023
4/2/2023,19:30:29,-1,0.8308896064,0.7820137023
4/2/2023,19:30:39,-1,0.8308896064,0.7820137023
4/2/2023,19:30:50,-1,0.8308896064,0.7820137023
4/2/2023,19:45:9,-1,0.8308896064,0.7820137023
4/2/2023,19:45:20,-1,0.8553275108,0.8064516067
4/2/2023,19:45:30,-1,0.8553275108,0.8064516067
4/2/2023,19:45:41,-1,0.8553275108,0.8064516067
4/2/2023,19:45:51,-1,0.8553275108,0.8064516067
4/2/2023,20:0:0,-1,0.8553275108,0.7820137023
4/2/2023,20:0:11,-1,0.8797654151,0.8064516067
4/2/2023,20:0:21,-1,0.8797654151,0.8064516067
4/2/2023,20:0:31,-1,0.8797654151,0.8064516067
4/2/2023,20:0:42,-1,0.8797654151,0.8064516067
4/2/2023,20:0:52,-1,0.8797654151,0.8064516067
4/2/2023,20:15:1,-1,0.9775171279,0.8797654151
4/2/2023,20:15:12,-1,0.9775171279,0.9042033195
4/2/2023,20:15:22,-1,0.9775171279,0.9042033195
4/2/2023,20:15:32,-1,1.0019550323,0.9042033195
4/2/2023,20:15:43,-1,0.9775171279,0.9286412239
4/2/2023,20:15:53,-1,1.0019550323,0.9042033195
4/2/2023,20:30:2,-1,0.9775171279,0.8797654151
4/2/2023,20:30:13,-1,0.9775171279,0.9042033195
4/2/2023,20:30:23,-1,1.0019550323,0.9286412239
4/2/2023,20:30:34,-1,0.9775171279,0.9042033195
4/2/2023,20:30:44,-1,1.0019550323,0.9286412239
4/2/2023,20:30:54,-1,1.0019550323,0.9286412239
4/2/2023,20:45:4,-1,1.0019550323,0.9042033195
4/2/2023,20:45:14,-1,1.0263930559,0.9286412239
4/2/2023,20:45:24,-1,1.0263930559,0.9286412239
4/2/2023,20:45:35,-1,1.0263930559,0.9286412239
4/2/2023,20:45:45,-1,1.0019550323,0.9286412239
4/2/2023,20:45:55,-1,1.0263930559,0.9286412239
4/2/2023,21:0:5,-1,0.9775171279,0.8797654151
4/2/2023,21:0:15,-1,0.9775171279,0.9042033195
4/2/2023,21:0:25,-1,0.9775171279,0.9042033195
4/2/2023,21:0:36,-1,0.9775171279,0.9042033195
4/2/2023,21:0:46,-1,0.9775171279,0.9042033195
4/2/2023,21:0:57,-1,0.9775171279,0.9042033195
4/2/2023,21:15:6,-1,0.8553275108,0.8064516067
4/2/2023,21:15:16,-1,0.8797654151,0.8308896064
4/2/2023,21:15:27,-1,0.8797654151,0.8064516067
4/2/2023,21:15:37,-1,0.8797654151,0.8064516067
4/2/2023,21:15:47,-1,0.8797654151,0.8064516067
4/2/2023,21:15:58,-1,0.8797654151,0.8308896064
4/2/2023,21:30:7,-1,0.8797654151,0.8064516067
4/2/2023,21:30:17,-1,0.8797654151,0.8308896064
4/2/2023,21:30:28,-1,0.8797654151,0.8308896064
4/2/2023,21:30:38,-1,0.9042033195,0.8308896064
4/2/2023,21:30:48,-1,0.9042033195,0.8308896064
4/2/2023,21:30:59,-1,0.8797654151,0.8308896064
4/2/2023,21:45:8,-1,0.8797654151,0.8064516067
4/2/2023,21:45:18,-1,0.8797654151,0.8308896064
4/2/2023,21:45:29,-1,0.8797654151,0.8308896064
4/2/2023,21:45:39,-1,0.8797654151,0.8308896064
4/2/2023,21:45:49,-1,0.8797654151,0.8308896064
4/2/2023,22:0:9,-1,0.8797654151,0.8064516067
4/2/2023,22:0:19,-1,0.8797654151,0.8308896064
4/2/2023,22:0:30,-1,0.8797654151,0.8308896064
4/2/2023,22:0:40,-1,0.8797654151,0.8553275108
4/2/2023,22:0:51,-1,0.8797654151,0.8308896064
4/2/2023,22:15:0,-1,0.8797654151,0.8064516067
4/2/2023,19:0:6,64,0.0000000000,0.0000000000
4/2/2023,19:0:16,0,0.0000000000,0.0000000000
4/2/2023,19:0:27,0,0.0000000000,0.0000000000
4/2/2023,19:0:37,0,0.0000000000,0.0000000000
4/2/2023,19:0:48,-1,0.0000000000,0.0000000000
4/2/2023,19:0:58,-1,0.0000000000,0.0000000000
4/2/2023,19:15:7,-1,8.1867065429,8.0400781631
4/2/2023,19:15:18,-1,8.3577718734,8.1867065429
4/2/2023,19:15:28,-1,8.3088960647,8.1867065429
4/2/2023,19:15:38,-1,8.3577718734,8.2111444473
4/2/2023,19:15:49,-1,8.7487783432,8.5777130126
4/2/2023,19:15:59,-1,8.3333339691,8.1867065429
4/2/2023,19:0:4,-1,8.3822097778,8.2111444473
4/2/2023,19:0:15,-1,9.1397848129,8.8465299606
4/2/2023,19:0:25,-1,9.3597269058,9.0175952911
4/2/2023,19:0:35,-1,9.3108510971,9.0175952911
4/2/2023,19:0:46,-1,8.5043992996,8.3088960647
4/2/2023,19:0:56,-1,9.0420331954,8.7976541519
4/2/2023,19:15:6,-1,0.0000000000,6.4760508537
4/2/2023,19:15:16,-1,0.0000000000,6.5249271392
4/2/2023,19:15:26,-1,0.0000000000,6.5004892349
4/2/2023,19:15:37,-1,0.0000000000,6.5004892349
4/2/2023,19:15:47,-1,0.0000000000,6.5004892349
4/2/2023,19:15:58,-1,0.0000000000,6.5004892349
5/2/2023,17:30:5,-1,5.1319651603,10.8504400253
5/2/2023,17:30:15,-1,4.5210165977,10.8993158340
5/2/2023,17:30:26,-1,4.4721407890,10.8748779296
5/2/2023,17:30:36,-1,4.5210165977,10.8748779296
5/2/2023,17:30:47,-1,4.5943307876,10.8993158340
5/2/2023,17:30:57,-1,4.5454545021,10.8748779296
5/2/2023,17:45:6,-1,0.0000000000,10.8504400253
5/2/2023,17:45:16,-1,0.0000000000,10.8748779296
5/2/2023,17:45:27,-1,0.0000000000,10.8748779296
5/2/2023,17:45:37,-1,0.0000000000,10.8748779296
5/2/2023,17:45:48,-1,0.0000000000,10.8504400253
5/2/2023,17:45:58,-1,0.0000000000,10.8748779296
5/2/2023,18:0:7,-1,0.0000000000,10.8504400253
5/2/2023,18:0:18,-1,0.0000000000,10.8748779296
5/2/2023,18:0:28,-1,0.0000000000,10.8993158340
5/2/2023,18:0:38,-1,0.0000000000,10.8748779296
5/2/2023,18:0:49,-1,0.0000000000,10.8748779296
5/2/2023,18:0:59,-1,0.0000000000,10.8748779296
5/2/2023,18:15:8,-1,0.0000000000,10.8504400253
5/2/2023,18:15:19,-1,0.0000000000,10.8993158340
5/2/2023,18:15:29,-1,0.0000000000,10.8993158340
5/2/2023,18:15:39,-1,0.0000000000,10.8993158340
5/2/2023,18:15:50,-1,0.0000000000,10.8748779296
5/2/2023,23:0:3,-1,0.0000000000,10.8748779296

As a new member, I can't attach files...Thank you!

You are getting data on serial monitor because you are using a while to read all values.

  while (mySDI12.available())
  {           // write the response to the screen
    Serial.write(mySDI12.read());
  }

To send the output to SD card you can follow this example.

String sdiResponse = "":

  while (mySDI12.available()) {  // build response string
    char c = mySDI12.read();
    if ((c != '\n') && (c != '\r')) {
      sdiResponse += c;
      delay(10);  // 1 character ~ 7.5ms
    }
  }

Then replace;

dataFile.print(mySDI12.read());

With:

dataFile.print(sdiResponse);

Also you shouldn't open the file before check the time.

// store data every 15 minute
  if ((now.minute() == 0) || (now.minute() == 15) || (now.minute() == 30) || (now.minute() == 45) )
  {
    File dataFile = SD.open("datalog.txt", FILE_WRITE);

    // if the file is available, write to it:
    if (dataFile)
    {
      .
      .
      .
      dataFile.close();
    }

It:

if ((now.minute() == 0) || (now.minute() == 15) || (now.minute() == 30) || (now.minute() == 45))

Could be like this:

if((now.minute() % 15) == 0)
{
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

    if (dataFile)
    {
      .
      .
      .
      dataFile.close();
    }
}

Or:

//Global
#define INTERVAL 15 // In minutes
unsigned long prevMillis = 0;

if((millis() - prevMillis) > (INTERVAL * 60 * 1000UL))
{
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

    if (dataFile)
    {
      .
      .
      .
      dataFile.close();
    }
 prevMillis = millis();
}

Thank you so much for your kind answer. I edited the sketch following your advice:

#include <Wire.h> 
#include "RTClib.h"  
#include <SDI12.h> 
#include <SPI.h> 
#include <SD.h> 

#define SERIAL_BAUD 9600 
#define DATA_PIN 2         
#define POWER_PIN 7     

RTC_DS1307 RTC;
SDI12 mySDI12(DATA_PIN);


String myCommand = "0R0!";  


const int chipSelect = 10; 

 
void setup() {

   pinMode(7, OUTPUT); 
   
  
   Serial.begin(SERIAL_BAUD);
   
   
 
  Wire.begin(); 
  RTC.begin();
  
  mySDI12.begin();
 
  
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running");}
   

  
  DateTime now = RTC.now();
  DateTime compiled = DateTime(__DATE__, __TIME__);
  if (now.unixtime() < compiled.unixtime()) {
    Serial.println("RTC is older than compile time! Updating");
    RTC.adjust(DateTime(__DATE__, __TIME__));}
 
  Serial.println("Setup complete.");


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

 
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    
  }
  Serial.println("card initialized.");




  
  if (POWER_PIN > 0) {
    Serial.println("Powering up sensors...");
    pinMode(POWER_PIN, OUTPUT);
    digitalWrite(POWER_PIN, HIGH);
    delay(200);
  }
 
}


 

 
void loop() {
  // Get the current time
  DateTime now = RTC.now();
   
  mySDI12.sendCommand(myCommand);
  delay(300);  // wait a while for a response

  String sdiResponse = "";
  while (mySDI12.available()) {
    
    // write the response to the screen
   char c=mySDI12.read();
   if ((c !='\n') && (c !='\r')) {
    sdiResponse +=c;
    delay(10); 
    
    }
   }
   


int val1; 
int val2;



  digitalWrite(7, HIGH); 
  

  val1=analogRead(0);     
float length1 = val1 * (25/1023.0); 
  val2=analogRead(1);     
float length2 = val2 * (25/1023.0); 
     

  
  Serial.print(now.day(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC); 
  Serial.print('/');
  Serial.print(now.year(), DEC);
  Serial.print(',');
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.print(',');
 Serial.write(mySDI12.read());
    Serial.print(',');
   Serial.print(length1*1,DEC);
  Serial.print(','); 
  Serial.println(length2*1,DEC);
  

  digitalWrite(7, LOW); 
 
   delay(10000);

 
 File dataFile = SD.open("datalog.txt", FILE_WRITE); 
 
 
  
    // store data every 15 minute
  if ((now.minute() % 15) == 0) 
  { 
    File dataFile = SD.open("datalog.txt", FILE_WRITE);
     // if the file is available, write to it:
    if(dataFile)
  {   
  dataFile.print(now.day(), DEC);
  dataFile.print('/');
  dataFile.print(now.month(), DEC); 
  dataFile.print('/');
  dataFile.print(now.year(), DEC);
  dataFile.print(',');
  dataFile.print(now.hour(), DEC);
  dataFile.print(':');
  dataFile.print(now.minute(), DEC);
  dataFile.print(':');
  dataFile.print(now.second(), DEC);
  dataFile.print(',');
  dataFile.print(sdiResponse);
  dataFile.print(',');
  dataFile.print(length1,DEC);
  dataFile.print(','); 
  dataFile.println(length2,DEC); 
  dataFile.close();
  }
  else {
    dataFile.close();
  }
  
 }
  
  else {
    Serial.println("error opening datalog.txt");
  } 
  } 

Unfortunately, the result I get from the serial monitor is this:

erro0,10.8993158340
Setup complete.
Initializing SD card...card initialized.
Powering up sensors...
10/2/2023,16:30:50,⸮,0.0000000000,24.3646144866
10/2/2023,16:31:1,⸮,0.0000000000,10.9237537384
error opening datalog.txt
10/2/2023,16:31:11,⸮,0.0000000000,10.8993158340
error opening datalog.txt
10/2/2023,16:31:22,⸮,0.0000000000,10.899315834

Anyway, the great thing is that on the sd card appears this:

10/2/2023,16:30:50,0-0.1+17.7,0.0000000000,24.3646144866

Thank you so much again!

The same mistake.

  Serial.write(mySDI12.read());

If dataFile returns false means that the file was not opened so there's no file to close.

    if(dataFile)
    {
    }
    else
    {
      dataFile.close();
    }

On the more complex programs, I suggest doing things one step at a time. For now I would suggest testing the ability to open and writing to the file, one line for each operation. And pay attention to the verbose output.

Adafruit has a great amount of learning writeups. A simple search turned up this:
Using the SD Card | Adafruit Data Logger Shield | Adafruit Learning System

See if any of that helps

Thanks for the tips and links! I edited the sketch this way:


#include <Wire.h> 
#include "RTClib.h"  
#include <SDI12.h> 
#include <SPI.h> 
#include <SD.h> 

#define SERIAL_BAUD 9600 
#define DATA_PIN 2         
#define POWER_PIN 7     

RTC_DS1307 RTC;
SDI12 mySDI12(DATA_PIN);


String myCommand = "0R0!";  


const int chipSelect = 10; 

 
void setup() {

   pinMode(7, OUTPUT); 
   
  
   Serial.begin(SERIAL_BAUD);
   
   
 
  Wire.begin(); 
  RTC.begin();
  
  mySDI12.begin();
 
  
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running");}
   

  
  DateTime now = RTC.now();
  DateTime compiled = DateTime(__DATE__, __TIME__);
  if (now.unixtime() < compiled.unixtime()) {
    Serial.println("RTC is older than compile time! Updating");
    RTC.adjust(DateTime(__DATE__, __TIME__));}
 
  Serial.println("Setup complete.");


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

 
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    return;
  }
  Serial.println("card initialized.");




  
  if (POWER_PIN > 0) {
    Serial.println("Powering up sensors...");
    pinMode(POWER_PIN, OUTPUT);
    digitalWrite(POWER_PIN, HIGH);
    delay(200);
  }
 
}


 

 
void loop() {
  // Get the current time
  DateTime now = RTC.now();
   
  mySDI12.sendCommand(myCommand);
  delay(300);  // wait a while for a response

  String sdiResponse = "";
  while (mySDI12.available()) {
    
    // write the response to the screen
   char c=mySDI12.read();
   if ((c !='\n') && (c !='\r')) {
    sdiResponse +=c;
    delay(10); 
    
    }
   }
   


int val1; 
int val2;



  digitalWrite(7, HIGH); 
  

  val1=analogRead(0);     
float length1 = val1 * (25/1023.0); 
  val2=analogRead(1);     
float length2 = val2 * (25/1023.0); 
     

  
  Serial.print(now.day(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC); 
  Serial.print('/');
  Serial.print(now.year(), DEC);
  Serial.print(',');
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.print(',');
 Serial.print(sdiResponse);
    Serial.print(',');
   Serial.print(length1*1,DEC);
  Serial.print(','); 
  Serial.println(length2*1,DEC);
  

  digitalWrite(7, LOW); 
 
   delay(10000);


 File dataFile = SD.open("datalog.txt", FILE_WRITE); 
 
 
  if (dataFile) { 
   
  if (now.minute()== 0  || now.minute()== 15 || now.minute()== 30 || now.minute()== 45) //store data every 15 min
  { 
  dataFile.print(now.day(), DEC);
  dataFile.print('/');
  dataFile.print(now.month(), DEC); 
  dataFile.print('/');
  dataFile.print(now.year(), DEC);
  dataFile.print(',');
  dataFile.print(now.hour(), DEC);
  dataFile.print(':');
  dataFile.print(now.minute(), DEC);
  dataFile.print(':');
  dataFile.print(now.second(), DEC);
  dataFile.print(',');
  dataFile.print(sdiResponse);
  dataFile.print(',');
  dataFile.print(length1*1,DEC);
  dataFile.print(','); 
  dataFile.println(length2*1,DEC); 
  dataFile.close();
  }
  else {
    dataFile.close();
  }
  
 }
  
  else {
    Serial.println("error opening datalog.txt");
  } 
  } 

The result is that now the data is written to the sd card, apart from the data from the soil sensor, which is written only once, at the beginning:

11/2/2023,16:0:41,0-0.1+18.0,0.0000000000,24.4134902954
11/2/2023,16:0:51,,0.0000000000,10.9481916427
11/2/2023,16:15:0,,0.0000000000,10.9481916427
11/2/2023,16:15:10,,0.0000000000,10.9481916427
11/2/2023,16:15:21,,0.0000000000,10.9481916427
11/2/2023,16:15:31,,0.0000000000,10.9237537384
11/2/2023,16:15:41,,0.0000000000,10.9237537384
11/2/2023,16:15:52,,0.0000000000,10.9237537384
11/2/2023,16:30:1,,0.0000000000,10.8748779296
11/2/2023,16:30:11,,0.0000000000,10.9237537384
11/2/2023,16:30:21,,0.0000000000,10.8993158340
11/2/2023,16:30:32,,0.0000000000,10.9237537384
11/2/2023,16:30:42,,0.0000000000,10.9237537384
11/2/2023,16:30:53,,0.0000000000,10.9237537384

I'm really trying to understand why...any ideas?

Did you miss that backwards question mark? That is something that the serial monitor cannot interpret.

Which is produced by this line:

 Serial.write(mySDI12.read());

What is that operation supposed to do?

Make sure that you can read the sensor and get reasonable values, before trying to write those values to the SD card.

For the Uno, you need to rewrite your program, avoiding the use of Strings. Strings cause memory problems, unpredictable errors and even program crashes. The Serial Input Basics tutorial on this forum explains how to safely handle serial input data.

No, this time there are not question marks... In the sketch, I replaced Serial.write(mySDI12.read()); with Serial.print(sdiResponse); : now, the soil data (0-0.1+18.0) is printed correctly on the first line, but then it "disappears".
I will have a look to the Serial Input Basics tutorial!

Please post the revised code in your next post, with sample output.

Try this:

#include <Wire.h>
#include "RTClib.h"
#include <SDI12.h>
#include <SPI.h>
#include <SD.h>

#define SERIAL_BAUD 9600
#define DATA_PIN 2
#define POWER_PIN 7

const int chipSelect = 10;

RTC_DS1307 RTC;
DateTime now;

SDI12 mySDI12(DATA_PIN);

unsigned long prevMillis = 0;

#define INTERVAL 10 // Time in seconds

void setup()
{
  Serial.begin(SERIAL_BAUD);

  pinMode(POWER_PIN, OUTPUT);

  Wire.begin();
  RTC.begin();

  mySDI12.begin();

  if (!RTC.isrunning())
  {
    Serial.println("RTC is NOT running");
  }

  now = RTC.now();
  DateTime compiled = DateTime(__DATE__, __TIME__);

  if (now.unixtime() < compiled.unixtime())
  {
    Serial.println("RTC is older than compile time! Updating");
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }

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

  if (!SD.begin(chipSelect))
  {
    Serial.println("Card failed, or not present");
  }
  else
  {
    Serial.println("card initialized.");
  }
 
  Serial.println("Setup complete.");
}

void loop()
{
  String myCommand = "0R0!";
  String sdiResponse = "";

  if((millis() - prevMillis) > (INTERVAL * 1000UL))
  {
    digitalWrite(POWER_PIN, HIGH);
    delay(300);

    // Get the current time
    now = RTC.now();

    mySDI12.sendCommand(myCommand);
    delay(300); // wait a while for a response

    while (mySDI12.available())
    {
      // write the response to the screen
      char c = mySDI12.read();
      if ((c != '\n') && (c != '\r'))
      {
        sdiResponse += c;
        delay(10);
      }
    }

    float length1 = analogRead(0) * (25 / 1023.0);
    float length2 = analogRead(1) * (25 / 1023.0);

    digitalWrite(POWER_PIN, LOW);

    Serial.print(now.day(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.year(), DEC);
    Serial.print(',');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.print(',');
    Serial.write(sdiResponse);
    Serial.print(',');
    Serial.print(length1 * 1,DEC);
    Serial.print(',');
    Serial.println(length2 * 1,DEC);

    // store data every 15 minute
    if ((now.minute() % 15) == 0)
    {
      File dataFile = SD.open("datalog.txt", FILE_WRITE);
      // if the file is available, write to it:
      if(dataFile)
      {
        dataFile.print(now.day(), DEC);
        dataFile.print('/');
        dataFile.print(now.month(), DEC);
        dataFile.print('/');
        dataFile.print(now.year(), DEC);
        dataFile.print(',');
        dataFile.print(now.hour(), DEC);
        dataFile.print(':');
        dataFile.print(now.minute(), DEC);
        dataFile.print(':');
        dataFile.print(now.second(), DEC);
        dataFile.print(',');
        dataFile.print(sdiResponse);
        dataFile.print(',');
        dataFile.print(length1,DEC);
        dataFile.print(',');
        dataFile.println(length2,DEC);
        dataFile.close();
      }
      else
      {
        Serial.println("error opening datalog.txt");
      }
    }
    prevMillis = millis();
  }
}

I replaced Serial.write(sdiResponse); with Serial.print(sdiResponse); ... Because with 'Serial.write' I get an error message (no matching function for call to 'Hardware Serial::write(String&)'...

Now it's almost perfect, this is what I read on the sd card

12/2/2023,12:0:8, /Z6[?#e)oek0-0.2+18.3,24.4379291534,24.4868049621 12/2/2023,12:0:19, /Z6[?#e)oek0-0.2+18.3,24.7311840057,24.7311840057 12/2/2023,12:0:30, /Z6[?#e)oek0-0.2+18.3,24.7311840057,24.7311840057 12/2/2023,12:0:41, /Z6[?#e)oek0-0.2+18.3,24.7311840057,24.7311840057 12/2/2023,12:0:52, /Z6[?#e)oek0-0.2+18.3,24.7311840057,24.7311840057 12/2/2023,12:15:4, /Z6[?#e)iyek0-0.2+18.6,24.7311840057,24.7311840057 12/2/2023,12:15:15, /Z6[?#e)iyek0-0.2+18.6,24.7556209564,24.7311840057 12/2/2023,12:15:26, /Z6[?#e)iyek0-0.2+18.6,24.7311840057,24.7311840057 12/2/2023,12:15:37, /Z6[?#e)iyek0-0.2+18.6,24.7311840057,24.7556209564 12/2/2023,12:15:47, /Z6[?#e)iyek0-0.2+18.6,24.7311840057,24.7556209564 12/2/2023,12:15:58, /Z6[?#e)iyek0-0.2+18.6,24.7311840057,24.7311840057 12/2/2023,12:30:10, /Z6[?#e)iyek0-0.2+18.6,24.7311840057,24.7311840057 12/2/2023,12:30:21, /Z6[?#e)iyek0-0.2+18.6,24.7311840057,24.7311840057 12/2/2023,12:30:32, /Z6[?#e)iyek0-0.2+18.6,24.7311840057,24.7311840057 12/2/2023,12:30:43, /Z6[?#e)iyek0-0.2+18.6,24.7311840057,24.7311840057 12/2/2023,12:30:54, /Z6[?#e)iyek0-0.2+18.6,24.7311840057,24.7311840057
So, the file is opened correctly, and the sensor data is also perfect.
I just don’t understand why now before the soil sensor identification code (in this case, 0) appears this inscription "/Z6[? # e)iyek"... But it's actually the best result I've gotten so far!

This chars has some meaning.

You can see here:

void printInfo(char i) {
  String command = "";
  command += (char)i;
  command += "I!";
  mySDI12.sendCommand(command, WAKE_DELAY);
  delay(100);

  String sdiResponse = mySDI12.readStringUntil('\n');
  sdiResponse.trim();
  // allccccccccmmmmmmvvvxxx...xx<CR><LF>
  Serial.print(sdiResponse.substring(0, 1));  // address
  Serial.print(", ");
  Serial.print(sdiResponse.substring(1, 3).toFloat() / 10);  // SDI-12 version number
  Serial.print(", ");
  Serial.print(sdiResponse.substring(3, 11));  // vendor id
  Serial.print(", ");
  Serial.print(sdiResponse.substring(11, 17));  // sensor model
  Serial.print(", ");
  Serial.print(sdiResponse.substring(17, 20));  // sensor version
  Serial.print(", ");
  Serial.print(sdiResponse.substring(20));  // sensor id
  Serial.print(", ");
}

Try this example:

I try to replace unsigned long prevMillis = 0; with char prevMillis = 0 : now on the serial monitor the data appears without the characters I mentioned in the previous post

19/2/2023,17:59:11,0-1.0+19.8,24.4379291534,0.0000000000
19/2/2023,17:59:12,0-1.0+19.8,24.4379291534,0.0000000000
19/2/2023,17:59:13,0-1.0+19.8,24.4379291534,0.0000000000
19/2/2023,17:59:13,0-1.0+19.8,24.4623661041,0.0000000000
19/2/2023,17:59:14,0-1.0+19.8,24.4623661041,0.0000000000
19/2/2023,17:59:15,0-1.0+19.8,24.4379291534,0.0000000000
19/2/2023,17:59:16,0-1.0+19.8,24.4379291534,0.0000000000
19/2/2023,17:59:16,0-1.0+19.8,24.4379291534,0.0000000000
19/2/2023,17:59:17,0-1.0+19.8,24.4623661041,0.0000000000
19/2/2023,17:59:18,0-1.0+19.8,24.4623661041,0.0000000000
19/2/2023,17:59:19,0-1.0+19.8,24.4379291534,0.0000000000
19/2/2023,17:59:19,0-1.0+19.8,24.4623661041,0.0000000000
19/2/2023,17:59:20,0-1.0+19.8,24.4379291534,0.0000000000
19/2/2023,17:59:21,0-1.0+19.8,24.4623661041,0.0000000000
19/2/2023,17:59:22,0-1.0+19.8,24.4379291534,0.0000000000

However, the data on the serial monitor appears at higher speeds, less than a second, and it seems to have lost accuracy in reading the potentiometers. Is it possible? It is as if a potentiometer reading every tot is wrong. I post the text of the file on the sd card

19/2/2023,18:0:32,0-1.0+19.8,24.7556209564,0.0000000000
19/2/2023,18:0:32,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:33,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:34,0-1.0+19.8,24.7556209564,0.0000000000
19/2/2023,18:0:35,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:35,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:36,0-1.0+19.8,24.7556209564,0.0000000000
19/2/2023,18:0:37,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:38,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:39,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:39,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:40,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:41,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:42,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:42,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:43,0-1.0+19.8,24.7067451477,0.0000000000
19/2/2023,18:0:44,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:45,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:46,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:46,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:47,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:48,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:49,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:49,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:50,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:51,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:52,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:53,0-1.0+19.8,24.7556209564,0.0000000000
19/2/2023,18:0:53,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:54,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:55,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:56,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:56,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:57,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:58,0-1.0+19.8,24.7311840057,0.0000000000
19/2/2023,18:0:59,0-1.0+19.8,24.7311840057,0.0000000000

Is there a way to keep the speed and accuracy of previous reading or should I consider going back to using unsigned long data and solving the character problem in another way?