Go Down

Topic: Get to know how to use RTC, Temp sensor, SDcard. (Read 388 times) previous topic - next topic

groundFungus

Code: [Select]
Needed for native USB port only
That is the comment that Delta_G was referring to.  It means that the whole
Code: [Select]
while (!Serial)
  {
    ; // wait for serial port to connect. Needed for native USB port only
  }

part is needed only for boards that have native USB ports like the Leonardo.  Uno, Nano, Mega (among other) boards don't need that part and it can be removed from your code.  

HellasT

Code: [Select]
while (!Serial)
  {
    ; // wait for serial port to connect. Needed for native USB port only
  }

part is needed only for boards that have native USB ports like the Leonardo.  Uno, Nano, Mega (among other) boards don't need that part and it can be removed from your code. 
I thought it means that you need a hardware serial port, not a software one and that the
while (!Serial)  {}  is a loop that keeps running (doing nothing) in order to give time to the PC to start communicating with the arduino via the serial.

Delta_G

No.  It's for the boards that have USB host controllers to make sure they have time to connect.  If you have an UNO or Nano or Mega then you can just get rid of that whole thing.  For those boards Serial is always going to be true. 
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

HellasT

#18
Sep 20, 2019, 08:28 pm Last Edit: Sep 20, 2019, 08:31 pm by HellasT
I am not sure i understand what a native USB port is. Bottom line is that UNO and MEGA dont need it :)

HellasT

So im back with more questions written as comments within the code :)

Also iv'e noticed that 1st if the file (test.txt) does not exist then it will be created and 2nd if it exists and holds some information, that info are wiped out...

What if i want to open the file and write to it after the last line of info already in it ?

Code: [Select]
#include <SPI.h>
#include <SD.h>

File myFile;

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
   
  Serial.print("Initializing SD card...");

  if (!SD.begin(4))
  {
    Serial.println("initialization failed!");
    while (1);
  }
 
  Serial.println("initialization done.");
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
 
  myFile = SD.open("test.txt", FILE_WRITE);// If test.txt does not exist on the SD then will it be
                                                           //created automatically ?

  // if the file opened okay, write to it:
  if (myFile)                            //How does this expression check that the file has been opened ?
  {                                         
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    // close the file:
    myFile.close();
    Serial.println("done.");
  }
  else
  {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }

  // re-open the file for reading:
  myFile = SD.open("test.txt");
  if (myFile)
  {
    Serial.println("test.txt:");

    // read from the file until there's nothing else in it:
    while (myFile.available())
    {
      Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  }
  else
  {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
}

void loop()
{
  // nothing happens after setup
}

HellasT

I've looked at the dataloger example. From what i understand, if i want to write values from multiple sensors to the SD then i first need to save their values in a String or maybe in a Char array ?

groundFungus

#21
Sep 20, 2019, 10:01 pm Last Edit: Sep 20, 2019, 10:02 pm by groundFungus
Quote
Also iv'e noticed that 1st if the file (test.txt) does not exist then it will be created and 2nd if it exists and holds some information, that info are wiped out...
That is not the behavior that I observe with my SD card connected to an Uno and your code.  When there is no test.txt on the card the file is created and testing 1, 2, 3. is written to the file.  Then each time that I reset the Uno a new line of testing 1, 2, 3. is appended to the file.

Please do not use Strings.  The String class, if misused, can result in weird memory bugs.  See the evils of Stings page

You could build a string (null terminated character array) using the strcat() and/or strcpy() functions or just use the file.print() and file.println() functions.  For example:
Code: [Select]

file.print(analogReadA0);
file.print(",");
file.print(analogReadA1);
file.print(",");
file.println(analogReadA2);

 That will print, to the file, the 3 readings on one line delimited by commas.

HellasT

You are correct. The contents are all there in the TXT file. So i was Wrong.

Well at the moment using the sd.h library i can write and read specific text on a TXT file on the SD card  :) hooray !

I also used the examples to set the time on the RTC but now i have no idea how to extract the information from the RTC and save them in a string of chars for later use or even print them directly on an LCD.

Could someone please help me a bit with this ? 

groundFungus

Which RTC?  Which RTC library?  Which LCD?  Which LCD library? 

HellasT

#24
Sep 21, 2019, 03:33 pm Last Edit: Sep 21, 2019, 03:45 pm by HellasT
Here is a list of what i have:
Arduino: 1. Uno board
          2. Mega board

RTC       1. DS1307Z

SDcard   1. cheap MicroSD card adapter
module

LCD        1. 20x4 LCD with I2c module

The libraries i use are : PaulStoffregen/DS1307RTC
                               PaulStoffregen/Time
                               SPI.h
                               SD.h
                               Wire.h
                               LiquidCrystal_I2C.h

groundFungus

#25
Sep 21, 2019, 03:42 pm Last Edit: Sep 21, 2019, 03:43 pm by groundFungus
I don't have much time right now but may I suggest a better library for the I2C display.   There are several libraries  named LiquidCrystalI2C and they are all a bit different.  And most are old and not actively supported.  The hd44780 library is, in my and other's opinion, the best library available for those displays.

