2

I am starting using Arduino and have very little to none experience coding. However, I have managed to code and understand how it works.

The problem that I have is that I am unable to log (record) data from the three sensors attached (Adafruit Anemometers). All of them work properly; the data file is created. However, there is no data (or time reference) being written on the file. When I verify the code, it's approved...Therefore, it should work, right?.=/ Then, I uploaded code.

I am using an Arduino uno with an SD Logger shield (Data Logging Shield v1.0, from Deek-Robot(TM)), which uses a DS1307 RTC.

All comments are more than welcome!

Thanks in Advance

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

// A simple data logger for the Arduino analog pins
#define LOG_INTERVAL  60000 // mills between entries
#define ECHO_TO_SERIAL   0 // echo data to serial port
#define WAIT_TO_START    0 // Wait for serial input in setup()

// the digital pins that connect to the LEDs
#define redLEDpin 3
#define greenLEDpin 4

// The analog pins that connect to the sensors
#define Anemometer0           // analog 0
#define Anemometer1           // analog 1
#define Anemometer2           // analog 2

RTC_DS1307 RTC; // define the Real Time Clock object

//Setup Variables of Anemometers

//Anemometer0
const int sensorPin0 = A0; //Defines the pin that the anemometer output is connected to
int sensorValue0 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage0 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float windSpeed0 = 0; // Wind speed in meters per second (m/s)

//Anemometer1
const int sensorPin1 = A1; //Defines the pin that the anemometer output is connected to
int sensorValue1 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage1 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float windSpeed1 = 0; // Wind speed in meters per second (m/s)

//Anemometer2
const int sensorPin2 = A2; //Defines the pin that the anemometer output is connected to
int sensorValue2 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage2 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float windSpeed2 = 0; // Wind speed in meters per second (m/s)

float voltageConversionConstant = .004882814; //This constant maps the value provided from the analog read function,
//which ranges from 0 to 1023, to actual voltage, which ranges from 0V to 5V
int sensorDelay = 1000; //Delay between sensor readings, measured in milliseconds (ms)

//Anemometer Technical Variables
//The following variables correspond to the anemometer sold by Adafruit but could be modified to fit other anemometers.

float voltageMin = .4; // Mininum output voltage from anemometer in mV.
float windSpeedMin = 0; // Wind speed in meters/sec corresponding to minimum voltage

float voltageMax = 2.0; // Maximum output voltage from anemometer in mV.
float windSpeedMax = 32; // Wind speed in meters/sec corresponding to maximum voltage

// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;

// the logging file
File logfile;

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);
  
  // red LED indicates error
  digitalWrite(redLEDpin, HIGH);
  
  while(1);
}

void setup() {
  // put your setup code here, to run once:

  Serial.begin(9600);
  Serial.println();
  
#if WAIT_TO_START
  Serial.println("Type any character to start");
  while (!Serial.available());
#endif //WAIT_TO_START

  // initialize the SD card
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
  
  // create a new file
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE); 
      break;  // leave the loop!
    }
  }
  
  if (! logfile) {
    error("couldnt create file");
  }
  
  Serial.print("Logging to: ");
  Serial.println(filename);

  Wire.begin();  
  if (!RTC.begin()) {
    logfile.println("RTC failed");
#if ECHO_TO_SERIAL
    Serial.println("RTC failed");
#endif  //ECHO_TO_SERIAL
  }
 
  pinMode(redLEDpin, OUTPUT);
  pinMode(greenLEDpin, OUTPUT);
 
   // If you want to set the aref to something other than 5v
  //analogReference(EXTERNAL);
}

