OLED display does not show anything

Hi,
I am posting here to get some help. I am using arduino Uno for displaying load cell value with 1306 OLED display. I am using HX711 as ADC. My code does not display anything in OLED, but shows data in serial monitor and saves data in SD card. For test purpose, I am trying to print " Hi" in display. Even this command has not been printed in display. Where am I doing wrong?

I have checked Display with some example code. It displays the commands, which proves display in is working condition. I am suspecting that there has some problem in my code. Can anyone please help to find out the problem?

#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#include "HX711.h"  //You must have this library in your arduino library folder

/*************************************************VARIABLES******************************************************/
#define DURATION 2                  //Number of hours you want this program to run once the button is pressed
#define LOG_INTERVAL 100            //Milliseconds between entries (reduce to take more/faster data)


#define SYNC_INTERVAL 1000          // millis between calls to flush() - to write data to the card
uint32_t syncTime = 0;              // time of last sync()

#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

RTC_DS1307 RTC;                     //define the Real Time Clock object

const int chipSelect = 10;          //for the data logging shield, we use digital pin 10 for the SD cs line
char timestamp[30];
const int pushbutton = 8;
const int done_light = 9;
/***All the variables for voltage reading function***/
const int voltage_in = A0;             //pin connected to the voltage divider output  
float voltage_raw;                     //raw 0 to 1023 integer reading from the ADCs
float voltage_reading;                 //voltage value between 0 and 5V
float voltage_true;                    //voltage value between 0 and 10V
uint32_t start_time;


#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

//the logging file
File bhoomiFile;

#include "HX711.h"  //You must have this library in your arduino library folder

#define DOUT  3
#define CLK  2

HX711 scale;

int average = 0;


//Change this calibration factor as pe
float calibration_factor = 122541;
/****************************************************************************************************************/
/****************************************************SETUP*******************************************************/
void setup() 
{
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); 
  delay(2000);
  display.clearDisplay();

  display.setTextSize(3);
  display.setTextColor(WHITE);
  display.setCursor(0, 5);
  // Display static text
  display.println("Hi!");
  display.display();
  
  
  pinMode(pushbutton, INPUT);                 //Set pushbutton as Input 
  pinMode(voltage_in, INPUT);                 //Set voltage 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
  
  //chip select pin mode set within SD_INIT()
  
  Serial.begin(115200);                         //Initialize the serial communication
   if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
   
   if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    display.println(F("SSD1306 allocation failed"));
    for(;;);
  }
 
  //display.display();
 // delay(2000); 
   // Clear the buffer
  display.clearDisplay();

  display.setTextSize(3);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  // Display static text
  
 rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // 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));
  }
   
  scale.begin(DOUT, CLK);
  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

                                                       
  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
  Wire.begin();                                                     //Wire.begin: Initiate the Wire library and join the I2C bus as a master or slave.                                                      
  if (!RTC.begin())                                                 //RTC.begin initializes the internal RTC. It needs to be called before any other RTC library methods 
  {                                                                 //Assume that it returns 1 on success and 0 on failure
    bhoomiFile.println("RTC failed");
    display.println("RTC failed");
    #if ECHO_TO_SERIAL
      Serial.println("RTC failed");
    #endif  //ECHO_TO_SERIAL
  }
  
  bhoomiFile.println("millis,Time (MM/DD/YYYY HH:MM:SS), weight (mg)");        //If RTC initializes successfully...set this as a header in the file 
  #if ECHO_TO_SERIAL
    Serial.println("millis,Time (MM/DD/YYYY HH:MM:SS), weight (mg)");
  #endif //ECHO_TO_SERIAL

  start_time = millis();              //The very next step after this will be the data recording
                                      //Therefore, note down the time at this moment as the start time                                        
}
/****************************************************************************************************************/

