Notifications
Clear all

Arduino Coding Problem

22 Posts
5 Users
1 Likes
6,698 Views
Photo Bud
(@photo-bud)
Member
Joined: 5 years ago
Posts: 89
Topic starter  

Yes, I'm a NOOB!

As part of my endeavor to broadcast a fast clock to individual buildings to control lighting on an HO layout, I've attempted to copy and use fast clock sketch from which I will (hopefully) extract and modify as needed. However, I'm getting an error on trying to Verify/Compile and I don't know what I'm doing nor how to proceed. Here is a portion of the sketch and at the end, the error message I'm getting. Is it a coding problem, is it because one or more included items have changed, or something else. I don't know where to start.

Thanks in advance for any help you can give me.

/*
Fast_Clock.ino - Arduino Fast Clock for Model Railroading
Copyright (c) Dave Heili April 2018
...
#include <Arduino.h> // Define normal Arduino Library
#include <Wire.h> // Needed for I2C usage
#include <LiquidCrystal_I2C.h> // I2C LCD display https://github.com/marcoschwartz/LiquidCrystal_I2C
#include <TM1637Display.h> // 4 Digit LED display //github.com/avishorp/TM1637
#include <TimeLib.h> // Time management //github.com/PaulStoffregen/Time
//#include <DS1307RTC.h> // Basic DS1307 / DS3231 RTC //github.com/PaulStoffregen/DS1307RTC
#include <DS3232RTC.h> // Basic DS3232 RTC //github.com/JChristensen/DS3232RTC
#include <Bounce2.h> // Debounce library //github.com/thomasfredericks/Bounce2
#include <LiquidMenu.h> // Menu Library //github.com/VaSe7u/LiquidMenu
...
// Define the LCD menu system
LiquidCrystal_I2C lcd(0x27, 16, 2);

//Save dynamic memory by defining strings as Progmem
const char road_Name[] PROGMEM = ROAD_NAME;
const char welcome_text1[] PROGMEM = "Arduino Fast Clock";
const char welcome_text2[] PROGMEM = "V 1.0 - 4/5/2018";
const char welcome_text3[] PROGMEM = "By Futski";

// Define the LCD screen definitions
LiquidLine welcome_line1(1, 0, welcome_text1);
LiquidLine welcome_line2(2, 1, welcome_text2);
LiquidLine welcome_line3(5, 3, welcome_text3);
LiquidScreen welcome_screen(welcome_line1, welcome_line2, welcome_line3);

LiquidLine main1(4, 0, road_Name);
LiquidLine main2(0, 1, "Fast ", "Time ", pfcText);
LiquidLine main3(0, 2, "Real ", "Time ", prcText);
LiquidLine main_opt_pause(3, 3, pausedText);
LiquidLine main_opt_menu(12, 3, "Menu");
LiquidScreen main_screen(main1, main2, main3, main_opt_pause);

LiquidLine menu_opt_ratio(1, 0, "Clock ", "Ratio ", ratio, ":1");
LiquidLine menu_opt_set_clock_menu(1, 1, "Set ", "Clock ", ">");
LiquidLine menu_opt_restart(1, 2, "Restart ", "Clock ");
LiquidLine menu_opt_back(1, 3, "BACK");
LiquidScreen menu1(menu_opt_ratio, menu_opt_set_clock_menu, menu_opt_restart, menu_opt_back);

LiquidLine menu_opt_set_fc(1, 0, "Set ","Fast ", "Clock ", ">");
LiquidLine menu_opt_set_rc(1, 1, "Set ", "Real ", "Clock ", ">");
LiquidLine menu_opt_set_format(1, 2, "Time ", "Format ", milText);
LiquidScreen menu2(menu_opt_set_fc, menu_opt_set_rc, menu_opt_set_format, menu_opt_back);

LiquidLine menu_opt_set_clock_header(1, 0, "Set ", clockTypeText, "Clock ");
LiquidLine menu_opt_set_clock(1, 1, ptcText, " ", timePartText);
LiquidLine menu_opt_set_clock_save(1, 3, "Save");
LiquidLine menu_opt_set_clock_canc(8, 3, "Canc");
LiquidScreen menuSetClock(menu_opt_set_clock_header, menu_opt_set_clock, menu_opt_set_clock_save, menu_opt_set_clock_canc);

LiquidMenu menu(lcd);
...
no matching function for call to 'LiquidMenu::LiquidMenu(LiquidCrystal_I2C&)'

Photo Bud (aka John)
The Old Curmudgeon!


   
Quote
(@zeferby)
Member
Joined: 5 years ago
Posts: 355
 
Posted by: @photo-bud

no matching function for call to 'LiquidMenu::LiquidMenu(LiquidCrystal_I2C&)'

Hi John.

Keeping links to the actual libraries used was a very good idea ! ? 

So I had a look at https://github.com/VaSe7u/LiquidMenu and found this message (that you can probably only see when you compile if you enable the verbose option for compiling in the IDE) :

https://github.com/VaSe7u/LiquidMenu/blob/c57a58b3ae15e628579a86aa964d13c147a7f64e/src/LiquidMenu.h#L56

then I had a look at LiquidMenu_config.h and found this block where I guess you will have to comment the block for Arduino Parallel LCD (lines 33-35) and un-comment the block for the I2C LCD (lines 43-45) :

https://github.com/VaSe7u/LiquidMenu/blob/master/src/LiquidMenu_config.h#L21

 

 

Eric


   
ReplyQuote
codecage
(@codecage)
Member Admin
Joined: 5 years ago
Posts: 1037
 

@zeferby & @photo-bud

But shouldn't the URL to the library be commented out as all the others are?  Is that what is causing the error that is popping up?  The URL between the 3rd and 4th include in the code above.

 

SteveG


   
ReplyQuote
(@zeferby)
Member
Joined: 5 years ago
Posts: 355
 

@codecage

I think it's just a side effect of including the source code in the forum post.

...once again I am unable to locate the link to @robo-pi 's post about the best way to include source code in a forum post...

@photo-bud if you want your code to look cute in a post, you can right click it in the Arduino IDE and choose "copy as HTML", then with your post being currently in the post editor you can click on the "{;}" icon and then paste your code with Ctlr+V where you want in your post's HTML code. 

Eric


   
ReplyQuote
codecage
(@codecage)
Member Admin
Joined: 5 years ago
Posts: 1037
 

@zeferby

Makes sense!  I saw that and it just looked a little odd to me.  Thought maybe the third set of eyes might have seen something that got missed by the other two sets.  I can't say how many times I have looked a code with a GLARING error and not seen the error until another pair of eyes pointed it out to me.  One of those if I had a dollar for each one... events! ? 

SteveG


   
ReplyQuote
(@zeferby)
Member
Joined: 5 years ago
Posts: 355
 

LOL how many times did I spot a bug in my code first thing in the morning the next day, after spending an evening not seing it...

Eric


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

@zeferby

@photo-bud if you want your code to look cute in a post, you can right click it in the Arduino IDE and choose "copy as HTML", then with your post being currently in the post editor you can click on the "{;}" icon and then paste your code with Ctlr+V where you want in your post's HTML code. 

Generally agree, but it is useful to add a couple of blank lines in the message window first, then in the source code window, highlight <p> </p> and then paste the HTML from the Arduino IDE.


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

@photo-bud

Have I understood you correctly?

You are using Arduinos to control the lighting inside the buildings of your model railway!

Isn't that making everything too complex?

KISS!

I assume that you only need the building to light up when the ambient light goes down. This could be achieved without any Arduinos, nrf24l01s etc. Three resistors, one light dependent resistor(LDR) and one OpAmp per building would suffice to turn an LED on when the room housing your model railway goes dark.


   
ReplyQuote
Photo Bud
(@photo-bud)
Member
Joined: 5 years ago
Posts: 89
Topic starter  

@zeferby, @codecage, @pugwash - Thank you all for helpful comments and suggestions! I probably would never have found the need to comment out and uncomment the code in the included library.

And I'm sorry about the code format, I have done it the proper way in the past, but forgot to do it that way this time. Upon rereading my comment, I can understand how difficult it is to read this way.

And yes, this is probably overkill, but I'm using this as a learning experience to better understand Arduino coding. Plus, each building will have unique light patterns to better reflect real life. In some cases, one light at a time will come on in a building and stay on until "dawn", and then go off in sequence. In other, patterns will be used to reflect specific behavior, such as hall light comes on, then porch light, kitchen light on, hall light off, hall on, kitchen off, living room on, hall off, etc. All this is not necessary, but should add to believability, and draw attention to specific scenes throughout the "day/night" sequence.

As an aside, though I am NOOB with Arduino/Raspberry Pi (and old), I had about 35 years experience in I.T. with IBM mainframes and some mini-computers, mostly in COBOL, but also BAL, CYBOS (a Forth derivative), and Apple Basics, 6502 assembler, IBM Basic and Compiled Basic. Which just adds to my propensity to get confused.

Thanks again to all.

Will try to get this taken care of today, but we're currently getting the house cleaned and prepared for an onslaught of grandkids (and their mother).

Photo Bud (aka John)
The Old Curmudgeon!


   
ZeFerby reacted
ReplyQuote
(@zeferby)
Member
Joined: 5 years ago
Posts: 355
 
Posted by: @photo-bud

As an aside, though I am NOOB with Arduino/Raspberry Pi (and old), I had about 35 years experience in I.T. with IBM mainframes and some mini-computers, mostly in COBOL, but also BAL, CYBOS (a Forth derivative), and Apple Basics, 6502 assembler, IBM Basic and Compiled Basic. Which just adds to my propensity to get confused.

Then as a code warrior you may like to have a look at nicer IDEs than the basic Arduino IDE.  I very much like PlatformIO on Visual Studio Code, other guys are more used to Eclipse.  These IDEs usually provide "intellisense" code completion, direct access to declaration and definition of symbols, etc...

Eric


   
ReplyQuote
Photo Bud
(@photo-bud)
Member
Joined: 5 years ago
Posts: 89
Topic starter  

Fixed my previous problem, thanks, but now have a new one. In SetRealClockClick(), menu.change_screen(menuSetClock); returns an error, "no matching function for call to 'LiquidMenu::change_screen(LiquidScreen&)'". Yet in the previous subroutine, SetFastClockClick(), there is no error with identical statement. ????????? I looked in the _config file for  any other suspicious commenting/uncommenting, but found nothing.

Note that I highlighted the offending statement by making bold and 14pt type (most of way down the code).

Thanks in advance for any new suggestions/solutions.

 

[code]
/*
Fast_Clock.ino - Arduino Fast Clock for Model Railroading
Copyright (c) Dave Heili April 2018
This software is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public
License along with this software; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <Arduino.h> // Define normal Arduino Library
#include <Wire.h> // Needed for I2C usage
#include <LiquidCrystal_I2C.h> // I2C LCD display https://github.com/marcoschwartz/LiquidCrystal_I2C
#include <TM1637Display.h> // 4 Digit LED display //github.com/avishorp/TM1637
#include <TimeLib.h> // Time management //github.com/PaulStoffregen/Time
//#include <DS1307RTC.h> // Basic DS1307 / DS3231 RTC //github.com/PaulStoffregen/DS1307RTC
#include <DS3232RTC.h> // Basic DS3232 RTC //github.com/JChristensen/DS3232RTC
#include <Bounce2.h> // Debounce library //github.com/thomasfredericks/Bounce2
#include <LiquidMenu.h> // Menu Library //github.com/VaSe7u/LiquidMenu

//===============================================================================================
// Initial Settings - You may want to adjust these settings
//===============================================================================================
#define ROAD_NAME "L & BS"
#define INITIAL_PAUSE_STATE true // Tell if the fast clock starts paused or not (true / false)
#define DEFAULTHH 7 // Set starting FastClock Hour in Military Time
#define DEFAULTMM 0 // Set starting FastClock minute
#define MILITARY_TIME false // Display 24 hour clock or not. Use true or false
// else to not print messages, change DEBUG_MODE to DEBUG_MODE_OFF
#define FAST_CLOCK_RATIO 20 // Fastclock Speed ie. 4 is 4:1 factor or 4 fast minutes per 1 real minute,
// Or 1 fast minute every 15 real seconds
// For best operation, pick a ratio that is evenly divisible by 60.
// ie 1,2,3,4,5,6,10,12,15,20,30,60 Although any number will work
#define WELCOME_DELAY 3000 // Time, in millis, that the welcome screen will show
#define LCD_ADDRESS 0x27 // Address of LCD Display. Common addresses 0X27, 0x3F

#define DEBUG_MODE_off // When DEBUG_MODE is defined, Serial Prints will show status

//===============================================================================================

// SPI Pins for TM1637 LED 4 digit display
#define LED_CLK 11 // Pin # for TM1637 LED CLK pin
#define LED_DIO 12 // Pin # for TM1637 LED DIO pin

// Pins for Rotary Encoder
#define ROTARY_ENCODE_A 2
#define ROTARY_ENCODE_B 3
#define ROTARY_ENCODE_SW 4
#define DEBOUNCEINTERVAL 5 // Specify how long to wait for a stable debounce state (in milli-sec)

// Clock update Frequency variables
unsigned int clock_check_wait_time = 200; // in Millis - Default=200 or 5 times per second
unsigned long prev_millis = 0;

// Rotary Encoder variables
volatile boolean rotaryFired; //Volatile because this are updated in an interupt
volatile boolean rotaryDirection; //Volatile because this are updated in an interupt

// Setup deBounce object for rotary encoder switch
Bounce pushButton1 = Bounce();

// Clock Variables
time_t fastClock=0, realClock=0, prevRealClock=0, tempClock = 0; // Create clock variables
tmElements_t timeParts; // time_t Breakout
unsigned short rcmm = 0, prev_RcMM = 0;
unsigned short fcmm = 0, prev_FcMM = 0;

char rcText[10]; // Real Clock Display string
char fcText[10]; // Fast Clock Display string
char tcText[10]; // Temp Clock Display string
char* prcText; // Pointer to Real Clock Display string
char* pfcText; // Pointer to Fast Clock Display string
char* ptcText; // Pointer to Temp Clock Display string
char* timePartText = "Set HH";
char* clockTypeText = "Fast ";

bool fcPaused = true;
char* pausedText = "Paused ";
bool MilitaryTime = MILITARY_TIME;
char* milText = "12 HR ";
short ratio = FAST_CLOCK_RATIO;
byte storedHH, storedMM, storedByte;

// Setup LED
TM1637Display LED_Display(LED_CLK, LED_DIO);

// Define the LCD menu system
LiquidCrystal_I2C lcd(0x27, 16, 2);

//Save dynamic memory by defining strings as Progmem
const char road_Name[] PROGMEM = ROAD_NAME;
const char welcome_text1[] PROGMEM = "Arduino Fast Clock";
const char welcome_text2[] PROGMEM = "V 1.0 - 4/5/2018";
const char welcome_text3[] PROGMEM = "By Futski";

// Define the LCD screen definitions
LiquidLine welcome_line1(1, 0, welcome_text1);
LiquidLine welcome_line2(2, 1, welcome_text2);
LiquidLine welcome_line3(5, 3, welcome_text3);
LiquidScreen welcome_screen(welcome_line1, welcome_line2, welcome_line3);

LiquidLine main1(4, 0, road_Name);
LiquidLine main2(0, 1, "Fast ", "Time ", pfcText);
LiquidLine main3(0, 2, "Real ", "Time ", prcText);
LiquidLine main_opt_pause(3, 3, pausedText);
LiquidLine main_opt_menu(12, 3, "Menu");
LiquidScreen main_screen(main1, main2, main3, main_opt_pause);

LiquidLine menu_opt_ratio(1, 0, "Clock ", "Ratio ", ratio, ":1");
LiquidLine menu_opt_set_clock_menu(1, 1, "Set ", "Clock ", ">");
LiquidLine menu_opt_restart(1, 2, "Restart ", "Clock ");
LiquidLine menu_opt_back(1, 3, "BACK");
LiquidScreen menu1(menu_opt_ratio, menu_opt_set_clock_menu, menu_opt_restart, menu_opt_back);

LiquidLine menu_opt_set_fc(1, 0, "Set ","Fast ", "Clock ", ">");
LiquidLine menu_opt_set_rc(1, 1, "Set ", "Real ", "Clock ", ">");
LiquidLine menu_opt_set_format(1, 2, "Time ", "Format ", milText);
LiquidScreen menu2(menu_opt_set_fc, menu_opt_set_rc, menu_opt_set_format, menu_opt_back);

LiquidLine menu_opt_set_clock_header(1, 0, "Set ", clockTypeText, "Clock ");
LiquidLine menu_opt_set_clock(1, 1, ptcText, " ", timePartText);
LiquidLine menu_opt_set_clock_save(1, 3, "Save");
LiquidLine menu_opt_set_clock_canc(8, 3, "Canc");
LiquidScreen menuSetClock(menu_opt_set_clock_header, menu_opt_set_clock, menu_opt_set_clock_save, menu_opt_set_clock_canc);

LiquidMenu menu(lcd);

uint8_t myCursor[8] = {
0b00000,
0b00100,
0b00010,
0b11111,
0b00010,
0b00100,
0b00000,
0b00000
};

bool updateLcdScreen = false;

uint8_t whichClock = 0;
enum WhichClock {
eFastClock = 1,
eRealClock = 2,
};

uint8_t menuState= 0;
enum MenuState {
New = 0,
Done = 0,
InMenu = 1,
SetHH = 1,
SetMM =2,
};

enum UserAction {
ButtonPushed = 1,
RotateUp = 2,
RotateDown = 3,
};

enum RotaryResponse {
Up = true,
Down = false,
};

enum SaveDataAddress {
SaveMilMode = 0x07,
SaveMM = 0x08,
SaveHH = 0x09,
SaveRatio = 0x0A,
};

// Interrupt Service Routine Looks for a change to encoder pin A
void isr()
{
if (digitalRead(ROTARY_ENCODE_A))
// When A goes High - Used when isr is triggered by CHANGE or RISING
rotaryDirection = digitalRead(ROTARY_ENCODE_B);
else
// When A goes low - Used when isr is triggered by CHANGE or FALLING
rotaryDirection = !digitalRead(ROTARY_ENCODE_B);

rotaryFired = true;
}

void setup()
{

Serial.begin(115200);

// Setup Rotary Encoder
{
pinMode(ROTARY_ENCODE_A, INPUT_PULLUP); // enable pull-ups
pinMode(ROTARY_ENCODE_B, INPUT_PULLUP);
pinMode(ROTARY_ENCODE_SW, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ROTARY_ENCODE_A), isr, FALLING); // interrupt 0 is pin 2

pushButton1.attach(ROTARY_ENCODE_SW);
pushButton1.interval(DEBOUNCEINTERVAL); // interval in ms
}

// Setup LCD screen
{
lcd.init();
lcd.backlight();
// Get LCD started
lcd.begin(20, 4); // initialize the lcd for 20 chars 4 lines, turn on backlight
// lcd.blink(); // When blink is on, cursor will show regardless of noCursor setting
// lcd.noCursor(); // Make sure display Cursor is Off
lcd.noBlink(); // Make sure Cursor isn't blinking
}

// Finish setting up menu system
{
welcome_line1.set_asProgmem(1);
welcome_line2.set_asProgmem(1);
welcome_line3.set_asProgmem(1);
main1.set_asProgmem(1);

// Need to add 5th line to some screens
main_screen.add_line(main_opt_menu);

// Set custom cursor positions for some menu options
main_opt_pause.set_focusPosition(Position::CUSTOM, 2, 4);
menu_opt_set_clock_canc.set_focusPosition(Position::CUSTOM, 7, 3);

// Add function calls to selectable menu items.

// Set actions for main screen
main_opt_pause.attach_function(ButtonPushed, TogglePause);
main_opt_pause.attach_function(RotateUp, OptNext);
main_opt_pause.attach_function(RotateDown, noop);

main_opt_menu.attach_function(ButtonPushed, opt_menu1);
main_opt_menu.attach_function(RotateUp, noop);
main_opt_menu.attach_function(RotateDown, OptPrev);

// Set Menu 1 Actions
menu_opt_ratio.attach_function(ButtonPushed, ChangeRatioClick);
menu_opt_ratio.attach_function(RotateUp, ChangeRatioRotateUp);
menu_opt_ratio.attach_function(RotateDown, ChangeRatioRotateDown);

menu_opt_restart.attach_function(ButtonPushed, InitialSetClocks);
menu_opt_restart.attach_function(RotateUp, OptNext);
menu_opt_restart.attach_function(RotateDown, OptPrev);

menu_opt_set_clock_menu.attach_function(ButtonPushed, opt_menu2);
menu_opt_set_clock_menu.attach_function(RotateUp, OptNext);
menu_opt_set_clock_menu.attach_function(RotateDown, OptPrev);

menu_opt_back.attach_function(ButtonPushed, opt_back);
menu_opt_back.attach_function(RotateUp, noop);
menu_opt_back.attach_function(RotateDown, OptPrev);

// Set Menu 2 Actions
menu_opt_set_fc.attach_function(ButtonPushed, SetFastClockClick);
menu_opt_set_fc.attach_function(RotateUp, OptNext);
menu_opt_set_fc.attach_function(RotateDown, noop);

menu_opt_set_rc.attach_function(ButtonPushed, SetRealClockClick);
menu_opt_set_rc.attach_function(RotateUp, OptNext);
menu_opt_set_rc.attach_function(RotateDown, OptPrev);

menu_opt_set_format.attach_function(ButtonPushed, ToggleMilTime);
menu_opt_set_format.attach_function(RotateUp, OptNext);
menu_opt_set_format.attach_function(RotateDown, OptPrev);

// Set Clock screen actions
menu_opt_set_clock.attach_function(ButtonPushed, ChangeTimeClick);
menu_opt_set_clock.attach_function(RotateUp, ChangeTimeRotateUp);
menu_opt_set_clock.attach_function(RotateDown, ChangeTimeRotateDown);

menu_opt_set_clock_save.attach_function(ButtonPushed, SaveClick);
menu_opt_set_clock_save.attach_function(RotateUp, OptNext);
menu_opt_set_clock_save.attach_function(RotateDown, OptPrev);

menu_opt_set_clock_canc.attach_function(ButtonPushed, CancClick);
menu_opt_set_clock_canc.attach_function(RotateUp, noop);
menu_opt_set_clock_canc.attach_function(RotateDown, OptPrev);

// Add screens to menu
menu.add_screen(welcome_screen);
menu.add_screen(main_screen);
menu.add_screen(menu1);
menu.add_screen(menu2);
menu.add_screen(menuSetClock);
menu.set_focusPosition(Position::LEFT);
menu.set_focusSymbol(Position::LEFT, myCursor);
menu.update();
}
delay(WELCOME_DELAY); // Show welcome screen for 5 seconds

// Get Real Time clock Time
setSyncProvider(RTC.get); // the function to get the time from the RTC
#ifdef DEBUG_MODE
if (timeStatus() != timeSet)
Serial.println(F("Unable to sync with the RTC"));

else {
Serial.println(F("RTC has set the system time"));
}
#endif // DEBUG_MODE

// Get any saved ratio - Override default if ration is not zero
storedByte = RTC.readRTC(SaveRatio);
if (storedByte >= 0 && storedByte <= 60) {
ratio = storedByte;
}

storedByte = RTC.readRTC(SaveMilMode);
if (storedByte == 0 || storedByte == 1) {
MilitaryTime = storedByte;
}

// This block sets the real and fast clocks
{
InitialSetClocks();

/* // Get time from the Real Time Clock
if (timeStatus() != timeSet) { // Check if RTC set the real clock
realClock = 1; // When RTC fails, Set real clock time to midnight 1/1/1970
setTime(realClock);
}
realClock = now();
prevRealClock = realClock;
// Set default start time for fastClock
timeParts.Hour = DEFAULTHH;
timeParts.Minute = DEFAULTMM;
timeParts.Second = 0;
timeParts.Wday = weekday(); // Set Day of week, sunday is day 1 - Default to Real Clock
timeParts.Day = day(); // Set Day of month - Default to Real Clock
timeParts.Month = month(); // Set Month - Default to Real Clock
timeParts.Year = year() - 1970; // Set year offset from 1970 - Default to Real Clock
fastClock = makeTime(timeParts); //Create FastClock storage
//fastClock = 68400UL; //Set starting fasttime
*/
#ifdef DEBUG_MODE
Serial.print(F("Real="));
Serial.print(hour());
Serial.print(F(":"));
Serial.print(minute());
Serial.print(F(":"));
Serial.print(second());
Serial.print(F(":"));
Serial.print(month());
Serial.print(F("/"));
Serial.print(day());
Serial.print(F("/"));
Serial.println(year());