void loop() {
  // put your main code here, to run repeatedly:

  DateTime now;

  // delay for the amount of time we want between readings
  delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
  
  digitalWrite(greenLEDpin, HIGH);

  // log milliseconds since starting
  uint32_t m = millis();
  logfile.print(m);           // milliseconds since start
  logfile.print(", ");    
#if ECHO_TO_SERIAL
  Serial.print(m);         // milliseconds since start
  Serial.print(", ");  
#endif

  // fetch the time
  now = RTC.now();
  // log time
//logfile.print(); // seconds since 2000
  logfile.print(", ");
  logfile.print(now.year(), DEC);
  logfile.print("/");
  logfile.print(now.month(), DEC);
  logfile.print("/");
  logfile.print(now.day(), DEC);
  logfile.print(" ");
  logfile.print(now.hour(), DEC);
  logfile.print(":");
  logfile.print(now.minute(), DEC);
  logfile.print(":");
  logfile.print(now.second(), DEC);

#if ECHO_TO_SERIAL
  Serial.print(now.get()); // seconds since 2000
  Serial.print(", ");
  Serial.print(now.year(), DEC);
  Serial.print("/");
  Serial.print(now.month(), DEC);
  Serial.print("/");
  Serial.print(now.day(), DEC);
  Serial.print(" ");
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  Serial.print(now.minute(), DEC);
  Serial.print(":");
  Serial.print(now.second(), DEC);
#endif //ECHO_TO_SERIAL
  
//Anemometer0
const int sensorPin0 = A0; //Defines the pin that the anemometer output is connected to
int sensorValue0 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage0 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float windSpeed0 = 0; // Wind speed in meters per second (m/s)

//Anemometer1
const int sensorPin1 = A1; //Defines the pin that the anemometer output is connected to
int sensorValue1 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage1 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float windSpeed1 = 0; // Wind speed in meters per second (m/s)

//Anemometer2
const int sensorPin2 = A2; //Defines the pin that the anemometer output is connected to
int sensorValue2 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage2 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float windSpeed2 = 0; // Wind speed in meters per second (m/s)

float voltageConversionConstant = .004882814; //This constant maps the value provided from the analog read function,
//which ranges from 0 to 1023, to actual voltage, which ranges from 0V to 5V
int sensorDelay = 1000; //Delay between sensor readings, measured in milliseconds (ms)

//Anemometer Technical Variables
//The following variables correspond to the anemometer sold by Adafruit but could be modified to fit other anemometers.

float voltageMin = .4; // Mininum output voltage from anemometer in mV.
float windSpeedMin = 0; // Wind speed in meters/sec corresponding to minimum voltage

float voltageMax = 2.0; // Maximum output voltage from anemometer in mV.
float windSpeedMax = 32; // Wind speed in meters/sec corresponding to maximum voltage
  
  logfile.print(", ");    
  logfile.print(A0);
  logfile.print(", ");
  logfile.print(A1);    
  logfile.print(",");
  logfile.println(A2);

#if ECHO_TO_SERIAL
  Serial.print(", ");   
  Serial.print(Anemometer0);
  Serial.print(", ");    
  Serial.print(Anemometer1);
  Serial.print(",");
  Serial.println(Anemometer2);
#endif //ECHO_TO_SERIAL

  digitalWrite(greenLEDpin, LOW);
}
´´´ 
8
  • 1
    You "verified", yes. But did you "upload"? Commented Nov 8, 2020 at 16:00
  • you don't open the file if it exists Commented Nov 8, 2020 at 16:42
  • @Juraj That bit of code is to create a new file with sequential numbering. It will find the first file that doesn't exist in LOGGER00.CSV to LOGGER99.CSV and open that. Commented Nov 8, 2020 at 16:50
  • Yes @Majenko, the code was uploaded correctly to the board. But I haven't mentioned that in the written explanation, thanks for pointing that out. Should the file contain some data and date/time? Commented Nov 8, 2020 at 20:38
  • I suspect you aren't giving it enough time to flush the data to the SD card and it's only in the buffer. You should call logfile.flush(); after each iteration. Commented Nov 8, 2020 at 21:04

1 Answer 1

2

Thanks for all your help. I managed to log data in the SD card including date and time. The new code is the following:

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

RTC_DS1307 rtc; // create local instances of library class objects

DateTime time;

File dataFile;

const int chipSelect = 10;

// Anemometer at 0.15 magl

const int sensorPinA0 = A0; //Defines the pin that the anemometer output is connected to
int sensorValue0 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage0 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float WindSpeed0 = 0; // Wind speed in meters per second (m/s)

float voltageConversionConstant0 = .0048828125; //This constant maps the value provided from the analog read function, which ranges from 0 to 1024, to actual voltage, which ranges from 0V to 5V
// hence, this value corresponds to 5.00V/1024. Check https://forum.allaboutcircuits.com/threads/why-adc-1024-is-correct-and-adc-1023-is-just-plain-wrong.80018/
int sensorDelay0 = 60000; //Delay between sensor readings, measured in milliseconds (ms)

//Anemometer Technical Variables
//The following variables correspond to the anemometer sold by Adafruit but could be modified to fit other anemometers.

float voltageMin0 = .4; // Mininum output voltage from anemometer in mV.
float windSpeedMin0 = 0; // Wind speed in meters/sec corresponding to minimum voltage

float voltageMax0 = 2.0; // Maximum output voltage from anemometer in mV.
float windSpeedMax0 = 32; // Wind speed in meters/sec corresponding to maximum voltage

// Anemometer at 0.5 magl

const int sensorPinA1 = A1; //Defines the pin that the anemometer output is connected to
int sensorValue1 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage1 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float WindSpeed1 = 0; // Wind speed in meters per second (m/s)

float voltageConversionConstant1 = .0048828125; //This constant maps the value provided from the analog read function, which ranges from 0 to 1024, to actual voltage, which ranges from 0V to 5V
// hence, this value corresponds to 5.00V/1024. Check https://forum.allaboutcircuits.com/threads/why-adc-1024-is-correct-and-adc-1023-is-just-plain-wrong.80018/
int sensorDelay1 = 1000; //Delay between sensor readings, measured in milliseconds (ms)

//Anemometer Technical Variables
//The following variables correspond to the anemometer sold by Adafruit but could be modified to fit other anemometers.

float voltageMin1 = .4; // Mininum output voltage from anemometer in mV.
float windSpeedMin1 = 0; // Wind speed in meters/sec corresponding to minimum voltage

