Confused about #include error

I have a folder with 2 files in it: myTimer.ino and myTimer.h

The first line of the .ino file is #include “myTimer.h”
At compile time there is an error claiming that myTimer.h doesn’t exist.
Why is this happening? Arduino 1.8.10

Here is the error message

Arduino: 1.8.10 (Windows 10), Board: “Arduino Uno WiFi Rev2, ATMEGA328”

myTimer:1:10: error: myTimer.h: No such file or directory

#include “myTimer.h”

^~~~~~~~~~~

compilation terminated.

exit status 1
myTimer.h: No such file or directory

This report would have more information with
“Show verbose output during compilation”
option enabled in File → Preferences.

Here is myTimer.h

/*  myTimer class is an easy way to create multiple millisecond timers for use in your programs.
    It works equally well as a microsecond timer if you replace all the millis(); with micros();
    To use just call the constructor with the number of milliseconds to be timed. Example: myTimer T1(500); 
    will create a timer named T1 with a duration of 500 ms. The timer begins immidiately and each time 
    T1.Expired(); is called, the function will return true if the time has expired or false if not. The 
    timers run continuously. If desired for synchronization, the timer can be reset to run for the full 
    duration by calling T1.Reset(); and optionally add the timer interval value to be changed, T1.Reset(ms);
  USAGE:
    In your program, myTimer T1(100); creates a 100 ms timer nameed T1
    T1.Expired(); returns true if 100 ms has passed and false if not
    T1.Reset(); Restarts the timeer for the full duration
    T1.Reset(200); Restarts the timer for the full duration and changes the interval to 200 ms   
*/

class myTimer                                         // an easy to use timer class
{
  private:
    unsigned long currentTime, previousTime, interval;

  public:
    myTimer(unsigned long timeInterval)               // constructor
    {
      previousTime = millis();                        // set the start time
      interval = timeInterval;                        // set the initial time interval
    }

    boolean Expired()                                 // see if the time interval has expired
    {
      currentTime = millis();
      if (currentTime >= previousTime + interval)
      {
        previousTime = currentTime;                   // Remember the time
        return true;
      }
      return false;
    }

    void Reset(unsigned long timeInterval = NULL)
    {
      previousTime = millis();                        // Reset the timer's start point
      if (timeInterval != NULL)                       // and optionally change the interval
      {
        interval = timeInterval;
      }
    }
};

Here is myTimer.ino

#include "myTimer.h"

// Create 3 separate millisecond polled timers
myTimer t1(500);                // Create an instance of timer T1 by calling the constructor
myTimer t2(750);                // Create an instance of timer T2
myTimer t3(1000);               // Create an instance of timer T3

bool first = true;              // flag to indicate this is the first time through

void setup()
{
  Serial.begin(115200);
  // assuming some time was consumed during setup, reset all 3 timers before entering the loop.
  t1.Reset();
  t2.Reset();
  t3.Reset();
}

void loop()
{
  /* In this example use of the timers we print the timer name as each timer interval expires
    On the first pass T1 expires after 500 ms and then it is changed by T1.Reset to 3000 ms
    The T3 timer will never expire because it is reset just before each poll.
  */
  if (T1.Expired())             // poll the T1 timer to see if the interval has passed
  {
    Serial.println("T1");       // prints after 500 ms the first time and after 3000 ms thereafter
    if (first)
    {
      T1.Reset(3000);           // change T1 interval to 3000 ms
      first = false;            // only do this once
    }
  }
  if (T2.Expired())
  {
    Serial.println("T2");       // prints every 750 ms
  }

  T3.Reset();                   // T3 will never expire because of this reset just before the poll

  if (T3.Expired())             // poll T3 timer for expiration
  {
    Serial.println("T3");       // prints every 1000 ms (unless reset)
  }
}

I get a lot of different warnings/errors.

In file included from Somewhere\myTimer\myTimer.ino:2:0:
Somewhere\AppData\Local\Temp\arduino_build_302593\sketch\myTimer.h:39:45: warning: converting to non-pointer type 'long unsigned int' from NULL [-Wconversion-null]
     void Reset(unsigned long timeInterval = NULL)
                                             ^~~~
Somewhere\AppData\Local\Temp\arduino_build_302593\sketch\myTimer.h: In member function 'void myTimer::Reset(long unsigned int)':
Somewhere\AppData\Local\Temp\arduino_build_302593\sketch\myTimer.h:42:27: warning: NULL used in arithmetic [-Wpointer-arith]
       if (timeInterval != NULL)                       // and optionally change the interval
                           ^~~~
Somewhere\myTimer\myTimer.ino: In function 'void setup()':
Somewhere\myTimer\myTimer.ino:15:12: warning: converting to non-pointer type 'long unsigned int' from NULL [-Wconversion-null]
   t1.Reset();
            ^
