LCD + DS1307+ I2C + Keypad + password entry + Menu and sub-m

Hi,

I am currently trying to program my Arduino Uno to read the clock which is a DS1307. Please see attached Fritzing Diagram… The DS1307 is hooked up to the LCD and Arduino via I2C. There is also a 4x4 matrix keypad which is used for the password entry and eventually for number selection of the various menu’s, but the menu is still to be coded properly and set up.

This program eventually will be compiled with other codes to monitor and operate my Hydroponic Window farm which will eventually converted into an Aquaponics system. Because of all the sensors, I will need to set up a serial communication line to communicate with the slave Arduino Mega. But that’s way way way in the future if I ever get there.

I have tried various codes for the DS1307 but have had no luck in compiling onto my Arduino. I think the main reason might be because I am using a significantly newer version of the IDE, most of the applicable clock codes have been done 4-5 years ago. I am really new to Arduino and programming but despite the errors have had a lot of fun operating different things which has inspired me to take on this project, Piece by piece.

I hope to eventually have a menu with sub-menu’s. But currently I can’t even get the clock to compile. I have even tried various DS1307 Codes and working through the associated issues with .h files etc.

This particular clock code seems to compile by itself, but I can’t tell what it is doing without the LCD.

Once I add the clock code into my LCD and Keypad code I get the following error message from the Arduino IDE:

MENU_CONTROL_CLOCK.ino:419:3: error: expected unqualified-id before ‘{’ token

Error compiling.

At line 419 (Highlighted in RED page 6/7) I have tried adding and removing, ‘;’ and checking the above code to make sure all the brackets ‘{’ and ‘}’ are closed but I still can’t seem to figure out what I am missing or what exactly an unqualified ID is.

Attached is my code in PDF format, any help would be freaking awesome! Thanks

/*
////////////////////////////////////////////////////////////////////////////////////////////////////MENU_CONTROLLER_UNO /////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////MENU_CONTROLLER_UNO /////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////MENU_CONTROLLER_UNO /////////////////////////////////////////////////////////////
LCD I2C &: Keypad Code: Mike Myers (http://mikemyers.me)  @netnutmike - Let's Make It Episode 6 
           (http://tech-zen.tv/index.php/shows/let-s-make-it/episodes/59-sensor-fun-with-arduino-1-massive-failure-but-4-successes-let-s-make-it-episode-6)
Menu Code: Alexander Brevig (alexanderbrevig@gmail.com) - Menu Library for Arduino
           (http://playground.arduino.cc/Code/Menu)
RTC DS1307: ARDUINO - (http://playground.arduino.cc/code/time)
I2C LCD & RTC DS1307: brainstorm ABC (brainstorm.abc@gmail.com) - Clock using Arduino I2C bus for both RTC and 16x2 LCD display
           (https://www.youtube.com/watch?v=kukV4xrqRl4&feature=share)
Arduino Real Time Clock (DS1307) -  Naren_Murali   
           (http://www.instructables.com/id/Arduino-Real-Time-Clock-DS1307/?ALLSTEPS)
           




*/
//*-----( Import needed libraries )-----*//
#include <LiquidCrystal_I2C.h>
#include <Wire.h> 
#include <Keypad.h>
#include <Time.h>
#include <RealTimeClockDS1307.h>


//*-----( Declare Constants )-----*//
const byte rows = 4;
const byte cols = 4;
int redLEDpin = 4;
int greenLEDpin = 5;

//*-----( Declare objects )-----*//

// *-----( Declare Variables )-----*//


/*
///////////////////////////////////////////////////////////////////////////////////////////////////////REAL-TIME CLOCK MODULE DS1307
*/

#define Display_Clock_Every_N_Seconds 10           // n.secs to show date/time
#define Display_ShortHelp_Every_N_Seconds 60       // n.secs to show hint for help
//#define TEST_Squarewave
//#define TEST_StopStart
//#define TEST_1224Switch

int count  =  0;
char formatted[] = "00-00-00 00:00:00x";



/*
///////////////////////////////////////////////////////////////////////////////////////////////////////LIQUID CRYSTAL IC2 DISPLAY
*/
#define address 0x27

/*
///////////////////////////////////////////////////////////////////////////////////////////////////////MENU & SUB-MENU
*/

/* 
///////////////////////////////////////////////////////////////////////////////////////////////////////4X4 MATRIX KEYPAD
*/
char keys[rows][cols] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[rows] = {13,11,12,10};
byte colPins[cols] = {9,8,7,6};

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rows, cols);

