I play GTA 5 and the clock in the game runs faster than an actual clock. I want to have a display that will show game time. I found a sketch that doesn’t use the RTC but there’s something wrong with it. Once it hits (what should be) 10:00:00 it displays 248:243:236 and seems to jump around from there. Also, if I change the start time (line 16) to 08 or 09, I get an error.
error: invalid digit "9" in octal constant
int initialHours = 09;//variable to initiate hours
I posted this to the original writer but they haven't replied.
I do want it to display 2 digits each (01:03:59) and in 24 hour format. If possible, I'd like it to display the day of the week too.
I'm REALLY new at this so please don't explain it as if to an expert. Thanks
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup() {
lcd.print("What time is it?");
delay(1000);
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Apr, 15, 2013"); // print out the date
}
//thhis is a list of int variables used in this clock program
int s=0;
int sec=0;
int hrs=0;
int minutes=0;
int initialHours = 09;//variable to initiate hours
int initialMins = 59;//variable to initiate minutes
int initialSecs = 55;//variable to initiate seconds
//this method is for seconds
int seconds()
{
s = initialHours*3600;
s = s+(initialMins*60);
s = s+initialSecs;
s = s+(millis()/1000); // Speeds up the clock to match time in GTA5 - s = s+(millis()/33.33
return s;
}
//this method is for hours
int hours()
{
hrs = seconds();
hrs = hrs/3600;
hrs = hrs%24;
return hrs;
}
//this method is for minutes
int mins()
{
minutes = seconds();
minutes = minutes/60;
minutes = minutes%60;
return minutes;
}
int secs()
{
sec = seconds();
sec = sec%60;
return sec;
}
//this loop will conintue to keep looping so that the time can go as follows
void loop(){
digitalClockDisplay();
}
void printDigits(byte digits){
if(digits < 10)
lcd.print('0');
lcd.print(digits);
}
char sep()
{
s = millis()/1000;
if(s%2==0)
{
lcd.print(":");
}
else {
lcd.print(" ");
}
}
void digitalClockDisplay(){
lcd.setCursor(0,1);
printDigits(
hours());
sep();
printDigits(mins());
sep();
printDigits(secs());
}
Also, if I change the start time (line 16) to 08 or 09, I get an error.
error: invalid digit "9" in octal constant
int initialHours = 09;//variable to initiate hours
Well, of course you do. When you (uselessly) preface a value with 0, the compiler knows that the value is being expressed in octal. The only valid digits are 0 to 7.
s = initialHours*3600;
When initialHours becomes 10, what value are you trying to assign to s? Is that a valid thing to be doing?
One thing you should know is that an int only holds numbers up to 32767. If it's an unsigned int, it will go up to 65535. One day is 86400 seconds, so you will need to use a long instead of an int.
Your project reminds me of something I have made for my own uses. Here is a link to the thread on it. Keep in mind that, when I wrote that thread, the clock was a work in progress, so there are several different versions of the code, each of which behaves differently. https://forum.arduino.cc/index.php?topic=408565.0
You need to know that if you start a number by a zero you indicate that this number is written in base 8 (octal) (if you start your number by 0x you tell the compiler that it is base 16).
So when you write 07 you are saying it's 7 in octal, which is also 7 in decimal. But in octal you can only use symbols from 0 to 7 and thus writting 09 makes the compiler bark at you. so if you want to represent 9 its 8+1 so would be 0****11 in octal. the first 0 is to say it's octal (base 8 ) then the number in decimal will be 1x8+1 = 9
We - standard humans - are more used to decimal, so don't put a leading 0 and the compiler will read that as a decimal representation which is the way you want it
To complement the comment from odometer, when you are using millis() (here you are pretty safe as dividing by 1000) you should use an unsigned long type
odometer:
Did you read the original post? He wants a clock that runs fast.
Yes, I read it.
Using Time library, OP would need to merely reduce the number of milliseconds per sysTime tick to get a clock to run faster than real time:
time_t now(){
while( millis() - prevMillis >= 1000){ // <<<<<<<< Here
sysTime++;
prevMillis += 1000; // <<<<<<<< And here
#ifdef TIME_DRIFT_INFO
sysUnsyncedTime++; // this can be compared to the synced time to measure long term drift
#endif
}
if(nextSyncTime <= sysTime){
if(getTimePtr != 0){
time_t t = getTimePtr();
if( t != 0)
setTime(t);
else
Status = (Status == timeNotSet) ? timeNotSet : timeNeedsSync;
}
}
return sysTime;
}
I'll get this sorted out tomorrow (hopefully) and see what happens.
Odometer, I DL'd your code so I'll sort through that too.
You should see two lines that look something like this:
const uint32_t ONE_TICK_USEC = 50000UL; // update the time every 0.05 second
const uint32_t ONE_TICK_PACKED = 0x00000005; // see previous line
The first line controls how often the time is updated (in microseconds, real time).
The second line controls how far the clock actually moves, with the last two digits being hundredths of a second. So, once every 50000 microseconds (that being 0.05 second real time), the clock advances by 0.05 second, so as to keep honest real time.
You want the clock to run fast. GTA V time runs exactly 30 times as fast as real time. So change those lines to:
const uint32_t ONE_TICK_USEC = 50000UL; // update the time every 0.05 second
const uint32_t ONE_TICK_PACKED = 0x00000150; // advance the time by 1.50 seconds
That is because 0.05 second times 30 equals 1.50 seconds. So every 0.05 second real time, your clock should advance by 1.50 seconds.