Help need to display file name after experiment finishes

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.

When the experiment runs, my screen shows some information like "current value", "max value upto that current time" and "file name" where the data is being saved.

And when experiment finishes, I wanted to show "maximum value for total 3 minute run", "value at 1 min" and "file name where the data is being saved". Right now, I have implemented "maximum value for total 3 minute run", "value at 1 min". Somehow I cannot show "file name where the data is being saved". This is not visible in the screen after experiment finishes. I tried to print the filename using loop. But it is not being printed.

I have attached the screen and code here. Can someone please help me? How can I add file name at the end of experiment?

after run screeen

//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.005                //3 minutes in hours=0.05hr; 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 50              //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;
float val1 = 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), 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(2, 0);
      u8x8.print(filename);
        
     }
}



//------------------------------------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(){
      char 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(200);
}

//-----------------------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();
    bhoomiFile.print(currentReading * 1, 4);        //read upto 4 decimal
      if (currentReading < maxi)  {
        maxi = maxi;
        }
      else if (currentReading >= maxi)  {
        maxi = currentReading;
        }
        
     if (currentTime = 60000) {
              val1=currentReading;
     }
        
    //----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.
    }

The filename is local and known only to the createFile() function. To print it at the end of data collection, or anywhere outside of createFile(), you will need to make filename a global variable.

1 Like
      u8x8.setCursor(2, 0);
      for (int i=0;i<sizeof(filename);i++)
        u8x8.print(filename[i]);
      u8x8.setCursor(2, 0);
      u8x8.print(atos(filename));

Just reading now, I see that

  SD_INIT();
  createFile();

No matter what SD_INIT() says, you go ahead as if no error message was issued with the initialisation call. You always cheerfully print

  Serial.println("card initialized.");

Let us assume that is not a problem, but flag that issue and get around to stopping if you can't begin() the SD.

Can you try / have you tried / serial printing that which is mysteriously (so far) not appearing on the display?

You may want to crank up the band rate to something 21st century like 115200 before you do.

This. you have a global filename[], but hide it with a local declaration of a variable with the same name.

void createFile(){
      char filename[] = "00.CSV";

Try instead:

void createFile(){
      strcpy(filename, "00.CSV");

I can't test that just now, but the idea is to copy the initial filename into the global filename array of chars.

HTH and good eye @jremington!

a7

Also good catch, but presumably the above should read "as if no error message was issued".

1 Like

Well it does now. :expressionless:

THX!

a7

I see a lot of good comments here.

I've been using the below code for DAQ function. Maybe it will help.
BTW you don't need the createFile() function.

In the below I initialize the gFileNumb to 100 or 200 etc. This sets the base number for the next round of data collection.
Then I look for a file that doesn't exist and use that for the data about to be taken. This means the program will find the next file even if it lost power and rebooted.


// ************************************************************
// *** initialization functions *******************************
// ************************************************************

// --- SD Card initialization function ---
void initSD_Card(void) {
   if (!SD.begin(SD_CSPin)) {
      SD_Error = true;
   }
   // loop until we find a file that doesn't already exist.......
   do
   {
      itoa(gFileNumb, gDataFile, 10);  // (value, Array, base)
      const char *extension = ".csv";
      strcat(gDataFile, extension);  // syntax:  strcat(dest, source)
      ++gFileNumb;
   } while (SD.exists(gDataFile));  // assume will Rtn false if  no communication.

   myFile = SD.open(gDataFile, FILE_WRITE);
   if (myFile) {      // if the file opened okay, write to it:
      myFile.print(" init...");
      //myFile.println(gDataFile);
      myFile.close();
   }
   else {
      SD_Error = true;   // if the file didn't open, print an error:
   }
   return;
}  // --- initSD_Card ---


1 Like

Using strcpy(filename, "00.CSV"); , now I can see file name at the end of experiment. So grateful. Thanks.

Also thanks for indicating about SD_INIT() and printing Serial.println("card initialized.");. I am going to fix this issue.

1 Like

Hi all,

Thanks for your previous help. I need another help again please.

If for some reason I have to save 1 min(60000ms) data in csv in a seperate column of csv file corresponding to 1 min(60000ms) time, then, how to write the code for arduino uno?

When I try to get 60000ms data, it might need to get the value from averaging, as arduino has some lag. I have attached a screenshot to give an idea what I want to do. I want to find out what the Y value is. Attached is the screenshot to elaborate my question.
1 min value

Any help is really appreciated

This is completely up to you. Your code already presents things by formatting them ahead of placing them on the display, same I assume from looking through the tiny window with what you write onto the SD card.

Ppl often write to the SD card in a simple and efficient if less pretty format like CSV. Then any analysis and beautification, so to speak, can be done at the desktop using the full power of Excel or other program like it.

Maths can break up a huge number of milliseconds into hours, minutes and seconds, for example, but why strukkle with wrestling Arduino code to do that when you can do it later elsewhere easily?

But srsly, you have maximum flexibility, it's all a question of what kind of fun you like to have.

HTH

a7

I have to show 1 min value in display and need to save it in a separate column in csv file for decision making purpose. If max value is very high than 1 min value, I will discard this data and will not waste time on examining csv file. I will have to take lots of lots of file. So, if I can see this data in display, that will save time.

But I do not know how to display(in OLED display) or save(in csv) around 1 min(60000ms+-300ms) data . And in current code, I am getting all zero for the column corresponding to 1 min value.

I have created another thread to seek help.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.