Somewhere\myTimer\myTimer.ino:16:12: warning: converting to non-pointer type 'long unsigned int' from NULL [-Wconversion-null]
   t2.Reset();
            ^
Somewhere\myTimer\myTimer.ino:17:12: warning: converting to non-pointer type 'long unsigned int' from NULL [-Wconversion-null]
   t3.Reset();
            ^
Somewhere\myTimer\myTimer.ino: In function 'void loop()':
myTimer:26:7: error: 'T1' was not declared in this scope
   if (T1.Expired())             // poll the T1 timer to see if the interval has passed
       ^~
Somewhere\myTimer\myTimer.ino:26:7: note: suggested alternative: 't1'
   if (T1.Expired())             // poll the T1 timer to see if the interval has passed
       ^~
       t1
myTimer:35:7: error: 'T2' was not declared in this scope
   if (T2.Expired())
       ^~
Somewhere\myTimer\myTimer.ino:35:7: note: suggested alternative: 't2'
   if (T2.Expired())
       ^~
       t2
myTimer:40:3: error: 'T3' was not declared in this scope
   T3.Reset();                   // T3 will never expire because of this reset just before the poll
   ^~
Somewhere\myTimer\myTimer.ino:40:3: note: suggested alternative: 't3'
   T3.Reset();                   // T3 will never expire because of this reset just before the poll
   ^~
   t3
exit status 1
'T1' was not declared in this scope

I have a folder with 2 files in it: myTimer.ino and myTimer.h

Where exactly is this folder located ?

The folder is on my windows 10 desktop and it is named myTimer

PickyBiker:
The folder is on my windows 10 desktop and it is named myTimer

How do you expect the compiler to find it ?

Put the .h and .cpp files in the same folder as the sketch or put them in the libraries folder of your sketch directory in a folder named myTimer

Not sure I understand. There is a myTimer.h file and myTimer.ino file and they are both in a folder named myTimer on the desktop. Why is that a problem?

Why is that a problem?

Because the compiler will not know where to find the library files

Using "" round the library name with the #include tells the compiler to look for the library first in the same folder as the sketch, then in the libraries folder of the sketchbook folder then in the system libraries folders.

Using “” round the library name with the #include tells the compiler to look for the library first in the same folder as the sketch

As you can see in the attached image, there are only 2 files involved and they are both in the folder with the same name. According to the above quote, (and my understanding), the include statement should look first in the folder where the sketch is.

This doesn’t use any libraries, just the sketch file and the header file and both of those are in the folder where all 3 names match.

So I still don’t see what am I missing?

I don't see any reason why you would get this error with the sketch structure you describe. Please post the verbose compilation output and maybe that will provide a clue as to what is going wrong:

Please do this:

  • (In the Arduino IDE) click File > Preferences
  • Check the box next to "Show verbose output during: > compilation
  • Click "OK"
  • Sketch > Verify/Compile
  • After the compilation fails you'll see a button on the right side of the orange bar "Copy error messages". Click that button.
  • Paste the output in a reply here.

If the length of the output exceeds the forum's 9000 character limit, save it in a .txt file and post it here as an attachment. If you click the "Reply" button you'll see the "Attachments and other options" link.

I just did as you describe:

  • created a folder on my desktop called "myTimer"
  • created a .ino file called "myTimer.ino"
  • created a new tab in the IDE, named it "myTimer.h" and copied your code there

My sketch is:

#include "myTimer.h"

void setup()
{
}//setup

void loop()
{
}//loop

and it compiles without error.

I suspect your .h file may be not called "myTimer.h" but rather, say, "myTimer.h.ino" or something.

I found the problem and it appears to be a Win 10 thing…

The folder name on the desktop is myTimer
Inside that folder the file names are myTimer.ino and myTimer.h

I changed the naming to capitalize the folder and the files.
Now the folder name is MyTimer
The file names are MyTimer.ino and MyTimer.h
NOTE: I did not capitalize the name for #include "myTimer.h"

This configuration does not get the error. So there was a problem with the folder name. The clue came from the image I posted Previously: You can see in that image the first line shows the folder capitalized (MyTimer), but the lower listing shows it as myTimer.

I then saved the 2 files in a different folder and deleted the myTimer folder. I created a new myTimer folder on the desktop and copied the saved files back into it. I renamed the files to the original myTimer.ino and myTimer.h.

This configuration compiles without the #include error. I attached another image of the file structure and now the folder name on the first and second lines are both myTimer.

For completeness. In the OP, the myTimer.ino sketch has a couple other errors where I had inconsistent capitalization on T1 vs t1, T2 vs t2 and T3 vs t3. After correcting that the whole sketch compiles, uploads, and works as intended.

I final note: Normally, if the enclosing folder doesn’t have the same name as the sketch inside it, the compiler warns you that the sketch must be in a folder with the same name. Curiously, that warning did not occur.