What changed? Now I get the error message: 'RTC_DS1307' does not name a type

I've been using the code below for the last year or so with no issues, but when my board lost power and I needed to reupload the sketch I got the following message when I tried to compile:

/tmp/300061567/Catomatic_V5/Catomatic_V5.ino:41:1: error: 'RTC_DS1307' does not name a type

RTC_DS1307 RTC; //this defines a variable named RTC of type RTC_DS1307; it's defined in RTClib.h

^

/tmp/300061567/Catomatic_V5/Catomatic_V5.ino: In function 'time_t syncProvider()':

/tmp/300061567/Catomatic_V5/Catomatic_V5.ino:44:10: error: 'RTC' was not declared in this scope

return RTC.now().unixtime();

^

/tmp/300061567/Catomatic_V5/Catomatic_V5.ino: In function 'void setup()':

/tmp/300061567/Catomatic_V5/Catomatic_V5.ino:72:5: error: 'RTC' was not declared in this scope

RTC.begin(); //Starts the RTC library

^

/tmp/300061567/Catomatic_V5/Catomatic_V5.ino: In function 'void loop()':

/tmp/300061567/Catomatic_V5/Catomatic_V5.ino:114:20: error: 'RTC' was not declared in this scope

DateTime now = RTC.now(); //this calls current time and date from RTC

^

exit status 1

Did something change in the RTClib? This was stable code that lives in the web editor so I can't think of what may have changed.

Ive attached my code below. Any help would be greatly appreciated, the sketch is for my cat feeder and the beast needs to eat!

//Catomatic: An automated cat food and water station
//A hair-brained project by Wayne Gatlin
//last edit 25Jan2018 this version solves the delay block that was making the water dispense too long

/*
Description of the project:
The purpose of this project is to control the timing of two outputs that are used to
dispense food and water to Murf.  One output is a low-torque electric motor (12v)
that turns a worm drive to dispense food and the other is a soleniod (12v) that
dispenses water.  An Arduino Uno with a RTC controls the timing of food and water cycles.
Each output is activated by a seperate TIP120 transistor that receives a 5v signal from the
Arduino that opens the defined output to the 12v current.


The objective of this code is to:
1. Use the arduino's outputs to send 5v signals to the transistors for the motor and solenoid
so that they turn on at the defined times and are open for the correct amount of time
2. Define a set amount of time that each output is open (longer=more food or water dispensed)
3. Create a timed daily cycle of three food and water events (breakfast, lunch, dinner)
4. Ideally allow the Arduino to "sleep" until it is interruped for the next event
*/

//Step 1: Call libraries
#include <Wire.h>       //This library allows the Uno to communicate with I2C / TWI devices. On the Arduino boards with the R3 layout (1.0 pinout), the SDA (data line) and SCL (clock line) are on the pin headers close to the AREF pin.
#include "RTClib.h"     //I beleive this library allows the RTC to communicate with the Arduino
#include <TimeLib.h>    //This header file contains definitions of functions to get and manipulate date and time information.
#include <TimeAlarms.h> //I believe this libarry allows me to schedule time-based tasks

RTC_DS1307 RTC;         //this defines a variable named RTC of type RTC_DS1307; it's defined in RTClib.h
time_t syncProvider()   //this does the same thing as RTC_DS1307::get()
  {
  return RTC.now().unixtime();
  }


//Step 2: Define the variables
//int is the 'data type' for the variables --int means integer (whole number)

int feedmotor = 3;      //The motor for food will be controlled by digial output pin 3
int watersolenoid = 4;  //The solenoid for water will be controlled by digial output pin 4

/**************************

     SETUP FUNCTION

***************************/

// Step 3: Run the setup
    //The setup() function is called when a sketch starts. Use it to initialize variables, pin modes, start using libraries, etc.
    //The setup function will only run once, after each powerup or reset of the Arduino board.

void setup()
{
    //establish communication with computer
    Serial.begin(9600); //My understanding is that this sets the communiaction rate with the computer(?) and is necessary for all sketches
    

    //Call the libraries that were included in Step 1
    Wire.begin();       //Starts the wire library
    RTC.begin();        //Starts the RTC library
    
    setSyncProvider(syncProvider);     //reference our syncProvider function instead of RTC_DS1307::get()

    //Tell the arduino what I've called the outputs
    pinMode(feedmotor, OUTPUT);      //Defines that the feedmotor (pin 3 from step 2) is an output device
    pinMode(watersolenoid, OUTPUT);  //Defines that the watersolenoid (pin 4 from step 2) is an output device
    pinMode(LED_BUILTIN, OUTPUT);   //defines onboard LED

    //Test to see if the RTC is NOT running properly
    if (! RTC.isrunning())
    {
        Serial.println("RTC is NOT running!");
    }
    
        //Test to make sure the RTC is running properly
    if (RTC.isrunning())
    {
        Serial.println("RTC is workin fine!");
    }
    
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));

    //Define the times that food and water will be delivered
    Alarm.alarmRepeat(12,00,00, Breakfast);    // An alarm called Breakfast happens at 6:30am every day
    Alarm.alarmRepeat(18,30,00, Lunch);        // An alarm called Lunch happens at 12:30pm every day
    Alarm.alarmRepeat(23,00,00, Dinner);       // An alarm called Dinner happens at 6:00pm every day
    //for some reason the RTC gets set 5 hours ahead of the current time when the sketch uploads from my macbook
}
/**************************

           LOOPS

***************************/

//Step 4: Describe the loop

