Real time clock, increment and display on LED in C - c

I have a loop for my clock, that I am trying to make an add 30 sec if keypad sends an x value of 30. It then displays on the LED display. It works, but I seem to be having an issue with adding 30 seconds and over 59 sec. The way it worked originally was it kept adding 30 to 60 to 90 + 120, etc. But I want it to roll over every 60 secs, when I add 30 sec. If I should rewrite the code, I am all game, but any leads would be helpful. Know this code is for an embedded item and is only a snippet. the inital set time is added before set loop, and is held as the value for test.
n=test;
for(i=0;i<n;i++){
q = test %100; /*q makes real time clock work in 60 sec decriments*/
if(q==0){
test = test - 40;
}
key = KeypadReadPort();
x = keys[key];
if(x==30){ /*add 30 seconds during count*/
n = n + 30;
sec1=(test+30)%90;
if(sec1>=60){
min=q;
sec2=(test+30)%60;
test=sec2+(100+q);
} else if (sec1<60){
test=test+30;
}
SevenSegWrite(test);/* display result on LED*/
}
test = test - 1; /*count down tick*/
SevenSegWrite(test);
OSTimeDlyHMSM(0, 0, 1, 0);/*1 second tick*/
if(test==0){
for(i=0;i<750;i++){ /*buzzer*/
PTT = PTT | 0x20;
OSTimeDlyHMSM(0,0,0,1);
PTT = PTT & 0xDF;
OSTimeDlyHMSM(0,0,0,1);
}
}
}
test=0;