Serial.print(F("Fast="));
Serial.print(hour(fastClock));
Serial.print(F(":"));
Serial.print(minute(fastClock));
Serial.print(F(":"));
Serial.print(second(fastClock));
Serial.print(F(":"));
Serial.print(month(fastClock));
Serial.print(F("/"));
Serial.print(day(fastClock));
Serial.print(F("/"));
Serial.println(year(fastClock));
#endif // DEBUG_MODE

FormatTimeText(rcText, realClock);
FormatTimeText(fcText, fastClock);
prcText = (char*)rcText;
pfcText = (char*)fcText;

#ifdef DEBUG_MODE
Serial.print("rcText: ");
Serial.println(rcText);
Serial.print("fcText: ");
Serial.println(fcText);
#endif // DEBUG_mode
}

// Initial LED screen
{
LED_Display.setBrightness(0x04, true);
// int x = 1234;
// LED_Display.showNumberDecEx(x, 4, true);
int iTime = 0000;
LED_Display.showNumberDecEx(iTime, iTime, true);
uint8_t segto;
segto = 0x80 | LED_Display.encodeDigit((iTime / 100) % 10);
LED_Display.setSegments(&segto, 1, 1);
}

// Go to the Main Screen
SetPause(INITIAL_PAUSE_STATE);
menu.next_screen();
menu.switch_focus();
// menu.update();

}