/*************************************************LOOP***********************************************************/
void loop() 
{
    //Below: As long as current time - start time < required duration, keep recording the data
    for(start_time; (millis() - start_time) < (DURATION * 60 * 60 * 1000L); )
    //To have record time in HOURS: (DURATION * 60 * 60 * 1000L)
      
    {
      doTheThing();
    }
    display.clearDisplay();
    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);
      //lcd.home();
      display.println("ALL DONE");
      //lcd.home();      
    }                       
}
/****************************************************************************************************************/

/************************************************FUNCTIONS*******************************************************/

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);
  
  while(1);
}

void SD_INIT()
{
  Serial.print("Initializing SD card...");
  pinMode(chipSelect, OUTPUT);
  
  //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  
  {
    display.println("SD Card failed");
    delay(30);
    error("Card failed, or not present");                         //Error function displays the error message if SD.begin fails and returns 0
    return; 
  }
  Serial.println("card initialized.");                            //If SD.begin is successful
}

void createFile()
{
  // create a new file
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++)                               //Make a new file every time the Arduino starts up
  {                                                               //Goes from 00 to 99
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (!SD.exists(filename))                                     //SD.exists() tests whether a file or directory exists on the SD card
    {                                                             //It returns true if the file or directory exists, false if not
      //only open a new file if it doesn't exist
      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).
                                                                  It returns a File object referring to the opened file; if the file couldn't be opened, 
                                                                  this object will evaluate to false in a boolean context*/
                                                                  //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");
  }
  Serial.print("Logging to: ");                                   //Otherwise, display the name of the file generated  
  display.println("Hello, world!");
  Serial.println(filename);
  
  
}

void doTheThing()
{
  DateTime now;
 
    //delay for the amount of time we want between readings
    delay((LOG_INTERVAL - 1) - (millis() % LOG_INTERVAL));
        
    //fetch the time
    now = RTC.now();
    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.print("");
    bhoomiFile.print(millis(),DEC);
    bhoomiFile.print(" , ");
    display.println("filename");
    
     //now = RTC.now();
    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("");
    #if ECHO_TO_SERIAL
//      Serial.print(now.month(), DEC);
//      Serial.print("/");
//      Serial.print(now.day(), DEC);
//      Serial.print("/");
//      Serial.print(now.year(), DEC);
//      Serial.print(" ");
//      Serial.print(now.hour(), DEC);
//      Serial.print(":");
//      Serial.print(now.minute(), DEC);
//      Serial.print(":");
//      Serial.print(now.second(), DEC);
//      Serial.print("");
//       Serial.print(millis(),DEC);
//        Serial.print("");
    #endif //ECHO_TO_SERIAL


  
 //Serial.print(scale.get_units()*1000, 4);  //Up to 4 decimal points
    //Log the voltage reading
    bhoomiFile.print(", ");    
    bhoomiFile.print(scale.get_units()*1000, 4);               //for variables of datatype 'float', the number in the print() funtion specifies
                                                        //the number of digits to be printed out

             //for variables of datatype 'float', the number in the print() funtion specifies
                                                        //the number of digits to be printed out
    

    #if ECHO_TO_SERIAL
      Serial.print(", ");   
      Serial.print(scale.get_units()*1000, 4);
    #endif //ECHO_TO_SERIAL
  
    bhoomiFile.println();
    #if ECHO_TO_SERIAL
      Serial.println();
    #endif // ECHO_TO_SERIAL
 
     
    //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. 
    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
}
/****************************************************************************************************************/

The test code I used is given below. After running this code, display shows " Hello world"

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {
  Serial.begin(115200);

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(2000);
  display.clearDisplay();

  display.setTextSize(3);
  display.setTextColor(WHITE);
  display.setCursor(0, 5);
  // Display static text
  display.println("Hello, world!");
  display.display(); 
}