LiquidCrystal_I2C lcd(0x27,20,4);              // set the LCD address to 0x27 for a 20 chars and 4 line display


char* ourCode = "3308";                        //set our code
int currentPosition = 0;
char* Select1 = "1";

/*
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VOID SETUP///////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VOID SETUP///////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VOID SETUP///////////////////////
*/

void setup()                                    // Write setup function
{
/*  
/////////////////////////////////////////////// REAL-TIME CLOCK MODULE SETUP ///////////////////////////////////////////////
*/
{
//  Wire.begin();
  Serial.begin(9600);                         // Allows us to listen to the serial communication from the arduino
    pinMode(A4, OUTPUT);                      //*** pin 16 (Analog pin 2) as OUTPUT   ***
  digitalWrite(A4, HIGH);                     //*** pin 16 (Analog pin 2) set to LOW  ***
  pinMode(A5, OUTPUT);                        //*** pin 17 (Analog pin 3) as OUTPUT   ***
  digitalWrite(A5, LOW);                      //*** pin 17 (Analog pin 3) set to HIGH ***
                                              //*** Analog Pin settings to power RTC module ***
}
 
  
  
/*  
//////////////////////////////////////////////// LIQUID CRYSTAL IC2 SETUP ////////////////////////////////////////////////
*/

  lcd.init();                                  // initialize the lcd 
  lcd.init();                                  // Print a message to the LCD.
  lcd.backlight();  
  
  
  displayCodeEntryScreen();
  
  
  pinMode(redLEDpin, OUTPUT);                   //setup and turn off both LEDs
  pinMode(greenLEDpin, OUTPUT);
  digitalWrite(redLEDpin, LOW);
  digitalWrite(greenLEDpin, LOW);
  
  
/*   
//////////////////////////////////////////////// MENU & SUB-MENU SETUP ////////////////////////////////////////////////
*/



}
/*
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VOID LOOP////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VOID LOOP///////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VOID LOOP///////////////////////
*/
  