void loop() {
// Don't waste unnecessary time checking the clock.
// So check to see if it's time to check the clock
if (millis() - prev_millis > clock_check_wait_time) {
prev_millis = millis();
if (UpdateFastClock()) {
// If the fast clock was updated, then check to see if the minute changed
// on either the real clock or the fast clock
if (minute(fastClock) != prev_FcMM || minute(realClock) != prev_RcMM) {
prev_FcMM = minute(fastClock);
prev_RcMM = minute(realClock);

FormatTimeText(rcText, realClock);
FormatTimeText(fcText, fastClock);
prcText = (char*)rcText;
pfcText = (char*)fcText;

updateLcdScreen = true;
DisplayLED(fastClock);
}
}
}

pushButton1.update(); // Update Rotary Encoder Switch status
if (pushButton1.fell()) {
menu.call_function(1);
}

if (rotaryFired) {
if (rotaryDirection == Up)
menu.call_function(2);
else
menu.call_function(3);
rotaryFired = false;

} // end if fired

if (updateLcdScreen) {
menu.softUpdate();
updateLcdScreen = false;
}
}

void InitialSetClocks() {
// Get time from the Real Time Clock
if (timeStatus() != timeSet) { // Check if RTC set the real clock
realClock = 1; // When RTC fails, Set real clock time to midnight 1/1/1970
setTime(realClock);
}
realClock = now();
prevRealClock = realClock;

// Set default start time for fastClock
storedHH = RTC.readRTC(SaveHH);
storedMM = RTC.readRTC(SaveMM);
#ifdef DEBUG_MODE
Serial.print("Sto");
Serial.print(storedHH);
Serial.print(":");
Serial.print(storedMM);
#endif // DEBUG_mode
if (storedHH >= 0 && storedHH <= 23 && storedMM >= 0 && storedMM <= 59) {
timeParts.Hour = storedHH;
timeParts.Minute = storedMM;
}
else {
timeParts.Hour = DEFAULTHH;
timeParts.Minute = DEFAULTMM;
}
timeParts.Second = 0;
timeParts.Wday = weekday(); // Set Day of week, sunday is day 1 - Default to Real Clock
timeParts.Day = day(); // Set Day of month - Default to Real Clock
timeParts.Month = month(); // Set Month - Default to Real Clock
timeParts.Year = year() - 1970; // Set year offset from 1970 - Default to Real Clock
fastClock = makeTime(timeParts); //Create FastClock storage
//fastClock = 68400UL; //Set starting fasttime
SetPause(true);

};