For an I2C LCD display to work, the I2C address and the I2C backpack to LCD pin mapping must be correct.  If the library default settings for either or both are not correct the LCD will not work.  You can try to figure out the right pin mapping and use an I2C scanner to find the address, but if you install and use the hd44780 library that is done automatically by the library.

Get the LCD to work by itself before trying to integrate it with the other parts.

Install the hd44780 library.  The hd44780 library is the best available for I2C LCDs.  The library is available in the Library Manager.  Go to Library Manager (in the IDE, Sketch, Include Libraries, Manage Libraries) and in the Topics dropdown choose Display and in the Filter your search box enter hd44780.  Select and install the hd44780 library by Bill Perry.

The class that you want to use is the hd44780_I2Cexp class.  There are examples to show how to use the library.  The nice thing about the hd44780 library is that it will autodetect the I2C address and the I2C backpack to LCD pin mapping. 

In the examples, there is a diagnostic sketch that will help us to help you if you still have trouble with the display.  Run the diagnostic sketch and post the results.

I will look into the RTC as soon as I have time.  I have a DS1307 RTC so can help you develop the code and test the code on my Uno.

HellasT

First of all THANK YOU for your reply. It is indeed very good.

At the moment i have no problem with the LCD and it's library. It works okay.
the address is pretty much standrd for these LCD's and is declared like this :
LiquidCrystal_I2C lcd(0x27,20,4);
I only use simple commands like LCD.print ("something"); or lcd.noBacklight(); etc.

I will look into the RTC as soon as I have time.  I have a DS1307 RTC so can help you develop the code and test the code on my Uno.
Awesome !  Thank you so much. Please take your time :)

groundFungus

Like I said, there are several LCD libraries by that same name.  In order to run and test your code I need the same library as you.  I need to know where you got the library so i can use the same one.  Or you could install the (better) hd44780 library.  The point is that we both need to use the same one.

groundFungus

#28
Sep 21, 2019, 09:27 pm Last Edit: Sep 21, 2019, 09:31 pm by groundFungus
Here is an example sketch using a 20x4 I2C LCD and a DS1307 RTC.  I used the hd44780 library for the LCD as I don't know, exactly, which LiquidCrystalI2C library that you have.  I use the sprintf() function to build the date and time strings for printing.  You could do the same with multiple prints, but I like to do it with sprintf and the printf format specifiers to print 2 digit numbers with a leading zero for single digits.  Timing done with non-blocking millis() methods to avoid blocking (like the delay() function does).  Use the DS1307RTC library  SetTime example to set the time before running this code.

Non-blocking timing tutorials:
Several things at a time.
Beginner's guide to millis().
Blink without delay().

Code: [Select]

#include <Wire.h>
#include <hd44780.h>                       // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
#include <TimeLib.h>
#include <DS1307RTC.h>

hd44780_I2Cexp lcd; // declare lcd object: auto locate & auto config expander chip
tmElements_t tm;

const int LCD_COLS = 20;
const int LCD_ROWS = 4;

char thisDate[12]; // holds date string
char thisTime[12]; // holds time string

void setup()
{
   Serial.begin(115200);
   Serial.println("LCD, RTC test");
   lcd.begin(LCD_COLS, LCD_ROWS);
   lcd.print("Date Time Display");
   delay(3000);   
}

void loop()
{
   getDateTime();
   updateDisplay();
}

void getDateTime()
{
   static unsigned long timer = 0;
   unsigned long interval = 1000;
   if (millis() - timer >= interval)
   {
      timer = millis();
      if (RTC.read(tm))
      {
         sprintf(thisDate, "%02d/%02d/%d", tm.Month, tm.Day, tmYearToCalendar(tm.Year));
         Serial.print(thisDate);
         Serial.print("    ");
         sprintf(thisTime, "%02d:%02d:%02d", tm.Hour, tm.Minute, tm.Second);
         Serial.println(thisTime);
      }
      else
      {
         Serial.println("no RTC check wiring");
      }
   }

}

void updateDisplay()
{
   static unsigned long timer = 0;
   unsigned long interval = 1000;  // update display every second
   if (millis() - timer >= interval)
   {
      timer = millis();
      lcd.setCursor(0, 2);
      lcd.print("Date  ");
      lcd.print("              "); // ovrwrite old data
      lcd.setCursor(7, 2);
      lcd.print(thisDate);
      lcd.setCursor(0, 3);
      lcd.print("Time  ");
      lcd.print("              "); // ovrwrite old data
      lcd.setCursor(7, 3);
      lcd.print(thisTime);
   }
}

HellasT

#29
Sep 23, 2019, 10:55 pm Last Edit: Sep 23, 2019, 11:11 pm by HellasT
I bought this LCD off ebay (link below). I dont really remember where i've got the library from :(.
https://www.ebay.com/itm/Blue-Serial-IIC-I2C-TWI-2004-204-20X4-Character-LCD-Module-Display-For-Arduino/381375068233?epid=894371540&hash=item58cbb9b849:g:oL8AAOSwFAZTviYj

Ive been looking at your code and it is so well written. Though i have to confess that i feel  a little depressed. I feel like im asking you to teach the old dog new tricks :smiley-sad: . I sure want to learn though.
:)

Go Up