Hi all,
I am using arduino Uno for displaying 100g load cell value in .96 OLED display . Communication is through I2C. I am using HX711 as ADC.
I am saving some data in csv file. The columns in csv are "millisecond", "Time (MM/DD/YYYY HH:MM:SS)" "weight (g)", "1 min weight"," Max weight(g)".
At the same time, I want to display in OLED display some information like " current value", " max value", and "file name" in the display. "Current value" is dynamic which is ever changing.
At the end of experiment, the display finally will be showing "maximum value for total 3 minute run", "value at 1 min" and "file name where the data is being saved".
But, now I am having trouble in saving 1 min(60000ms) weight data. I want to display this information at the end of experiment and save weight value at csv column that happens at 1 min(60000ms) time. But I am getting all 0 with both in csv file and in display.
I could not understand where in the code I am messing up. Attached is the code portion screenshot.
This whole data logging has some lag of around 300ms. It never saves exactly at 1 min(60000ms) time. But I can save weight value near to 1 min(60000ms+-300ms), that is okay for my case. How could I implement it?
I have attached the screenshot and code here. Can someone please help me?
//TIME IS RIGHT INSIDE CSV FILE, MAX VALUE RIGHT, DISPLAY RIGHT WITH THIS PROGRAM AS OF 10/11/2011
//check font here: https://github.com/olikraus/u8g2/wiki/fntlist8x8
#include <Arduino.h>
#include <U8x8lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
#include <SD.h>
#include "RTClib.h"
#include "HX711.h" //You must have this library in your arduino library folder
//---------------------------------------------------------------------------
#define DURATION 0.020 //3 minutes in hours=0.05hr; 4 min in hr=0.0666667 hr,5 min=0.0833333hour, 10 min=0.166667 hour //Number of minutes, expressed/converted into hours, here 2 hours you want this program to run once the button is pressed
#define LOG_INTERVAL 20 //Milliseconds between entries (reduce to take more/faster data)
#define SYNC_INTERVAL 50 // millis between calls to flush() - to write data to the card
#define ECHO_TO_SERIAL 1 //Echo data to serial port, Easy method to turn serial printing on and off. Set to 0 if you don't want to print to the Serial Monitor
uint32_t syncTime = 0; // time of last sync()
uint32_t start_time;
uint32_t currentTime;
int counter = 0;
//---------------------------------------------------------------------------
RTC_DS1307 RTC; //define the Real Time Clock object
const int chipSelect = 10; //SD chip select;for the data logging shield, we use digital pin 10 for the SD cs line
char timestamp[30];
char filename[30];
const int pushbutton = 8;
const int done_light = 9;
float maxi = 0;
char val1 = 0;
char time1=0;
/***All the variables for voltage reading function***/
//the logging file
File bhoomiFile;
//-------------------Hx711 pins-----------------------------------------------
#define DOUT 3
#define CLK 2
HX711 scale;
float calibration_factor =7381.000195;//7252.100097;//7311.899902;// 7311.899902;//7303.299316;//7286.200195;//6981.299804;//7037.143066;//7311.899902; //7383.399902;//7370.040039; //7370.379882; // for 100g load cell
//--------------------DISPLAY--------------------------------------------------
U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);
//------------------------SETUP--------------------------------------------
//-------------------------------------------------------------------------
void setup(){
scale.begin(DOUT, CLK);
Serial.begin(9600); //Initialize the serial communication
u8x8.clear();
u8x8.begin();
Wire.begin(); //Wire.begin: Initiate the Wire library and join the I2C bus as a master or slave.
Serial.println("Press T to tare");
scale.set_scale(calibration_factor); //Calibration Factor obtained from first sketch
scale.tare(); //Reset the scale to 0
#if ECHO_TO_SERIAL
Serial.println("Press button to start"); //Prompt user to press button
#endif
pinMode(pushbutton, INPUT); //Set pushbutton as Input
pinMode(done_light, OUTPUT); //Set the LED as an output
digitalWrite(done_light, LOW); //Make sure the LED is off when we start the program
while (digitalRead(pushbutton)) {}; //Wait for pushbutton input
#if ECHO_TO_SERIAL
Serial.println("(BUTTON PRESSED!)"); //Once pressed, display a message saying so
#endif
SD_INIT();
createFile();
//-----------------connect to RTC----------------------
if (!RTC.begin()){ //RTC.begin initializes the internal RTC. It needs to be called before any other RTC library methods
bhoomiFile.println("RTC failed");
}
// RTC.adjust(DateTime(F(__DATE__), F(__TIME__))); //----uncomment this command if you need to adjust the time with RTC running----//
//if (! RTC.isrunning()) //----uncomment this command if you need to adjust the time when RTC is not running----//
// {
// 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
//RTC.adjust(DateTime(2014, 1, 21, 3, 0, 0)); January 21, 2014 at 3am you would call:
// }
bhoomiFile.println("millisecond,Time (MM/DD/YYYY HH:MM:SS), weight (g), 1 min weight, Max weight(g)"); //If RTC initializes successfully...set this as a header in the file
#if ECHO_TO_SERIAL
Serial.println("millisecond,Time (MM/DD/YYYY HH:MM:SS), weight (g), Max weight(g)");
#endif //ECHO_TO_SERIAL
start_time = millis(); //The very next step after this will be the data recording
}
//-------------------------------LOOP---------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
void loop(){
for (start_time; (millis() - start_time) < (DURATION * 60 * 60 * 1000L); ) //Below: As long as current time - start time < required duration, keep recording the data
//To have record time in HOURS: (DURATION * 60 * 60 * 1000L)
doTheThing();
u8x8.clear();
while (1) {
#if ECHO_TO_SERIAL
Serial.println("ALL DONE"); //Once the set amount of time has passed, display message saying so
#endif //ECHO_TO_SERIAL
digitalWrite(done_light, HIGH);
//-------DISPLAY MAX VALUE--------
u8x8.setFont(u8x8_font_8x13B_1x2_f); // big font
u8x8.setCursor(0, 32);
//u8x8.print(" g Max "); //Unit in gram
u8x8.print(" gMax 3min"); //Unit in gram
u8x8.print(maxi , 3); //read upto 4 decimal point
//-------DISPLAY 1 min VALUE--------
u8x8.setFont(u8x8_font_8x13B_1x2_f); // big font
u8x8.setCursor(0, 2);
//u8x8.print(" g Max "); //Unit in gram
u8x8.print(" g 1min "); //Unit in gram
u8x8.print( val1 , 3); //read upto 4 decimal point
//-------DISPLAY STORING DONE INFORMATION--------
// u8x8.setFont(u8x8_font_8x13B_1x2_f); // big font
// u8x8.setCursor(0, -32);
// u8x8.print(" Done 3 min ");
// u8x8.setCursor(0, 5);
//u8x8.print(" 3 min ");
u8x8.setFont(u8x8_font_8x13B_1x2_f);
u8x8.setCursor(0, 22);
u8x8.print(filename);
// for (int i=0;i<sizeof(filename);i++)
// u8x8.print(filename[i]);
}
}
//------------------------------------FUNCTIONS-------------------------------------------
//------------------------------------------------------------------------------------
void error(char *str){
Serial.print("error: ");
Serial.println(str);
while (1);
}
//-----------------------FUNCTION SD CARD INITIALIZATION---------------------------------------
//------------------------------------------------------------------------------------
void SD_INIT(){
// Serial.print("Initializing SD card...");
pinMode(chipSelect, OUTPUT);
// Serial.println("card initialized."); //If SD.begin is successful
//Check if the card is present and can be initialized:
if (!SD.begin(chipSelect)) { //SD.begin initializes the SD library and card; Returns 1 on success, 0 on failure
u8x8.setFont(u8x8_font_courR18_2x3_r);
u8x8.setCursor(3, 19);
u8x8.println("No SD");
return;
}
}
//-----------------------FUNCTION FILE CREATION---------------------------------------
//------------------------------------------------------------------------------------
void createFile(){
strcpy(filename, "00.CSV");
for (uint8_t i = 0; i < 100; i++) { //Make a new file every time the Arduino starts up, Goes from 00 to 199
filename[0] = '0' + ((i / 10) % 10);
filename[1] = '0' + ((i / 1) % 10);
// filename[2] = '0' + ((i / 1) % 10);
// filename[3] = '0' + (i % 10);
if (!SD.exists(filename)) { //SD.exists() tests whether a file or directory exists on the SD card
bhoomiFile = SD.open(filename, FILE_WRITE); //SD.open() opens a file on the SD card. If the file is opened for writing,
//it will be created if it doesn't already exist (but the directory containing it must already exist).
//FILE_WRITE enables read and write access to the file
break; // leave the loop!
}
}
if (!bhoomiFile){ //If file couldn't be opened/created
error("couldn't create file");
}
//-----------LOG FILE NAME BOTH IN SERIAL PORT AND DISPLAY-----
Serial.print(" Logging to: "); //Otherwise, display the name of the file generated
Serial.print(filename);
u8x8.setFont(u8x8_font_8x13B_1x2_f);
u8x8.setCursor(2, 22);
u8x8.print(filename);
// delay(500);
}
//-----------------------FUNCTION DO THE THING---------------------------------------
//------------------------------------------------------------------------------------
void doTheThing() { /*uncomment lower IF statement if you want to set up time for your RTC. IF the RTC battery is being removed,
it will set the time to 1/1/00 like this. But after uncommenting and compiling,complilation time will be current time and clock will start acting*/
// 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));
// }
DateTime now = RTC.now();
delay((LOG_INTERVAL - 1) - (millis() % LOG_INTERVAL));//delay for the amount of time we want between readings
//sprintf(timestamp, "%02d:%02d:%02d %2d/%2d/%2d \n", now.hour(), now.minute(), now.second(), now.month(), now.day(), now.year() - 2000);
//Serial.println(timestamp);
bhoomiFile.println(); //WITHOUT THIS INSTRUCTION,CSV DATA WILL BE SAVED ROWWISE,, NOT COLUMNWISE
//--------LOG ALL MILISECOND IN ONE COLUMN IN CSV FILE--------
bhoomiFile.print("");
bhoomiFile.print(millis(), DEC);
bhoomiFile.print(" , ");
//--------LOG DATE& TIME IN ANOTHER COLUMN IN CSV FILE--------
bhoomiFile.print(" "); //This space is important. If you remove this, the seconds will not be recorded in the log file
bhoomiFile.print(now.month(), DEC);
bhoomiFile.print("/");
bhoomiFile.print(now.day(), DEC);
bhoomiFile.print("/");
bhoomiFile.print(now.year(), DEC);
bhoomiFile.print(" ");
bhoomiFile.print(now.hour(), DEC);
bhoomiFile.print(":");
bhoomiFile.print(now.minute(), DEC);
bhoomiFile.print(":");
bhoomiFile.print(now.second(), DEC);
bhoomiFile.print("");
bhoomiFile.print(millis(), DEC);
bhoomiFile.print("");
//---------- Log LOAD CELL MAXIMUM reading---------------------------
bhoomiFile.print(", "); //Unit in gram
float currentReading = scale.get_units();
currentTime=millis();
bhoomiFile.print(currentReading * 1, 4); //read upto 4 decimal
if (currentReading < maxi) {
maxi = maxi;
}
else if (currentReading >= maxi) {
maxi = currentReading;
}
if (currentTime >50800 && currentTime <60200) {
val1=currentReading;
}
bhoomiFile.print(", "); //Unit in gram
bhoomiFile.print(val1, 4); //read upto 4 decimal
//----LOG LOAD CELL MAX READING IN CSV FILE AND DISPLAY ---------------
bhoomiFile.print(", "); //Unit in gram
bhoomiFile.print(maxi, 4); //read upto 4 decimal
u8x8.setFont(u8x8_font_8x13B_1x2_f);//small font
u8x8.setCursor(0, 3);
u8x8.print(" g Max "); //Unit in gram
u8x8.print(maxi, 3); //read upto 4 decimal point
//----LOG LOAD CELL IN CSV FILE AND DISPLAY LOAD CELL MAX READING---------------
#if ECHO_TO_SERIAL
Serial.print(", ");
Serial.println(scale.get_units() * 1, 4); //read upto 4 decimal
Serial.print("g "); //Unit in gram
#endif //ECHO_TO_SERIAL
u8x8.setFont(u8x8_font_courR18_2x3_r); // big font
u8x8.setCursor(90, 32);
u8x8.print(" g "); //Unit in gram
u8x8.print(scale.get_units() * 1, 3); //read upto 4 decimal point
#if ECHO_TO_SERIAL
Serial.print(", ");
Serial.print(maxi, 4); //read upto 4 decimal
Serial.print("g "); //Unit in gram
#endif //ECHO_TO_SERIAL
delay(100);
//--------------CLOSE CSV FILE BY FLUSHING---------------------------------------
if ((millis() - syncTime) < SYNC_INTERVAL) return;
syncTime = millis();
bhoomiFile.flush(); //flush() ensures that any bytes written to the file are physically saved to the SD card
//When you use file.write(), it doesn't write to the card until you flush() or close().
//Whenever you open a file, be sure to close it to save your data.
}