void loop()
/*  
////////////////////////////////////////////// REAL-TIME CLOCK MODULE LOOP ///////////////////////////////////////////////
*/
 {
   if(Serial.available())
  {
    processCommand();
  }

  RTC.readClock();
  count++;
  if(count % Display_Clock_Every_N_Seconds == 0){
    Serial.print(count);
    Serial.print(": ");
    RTC.getFormatted(formatted);
    Serial.print(formatted);
    Serial.println();
  }
  
  if(count % Display_ShortHelp_Every_N_Seconds == 0) {
    Serial.println("Send ? for a list of commands.");
  }
#ifdef TEST_Squarewave
if(count%10 == 0)
{
  switch(count/10 % 6)
  {
    case 0:
    Serial.print("Squarewave disabled (low impedance): ");
    RTC.sqwDisable(0);
    Serial.println((int) RTC.readData(7));
    break;
    case 1:
    Serial.print("Squarewave disabled (high impedance): ");
    RTC.sqwDisable(1);
    Serial.println((int) RTC.readData(7));
    break;
    case 2:
    Serial.println("Squarewave enabled at 1 Hz");
    RTC.sqwEnable(RTC.SQW_1Hz);
    break;
    case 3:
    Serial.println("Squarewave enabled at 4.096 kHz");
    RTC.sqwEnable(RTC.SQW_4kHz);
    break;
    case 4:
    Serial.println("Squarewave enabled at 8.192 kHz");
    RTC.sqwEnable(RTC.SQW_8kHz);
    break;
    case 5:
    Serial.println("Squarewave enabled at 32.768 kHz");
    RTC.sqwEnable(RTC.SQW_32kHz);
    break;
    default:
    Serial.println("Squarewave test not defined");
  }//switch
}
#endif

#ifdef TEST_StopStart
if(count%10 == 0)
{
  if(!RTC.isStopped()) 
  {
    if(RTC.getSeconds() < 45) 
    {
      Serial.println("Stopping clock for 10 seconds");
      RTC.stop();
    }//if we have enough time
  } else {
    RTC.setSeconds(RTC.getSeconds()+11);
    RTC.start();
    Serial.println("Adding 11 seconds and restarting clock");
  }
}                                                  //if on a multiple of 10 counts
#endif

#ifdef TEST_1224Switch  
  if(count%10 == 0)
  {
    if(count %20 == 0)
    {
      Serial.println("switching to 12-hour time");
      RTC.switchTo12h();
      RTC.setClock();
    }
    else
    {
      Serial.println("switching to 24-hour time");
      RTC.switchTo24h();
      RTC.setClock();
    }
  }
#endif
 }

void processCommand() {
  if(!Serial.available()) { return; }
  char command = Serial.read();
  int in,in2;
  switch(command)
  {
    case 'H':
    case 'h':
    in=SerialReadPosInt();
    RTC.setHours(in);
    RTC.setClock();
    Serial.print("Setting hours to ");
    Serial.println(in);
    break;
    case 'I':
    case 'i':
    in=SerialReadPosInt();
    RTC.setMinutes(in);
    RTC.setClock();
    Serial.print("Setting minutes to ");
    Serial.println(in);
    break;
    case 'S':
    case 's':
    in=SerialReadPosInt();
    RTC.setSeconds(in);
    RTC.setClock();
    Serial.print("Setting seconds to ");
    Serial.println(in);
    break;
    case 'Y':
    case 'y':
    in=SerialReadPosInt();
    RTC.setYear(in);
    RTC.setClock();
    Serial.print("Setting year to ");
    Serial.println(in);
    break;
    case 'M':
    case 'm':
    in=SerialReadPosInt();
    RTC.setMonth(in);
    RTC.setClock();
    Serial.print("Setting month to ");
    Serial.println(in);
    break;
    case 'D':
    case 'd':
    in=SerialReadPosInt();
    RTC.setDate(in);
    RTC.setClock();
    Serial.print("Setting date to ");
    Serial.println(in);
    break;
    case 'W':
    Serial.print("Day of week is ");
    Serial.println((int) RTC.getDayOfWeek());
    break;
    case 'w':
    in=SerialReadPosInt();
    RTC.setDayOfWeek(in);
    RTC.setClock();
    Serial.print("Setting day of week to ");
    Serial.println(in);
    break;
    
    case 't':
    case 'T':
    if(RTC.is12hour()) {
      RTC.switchTo24h();
      Serial.println("Switching to 24-hour clock.");
    } else {
      RTC.switchTo12h();
      Serial.println("Switching to 12-hour clock.");
    }
    RTC.setClock();
    break;
    
    case 'A':
    case 'a':
    if(RTC.is12hour()) {
      RTC.setAM();
      RTC.setClock();
      Serial.println("Set AM.");
    } else {
      Serial.println("(Set hours only in 24-hour mode.)");
    }
    break;
    
    case 'P':
    case 'p':
    if(RTC.is12hour()) {
      RTC.setPM();
      RTC.setClock();
      Serial.println("Set PM.");
    } else {
      Serial.println("(Set hours only in 24-hour mode.)");
    }
    break;

    case 'q':
    RTC.sqwEnable(RTC.SQW_1Hz);
    Serial.println("Square wave output set to 1Hz");
    break;
    case 'Q':
    RTC.sqwDisable(0);
    Serial.println("Square wave output disabled (low)");
    break;
    
    case 'z':
    RTC.start();
    Serial.println("Clock oscillator started.");
    break;
    case 'Z':
    RTC.stop();
    Serial.println("Clock oscillator stopped.");
    break;
    
    case '>':
    in=SerialReadPosInt();
    in2=SerialReadPosInt();
    RTC.writeData(in, in2);
    Serial.print("Write to register ");
    Serial.print(in);
    Serial.print(" the value ");
    Serial.println(in2);
    break;    
    case '<':
    in=SerialReadPosInt();
    in2=RTC.readData(in);
    Serial.print("Read from register ");
    Serial.print(in);
    Serial.print(" the value ");
    Serial.println(in2);
    break;

    default:
    Serial.println("Unknown command. Try these:");
    Serial.println(" h## - set Hours [range 1..12 or 0..24]");
	Serial.println(" i## - set mInutes [range 0..59]");
	Serial.println(" s## - set Seconds [range 0..59]");
	Serial.println(" d## - set Date [range 1..31]");
    Serial.println(" m## - set Month [range 1..12]");
    Serial.println(" y## - set Year [range 0..99]");
    Serial.println(" w## - set arbitrary day of Week [range 1..7]");
    Serial.println(" t   - toggle 24-hour mode");
    Serial.println(" a   - set AM          p   - set PM");
    Serial.println();
    Serial.println(" z   - start clock     Z   - stop clock");
    Serial.println(" q   - SQW/OUT = 1Hz   Q   - stop SQW/OUT");
    Serial.println();
    Serial.println(" >##,###  - write to register ## the value ###");
    Serial.println(" <##      - read the value in register ##");
    
  }//switch on command
  
}