bool UpdateFastClock() {
realClock = now(); // Get current Real Time
if (realClock != prevRealClock) { // If Real Time is not = Prev real time, then at least one second
// has passed, so it's time to update the fast clock.
// Figure out exactly how many seconds have passed since the last update. Then multiply
// those seconds by the FastClock ratio and add those additional seconds to the fast clock
if (!fcPaused) {
fastClock = fastClock + ((realClock - prevRealClock) * ratio);
}

prevRealClock = realClock; // Save the time as PrevRealTime
return true; // Return true to indicate that the fast clock time has bee updated
}
return false; // Fast time was not updated so return false
}

void FormatTimeText(char myTimeText[], time_t myTime) {
if (MilitaryTime)
sprintf(myTimeText, "%02d:%02d", hour(myTime), minute(myTime));
else
sprintf(myTimeText, "%2d:%02d %s", hourFormat12(myTime), minute(myTime), (isAM(myTime) ? "AM" : "PM"));
}

void DisplayLED(time_t myTime) {

int8_t hh = 0;
if (MilitaryTime)
hh = hour(myTime);
else
hh = hourFormat12(myTime);

int16_t dispTime = (hh * 100) + minute(myTime); // Put time in 4 digit format
LED_Display.showNumberDecEx(dispTime, myTime, (MilitaryTime ? true : false)); //Display the digits on the LED
//Compute and display the colon.
// uint8_t segto;
uint8_t segto = 0x80 | LED_Display.encodeDigit((dispTime / 100) % 10);
LED_Display.setSegments(&segto, 1, 1);

}

