Unexpected data logged...

Hi,

New to arduino and forum. First project just built. It is a mobile data logger, measuring time and distance to water level (measuring drops for soil infiltration tests in the field)

  • Adalogger 32u4
  • DS3231 RTC Wing
  • Maxbotix XL 7092 Ultrasonic Sensor (cm accuracy)
  • 4400mah LiPoly

It idles for 30 seconds to allow positioning after power on. It logs date and time to sd card. It begins taking measurements at approx. 10 second intervals. It is supposed to only log a reading and time in seconds to file if the reading is different to the previous logged value. To reduce the dataset for graphing and calcs.

It is working ok at the moment but is unexpectedly logging same readings in a row intermittently where I thought my code would only log a value if it was different than the previous logged value.

I haven’t got an actual test log at the moment but it goes something like this:

(first value is distance in cm, second value is time in seconds from startup)

31/08/2016 - 15:16
29,1
30,60
31,100
31,125
32,200
33,400
33,420
33,438
34,600
35,850
35,910
35,925
35,1040
35,1055
36,1200
37,1500

#include <SPI.h> //Serial Peripheral Interface Library

#include <Maxbotix.h> //Maxbotix Ultrasonic Sensor Library

#include <SD.h> //SD Card Access Library

#include <RTClib.h> //RTC Access Library

RTC_DS3231 rtc; //Declare RTC as rtc


/*

      SENSOR Command Pin 4 is digital pin 6
      SENSOR Pin AN is analog pin A1

*/

Maxbotix rangeSensorAD(A1, Maxbotix::AN, Maxbotix::XL);       // Initialise Maxbotix Sensor

int waterDistance = 15000; // Declare and set variable waterDistance

long startUnix;   // Declare Long integers
long logTime;     

File logFile;     // Declare file logFile

void setup()

{

  #define VBATPIN A9                          // Define VBATPIN as Analogue pin 9 
  float measuredvbat = analogRead(VBATPIN);   // Declare and set measuredvbat
  
  rtc.begin();        // Begin the Real Time Clock
  
  DateTime now = rtc.now();   // Set DateTime library source to RTC

  Serial.begin(9600); // Begin Serial Communication
  SD.begin(4);        // Begin SD card Communication

  pinMode(A1, INPUT);  // Sensor In
  pinMode(5, OUTPUT);  // Button LED
  pinMode(6, OUTPUT);  // Sensor Command
  pinMode(13, OUTPUT); // Red LED

  for (int i = 0; i <= 60; i++) { // Flash Button LED and delay start of operations for approx 30 seconds
    digitalWrite(5, HIGH);
    delay(250);
    digitalWrite(5, LOW);
    delay(250);
  }
  delay(2000);
  startUnix = (now.unixtime()) + 32;   // Establish start time of operations in unixtime

  logFile = SD.open("datalog.txt", FILE_WRITE);     // Open log file
  delay (500);
  logFile.print(now.day(), DEC);                       // Print date and time to log file
  logFile.print('/');
  logFile.print(now.month(), DEC);
  logFile.print('/');
  logFile.print(now.year(), DEC);
  logFile.print(" - ");
  logFile.print(now.hour(), DEC);
  logFile.print(':');
  logFile.println(now.minute(), DEC);
   
  logFile.close();                                   // Close log file
  
  Serial.print(now.day(), DEC);                       // Print date and time to com
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.year(), DEC);
  Serial.print(" - ");
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.println(now.minute(), DEC);
  
    
    delay (500);
  
}


void loop()
{

  float measuredvbat = analogRead(VBATPIN);  // Battery voltage check
  measuredvbat *= 2;    // Convert value to true voltage
  measuredvbat *= 3.3;  
  measuredvbat /= 1024;
  
  if (measuredvbat < 3.6)
  {digitalWrite(13, HIGH);}  // Light Red LED if battery is low
  
  
  DateTime now = rtc.now();     // Set DateTime library source to RTC  
  String dataString = "";       // Declare and empty data string

  digitalWrite(5, HIGH);   // turn the Button LED on (HIGH is the voltage level)
  digitalWrite(6, HIGH);   //Turn the sensor on
  delay(1000);             //Delay 1 second
  digitalWrite(5, LOW);    // turn the Button LED off (LOW is the voltage level)
  digitalWrite(6, LOW);    //Turn the sensor off


  if ((rangeSensorAD.getRange()) != waterDistance) // If current measured distance is different than previous then print it and change the old value
  {

    long nowUnix = (now.unixtime());          // Set variable nowUnix to current unixtime

    logTime = nowUnix - startUnix;            // Calculate seconds since start of logging

    Serial.print("AD: ");                         // Print results to serial monitor
    Serial.print(rangeSensorAD.getRange());
    Serial.print("cm   -    Seconds: ");
    Serial.print(logTime);
    Serial.println();


    waterDistance = (rangeSensorAD.getRange()); // Set waterDistance to new value


    logFile = SD.open("datalog.txt", FILE_WRITE); // Open log file
    delay (1000);

    dataString += String(waterDistance);               // Create data string
    dataString += ",";
    dataString += String(logTime);

    logFile.println(dataString);                       // Print data to log file

    logFile.close();                                   // Close log file
    delay (1000);

  }
  

  delay(8000); // Eight second delay

}

Hoping someone could shed some light on this behaviour. It is probably something really simple that I am missing. Thanks in advance!

  if ((rangeSensorAD.getRange()) != waterDistance) // If current measured distance is different than previous then print it and change the old value
  {
    long nowUnix = (now.unixtime());          // Set variable nowUnix to current unixtime

    logTime = nowUnix - startUnix;            // Calculate seconds since start of logging

    Serial.print("AD: ");                         // Print results to serial monitor
    Serial.print(rangeSensorAD.getRange());
    Serial.print("cm   -    Seconds: ");

You're reading the range twice.

Edit: Make that three times.

Thx for reply. Apologies, but I don't understand what you mean?

In "loop" you're measuring the range three times.
You should measure it only once, before the "if".

I don't understand what you mean?

He means that you should read the sensor ONCE. Store the result in a variable, and use the variable in all three places where you now make the calls. You are assuming that, since you print the result of one of the calls, that the other two (that you don't print) returned the same value. Not a valid assumption at all.

Hi,

Thanks, I think I understand what you mean now. I thought that the value would remain the same until the next time the sensor is triggered, but I assume from your collective comments that the value is changing dynamically during the rest of the code execution. I will set it to a variable and use that instead. My understanding of all this is just beginning, apologies if I sound stupid.

I thought that the value would remain the same until the next time the sensor is triggered

Ask yourself “when is the sensor triggered?”

Ok so I now assume that every time I use the library function it triggers the sensor :slight_smile: I thought that I had to actually send the trigger pin high to get it to take a reading and that it would store the value in a register until I put the trigger pin high again. I thought that calling the library function just read the register. Does that mean my manual trigger pin high line at the start of the loop is unnececessary also?

Does that mean my manual trigger pin high line at the start of the loop is unnececessary also?

Comment it out and see what happens.

Ok it didn't work without the pin high! So I have changed it around now using only one call and new variable and it seems to be working better. I understand the process a lot better now. Thanks very much for the help lads...