//read in numeric characters until something else
//or no more data is available on serial.
int SerialReadPosInt() {
  int i = 0;
  boolean done=false;
  while(Serial.available() && !done)
  {
    char c = Serial.read();
    if (c >= '0' && c <='9')
    {
      i = i * 10 + (c-'0');
    }
    else 
    {
      done = true;
    }
  } 
  return i;
}
    
/*  
//////////////////////////////////////////////////// KEYPAD LOOP /////////////////////////////////////////////////////
*/

int l;
  {
  char key = keypad.getKey();
  
  if (int(key) != 0) {
    lcd.setCursor(14,3);
    lcd.print("    ");
    lcd.setCursor(14,3);
    
    for (l=0; l<=currentPosition; ++l)
    {
      lcd.print("*");
    }
    
    if (key == ourCode[currentPosition])
      {
        ++currentPosition;
        if (currentPosition == 4)
        {
          unlockDoor();
          currentPosition = 0;
        }
      } else {
        invalidCode();
        currentPosition = 0;
      }
  }
}

/*  
//////////////////////////////////////////// LIQUID CRYSTAL IC2 LOOP ////////////////////////////////////////////
*/

void displayCodeEntryScreen()                                              //Entry Screen 1.0
{
  clearScreen();
  lcd.setCursor(0,0);
  lcd.print("AFFINITY  AQUAPONICS"); 
  lcd.setCursor(1,1);                                                      // Go to the 2nd line
  lcd.print("URBAN FARM SYSTEM");   
  lcd.setCursor(3,3);                                                      // Go to the 3rd line
  lcd.print("Passcode:");
  lcd.setCursor(16,3);
}

void invalidCode()                                                          //Invalid Code Screen 1.1
{
  digitalWrite(redLEDpin, HIGH);
  clearScreen();
  lcd.setCursor(0,0);
  lcd.print("********************");
  lcd.setCursor(0,1);
  lcd.print("** ACCESS DENIED! **");
  lcd.setCursor(0,2);
  lcd.print("**  INVALID CODE  **");
  lcd.setCursor(0,3);
  lcd.print("********************");
  
  delay(5000);
  digitalWrite(redLEDpin, LOW);
  displayCodeEntryScreen();
}