bool TogglePause() {
return SetPause(!fcPaused);
}

bool SetPause(bool myPause) {
fcPaused = myPause;
if (fcPaused)
pausedText = "Paused";
else
pausedText = "Running";
return fcPaused;
}

bool ToggleMilTime() {
return SetMilTime(!MilitaryTime);
}

bool SetMilTime(bool myMiltime) {
MilitaryTime = myMiltime;
RTC.writeRTC(SaveMilMode, MilitaryTime);
SetMilText();
menu.softUpdate();
return MilitaryTime;
}

void SetMilText() {
if (MilitaryTime)
milText = "24 HR";
else
milText = "12 HR";
}

void noop() {
return;
}

void OptNext() {
menu.switch_focus(true);
return;
}

void OptPrev() {
menu.switch_focus(false);
return;
}

void opt_back() {
menu.switch_focus(true);
menu.previous_screen();
FormatTimeText(rcText, realClock);
FormatTimeText(fcText, fastClock);
prcText = (char*)rcText;
pfcText = (char*)fcText;
updateLcdScreen = true;
return;
}

void opt_menu1() {
menu.change_screen(menu1);
menu.switch_focus(true);
return;
}

void opt_menu2() {
SetMilText();
menu.change_screen(menu2);
menu.switch_focus(true);
return;
}