float voltageMax1 = 2.0; // Maximum output voltage from anemometer in mV.
float windSpeedMax1 = 32; // Wind speed in meters/sec corresponding to maximum voltage

// Anemometer at 1.2 magl

const int sensorPinA2 = A2; //Defines the pin that the anemometer output is connected to
int sensorValue2 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage2 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float WindSpeed2 = 0; // Wind speed in meters per second (m/s)

float voltageConversionConstant2 = .0048828125; //This constant maps the value provided from the analog read function, which ranges from 0 to 1024, to actual voltage, which ranges from 0V to 5V
// hence, this value corresponds to 5.00V/1024. Check https://forum.allaboutcircuits.com/threads/why-adc-1024-is-correct-and-adc-1023-is-just-plain-wrong.80018/
int sensorDelay2 = 60000; //Delay between sensor readings, measured in milliseconds (ms)

//Anemometer Technical Variables
//The following variables correspond to the anemometer sold by Adafruit but could be modified to fit other anemometers.

float voltageMin2 = .4; // Mininum output voltage from anemometer in mV.
float windSpeedMin2 = 0; // Wind speed in meters/sec corresponding to minimum voltage

float voltageMax2 = 2.0; // Maximum output voltage from anemometer in mV.
float windSpeedMax2 = 32; // Wind speed in meters/sec corresponding to maximum voltage

void setup() {
 Serial.begin(9600);
 while (!Serial) {;} // wait for serial port to connect.
 Serial.print("Initializing SD card...");
 if (!SD.begin(chipSelect)) {
 Serial.println("Card failed, or not present");
 while (1); // loop forever
 }
 Serial.println("Have SD card");
 rtc.begin();
}

void loop() {
  
sensorValue0 = analogRead(A0); //Get a value between 0 and 1023 from the analog pin connected to the anemometer
sensorValue1 = analogRead(A1); //Get a value between 0 and 1023 from the analog pin connected to the anemometer
sensorValue2 = analogRead(A2); //Get a value between 0 and 1023 from the analog pin connected to the anemometer

sensorVoltage0 = sensorValue0 * voltageConversionConstant0; //Convert sensor value to actual voltage
sensorVoltage1 = sensorValue1 * voltageConversionConstant1; //Convert sensor value to actual voltage
sensorVoltage2 = sensorValue2 * voltageConversionConstant2; //Convert sensor value to actual voltage

//Convert voltage value to wind speed using range of max and min voltages and wind speed for the anemometer
if (sensorVoltage0 <= voltageMin0){
WindSpeed0 = 0; //Check if voltage is below minimum value. If so, set wind speed to zero.
}

else {
  WindSpeed0 = (sensorVoltage0 - voltageMin0)*windSpeedMax0/(voltageMax0 - voltageMin0); //For voltages above minimum value, use the linear relationship to calculate wind speed on A0.
    }

if (sensorVoltage1 <= voltageMin1){
WindSpeed1 = 0; //Check if voltage is below minimum value. If so, set wind speed to zero.
}

else {
  WindSpeed1 = (sensorVoltage1 - voltageMin1)*windSpeedMax1/(voltageMax1 - voltageMin1); //For voltages above minimum value, use the linear relationship to calculate wind speed on A1.
    }   

if (sensorVoltage2 <= voltageMin2){
WindSpeed2 = 0; //Check if voltage is below minimum value. If so, set wind speed to zero.
}

else {
  WindSpeed2 = (sensorVoltage2 - voltageMin2)*windSpeedMax2/(voltageMax2 - voltageMin2); //For voltages above minimum value, use the linear relationship to calculate wind speed on A2.
    }

 time = rtc.now(); // Read RTC
 String dataString = ""; // Assemble data

log:
 dataString = time.timestamp(DateTime::TIMESTAMP_DATE);
 dataString += ", ";
 dataString += time.timestamp(DateTime::TIMESTAMP_TIME);
 dataString += ", ";
 dataString += String(sensorVoltage0);
 dataString += ", ";
 dataString += String(WindSpeed0);
 dataString += ", ";
 dataString += String(sensorVoltage1);
 dataString += ", ";
 dataString += String(WindSpeed1);
 dataString += ", ";
 dataString += String(sensorVoltage2);
 dataString += ", ";
 dataString  += String(WindSpeed2);
 dataFile = SD.open("Speedlog.txt", FILE_WRITE);
 if (dataFile) { // Write to logfile

 dataFile.println(dataString);
 dataFile.close();
 Serial.println(dataString);
 delay(1000); // pause for one second between sensor logs
 }
 else {
 Serial.println("error opening datalog.txt");
 }
}
1
  • You shouldn't use a String, and you don't need to because you can just write all the bits to the file without concatenating them first. If you must, you should remove String dataString = ""; from the loop and add it as a global at the top; it may help a bit with keeping your heap intact, but it's better to avoid String altogether. Commented Dec 5, 2020 at 15:43

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.