I have a function that runs every second automatically,
inside the function i have a counter "i" that increments by 1 so every 1sec. i dont want to run stuff every second but at every x seconds e.g. every 10 seconds.
so i presume the best approach is to detect the increments of i, when it increases by 13?
or a timer/sleep function to be called for the function to wait?
question: how do i detect increments i.e. how do i check if "i" goes up by 13?
void func(void){
static int i = 0;
if (every i seconds)
{
do something
}
i++;
}
Thanks for any help i get
I think you are looking for modulo operation (http://en.wikipedia.org/wiki/Modulo_operation):
void func(void){
static int i = 0;
int x = 13
if (i % x == 0)
{
do something
}
i++;
}
I am not sure I have completely understood your question.
You can try this:
void func(void){
static int i = 0;
int interval = 13;
if (i % interval == 0) /* interval can be your every second */
{
do something
}
i++;
}
Perhaps using the time() function:
#include <time.h>
const time_t intervalTime = (13);
void func(void)
{
static time_t savedTime = 0; // results in 'do something' on first execution
time_t currentTime = time(NULL);
if ( intervalTime <= (currentTime - savedTime) )
{
if( 0 == savedTime )
{ // then first time through function
savedTime = currentTime;
}
savedTime += intervalTime; // this avoids time interval drifting
do something
}
}
Your approach is legit.
Answering your question about running things every 13 seconds:
if (i > 0 && (i % 13) == 0) {
//do something
}
If you don't need to run your loop every second, then a more robust mechanism would be to use the alarm functionality available in libc: http://www.gnu.org/software/libc/manual/html_node/Setting-an-Alarm.html
Related
int rec(int k)
{
static int temp = 0, counter = 0;
if(!k) return counter;
if(k%2 == 0){
counter++;
temp = rec(k/2);
}
if(k%2){
counter++;
temp = rec(k-1);
}
}
This function is supposed to get a number k and check how many operations are needed to get k to 0 only by multiplying by 2 or by adding 1.
this function works fine but returns zero instead of the last value in the counter. I tried to debug it, and I saw the counter value increasing, but after getting to the value it is supposed to return, the function goes back to complete all the calls, and returns 0.
I fixed it by making counter global and returning nothing, but my questions are:
Is there a way to fix it as it is with the counter inside the function?
Why is this function returning zero at the end?
Here's a nice recursive function that doesn't declare any variables at all, it's purely recursive!
int get_steps_to_zero(int n)
{
// Deal with negative values
if (n < 0) n *= -1;
if (n == 0) {
// Base case: we have reached zero
return 0;
} else if (n % 2 == 0) {
// Recursive case 1: we can divide by 2
return 1 + get_steps_to_zero(n / 2);
} else {
// Recursive case 2: we can subtract by 1
return 1 + get_steps_to_zero(n - 1);
}
}
get_steps_to_zero(457);
> 13
Others have addressed the general recursion issue, yet there remains a ...
Corner case
"this function works fine" --> Not quite.
The algorithm is an infinite loop for rec(-1) as it attempts -1 --> -2 --> -1 --> -2 ...
A better approach would sometimes add 1.
if(k%2) {
counter++;
// temp = rec(k-1);
temp = rec(k + (k < 0 ? 1 : -1));
}
This also well handles non-2's complement issue.
I will try to show a new side to this discussion,
Recursion is like a chain,
This means that any function can receive a value from its child and return a value to its parent.
In your program you are trying to return a value from the last child to the first parent,
So your program must have all links in the chain receive and send value in order.
But in your code you return a value only in the last call, and all other calls do not return this value back.
Your stop condition is here:
if(!k) return counter;
Only the last call enters this scope, but other calls do not reach any return statement.
they get to here:
if(k%2 == 0){
counter++;
temp = rec(k/2);
}
if(k%2){
counter++;
temp = rec(k-1);
here there is no return statement.
your compiler will warning you like this:
"warning: control reaches end of non-void function".
but your program will compile so it return zero like all non-void functions without return.
So if you want this program to work make it like Randomblock1, or like this:
int rec(int k)
{
static int counter = 0;
if(!k){
return counter;
}
else if(k%2 == 0){
counter ++;
counter += rec(k/2);
}
else{
counter++;
counter += rec(k-1);
}
return counter;
}
But this program also do not work well, what is the reason?
The reason is because you used by static variable.
It's a little hard to explain, but you can't use this recursion with a static variable, so add a patch to this line:
static int counter = 0;
like this
int counter = 0;
I hope what I wrote will be understandable
I have a perfect running code, BUT one criteria for this homework is that it has atleast two different functions. How can i devide this code into one more functions?
I want to sort the alarmClock() function into more functions. There's alot going on in there. Maybe a updateTime() function. I tried something like this but this doesn't work:
#include <stdio.h>
void alarmClock(int, int);
void updateTime(int, int, int);
int main() {
int present_time;
int time_for_alarm;
printf("Time indicates in HHMMSS! \nPresent time: ");
scanf("%d", &present_time);
printf("Time for alarm: ");
scanf("%d", &time_for_alarm);
if (present_time == time_for_alarm)
printf("ALARM!");
else
alarmClock(present_time, time_for_alarm);
return 0;
}
void alarmClock(int presT, int alarmT) {
int presentHH = presT / 10000;
int presentMM = (presT / 100) % 100;
int presentSS = presT % 100;
int combineTime;
while (presT != alarmT) {
printf("%02d:%02d:%02d \n", presentHH, presentMM, presentSS);
presentSS++;
updateTime(presentHH, presentMM, presentSS);
combineTime = presentHH * 100 + presentMM;
presT = combineTime * 100 + presentSS;
}
printf("ALARM!");
}
void updateTime(int presentHH, int presentMM, int presentSS) {
if (presentSS > 59) {
presentSS = 0;
presentMM++;
if (presentMM > 59) {
presentMM = 0;
presentHH++;
if (presentHH > 24) {
presentHH = 1;
}
}
}
}
My teacher hinted me saying "you could make on printTime() function and one updateTime() function sending present_time as arguments". But i dont know how...
This is my working code that needs atleast one more function.
#include <stdio.h>
void alarmClock(int, int);
int main() {
int present_time;
int time_for_alarm;
printf("Time indicates in HHMMSS! \nPresent time: ");
/ scanf("%d", &present_time);
/
printf("Time for alarm: ");
scanf("%d", &time_for_alarm);
if (present_time == time_for_alarm)
printf("ALARM!");
else
alarmClock(present_time, time_for_alarm);
return 0;
}
void alarmClock(int presT, int alarmT) {
int presentHH = presT / 10000;
int presentMM = (presT / 100) % 100;
int presentSS = presT % 100;
int combineTime;
while (presT != alarmT) {
printf("%02d:%02d:%02d \n", presentHH, presentMM, presentSS);
presentSS++;
if (presentSS > 59) {
presentSS = 0;
presentMM++;
if (presentMM > 59) {
presentMM = 0;
presentHH++;
if (presentHH > 24) {
presentHH = 1;
}
}
}
combineTime = presentHH * 100 + presentMM;
presT = combineTime * 100 + presentSS;
}
printf("ALARM!");
}
The working code gives this output (correct output);
if present_time = 115957
and time_for_alarm = 120001
output is
11:59:57
11:59:58
11:59:59
12:00:00
ALARM
but when i created the updateTime() function the code keeps running forever if i have these values:
if present_time = 115957
and time_for_alarm = 120001
output is
11:59:57
11:59:58
11:59:59
11:59:60
11:59:61
11:59:62
11:59:63
... and so on and on (presentSS keeps going +=1 forever)
The variables presentHH, presentMM, and presentSS in the function updateTime are distinct from the ones in alarmClock, so changes to those variables in updateTime are not visible in the calling function.
You need to pass the address of each of these variables and dereference those pointers in updateTime. Then you're actually changing the variables defined in alarmClock.
So change the definition of updateTime to:
void updateTime(int *presentHH, int *presentMM, int *presentSS);
And call it like this:
updateTime(&presentHH, &presentMM, &presentSS);
You'll also need to change the body of updateTime to reflect that the parameters are now pointers and to dereference them. I'll leave that as an exercise to the reader.
dbush shows a good way to solve the problem with not many changes to the general structure. I would suggest a different approach to the task. Instead of passing the addresses of these values, you could restructure your code to pass the composite time and return the updated time. Similiar to this
int updateTime(int presT){
//seperate, update and combine the time value
return updatedTime;
}
this would reduce the interface and would also enable you to write even more functions that can be reused. As you now will have to seperate and combine the time in updateTimeand alarmClock you can write functions that do this instead of writing the same code twice.
example:
int getHours(int time){
return time / 10000;
}
and:
int combineTime(int hours, int minutes, int seconds){
combinedTime = (presentHH * 100 + presentMM)* 100 + presentSS;
return combinedTime;
}
This will help you get more expierience with functions and also helps to let you see one big benefit of functions (having reusable code).
I have been trying to write a code to basically add points to a score whenever I pressed a button while a certain amount of time is running down. The problem I am finding is that it doesn't detect when the button is pressed while the time is decreasing, in fact it can only detect when the time starts to decrease and then it doesn't matter at which state the button is it will continue to add to the score. Anyway here is the main code:
void loop() {
buttonState01 = digitalRead(button01);
buttonState02 = digitalRead(button02);
buttonState03 = digitalRead(button03);
if (buttonState01){
time = 3000;
while(time > 0){
if (buttonState02){
score += 10;
Serial.println(score);
}
time--;
Serial.println(time);
}
}
}
And here is the full code if needed:
int button01 = 4;
int button02 = 3;
int button03 = 2;
int buttonState01 = 0;
int buttonState02 = 0;
int buttonState03 = 0;
float time;
int score;
void setup() {
score = 0;
time = 0;
pinMode(button01, INPUT);
pinMode(button02, INPUT);
pinMode(button03, INPUT);
Serial.begin(9600);
}
void loop() {
buttonState01 = digitalRead(button01);
buttonState02 = digitalRead(button02);
buttonState03 = digitalRead(button03);
if (buttonState01){
time = 3000;
while(time > 0){
if (buttonState02){
Serial.println("Points");
}
time--;
Serial.println(time);
}
}
}
You should read the status of a button inside the while loop. Like this:
while(time > 0)
{
buttonState02 = digitalRead(button02);
if (buttonState02){
Serial.println("Points");
}
time--;
Serial.println(time);
}
And in your code, there is no logic to add points to the score.
A hardware interrupt would do exactly what you need.
Attach an interrupt routine to the pin your button is linked to, and get it to set the 'score' variable. Make sure you introduce some sort of timeout to avoid button-bounce (I.e. set LastTimeIncremented when you increase the score, and only increment score if LastTimeIncremented is more than 1 second ago)
This way the score will always be set regardless of what else the program may be doing.
Information on this can be found in the Arduino https://www.arduino.cc/en/Reference/attachInterrupt
The example on that page would do exactly what you want, just replace 'blink' with 'incrementScore' and you're pretty much done
const byte ledPin = 13;
const byte interruptPin = 2;
int score = 0;
int increment = 1;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), incScore, RISING);
}
void loop() {
digitalWrite(ledPin, state);
}
void incScore() {
score = score+increment;
// add anti-bounce functionality here
}
int die[5] = { 0 };
int roll_die(void)
{
return rand(1, 6) % 6 + 1;
}
for (index = 0; index < 5; (++index) && (i++))
{
roll_die(die, 5); //tried as &die as well, but same problem
printf("die[%d]: %d\n\n", i, die[index]);
}
prints die[1] - die[5] will 0 values instead of randomly generated integers between 1 and 6
#include <stdio.h>
int roll_die()
{
return rand() % 6 + 1;
}
int main() {
int die[5] = { 0 }, index;
for (index = 0; index < 5; (++index))
{
die[index] = roll_die();
printf("die[%d]: %d\n\n",index, die[index]);
}
return 0;
}
you used rand wrong, didnt used the returned value, and the way you called the function was wrong.
hope that helps.
p.s.
its better also to call
srand(time(NULL));
once in the start
Rollling a Dice with JShell (Java)
https://www.youtube.com/watch?v=a2CIxn0C1qo
You are calling the function that takes no parameters (void) with parameters.
I'm talking about this line right here: roll_die(die, 5);
The way you declared and defined the function roll_die is so that it just returns a random number int roll_die(void)
Whatever value this function return must be assigned to someting like #t.elazari mentioned:
die[index] = roll_die();
Here you are saying that the value of the array die in the index index (die[index]) will equal whatever roll_die() returns.
Follow his example, I'm just giving you a short explanation of why you did it wrong.
The function that he mentioned (srand(time(NULL));) goes inside the main function, anywhere as long as it is BEFORE the for loop. This function changes the seed of the rand to be the current time. If you don't do this, your rand function will return the same values always, they are random but their seed is always the same.
Have you tried to replace roll_die(die, 5); by die[index] = roll_die(die, 5); ?
The code below is part of a larger project. The intent is to flash an led with a variable on time, reset the on time and accumulate the total "on" time. The on time is changed each time the "on" period has elapsed.
Code below appears to successfully change the "on" time at the end of each "on" time period, but does not accumulate the total time.
I expected ledtime to equal LED_ON on the first pass (for example 1000) and then equal the previous ledtime + LED_ON (for example 1000 + 2538 = 3528) on the second pass etc.
Instead ledtime is always equal to the current LED_ON, so it appears ledtime is always set to zero on each pass, which I don't understand.
I'm new at arduino/C programming and suspect I'm missing something pretty simple/obvious, but have played with this for awhile with no resolution (including moving the ledtime = etc statements to various areas within the blink routine).
long ledtime;
const int LED_PIN = 13;
const int grnled = 11;
unsigned long LED_ON = 800; //milliseconds
int LED_OFF = 2000;
int redled = 10;
int yellowled = 12;
unsigned long ms; //time from millis()
unsigned long msLast;
unsigned long mslast2;//last time the LED changed state
boolean ledState; //current LED state
void setup(void)
{
pinMode(grnled, OUTPUT);
pinMode(redled,OUTPUT);
pinMode(yellowled,OUTPUT);
Serial.begin(9600);
}
void loop(void)
{
while(millis()<5000) {
digitalWrite(redled,HIGH);
digitalWrite(yellowled,LOW);
}
while (millis() >(5000) && millis()< 20000){
ms = millis();
blinkLED();
}
if (millis() > 20000 && millis() < 30000) {
digitalWrite(redled,HIGH);
}
if (millis() > 30000) {
digitalWrite(yellowled,HIGH);
digitalWrite(redled, LOW);
}
}
void blinkLED(void)
{
if (ms - msLast > (ledState ? LED_ON : LED_OFF)) {
digitalWrite(grnled, ledState = !ledState);
msLast = ms;
long ledtime = ledtime + LED_ON; //this does not work
Serial.println("ledtime = ");
Serial.println(ledtime);
if (ms-mslast2> LED_ON) {
LED_ON = random(500,5000); //this works
LED_OFF = 2000;
mslast2 = ms;
Serial.println("LED_ON = ");
Serial.println(LED_ON);
}
}
}
I'm not very sure of what you're trying to do, but with the line you commented, you create a local variable ledtime which has the same name of your global one. And because it's local to your function, it gets erased at the end of your function.
So first initialize ledtime at 0 at its declaration,
Then try to replace this line by
ledtime += LED_ON;