void loop() { //curly bracket that defines start of the loop

    //this sets the RTC clock to current time and date in the serial monitor
    //Does this require an LCD?  I would like to add one in the future.
    DateTime now = RTC.now();         //this calls current time and date from RTC
  
    Serial.print(now.hour(), DEC);    //this set of functions prints the time every second in the serial monitor
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();


    //this is required, or the alarms won't fire.
    Alarm.delay(1000); // wait one second between clock display
}

//Create a loop that defines a feeding
void FoodWaterON() {                         // A title for this particular function
    digitalWrite(feedmotor, HIGH);        //Turns the feedmotor on
    Serial.println("Feeding the Beast");  //text on the future LCD
    //future project: LED indicator light
    //future project: LCD scrolling message
    //future project: sound bite to announce feeding
    delay(10000);                           //This is the amount of time the motor will turn dispensing food
    Serial.println("Feeding Complete");   //Text on the future LCD
    digitalWrite(feedmotor, LOW);        //Turns the feedmotor on
    
    delay(12000); //delay between food and water
    
    digitalWrite(watersolenoid, HIGH);    //Turns the watersolenoid on
    Serial.println("Hydrating");          //text on the future LCD
    //future project: LED indicator light
    //future project: LCD scrolling message
    //future project: sound bite to announce watering
    delay(3000);                           //This is the amount of time the motor will turn dispensing food
    Serial.println("Hydration Complete"); //Text on the future LCD
    digitalWrite(watersolenoid, LOW);    //Turns the watersolenoid on
}

//Create a loop that defines a watering
/*void WaterON() {                        //I think this is just a title for this particular function
    digitalWrite(watersolenoid, HIGH);    //Turns the watersolenoid on
    Serial.println("Hydrating");          //text on the future LCD
    //future project: LED indicator light
    //future project: LCD scrolling message
    //future project: sound bite to announce watering
    delay(3000);                           //This is the amount of time the motor will turn dispensing food
    Serial.println("Hydration Complete"); //Text on the future LCD
    digitalWrite(watersolenoid, LOW);    //Turns the watersolenoid on
}*/
    
//Define what will happen at each of the three scheduled meal times
void Breakfast() {
  Serial.println("test run");
    FoodWaterON();
}

void Lunch() {
    FoodWaterON();
}

void Dinner() {
    FoodWaterON();
}

Have you tried changing the line

#include "RTClib.h"

to

#include <RTClib.h>

Maybe the location of RTClib has changed.

Regards
Paul

Unlike the standard Arduino IDE, the Arduino Web Editor has all the 1875 libraries in the Arduino Library Manager index pre-installed. The problem this causes is that there might be multiple libraries which contain a file matching your #include directive (RTClib.h in this case) and the library your code might not happen to be the one the Arduino Web Editor decides to use. That is what has happened to you. Since the time that you successfully compiled your sketch, a new library "RTCLib by NeiroN" was added and that library is being used instead of the "RTCLib" library your sketch was written for.

The Arduino Web Editor gives preference to libraries in your "Favorites". So you can cause the RTCLib library to be used by doing this:

  • On the left sidebar, click "Libraries".
  • Click "Library Manager".
  • In the "Search Library" field, type "rtclib".
  • Press "Enter".
  • Click the star next to "RTCLIB A fork of Jeelab's fantastic RTC library". The star should now be solid teal instead of having a white space in the center.
  • Click "Done".

After doing the above, your sketch should now compile.

Good thoughts, but unfortunately library confusion doesn't seem to be my issue. I've had all the libraries that are called in the sketch living in my favorites tab since the code was stable. I tried removing and re-favoriting but that hasn't worked either.

While troubleshooting I will randomly get the code to compile (maybe once in 10 tries), only to see the serial port displaying a string of D's where the RTC usually displays the time (ex: RTCDDDDDDDDD...D). What's up with that? Haha I have no idea what's going on with this thing!

Sorry to hear that didn't work. I was able to reproduce your problem and then once I favorited the correct library the problem went away. You don't happen to have the "RTCLib by NeiroN" library also favorited, do you?

I have found the favoriting trick to not work as it was claimed to in the past. In fact, I was surprised that it worked for me this time. Another way of forcing the Arduino Web Editor to use the correct library that has worked more reliably for me is to import that library, since the Arduino Web Editor gives preference to your "Custom" libraries:

  • Download the RTCLib library: https://github.com/adafruit/RTClib/archive/1.2.0.zip
  • From the left sidebar of the Arduino Web Editor, click "Libraries".
  • Click the upward pointing arrow "Import" button.
  • If you get a dialog about importing your sketchbook, click "Import".
  • Select the downloaded file.
  • Click "Open".
  • Wait until a dialog shows to confirm the successful import of the library.

Hey that did the trick! Thank you so much for the troubleshooting! Now if I could only understand WHY this solved my problem haha.

You're welcome. I'm glad to hear it's working now.

The reason your code used to work without jumping through the import hoop was that there was only a single library (the "RTCLib" library) that contained a file matching your #include directive for RTCLib.h.

Since that time, someone else submitted a completely different library to the Arduino Library Manager index which also contains a file named RTCLib.h. So now the Arduino Web Editor needs to pick one of the two to use. It happened to pick the one that was not compatible with your code (the "RTCLib by NeiroN" library), thus the error.

When there are multiple libraries that contain a file matching an #include directive, the Arduino Web Editor gives preference to the one that you imported over the pre-installed libraries. So once you imported the "RTCLib" library your code was written for, that library was used instead of the unwanted "RTCLib by NeiroN" library and the error went away.