I would do it this way. It works for me. You have a great start! You just need to break down your clock numbers a bit.
if(start<15){
min=0; /*microwave keypad numeric input method*/
n = test;
for(i=0;i<n;i++){
q = test %100; /*q makes real time clock work in 60 sec decriments*/
if(q==0){
test = test - 40;
}
key = KeypadReadPort();
x = keys[key];
if(x==30){ /*add 30 seconds during count*/
d4 = test % 10;
d3 = (test / 10) % 10;
d2 = (test / 100) % 10;
d1 = (test / 1000) % 10;
min=(d1*1000)+(d2*100);
sec1=(d3*10)+d4;
n = n + 30;
sec2=(sec1+30)%90;
if(sec2>=60){
min=min+100;
sec1=(sec1+30)%60;
test=sec1+(min);
} else if (sec2<60){
test=test+30;
}
SevenSegWrite(test);
}
test = test - 1; /*count down tick*/
SevenSegWrite(test);
OSTimeDlyHMSM(0, 0, 1, 0);
if(test==0){
for(i=0;i<750;i++){ /*buzzer*/
PTT = PTT | 0x20;
OSTimeDlyHMSM(0,0,0,1);
PTT = PTT & 0xDF;
OSTimeDlyHMSM(0,0,0,1);
}
}

Related

Can someone explain to me why time is working like this?

I've spent a good hour on this, but I can't create a formula that works for my c program. (I have a new programmer).
I have to convert UTC time to its respective time in a particular city. My code works perfectly except here. Here it gives me the wrong answer. I can't wrap my head around it (I created a formula but it makes no sense to me).
In my program, time is entered as 24 hour time. 9AM = 900, 12PM = 1200, 12am = 0 etc.
If we are asked to convert 2359 to Eucla time (UTC +845) my program outputs 804. The correct answer is 844.
I figured out how to calculate 844, but I make no sense of it.
2359 + 845 = 3204 (adding the timezone offset 845 to the UTC time)
3204 - 60 = 3144 (minus 60 for some reason [I followed my time overflow formula]
3144 - 2400 = 2400 (minus 2400 because time cannot be more than 2359)
How my program works
First plus UTC and offset time
calculatedTime = UTC + offset;
Then under that
if (calculatedTime < 2359) {
calculatedTime = calculatedTime - 2400;
}
I also have another function which checks for overflow time underneath
if (((calculatedTime > 59) && (calculatedTime < 99)) || ((calculatedTime > 159) && (calculatedTime < 199))) {
// All the way to 2359
calculatedTime = calculatedTime - 60 + 100;
}
You need to separate the time into hours and minutes. Then add the time zone offsets to the hours and minutes separately. Handle roll-over. Finally, recombine the hours and minutes into the final answer.
Like this:
int main(void)
{
// inputs
int time = 2359;
int zone = 845;
// separate hours and minutes
int timeHours = time / 100;
int timeMinutes = time % 100;
int zoneHours = zone / 100;
int zoneMinutes = zone % 100;
// add the hours and minutes
int hours = timeHours + zoneHours;
int minutes = timeMinutes + zoneMinutes;
// handle the rollover conditions
if (minutes > 60) {
minutes -= 60;
hours++;
}
if (hours > 24) {
hours -= 24;
}
// recombine the hours and minutes
int adjustedTime = hours * 100 + minutes;
printf("%d\n", adjustedTime);
}
Note that this code only works for timezones with positive offsets. You'll need to figure out how to make it work for negative time zones.
OP's code has various off-by-one errors.
// if (((calculatedTime > 59) && (calculatedTime < 99)) ||
// ((calculatedTime > 159) && (calculatedTime < 199))) {
if (((calculatedTime > 59) && (calculatedTime < 100)) ||
((calculatedTime > 159) && (calculatedTime < 200))) {
// if (hours > 24) {
// hours -= 24;
// }
if (hours >= 24) {
hours -= 24;
}
Also code has more clarity using values like 60, 100
if (((calculatedTime >= 60) && (calculatedTime < 100)) ||
((calculatedTime >= 60*2) && (calculatedTime < 100*2))) {
Yet OP's approach fails with negative numbers.
To cope with positive and negative time values, split the "hhmm" time into a hours and minutes. Look for conditions of "minute" overflow. I recommend 2 helper functions to split and combine results.
#include <stdio.h>
#include <stdlib.h>
void hhmm_split(int hhmm, int *hour, int *min) {
*hour = hhmm / 100;
*min = hhmm % 100;
}
/* `min` may be outside the primary range of (-60 ... 60) */
int hhmm_combine(int hour, int min) {
hour += min / 60;
min %= 60;
if (hour < 0 && min > 0) {
min -= 60;
hour++;
} else if (hour > 0 && min < 0) {
min += 60;
hour--;
}
hour %= 24;
return hour * 100 + min;
}
Test code
void hhmm_add(int t1, int t2) {
int t1_hh, t1_mm, t2_hh, t2_mm;
hhmm_split(t1, &t1_hh, &t1_mm);
hhmm_split(t2, &t2_hh, &t2_mm);
int sum = hhmm_combine(t1_hh + t2_hh, t1_mm + t2_mm);
printf("t1:% 05d + t2:% 05d = sum:% 05d\n", t1, t2, sum);
}
int main(void) {
hhmm_add(2359, 845);
hhmm_add(2359, -845);
hhmm_add(-2359, 845);
hhmm_add(-2359, -845);
}
Output:
t1: 2359 + t2: 0845 = sum: 0844
t1: 2359 + t2:-0845 = sum: 1514
t1:-2359 + t2: 0845 = sum:-1514
t1:-2359 + t2:-0845 = sum:-0844

How to add time in C?

Essentially the program I've made adds time when the times are listed in the kind of military format (eg. 2300 is equal to 11pm) and then a duration is added (eg. 345, 3 hours 45 minutes.)
I've come across an issue in that when you add time to something that surpasses midnight it will continue to add past that. So for instance if you add 2 hours (200) to 11pm (2300) you will get a result of 2500 which is illogical for this purpose.
What I need my program to do is reach 2400 (midnight) and then reset to 0 but continue to add the remaining amount that needed to be added.
I've been trying to figure this out but I cannot figure out how I'm going to make it add what remains after you reset it to 0.
Since minutes are added modulo 60 and hours modulo 24, you need to handle them separately.
Something like
int add_time(int old_time, int addition)
{
/* Calculate minutes */
int total_minutes = (old_time % 100) + (addition % 100);
int new_minutes = total_minutes % 60;
/* Calculate hours, adding in the "carry hour" if it exists */
int additional_hours = addition / 100 + total_minutes / 60;
int new_hours = (old_time / 100 + additional_hours) % 24;
/* Put minutes and hours together */
return new_hours * 100 + new_minutes;
}
Break 24 hour/minute encode as a 4-digit int into hours and minutes. Avoid assuming values are in their primary range.
Add
Re-form time into the primary range.
Example
typedef struct {
int hour; // Normal range 0 - 23
int minute; // Normal range 0 - 59
} hhmm;
hhmm int_to_hhmm(int src) {
src %= 2400;
if (src < 0) src += 2400;
hhmm dest = { src / 100, src % 100 };
return dest;
}
int hhmm_to_int(hhmm src) {
src.hour += src.minute / 60;
src.minute %= 60;
if (src.minute < 0) {
src.minute += 60;
src.hour--;
}
src.hour %= 24;
if (src.hour < 0) {
src.hour += 24;
}
return src.hour * 100 + src.minute;
}
int add_mill_format_times(int t0, int t1) {
hhmm hhmm0 = int_to_hhmm(t0);
hhmm hhmm1 = int_to_hhmm(t1);
hhmm sum = { hhmm0.hour + hhmm1.hour, hhmm0.minute + hhmm1.minute };
return hhmm_to_int(sum);
}
you can do
addTime(int time1,int time2{
int first,last,addH,addM
last = func1(time1) + func2(time2);
last=last1+last2;
if(last > 60){
addH=last/60;
addM=last%60;
}
first=func2(time1)+func2(time2);
first+= addH;
last += addM;
first/=24;
return first*100 + addM;
}
func2(int time){
int i;
for(i=0;i<2;i++)
time/=10;
return time;
}
func1(int time){
int l=time%10;
time/=10;
int m=time%10;
return m*10 + l;
}

Simplifying Rounding code C

I'm new to coding and trying to figure out how to get code to round up to the next hour. The only method I've been able to think up (i.e. the only method I've been taught) is to just make else if statements for every hour. Clearly this isn't efficient at all and i know there's probably something much simpler. I was given a clue that there's a math equation involved?
Here's what i coded up so far:
#include <stdio.h>
int main()
{
//listens for value of "cost"
float cost;
printf("How much does this go-kart location charge per hour?\n");
scanf("%f", &cost);
//listens for value of "time"
float time;
printf("How many minutes can you spend there?\n");
scanf("%f", &time);
// i have to get it to round time to values of 60 (round up to next hour)
//really overcomplicated lack of knowledge workaround.txt
if (time < 60 && time > 0){
time = 1;
} else if(time > 61 && time < 70){
time = 2;
} else if(time > 71 && time < 80){
time = 3;
} else if(time > 81 && time < 90){
time = 4;
} else if(time > 91 && time < 100){
time = 5;
} else if(time > 101 && time < 160){
time = 6;
}
//etc etc
float total = cost * time;
printf("Your total will be $%f\n", total);
return 0;
}
For non regular intervals, one could do something like
int times[] = { 60; 70; 80; 90; 100; 160; INT_MAX }; // INT_MAX is to avoid segfault for bad input
int facts[] = { 1; 2; 3; 4; 5; 6; -1 }; // -1 is value for bad input
int it = 0;
while(times[it] < time) ++it;
int result = facts[it];
Note that you code doesnt have valid results for time = 60, 70, etc ... you should check the wanted behaviour
int hour = time/60;
if(60*hour < time)
++hour;
This is fairly basic math.
time / 60 would round down to to give you the hour.
Therefore (time / 60) + 1 rounds up.
If the maximum is 6 hours then simply check:
hour = time/60 + 1;
if (hour > 6) hour = 6;
Of course I'm assuming that time is an int. If it's a float then you can use floor or ceil to round up or down:
hour = floor(time/60 +1);
or
hour = ceil(time/60);
I think this is not bad
time = (time % 60) ? time / 60 + 1 : time / 60

Arduino Due C Timer Coding (Interrupt Counting)

I have an Arduino Due that I'm doing a lot of really neat stuff with in one section of code I'm handeling a flowsensor and getting readings from it. the flowsensor is hooked up to an interrupt as it is a hallsensor device. The problem I'm having is that my math is based off of a single seconds worth of collection data, when I turn on the interrupt and sleep for a second do the calculations for flowrate in gp/m it works great. For My purposes however I can't afford to pause and collect data, so instead I calculate a change in time of greater than a thousand milliseconds. then I take the amount of time passed since the last loop, devide it by 1000 milliseconds or 1 second then I have the percentage of 1 second stored in a variable, I multiply the count by the percentage and should arrive at the number of counts per second. This however results in an ever growing number regardless of the fact that I zero the numbers prior to the next loop. Below I've included the way I formatted the expressions and the loop code for the flowsensor, I'd post the whole code but I don't want to waste space on stackoverflow and I know that portion of code already works with the sleep method.
long currentMillis = 0;
long lastMillis = 0;
int checkMillis = 0;
volatile int NbTopsFan; //measuring the rising edges of the signal
int newNbTopsFan;
float realNbTopsFan;
float realMillis;
float Calc;
float Calcd;
int Calcf;
int hallsensor = 7;
void loop()
{
if (lastMillis = 0) {
lastMillis = millis();
}
currentMillis = millis();
checkMillis = (currentMillis - lastMillis);
if (checkMillis >= 1000) {
realMillis = (checkMillis / 1000);
realNbTopsFan = (NbTopsFan * realMillis);
newNbTopsFan = realNbTopsFan;
Calc = (newNbTopsFan * 60 / 7.5); //(Pulse frequency x 60) / 7.5Q, = flow rate
Calc = (Calc / 60);
Calc = (Calc / 3.78541);
Calc = (Calc * 1.47);
Calcd = (Calc * 100);
Calcf = Calcd;
NbTopsFan = 0;
lastMillis = 0;
checkMillis = 0;
realMillis = 0;
realNbTopsFan = 0;
newNbTopsFan = 0;
}
}
Your first line should read:
if ( lastMillis == 0 ) {
lastMillis = millis();
}
You need the double = to evaluate the variable

Dynamic C, How to add 2 "hours" as 4 digit Integer

I need to know how can I add 2 "hours" as integer?
It is 24-h format
int add2Hours(int _time1,int _time2)
{
}
sample: 13:45 is: (hhmm) 1345
1345 + 30 returns 1415
Your time is in hhmm format, separate the hh and mm part. Then add the parts separately.
int add2hours(int _time1, int _time2)
{
int hh1, hh2, mm1, mm2;
int rHH,rMM, res;
hh1 = _time1/100;
hh2 = _time2/100;
mm1 = _time1 % 100;
mm2 = _time2 % 100;
rMM = mm1 + mm2;
rHH = rMM/60;
rMM = rMM % 60;
rHH = rHH + hh1 + hh2;
res = rHH*100 + rMM;
return res;
}
NOTE: This will not handle any time greater than 24hrs. e.g. if the inputs are 2345 and 30, the output will be 2415 instead of 15(0015). You have to handle it if you need.
If the function for adding time is declared as follows,
int add2Hours(int _time1,int _time2);
and the syntax of passing time is as follows,
hhmm (For example 2230)
Then you can add the times as follow,
temp1= _time1;
temp2= _time2;
m1 = temp1 % 100;
m2 = temp2 % 100;
h1 = temp1 / 100;
h2 = temp2 / 100;
m3 = m1 + m2;
m3 > 59 ? m3=m3%60, h3=1 : h3=0;
h3 = h1 + h2 + h3;
h3 > 23 ? h3=h3%24, d=1 : d=0; /* If more than 23 hours */
printf("\nThe time is %d-%d-%d",d,h3,m3);
First convert the time to a common domain(sec/millisec...). Then add and make the result to the required format.
How about this?
int add2Hours(int _time1,int _time2)
{
int minutes = (_time1%100 + _time2%100)
int time = (((minutes/60)+(_time1/100 + _time2/100))%24)*100 + minutes%60;
return time;
}
Add the hours together. 13 + 0.
Get the minutes of each time by subtracting the time with the time/100*100. Note that integer arithmetic in C truncates. Example:
m = time - (time/100*100)
m = 1345 - (1345/100*100)
m = 1345 - (13*100)
m = 1345 - 1300
m = 45
Add the minutes together. 45 + 30 = 75.
Add "the minute sum/60" hours to the result. I.e. 75/60 = 1.
Then add "the minute sum modulo 60" minutes to the same result. I.e. 75%60 = 15.
Thanks guys... here is my function!
int Add2Times (int _time1, int _time2)
{
int hour = _time1 / 100 + _time2 / 100;
int min = _time1 % 100 + _time2 % 100;
hour += min / 60;
min = min % 60;
hour = hour % 24;
return hour * 100 + min;
}

Resources