void loop() {
  
}
```![arduino-hx711-load-cell_OLED|690x445](upload://mdQgXrrBTs5zBXAW1YCiPFx6y0f.png)

Post or point to this alleged example code. You may have mangled something trivial moving its good parts into you sketch.

a7

To send to the display, don't you need to call the display.display() function. The only call to display.display(), in loop, is commented.

Added the code with my post

I removed all unnecessary lines from code. Now when I was checking serial monitor, it gives me message "SSD1306 allocation failed". This happens when I use Load cell+HX711+SD card+arduino Uno. The code is below"

#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
#include "HX711.h"  //You must have this library in your arduino library folder
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

/****************************************************************************************************************/
/****************************************************************************************************************/
/****************************************************************************************************************/
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)

/****************************************************************************************************************/
/****************************************************************************************************************/
/*************************************************VARIABLES******************************************************/
#define DURATION 2                  //Number of hours you want this program to run once the button is pressed
#define LOG_INTERVAL 100            //Milliseconds between entries (reduce to take more/faster data)
#define SYNC_INTERVAL 1000          // millis between calls to flush() - to write data to the card
#define DOUT  3
#define CLK  2
#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

RTC_DS1307 RTC;                     //define the Real Time Clock object

const int chipSelect = 10;          //for the data logging shield, we use digital pin 10 for the SD cs line
char timestamp[30];
uint32_t start_time;
uint32_t syncTime = 0;              // time of last sync()
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

//the logging file
File bhoomiFile;
HX711 scale;
//int average = 0;


//Change this calibration factor as pe
float calibration_factor = 122541;

/****************************************************************************************************************/
/****************************************************SETUP*******************************************************/
void setup() 
{
  Serial.begin(115200);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); 
  delay(2000);
  display.clearDisplay();
  display.setTextSize(3);
  display.setTextColor(WHITE);
  display.setCursor(0, 5);
  // Display static text
  display.println("Hello, world!");
  display.display(); 
  
  scale.begin(DOUT, CLK);
  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   
  
  SD_INIT();
  createFile();
  
  //connect to RTC
  Wire.begin();                                                     //Wire.begin: Initiate the Wire library and join the I2C bus as a master or slave.                                                      
  if (!RTC.begin())                                                 //RTC.begin initializes the internal RTC. It needs to be called before any other RTC library methods 
  {                                                                 //Assume that it returns 1 on success and 0 on failure
    bhoomiFile.println("RTC failed");
   // lcd.println("RTC failed");
    #if ECHO_TO_SERIAL
      Serial.println("RTC failed");
    #endif  //ECHO_TO_SERIAL
  }
  
  bhoomiFile.println("millis,Time (MM/DD/YYYY HH:MM:SS), weight (mg)");        //If RTC initializes successfully...set this as a header in the file 
  #if ECHO_TO_SERIAL
    Serial.println("millis,Time (MM/DD/YYYY HH:MM:SS), weight (mg)");
  #endif //ECHO_TO_SERIAL

  start_time = millis();              //The very next step after this will be the data recording
                                      //Therefore, note down the time at this moment as the start time                                        
}
/****************************************************************************************************************/
/****************************************************************************************************************/
/*************************************************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();
    }
    
    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

    }                       
}
/****************************************************************************************************************/

/************************************************FUNCTIONS*******************************************************/

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);
  
  while(1);
}

void SD_INIT()
{
  Serial.print("Initializing SD card...");
  pinMode(chipSelect, OUTPUT);
  
  //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  
  {
     delay(30);
    error("Card failed, or not present");                         //Error function displays the error message if SD.begin fails and returns 0
    return; 
  }
  Serial.println("card initialized.");                            //If SD.begin is successful
}

void createFile()
{
  // create a new file
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++)                               //Make a new file every time the Arduino starts up
  {                                                               //Goes from 00 to 99
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (!SD.exists(filename))                                     //SD.exists() tests whether a file or directory exists on the SD card
    {                                                             //It returns true if the file or directory exists, false if not
      //only open a new file if it doesn't exist
      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).
                                                                  It returns a File object referring to the opened file; if the file couldn't be opened, 
                                                                  this object will evaluate to false in a boolean context*/
                                                                  //FILE_WRITE enables read and write access to the file
      break;  // leave the loop!
    }
  }

 
  Serial.print("Logging to: ");                                   //Otherwise, display the name of the file generated  
  Serial.println(filename);
  delay(1300);

}

void doTheThing()
{
  DateTime now;
 
    //delay for the amount of time we want between readings
    delay((LOG_INTERVAL - 1) - (millis() % LOG_INTERVAL));
        
    //fetch the time
    now = RTC.now();
    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.print("");
    bhoomiFile.print(millis(),DEC);
    bhoomiFile.print(" , ");
    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("");
    
//    #if ECHO_TO_SERIAL
//      Serial.print(now.month(), DEC);
//      Serial.print("/");
//     Serial.print(now.day(), DEC);
//      Serial.print("/");
//      Serial.print(now.year(), DEC);
//      Serial.print(" ");
//      Serial.print(now.hour(), DEC);
//      Serial.print(":");
//      Serial.print(now.minute(), DEC);
//      Serial.print(":");
//      Serial.print(now.second(), DEC);
//      Serial.print("");
//      Serial.print(millis(),DEC);
//      Serial.print("");
//    #endif //ECHO_TO_SERIAL
//Serial.print(scale.get_units()*1000, 4);  //Up to 4 decimal points
    //Log the voltage reading
    bhoomiFile.print(", ");    
    bhoomiFile.print(scale.get_units()*1000, 4);               //for variables of datatype 'float', the number in the print() funtion specifies
                                                        //the number of digits to be printed out

             //for variables of datatype 'float', the number in the print() funtion specifies
                                                        //the number of digits to be printed out   
    #if ECHO_TO_SERIAL
      Serial.print(", ");   
      Serial.print(scale.get_units()*1000, 4);
    #endif //ECHO_TO_SERIAL
  
    bhoomiFile.println();
    #if ECHO_TO_SERIAL
      Serial.println();
    #endif // ECHO_TO_SERIAL

  delay(1000);
    
    
  
     
    //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. 
    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
}
/****************************************************************************************************************/

On the other hand, when I run " Hello world " program (given in my original post), serial monitor does not show any error message and display prints the command properly.

Is there any conflict with clock?
Please help.
Attached is the connection diagram of my circuit. Additionally, I have attached a data logger shield above Arduino Uno to insert SD card.

Please include the entire error message. It is easy to do. There is a button (lower right of the IDE window) called "copy error message". Copy the error and paste into a post in code tags. Paraphrasing the error message leaves out important information.

The code compiles with no errors, but a few warnings for me. Win 10, IDE ver 1.8.12.

The code runs without any error. When I open serial monitor, it shows message "SSD1306 allocation failed".
It comes from the code

 if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }

You call this more than once. It may not be the (only) problem, but it is at least unnecessary.

a7

Right. There is no error message. But after opening the serial monitor, after the "
SSD1306 allocation failed" dialogue, it means that display was not found on 0x3C address. But how is this possible? For other codes ( ref: original post), display was found on that address. Do not understand why this is happening.

So, you meant if I have

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

this line, I do not have to have

display.begin(SSD1306_SWITCHCAPVCC, 0x3C); 

this line?

No, sry, I was looking at the wrong code. It looks like the latest does only and the same as the working example with respect to the display.

You do have both

 Serial.begin(115200);

and

 Serial.begin(9600);

Pick one baud rate; the earlier call is in the right place for Serial.begin.

Can you try your last program with the other device(s) electrically disconnected from the I2C bus?

You call Wire.begin before you RTC.begin, this Wire.begin call is not found in all RTC example code. It is down past where you have problems, tho, so I would guess not the, or even a, problem.

I don't think it would hurt and might help if you posted a schematic, a hand-drawn diagram showing how you've connected everything together. Don't get too carried away drawing it - meet us more than halfway is fine.

a7


Attached is the connection diagram I am using. Additionally, I am using a adafruit data logger shield above Arduino UNO to be able to insert SD card.

Thanks for your kind reply and for all the things you mentioned.

Pick one baud rate; the earlier call is in the right place for *Serial.begin*.

I picked one baud rate 115200 and edited the code.

Can you try your last program with the other device(s) electrically disconnected from the I2C bus?

I tried the program after disconnecting HX711 from Arduino. But it did not help. Still nothing on display.

I have seen that if I comment SD library,

#include <SD.h>

and everything other line realted to SD, then display shows

"Hello, world!"

So, may be it the problem of RAM. But I do not know how to solve the problem.

Please help

Hi,
I solved the issue by using different library. The initial problem was in memory.
The code that worked for me is

#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 <Wire.h>
#include "RTClib.h"
#include "HX711.h"  //You must have this library in your arduino library folder
/****************************************************************************************************************/
/****************************************************************************************************************/
/****************************************************************************************************************/
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
//#define SCREEN_WIDTH 128 // OLED display width, in pixels
//#define SCREEN_HEIGHT 64 // OLED display height, in pixels
//#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)

/****************************************************************************************************************/
/****************************************************************************************************************/
/*************************************************VARIABLES******************************************************/
U8X8_SSD1306_64X32_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE); 

/*************************************************VARIABLES******************************************************/
#define DURATION 2                  //Number of hours, here 2 hours you want this program to run once the button is pressed
#define LOG_INTERVAL 10            //Milliseconds between entries (reduce to take more/faster data)
#define SYNC_INTERVAL 50          // millis between calls to flush() - to write data to the card
uint32_t syncTime = 0;              // time of last sync()
uint32_t start_time;

#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
RTC_DS1307 RTC;                     //define the Real Time Clock object
const int chipSelect = 10;          //for the data logging shield, we use digital pin 10 for the SD cs line
char timestamp[30];
const int pushbutton = 8;
const int done_light = 9;
/***All the variables for voltage reading function***/
//the logging file
File bhoomiFile;
//Hx711 pins:
#define DOUT  3
#define CLK  2
HX711 scale;
int average = 0;
//Change this calibration factor as pe
//float calibration_factor = 122541;// for 20g load cell
float calibration_factor = 7370.379882; // for 100g load cell
/****************************************************************************************************************/
/****************************************************SETUP*******************************************************/
void setup() 
{
  scale.begin(DOUT, CLK);
  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
  Serial.begin(9600);                         //Initialize the serial communication
  u8x8.begin();
  u8x8.setFont(u8x8_font_amstrad_cpc_extended_f);    
  delay(50);
                                                        
  while(digitalRead(pushbutton)){};                                         //Wait for pushbutton input
  #if ECHO_TO_SERIAL
    Serial.println("(BUTTON PRESSED!)");                                    //Once pressed, display a message saying so
  #endif

  //delay(1000);                                                              //Display the message for a second
  SD_INIT();
  createFile();

  //connect to RTC
  Wire.begin();                                                     //Wire.begin: Initiate the Wire library and join the I2C bus as a master or slave.                                                      
  if (!RTC.begin())                                                 //RTC.begin initializes the internal RTC. It needs to be called before any other RTC library methods 
  {                                                                 //Assume that it returns 1 on success and 0 on failure
    bhoomiFile.println("RTC failed");
    #if ECHO_TO_SERIAL
      Serial.println("RTC failed");
    #endif  //ECHO_TO_SERIAL
  }
  
  bhoomiFile.println("millisecond,Time (MM/DD/YYYY HH:MM:SS), 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)");
  #endif //ECHO_TO_SERIAL
  start_time = millis();              //The very next step after this will be the data recording
                                      //Therefore, note down the time at this moment as the start time                                        
}
/****************************************************************************************************************/

/*************************************************LOOP***********************************************************/
void loop() 
{
    //Below: As long as current time - start time < required duration, keep recording the data
    for(start_time; (millis() - start_time) < (DURATION * 60 * 60 * 1000L); )
    //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);
      u8x8.print(" Done storing   ");  
     u8x8.setFont(u8x8_font_amstrad_cpc_extended_r);
    // u8x8.drawString(1, 1, " Done storing  "); 
  u8x8.drawString(1, 2, " 2 hrs ");      
    }                       
}
/****************************************************************************************************************/

/************************************************FUNCTIONS*******************************************************/

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);
  while(1);
}

void SD_INIT()
{
  Serial.print("Initializing SD card...");
  pinMode(chipSelect, OUTPUT);
  
  //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  
  {
    //lcd.println("SD Card failed");
    u8x8.println(" SD failed      ");  
//    delay(30);
//    error("Card failed, or not present");                         //Error function displays the error message if SD.begin fails and returns 0
    return; 
  }
  Serial.println("card initialized.");                            //If SD.begin is successful
}
void createFile()
{
  // create a new file
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++)                               //Make a new file every time the Arduino starts up
  {                                                               //Goes from 00 to 99
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (!SD.exists(filename))                                     //SD.exists() tests whether a file or directory exists on the SD card
    {                                                             //It returns true if the file or directory exists, false if not
      //only open a new file if it doesn't exist
      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).
                                                                  It returns a File object referring to the opened file; if the file couldn't be opened, 
                                                                  this object will evaluate to false in a boolean context*/
                                                                  //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");
  }
  Serial.print("Logging to: ");                                   //Otherwise, display the name of the file generated  
  Serial.println(filename);
  u8x8.clear();
  u8x8.draw1x2String(-3,20,filename);
  u8x8.clear();
  u8x8.refreshDisplay();
  delay(20);
  }

void doTheThing()
{
  DateTime now;
 
    //delay for the amount of time we want between readings
    delay((LOG_INTERVAL - 1) - (millis() % LOG_INTERVAL));
        
    //fetch the time
    now = RTC.now();
    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.print("");
    bhoomiFile.print(millis(),DEC);
    bhoomiFile.print(" , ");
    
         //now = RTC.now();
    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("");
    #if ECHO_TO_SERIAL
//      Serial.print(now.month(), DEC);
//      Serial.print("/");
//      Serial.print(now.day(), DEC);
//      Serial.print("/");
//      Serial.print(now.year(), DEC);
//      Serial.print(" ");
//      Serial.print(now.hour(), DEC);
//      Serial.print(":");
//      Serial.print(now.minute(), DEC);
//      Serial.print(":");
//      Serial.print(now.second(), DEC);
//      Serial.print("");
//       Serial.print(millis(),DEC);
//        Serial.print("");
    #endif //ECHO_TO_SERIAL
    //Log the voltage reading
    bhoomiFile.print(", ");                           //Unit in gram
    bhoomiFile.print(scale.get_units()*1, 4);          //read upto 4 decimal                                                         
    #if ECHO_TO_SERIAL
      Serial.print(", ");                          
      Serial.print(scale.get_units()*1, 4);         //read upto 4 decimal 
      Serial.print("g ");                           //Unit in gram
    #endif //ECHO_TO_SERIAL
  
    bhoomiFile.println();
//    #if ECHO_TO_SERIAL
//      Serial.println();
//    #endif // ECHO_TO_SERIAL
    u8x8.print("g,     ");                 //Unit in gram
    u8x8.print(scale.get_units()*1, 4);    //read upto 4 decimal point

    if(Serial.available())
  {
    char temp = Serial.read();
    if(temp == 't' || temp == 'T')
      scale.tare();  //Reset the scale to zero  
           if(temp == '+' || temp == 'a')
      calibration_factor += 10;
    else if(temp == '-' || temp == 'z')
      calibration_factor -= 10;    
  }
  delay(50);
    
    //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. 
    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
}
/****************************************************************************************************************/