Puzzled about libraries

I’m puzzled about the list of libraries I see under either Sketch > Include Library or Tools > Manage Libaries.

I added the line #include <Time.h> to an existing sketch, and although I have not yet added any code using it I used Update and it was accepted without error. Yet it’s not shown in the library lists.

(I added the attachment using ‘Attachments…’ but it has resulted in a link?

You need to [u]install[/u] the Time library using the library manager, and include TimeLib.h in your code. It will be listed under "contributed libraries".

What do you mean, you "used Update"? Anyway, #including a library header file doesn't trigger an automatic upload of the library. If you're asking why it compiles without error, it's probably because there is an alias "Time.h" somewhere for the native C time library, called "time.h".

|339x500

The toolchain contains a file named time.h. Since Windows is filename case insensitive, the #include directive for "Time.h" matches with the file named time.h.

If you're planning to use the Time library, you should be aware that, for this very reason, a header file with a unique name was added to the library: TimeLib.h, and you should always use that filename instead of Time.h.

… unless you actually want to use Time.h instead of the DateTime library, which has some benefits such as a working time zone and daylight savings time adjustment.

Here is a demo:

/***************************************************
   Arduino AVR GCC time library demo
 ****************************************************/
// 2020-06-09 improve interface to time.h
// 2020-08-16 remove I/O customizations to make simple

/*
   tm structure shown here because it's hard to find the documentation

  struct tm {
  int8_t          tm_sec; //< seconds after the minute - [ 0 to 59 ]
  int8_t          tm_min; //< minutes after the hour - [ 0 to 59 ]
  int8_t          tm_hour; //< hours since midnight - [ 0 to 23 ]
  int8_t          tm_mday; //< day of the month - [ 1 to 31 ]
  int8_t          tm_wday; //< days since Sunday - [ 0 to 6 ]
  int8_t          tm_mon; //< months since January - [ 0 to 11 ]
  int16_t         tm_year; //< years since 1900
  int16_t         tm_yday; //< days since January 1 - [ 0 to 365 ]
  int16_t         tm_isdst; //< Daylight Saving Time flag
  };
*/

#include <time.h>
#include <locale.h>
#include <util/usa_dst.h> // https://www.nongnu.org/avr-libc/user-manual/usa__dst_8h_source.html

void setup() {
  Serial.begin(115200);
  printWelcome();
  
  // time system initialization:
  // required for correct local time
  set_dst(usa_dst);
  set_zone(-5 * ONE_HOUR);

  // optional extras
  // location is Toronto
  set_position( 43.741667 * ONE_DEGREE, -79.373333 * ONE_DEGREE);

  Serial.println(F("setting system time to Wednesday, January 1, 2020 12:00:00 AM"));
  set_system_time(1577836800L - UNIX_OFFSET);
  printInfo();
  Serial.println(F("press any key to continue..."));
  while (not (Serial.available() > 0));
  Serial.read();
}

void loop() {
  tickUpdate();
}

void printInfo()
{
  time_t timeNow;
  time_t sunrise;
  time_t sunset;
  time_t solarNoon;
  char sunRiseString[12];
  char sunSetString[12];
  char solarNoonString[12];
  struct tm * timeElements;

  timeNow = time(NULL);
  timeElements = localtime(&timeNow);
  sunrise = sun_rise(&timeNow);
  sunset = sun_set(&timeNow);
  solarNoon = solar_noon(&timeNow);
  strftime(sunRiseString, 12, "%I:%M:%S %p", localtime(&sunrise));
  strftime(sunSetString, 12, "%I:%M:%S %p", localtime(&sunset));
  strftime(solarNoonString, 12, "%I:%M:%S %p", localtime(&solarNoon));

  Serial.print(F("Local time using localtime()/isotime(): "));
  timeElements = localtime(&timeNow);
  Serial.println(isotime(timeElements));
  //show local time
  Serial.print(F("Local time using time()/ctime(): "));
  timeNow = time(NULL);
  Serial.println(ctime(&timeNow));

  Serial.print(F("Daylight Savings Time "));
  Serial.print(timeElements->tm_isdst ? "is" : "is not");
  Serial.println(F(" in effect."));

  Serial.print(F("Sun rises at: "));
  Serial.println(sunRiseString);

  Serial.print(F("Sun sets at: "));
  Serial.println(sunSetString);

  Serial.print(F("Solar noon is at: "));
  Serial.println(solarNoonString);

  Serial.print(F("Solar declination: "));
  Serial.print(solar_declination(&timeNow)*RAD_TO_DEG);
  Serial.println('\260');

  Serial.print(F("Day "));
  Serial.print(timeElements->tm_yday);
  Serial.print(" of ");
  Serial.println(timeElements->tm_year + 1900);

  Serial.print(F("Week "));
  Serial.print(week_of_year(timeElements, SUNDAY));
  Serial.print(F(" of "));
  Serial.println(timeElements->tm_year + 1900);

  Serial.print(F("Week "));
  Serial.print(week_of_month(timeElements, SUNDAY));
  Serial.println(" of the month");

  Serial.print(F("Days in this month: "));
  Serial.println(month_length(timeElements->tm_year, timeElements->tm_mon + 1));

  Serial.print(F("This year "));
  Serial.print(is_leap_year(timeElements->tm_year) ? "is" : "is not");
  Serial.println(F(" a leap year."));

  Serial.print(F("moon phase: "));
  Serial.print(moon_phase(&timeNow));
  Serial.println('%');
}

void printWelcome()
{
  Serial.print(F("\n\nWelcome, testing the AVR GCC time library\n"));
}

/*
   System timer tick uses micros() for timing
*/
void tickUpdate() {
  static unsigned long lastTickTime;
  static int syncIntervalCount = 0;
  if (micros() - lastTickTime >= 1000000) {
    lastTickTime += 1000000;
    system_tick();
    printTime();
  }
}

void printTime() {
  time_t timeNow;
  struct tm * timeElements;
  //show UTC time in ISO (also Canadian :=)
  timeNow = time(NULL);
  timeElements = gmtime(&timeNow);
  Serial.println(isotime(timeElements));
}

Thanks all, understood. I’ll get on the case in the morning.

One point I didn’t mention is that I use Arduino on two PCs: an old one in my shed workshop running XP and my Win 10 PC in the house. The former has no internet connection. So I assume I must download the appropriate library on the latter and copy it across with a USB stick.

You could put a portable Arduino installation on a memory stick and use it on both PCs without the need to copy anything between them

aarg: What do you mean, you "used Update"?

I meant Upload, the second icon from the left.

aarg:
… unless you actually want to use Time.h instead of the DateTime library

But if you wanted to do that it wouldn’t be Time.h. It would be time.h.

Just because Windows lets you get away with incorrect filenames doesn’t mean you should. I’ve had to fix dozens of libraries written by people using Windows who added an #include directive for “arduino.h” instead of “Arduino.h”, causing their library to be incompatible with Linux.

Even on Windows, being sloppy with filename case will get you in trouble. Although it’s not imposed by the OS, the Arduino IDE still requires the correct case to be used for #include directives of Arduino library files. For example:

#include <spi.h>
fatal error: spi.h: No such file or directory

jremington:
You need to install the Time library using the library manager, and include TimeLib.h in your code. It will be listed under “contributed libraries”.

Could you step me through that please? I opened the Library Manager but could not see it in the list. And entering ‘TimeLib’ in the Filter box got no hits. However, neither did ‘time.h’ even though I can add the line
#include <time.h>
to a new sketch without getting an error. In contrast
#include <TimeLib.h>
gave the message “TimeLib.h: No such file or directory”

In the Arduino IDE select tools>manage libraries

wait for libraries list to be updated, type time in the search box

Install Time by Michael Margolis

Replying to post #10.

Thanks a bunch, found it and duly installed.

Previously, after seeing the result of the search, I’d assumed it was (surprisingly) not in alphabetic order and so my subsequent browsing wasn’t methodical. But I now see that apart from those first few inconsistent entries, it is. Even so, it took a lot of browsing to locate it! For anyone else seeking it, I suggest a search target of ‘TimeAlarm’ instead.

P.S. Why do my attached images appear as links? I’m pretty sure that’s changed.

Why do my attached images appear as links?

Because they are attached, not linked. See Simple image insertion

Here are links to your attached images

|485x500 |500x483

Terrypin: But I now see that apart from those first few inconsistent entries

Arduino's official libraries are shown first in the search results, in alphabetical order, followed by the libraries written by 3rd parties, again in alphabetical order.

pert: Arduino's official libraries are shown first in the search results, in alphabetical order, followed by the libraries written by 3rd parties, again in alphabetical order.

Thanks, understood.

Replying to post #12 from @UKHeliBob.

Thanks, got it. Just inserting a link is clearly the simplest and most intuitive method.

Just inserting a link is clearly the simplest and most intuitive method.

But turning it into an inserted image is more helpful

UKHeliBob: But turning it into an inserted image is more helpful

Maybe I didn't phrase that unambiguously. I tried it before posting and it worked as you described. This is what I did:

I had a link on the clipboard. I was in Quick Reply so as an initial step I first clicked Preview . That gave me access to the image tool 'Insert an image'. I clicked it and pasted in my URL. (I "inserted a link".)

That was then displayed as an 'inserted image'.

Unfortunately I cannot treat 'Libraries' like the engine of my car: ignore the hidden detail and just enjoy driving. One of my PCs has no internet connection and I'm nervous about installing a 'portable' version of Arduino. So after installing a new library on my Win 10 PC, as I've just done with Time.h, I need to copy across the necessary files to my shed PC.

I'm hoping this is more straightforward than it seems. The first difficulty is that it's not clear what files the installation process generates. Nor [u]where[/u] it puts them. For instance, I (eventually) found time.h in three locations:

C:\Program Files (x86)\Arduino\hardware\tools\avr\avr\include\time.h

C:\Users\terry\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino5\avr\include\time.h

C:\Users\terry\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\avr\include\time.h

I'm not sure how or when they were created but I guess they were installed with the IDE?

But Time.h, which I've just 'installed', is just the single file:

C:\Users\terry\Dropbox\Electronics\Arduino\SKETCHES\libraries\arduino_293683\Time.h

So: Q1: Is xyz.h the only file that's needed for its library to be included in a sketch?

Q2: If several identical versions of xyz.h exist, should I copy across just one of them, and if so, which one?

Terrypin: Unfortunately I cannot treat 'Libraries' like the engine of my car: ignore the hidden detail and just enjoy driving.

Good way to be! Fortunately, in the open source world we are always free to take a look and even do some tinkering around under there if you feel like it.

Terrypin: it's not clear what files the installation process generates.

The entire contents of the library repository at the time of the release are downloaded to your computer. So it's up to each library author which files are installed. For security/compatibility reasons, libraries in the Arduino Library Manager index are prohibited from containing .exe files or symlinks, so you won't ever see any of those in the libraries you install via Library Manager.

Terrypin: Nor [u]where[/u] it puts them.

Both Library Manager and the Arduino IDE's Sketch > Libraries > Add .ZIP Library always install libraries to the "libraries" subfolder of your sketchbook folder.

You can find the location of the sketchbook folder in the Arduino IDE at File > Preferences > Sketchbook location.

You will sometimes find some low quality tutorials that instruct you to manually install libraries to a different location, but if you're doing that you'll know exactly where you put it.

Terrypin: C:\Program Files (x86)\Arduino\hardware\tools\avr\avr\include\time.h

C:\Users\terry\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino5\avr\include\time.h

C:\Users\terry\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\avr\include\time.h

This is the time.h included with the toolchain that I mentioned in my earlier reply. This is different from the Time library.

Terrypin: I'm not sure how or when they were created but I guess they were installed with the IDE?

The first one was: C:\Program Files (x86)\Arduino\hardware\tools\avr\avr\include\time.h This is a tool dependency of the copy of the Arduino AVR Boards platform that is bundled with the Arduino IDE installation.

The second two are the versions of avr-gcc that were installed as tool dependencies of boards platforms you installed via the Arduino IDE's Boards Manager (Tools > Board > Boards Manager).

Terrypin: But Time.h, which I've just 'installed', is just the single file:

C:\Users\terry\Dropbox\Electronics\Arduino\SKETCHES\libraries\arduino_293683\Time.h

Q1: Is xyz.h the only file that's needed for its library to be included in a sketch?

You shouldn't think of it as a "single file". Because we typically only need to add an #include directive for a single .h file in order to use an Arduino library in our sketch, it's easy to assume that .h file is the library. We regularly see beginners get the "no such file or directory" error for a .h file in their sketch and think they can solve it by just downloading that single file from some Google search result. But the .h file typically only contains declarations. The actual source code is typically in the .cpp or .c files. The Arduino IDE's build system identifies the library that matches the .h file in your #include directive and then compiles the entire library. That #include directive only pastes the declarations from the .h file (and any other .h files that .h file #includes) into your sketch so you can use the compiled functions implemented in the source files.

There is also usually a library.properties metadata file that can control how the library works.

So it was that "arduino_293683" folder and all its content that you installed via Library Manager.

Normally the folder name will match the name shown in Library Manager, except with spaces replaced with _. Sometimes, the installation is not able to create that folder ("Time" in this case), so the library remains installed in the staging folder. Typically, this won't cause any problems other than not being a very descriptive folder name.

Terrypin: Q2: If several identical versions of xyz.h exist, should I copy across just one of them

No. Copy the entire arduino_293683 folder.

Terrypin: which one?

If you have the Arduino IDE installed, then you will already have the avr-gcc tool installed with its time.h, so forget about those.