void ChangeRatioClick() {
switch (menuState) {
case New:
menuState = InMenu;
break;
case InMenu:
menuState = Done;
break;
default:
break;
}
return;
}

void ChangeRatioRotateUp() {
switch (menuState) {
case New:
OptNext();
return;
case InMenu:
ratio++;
RTC.writeRTC(SaveRatio, ratio);
menu.softUpdate();
return;
}
}

void ChangeRatioRotateDown() {
switch (menuState) {
case New:
noop(); // Top entry on screen, so don't go anywhere
return;
case InMenu:
ratio--;
RTC.writeRTC(SaveRatio, ratio);
menu.softUpdate();
return;
}
}

void SetFastClockClick() {
whichClock = eFastClock;
tempClock = fastClock;
FormatTimeText(tcText, tempClock);
ptcText = (char*)tcText;
timePartText = "";
clockTypeText = "Fast ";
menuState = New;
menu.change_screen(menuSetClock);
menu.switch_focus(true);
}

void SetRealClockClick() {
whichClock = eRealClock;
tempClock = realClock;
FormatTimeText(tcText, tempClock);
ptcText = (char*)tcText;
timePartText = "";
clockTypeText = "Real ";
menuState = New;
menu.change_screen(menuSetClock);
menu.switch_focus(true);
}