void unlockDoor()                                                             //Invalid Code Screen 1.2.
{
  digitalWrite(greenLEDpin, HIGH);
  clearScreen();
  lcd.setCursor(0,0);
  lcd.print("********************");
  lcd.setCursor(0,1);
  lcd.print("** ACCESS GRANTED **");
  lcd.setCursor(0,2);
  lcd.print("**    WELCOME!!   **");
  lcd.setCursor(0,3);
  lcd.print("********************");
   
  delay(5000);                                                         //add any code to unlock the door here
  digitalWrite(greenLEDpin, LOW);
  menuScreen();
}

void menuScreen()                                                             //Main Menu Screen 2.0.
{
  digitalWrite(greenLEDpin, HIGH);
  clearScreen();
  lcd.setCursor(8,0);
  lcd.print("MENU");
  lcd.setCursor(0,1);
  lcd.print("1.SENSORS");
  lcd.setCursor(0,2);
  lcd.print("2.CONTROLS");
  lcd.setCursor(0,3);
  lcd.print("3.SETTINGS");
  lcd.setCursor(11,1);
  lcd.print("4.SUBSYS");
  lcd.setCursor(11,2);
  lcd.print("4.DASHBOARD");
  lcd.setCursor(11,3);
  lcd.print("4.SOLAR");
  lcd.setCursor(22,1);
  lcd.print("4.LOCK SYS");
  
}

void sensorScreen()                                                             //Main Menu Screen 2.1.
{
  digitalWrite(greenLEDpin, HIGH);
  clearScreen();
  lcd.setCursor(0,0);
  lcd.print("SENSORS");
  lcd.setCursor(0,1);
  lcd.print("1.LIGHT");
  lcd.setCursor(0,2);
  lcd.print("2.TEMP/HU");
}

void clearScreen()                                                             //Main Menu Screen 2.1.
{
  lcd.setCursor(0,0);
  lcd.print("                    ");
  lcd.setCursor(0,1);
  lcd.print("                    ");
  lcd.setCursor(0,2);
  lcd.print("                    ");
  lcd.setCursor(0,3);
  lcd.print("                    ");
}


/*  
//////////////////////////////////////////////// MENU & SUB-MENU LOOP ////////////////////////////////////////////////
*/

Well, what are you trying to do with that “KEYPAD LOOP” block of code between line 419 and 445? That’s an orphan code-block. It’s not inside any other function so the compiler doesn’t know what to do with it. It’s not part of loop() or setup() nor in any of your own declared functions. So the solution is to move it into the proper function and proper place where it fits the sequence of execution. Or you forgot to give it a function header (hence “unqualified-id”), or somehow accidentally deleted it.

Or simply disable it entirely by commenting it between /* and */ brackets if you do not have any use for that code yet, but still wish to keep it for the future.

I don’t know how the newest versions of the Arudino IDE displays the code, but I find it more clear to read if I look at the code with Notepad++. Using the language interpretation options in the menu (c-code) it can identify which {-bracket belongs to which }-bracket. And it highlights that with a connecting line across indented sections. Indented sections of your code can also be collapsed to reduce clutter. See this screendump of the orphan code section:

p.s. Disregard the backup message popup. It’s a screen artifact which has nothing to do with Notepad++.

Thanks Valen,

I moved that section of code to below the LCD SETUP and it magically compiled. However the keypad no longer functions to be able to enter the password. I work on a Mac so I wasn’t able to download Notepad ++ cause its an .exe file. I thought that particular section of Keypad code had to stay there cause if the code is wrong then it goes in a loop until you enter the correct password. I wish you could add attachments so I can show you a hierarchy tree layout of the menu and sub-menu layout.

You can attach files to a reply. Use the full editor and look below the editing box.