hello everyone,
i have a project where i want to read displacements from a linear displacement sensor, and temperature and humidity from dht11 sensor and writing everything on SD card with datalogger while initiating the reading and logging by a button and stopping with the same button ( when i press the button the program starts, and when i press again it stops).
i had a problem with precision (it didn't go from 0 to 100 as i wanted but from values in between, so i added a calibration part in the setup void() (lines 113 to 136) and used a constrain() and map() functions in the loop ( lines 206 to 210), now the program works but stops after around 18 iterations without me pressing the button.
question is: what may caused this problem and how to fix that?
my full code is :
[code]
#include <ezButton.h>
#include <RTClib.h>
#include <DHT.h>
#include <DHT_U.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#define DHTPIN 3 // Digital pin connected to the DHT sensor dht DHT11; //Sensor object named as DHT
#define DHTTYPE DHT11 // DHT 11
#define LOOP_STATE_STOPPED 0
#define LOOP_STATE_STARTED 1
ezButton button(2); // create ezButton object that attach to pin 2;
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 16, 2);
RTC_DS1307 RTC;
double timer;
double startTime;
double elapsedTime;
int loopState = LOOP_STATE_STOPPED; //button state
int samplingfreq; //sampling frequency [milliseconds]
int sensorValue = 0; //for the raw data
int sensorMin = 1023; // minimum sensor value
int sensorMax = 0; // maximum sensor value
float distance = 0; //for the calibrated distance
float h; // Humidity
float t;// Temperature as Celsius (the default)
const char* filename = "Disp.txt";
const int OUTPUT_PIN = 4;
File dataFile;
DateTime now;
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 115200 bits per second:
Serial.begin(115200);
// some info to know what is on the Arduino
Serial.println("KTR-100mm Displacement sensor, DHT11, LCD, Buttons.");
Serial.print("\n"); //linebreak
Serial.println("--------------------------------------------------");
//-----------------Taking care of LCD-------------------
//NOTE: if you cannot see the text on the LCD, try to change the potmeter on the back of it.
//Sometimes you just have wrong contrast settings and nothing shows up on the screen because of it.
lcd.begin(16, 2); // initialize the lcd
lcd.backlight(); //initialize backlight
//------------------------------------------------------
lcd.clear(); //clear the LCD
lcd.setCursor(0, 0); //Defining positon to write from first row,first column .
lcd.print("KTR-100mm"); //some message
lcd.setCursor(0, 1); //Cursor is moved to the 2nd line of the LCD
lcd.print("Reading displ."); //You can write 16 Characters per line .
delay(3000); //wait 3 sec
// seting pinMode for pin 10 (SD Chipselect)
pinMode(10, OUTPUT);
// seting pinMode for pin 04 (Reset Pin)
digitalWrite(OUTPUT_PIN, HIGH);
pinMode(OUTPUT_PIN, OUTPUT);
//----Set default------
dht.begin();
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t) ) {
Serial.println(F("Failed to read from DHT sensor!"));
lcd.clear(); //clear the LCD
lcd.setCursor(0, 0); //Defining positon to write from first row,first column .
lcd.print("DHT failed"); //some message
// Restart:
delay(3000);
digitalWrite(OUTPUT_PIN, LOW);
return;
}
RTC.begin();
//check or the Real Time Clock is on
if (! RTC.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
// uncomment it & upload to set the time, date and start run the RTC!
RTC.adjust(DateTime(__DATE__, __TIME__));
}
// see if the card is present and can be initialized:
if (!SD.begin(10)) {
Serial.println("Error : Push the reset button");
lcd.clear(); //clear the LCD
lcd.setCursor(0, 0); //Defining positon to write from first row,first column .
lcd.print("SD Card failed"); //some message
// Restart:
delay(3000);
digitalWrite(OUTPUT_PIN, LOW);
for (;;);
}
// calibrate during the first five seconds
timer = millis();
lcd.clear(); //clear the LCD
lcd.setCursor(0, 0); //Defining positon to write from first row,first column .
lcd.print("Calibration..."); //some message
while ((millis() - timer) < 10000) {
sensorValue = analogRead(A0);
// record the maximum sensor value
if (sensorValue > sensorMax) {
sensorMax = sensorValue;
}
// record the minimum sensor value
if (sensorValue < sensorMin) {
sensorMin = sensorValue;
}
}
// signal the end of the calibration period
lcd.clear(); //clear the LCD
lcd.setCursor(0, 0); //Defining positon to write from first row,first column .
lcd.print("Calibration Done"); //some message
delay(500);
lcd.clear(); //clear the LCD
lcd.setCursor(0, 0); //Defining positon to write from first row,first column .
lcd.print("Press Button to"); //some message
lcd.setCursor(0, 1); //Defining positon to write from first row,first column .
lcd.print("Start Reading!"); //some message
//----------------Initializing SD Card---------------------
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
//write down the date (year / month / day)
//prints only the start, so if the logger runs for sevenal days you only findt the start back at the begin.
now = RTC.now();
dataFile = SD.open(filename, FILE_WRITE);
dataFile.print("Start logging on: ");
dataFile.print(now.year(), DEC);
dataFile.print('/');
dataFile.print(now.month(), DEC);
dataFile.print('/');
dataFile.print(now.day(), DEC);
dataFile.print(":");
dataFile.print(now.hour(), DEC);
dataFile.print(":");
dataFile.print(now.minute(), DEC);
dataFile.print(":");
dataFile.print(now.second(), DEC);
dataFile.println("\n"); //linebreak
dataFile.print("Time [Sec]");
dataFile.print(",");
dataFile.print("Displacement [mm]");
dataFile.print(",");
dataFile.print("Temperature [C°]");
dataFile.print(",");
dataFile.print("Humidity [%]");
dataFile.close();
button.setDebounceTime(50); // set debounce time to 50 milliseconds
}
// the loop routine runs over and over again forever:
void loop() {
button.loop(); // MUST call the loop() function first
if (button.isPressed()) {
if (loopState == LOOP_STATE_STOPPED)
loopState = LOOP_STATE_STARTED;
else // if(loopState == LOOP_STATE_STARTED)
loopState = LOOP_STATE_STOPPED;
}
if (loopState == LOOP_STATE_STARTED) {
startTime = millis(); //define the time NOW. This will be useful when we need some time readings
//--------------------------Reading data and sending to PC-----------------------------------------
elapsedTime = millis() - startTime; //start another timer
// read the input on analog pin 0:
sensorValue = analogRead(A0);
// in case the sensor value is outside the range seen during calibration
sensorValue = constrain(sensorValue, sensorMin, sensorMax);
// apply the calibration to the sensor reading
sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 1023);
// Convert the analog reading (which goes from 0 - 1023) to a distance (0 - 100 mm):
distance = sensorValue * (100.0 / 1023);
// Read Humidity
h = dht.readHumidity();
// Read temperature as Celsius (the default)
t = dht.readTemperature();
// Read
//---------------------------------Serial printout-------------------------------------------------
Serial.print("\n"); //linebreak
Serial.print("Displacement = "); //tab for separation
Serial.print(distance, 4); //calibrated data (displacement), 4 decimals
Serial.print(" mm");
Serial.print("\n"); //linebreak
Serial.print("Current humidity = ");
Serial.print(h);
Serial.print("% ");
Serial.print("\t"); //tab for separation
Serial.print("temperature = ");
Serial.print(t);
Serial.print("C ");
Serial.print("\n"); //linebreak
Serial.print("--------------------------------------------------------------------");
//-----------------------------------------LCD Printout------------------------------------------
lcd.clear(); //clear LCD
lcd.setCursor(0, 0); //Defining positon to write from first row,first column .
lcd.print(" ");
lcd.print(distance, 4); // calibrated data (displacement), 4 decimals
lcd.print(" mm");
lcd.setCursor(0, 1); //Defining positon to write from second row,first column .
lcd.print(t);
lcd.print(" C ");
lcd.print(h);
lcd.print(" %");
//-------------------------Writing on SD Card---------------------------------------------------
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
dataFile = SD.open(filename, FILE_WRITE);
// if the file is available, write to it:
// log the temperature and time.
if (dataFile) {
dataFile.print("\n"); //linebreak
dataFile.print(elapsedTime);
dataFile.print(",");
dataFile.print(distance);
dataFile.print(",");
dataFile.print(t);
dataFile.print(",");
dataFile.print(h);
dataFile.close();
// print to the serial port too:
Serial.print("\n"); //linebreak
Serial.println("data stored");
}
// if the file isn't open, pop up an error:
else {
Serial.print("\n"); //linebreak
Serial.println("error opening Disp.txt");
}
delay(50);
}
}
[/code]