void ChangeTimeClick(){

// Need to Click on Date to start setting, otherwise you can scroll past it
switch (menuState) {
case New:
menuState = SetHH;
timePartText = "Set HH";
return;
case SetHH:
menuState = SetMM;
timePartText = "Set MM";
return;
case SetMM:
timePartText = "";
menu.switch_focus(true); //When Clicking on on Minute, Go to Save Option
menuState = Done;
return;
}

}

void ChangeTimeRotateUp() {
switch (menuState) {
case New:
menu.switch_focus(true); //When Clicking on on Minute, Go to Save Option
return;
case SetHH: // Increase 1 Hour
tempClock += 3600;
FormatTimeText(tcText, tempClock);
ptcText = (char*)tcText;
menu.softUpdate();
return;
case SetMM: // Increase 1 minute
tempClock += 60;
FormatTimeText(tcText, tempClock);
ptcText = (char*)tcText;
// menu.softUpdate();
return;
}
}

void ChangeTimeRotateDown() {
switch (menuState) {
case New:
noop(); //Cant scroll up
return;
case SetHH:
tempClock -= 3600; // Decease 1 hour
FormatTimeText(tcText, tempClock);
ptcText = (char*)tcText;
menu.softUpdate();
return;
case SetMM:
tempClock -= 60; // Decease 1 minute
FormatTimeText(tcText, tempClock);
ptcText = (char*)tcText;
menu.softUpdate();
return;
}

}

void SaveClick() {

if (whichClock == eFastClock) {
fastClock = tempClock;
SetPause(true);
storedHH = hour(fastClock);
storedMM = minute(fastClock);
RTC.writeRTC(SaveHH, storedHH);
RTC.writeRTC(SaveMM, storedMM);
}
else {
realClock = tempClock;
prevRealClock = realClock;
RTC.set(realClock);
setTime(realClock);
}

FormatTimeText(rcText, realClock);
FormatTimeText(fcText, fastClock);
prcText = (char*)rcText;
pfcText = (char*)fcText;
DisplayLED(fastClock);

menuState = Done;
menu.switch_focus(false);
menu.switch_focus(false);
menu.previous_screen();
}

void CancClick() {
menu.switch_focus(true);
menu.previous_screen();
menuState = Done;
}
[/code]

Photo Bud (aka John)
The Old Curmudgeon!


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 5 years ago
Posts: 2042
 

@Photo Bud,

I notice you used [code] at the start of the source code and [/code] at the end.  Perhaps you have memory of me saying that is how easy it is to do on another forum i post to?  It doesn't work on this forum.

Robo Pi suggests this method.

1. Select the code to be posted in the Arduino IDE.

2. Right-click on  the selected code and choose "Copy as HTML" from the pop-up menu.

3. Then in the forum editor window  choose the source code icon {:} at the top of the editor.

4. Paste the  HTML code into the pop-up window and select ok.

5. You can then select "Preview" at the bottom of the post editor to see exactly how the code will appear when posted.

This method preserves both the alignment and the color formatting of the Arduino code.

Pugwash also noted:

... it is useful to add a couple of blank lines in the message window first, then in the source code window, highlight <p> </p> and then paste the HTML from the Arduino IDE.

 


   
ReplyQuote
Photo Bud
(@photo-bud)
Member
Joined: 5 years ago
Posts: 89
Topic starter  

@casey and @zeferby - Thanks! Rather than repost the entire sketch, I have followed the instructions on {;} and it works like a charm, but then deleted it since I can't delete the previous one. Hopefully I will remember in the future.

However that doesn't solve my current quandary! Perhaps someone will spot my problem or give me an idea as to how to resolve it.

Photo Bud (aka John)
The Old Curmudgeon!


   
ReplyQuote
(@zeferby)
Member
Joined: 5 years ago
Posts: 355
 

@photo-bud

I'll have a look tomorrow morning (just saw the post right now, at 1am here...)

Eric


   
ReplyQuote
(@zeferby)
Member
Joined: 5 years ago
Posts: 355
 

@photo-bud

Ok I think you may have an issue because the library is evolving and the sample code does not (yet?) reflect the changes in its API : from https://github.com/VaSe7u/LiquidMenu/commits/master you find the change in arguments of LiquidMenu::change_screen(...) from a reference to a pointer :

image

 

I have reproduced your code in a PlatformIO project with all libraries installed locally to the project.

I had to add function prototype declarations before void setup() for all your functions defined after void loop() so the line numbers are not the same as yours : "void setup() {" is at line 227 instead of your line 193 so all my main.cpp line numbers in the attached Compile Error Log.txt are =yours +34.

So the error actually occurs for your 4 functions using change_screen : void opt_menu1(), void opt_menu2(), void SetFastClockClick() and void SetRealClockClick().

The current version of the library needs to be called with a pointer :

myMenu.change_screen(&myScreen);

instead of :

myMenu.change_screen(myScreen);

When I do these 4 changes, the code compiles (with warnings...) but the linker errors out because of a conflict between 2 other libraries both trying to define the RTC symbol.

 

 

EDIT:

I just saw you have commented out the DS1307RTC include, so doing the same in my platformio.ini, the sketch finally compiles and links OK.

 

Eric


   
ReplyQuote
Page 1 / 2