Not getting proper time duration in C - c

Let's consider a multi-sports race event like a triathlon. In this event when a person completes one activity (running, swimming, cycling etc) they immediately start a new activity after it. Suppose I have a device that continuously monitors the activity of the person. If you see the code, in "main()" function the volatile variable "activity" gets input from the device.
The race was started 2 Hr before.
My aim is to find out from how long till the current moment the person is in that particular activity. Say from past 1000 seconds the person is in running activity and earlier he/she was doing "cycling" (this could be anything in the general case). Also, the point is that the end time of previous activity is the start time current activity.
The "triathlonTim()" function is called after every 1 sec continuously. When I calculate time as per my code, it's coming out to be 1 sec but actually it should be 1000 seconds. Here, time(NULL) and "stateTim" are updating continuously. "StateTim" variable must only be updated at the point when the person stops one activity and start other activity. So how do I fix it out? Any other idea or hint can also be useful to me.
#include<stdio.h>
#include<time.h>
#define CYCLING 1
#define RUNNING 2
#define SWIMMING 3
static int state ;
static int prevState ;
int stateTim;
void triathlonTim(int activity)
{
int activtyTimDur ;
if(activity == 10)
{
printf("doing Cycling\n\r");
state = CYCLING;
}
else if(activity == 20)
{
printf("doing Running\n\r");
state = RUNNING;
}
else if(activity == 30)
{
printf("doing Swimming\n\r");
state = SWIMMING;
}
if(prevState != state)
{
activtyTimDur = time(NULL) - stateTim;
stateTim =time(NULL);
printf("Activity Time Duration = %d\n\r", activtyTimDur);
}
}
int main(void)
{
volatile int activity;
while(1)
{
triathlonTim(activity);
sleep(1);
}
return 0;
}

You need to set prevState whenever the state changes. Otherwise, every call will be treated as a state change.
if(prevState != state)
{
activtyTimDur = time(NULL) - stateTim;
stateTim =time(NULL);
prevState = state;
printf("Activity Time Duration = %d\n\r", activtyTimDur);
}

Related

How to make code run every X seconds in C programming language

I am trying to make a code run repeatedly every X seconds.
Let me paint a wrestling scenario.
I have already written a code line to give Tyson fury a 5Kg punch at 40 seconds into the fight and then stop.. but there's no way I'm going to win the match with just one 5kg punch at 40 seconds. I need to be able to keep punching every 40 seconds.
Please who knows how I can achieve this?
PS.
{
real punch;
real time = CURRENT_TIME;
real tau = 40;
if (time<=tau)
{
punch=5;
}
else
{
punch=0;
}
return punch;
}
In a scenario where time acquisition is possible, as I can see you use
CURRENT_TIME
You can do it like this:
static int lastTimeExecuted = 0; // Using int here, but you should mach type of CURRENT_TIME
// See how much time passed since last execution
if ((CURRENT_TIME - lastTimeExecuted) >= 40)
{
punch = 5;
lastTimeExecuted = CURRENT_TIME ;
}
else
{
punch = 0;
}
Just remember that code abowe shuld be in a loop.

How do I fix this code that minuses one life from the snake in the snake game?

Hi I am trying to solve this code, but I need help. I want the snake to loose one life every time it hits itself or the wall. It has 3 lives. Here is my code so far:
#include <stdio.h>
int main(void) {
printf("You will have life functions. You will get 3 lifes.\n");
char life [3];
int aa;
printf("You have 3 lifes");
printf("Press 'S' to start");
scanf("%i",&aa);
bool PlayerDied( PlayerData * pd )
{
bool alive = false;
--pd->Lives; // player died - one less life
return pd->Lives <= 0;
alive = true; // player still has a life left
return alive;
}
return 0;
}
So I seem to be not believing in no side-effects here. I would write this:
bool PlayerDied( PlayerData * pd )
{
return (--pd->Lives) > 0;
}
Decrement pd->lives then return whether or not any lives remain.
Thre's kind of this habit in C of doing something and returning a status as the function's return value. You'll find it all over the standard APIs for various OSes.
Your mistake was having a return with more code after it. If the return is reached (and since it's unconditional it will be reached), nothing past the ; of the return statement ever runs.

C Program Push button counts continuously when pushed for a long time

It counts from 0 to 3 only. Adds 1 when down is pressed and subtracts 1 when up is pressed. The problem is when i hold it, it counts continuously. I want it to count only once even if i hold the push button for a long time. I'm using ATMEL SAM3X microcontroller if that helps. And that the push buttons are logic 0.
#include "..\ASF\common\services\gpio\sam_gpio\sam_gpio.h"
#include "delay.h"
#include "sam3x_ek.h"
#include "Press_Counter.h"
signed int UP_DOWN;
signed int LEFT_RIGHT;
void Press_Counter()
{
unsigned int Button_State;
Button_State=1;
if(UP) //if UP is pressed
{
delay_ms(50);
if(Button_State==1)
{
UP_DOWN--; //decrement
if (UP_DOWN<0)
{
UP_DOWN=0; // To ensure that the minimum value is 0
}
}
Button_State=0;
}
else if(DOWN) //if DOWN is pressed
{
delay_ms(50);
if(Button_State==1)
{
UP_DOWN++; //increment
if (UP_DOWN>3)
{
UP_DOWN=3; // To ensure that the maximum value is 3
}
}
Button_State=0;
}
else
{
Button_State=1;
}
count_UP_DOWN=UP_DOWN; // Get the value of counter cause imma use it later
}
You would have to change the values of your program when you release the button, since you don't really wan't the button to change the value while you're pressing it.
So you'll have to remember the state of the button in the following manner:
delay_ms(50);
If(Button_pressed==1){
if(previous_state==1){
//Do nothing
}
else {
UP_DOWN++;
previous_state = 1;
If(UP_DOWN > 3){
//Do your counter setting stuff here
}
}
else {
previous_state = 0
}
This should work; put it within the two if-clauses if(UP) and if(DOWN) and adjust accordingly.
Hope this helps :-)
only modify the count on state transitions of the button
rather than counting every time the code checks the state of the button.
so add a variable to remember the last state of the button.
(do not put this button on the local stack
as the prior state will be lost/forgotten each time
the press_counter() function is exited.
suggest placing the remembered state variable
in file global address space.)

how to stop a loop arduino

I have this loop, how would I end the loop?
void loop() {
// read the pushbutton input pin:
a ++;
Serial.println(a);
analogWrite(speakerOut, NULL);
if(a > 50 && a < 300){
analogWrite(speakerOut, 200);
}
if(a <= 49){
analogWrite(speakerOut, NULL);
}
if(a >= 300 && a <= 2499){
analogWrite(speakerOut, NULL);
}
This isn't published on Arduino.cc but you can in fact exit from the loop routine with a simple exit(0);
This will compile on pretty much any board you have in your board list. I'm using IDE 1.0.6. I've tested it with Uno, Mega, Micro Pro and even the Adafruit Trinket
void loop() {
// All of your code here
/* Note you should clean up any of your I/O here as on exit,
all 'ON'outputs remain HIGH */
// Exit the loop
exit(0); //The 0 is required to prevent compile error.
}
I use this in projects where I wire in a button to the reset pin. Basically your loop runs until exit(0); and then just persists in the last state. I've made some robots for my kids, and each time the press a button (reset) the code starts from the start of the loop() function.
Arduino specifically provides absolutely no way to exit their loop function, as exhibited by the code that actually runs it:
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
Besides, on a microcontroller there isn't anything to exit to in the first place.
The closest you can do is to just halt the processor. That will stop processing until it's reset.
Matti Virkkunen said it right, there's no "decent" way of stopping the loop. Nonetheless, by looking at your code and making several assumptions, I imagine you're trying to output a signal with a given frequency, but you want to be able to stop it.
If that's the case, there are several solutions:
If you want to generate the signal with the input of a button you could do the following
int speakerOut = A0;
int buttonPin = 13;
void setup() {
pinMode(speakerOut, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
}
int a = 0;
void loop() {
if(digitalRead(buttonPin) == LOW) {
a ++;
Serial.println(a);
analogWrite(speakerOut, NULL);
if(a > 50 && a < 300) {
analogWrite(speakerOut, 200);
}
if(a <= 49) {
analogWrite(speakerOut, NULL);
}
if(a >= 300 && a <= 2499) {
analogWrite(speakerOut, NULL);
}
}
}
In this case we're using a button pin as an INPUT_PULLUP. You can read the Arduino reference for more information about this topic, but in a nutshell this configuration sets an internal pullup resistor, this way you can just have your button connected to ground, with no need of external resistors.
Note: This will invert the levels of the button, LOW will be pressed and HIGH will be released.
The other option would be using one of the built-ins hardware timers to get a function called periodically with interruptions. I won't go in depth be here's a great description of what it is and how to use it.
The three options that come to mind:
1st) End void loop() with while(1)... or equally as good... while(true)
void loop(){
//the code you want to run once here,
//e.g., If (blah == blah)...etc.
while(1) //last line of main loop
}
This option runs your code once and then kicks the Ard into
an endless "invisible" loop. Perhaps not the nicest way to
go, but as far as outside appearances, it gets the job done.
The Ard will continue to draw current while it spins itself in
an endless circle... perhaps one could set up a sort of timer
function that puts the Ard to sleep after so many seconds,
minutes, etc., of looping... just a thought... there are certainly
various sleep libraries out there... see
e.g., Monk, Programming Arduino: Next Steps, pgs., 85-100
for further discussion of such.
2nd) Create a "stop main loop" function with a conditional control
structure that makes its initial test fail on a second pass.
This often requires declaring a global variable and having the
"stop main loop" function toggle the value of the variable
upon termination. E.g.,
boolean stop_it = false; //global variable
void setup(){
Serial.begin(9600);
//blah...
}
boolean stop_main_loop(){ //fancy stop main loop function
if(stop_it == false){ //which it will be the first time through
Serial.println("This should print once.");
//then do some more blah....you can locate all the
// code you want to run once here....eventually end by
//toggling the "stop_it" variable ...
}
stop_it = true; //...like this
return stop_it; //then send this newly updated "stop_it" value
// outside the function
}
void loop{
stop_it = stop_main_loop(); //and finally catch that updated
//value and store it in the global stop_it
//variable, effectively
//halting the loop ...
}
Granted, this might not be especially pretty, but it also works.
It kicks the Ard into another endless "invisible" loop, but this
time it's a case of repeatedly checking the if(stop_it == false) condition in stop_main_loop()
which of course fails to pass every time after the first time through.
3rd) One could once again use a global variable but use a simple if (test == blah){} structure instead of a fancy "stop main loop" function.
boolean start = true; //global variable
void setup(){
Serial.begin(9600);
}
void loop(){
if(start == true){ //which it will be the first time through
Serial.println("This should print once.");
//the code you want to run once here,
//e.g., more If (blah == blah)...etc.
}
start = false; //toggle value of global "start" variable
//Next time around, the if test is sure to fail.
}
There are certainly other ways to "stop" that pesky endless main loop
but these three as well as those already mentioned should get you started.
This will turn off interrupts and put the CPU into (permanent until reset/power toggled) sleep:
cli();
sleep_enable();
sleep_cpu();
See also http://arduino.land/FAQ/content/7/47/en/how-to-stop-an-arduino-sketch.html, for more details.
just use this line to exit function:
return;

How to set an int to 1 if dependent on a button and in a while loop?

I'm programming a robot, and unfortunately in its autonomous mode I'm having some issues.
I need to set an integer to 1 when a button is pressed, but in order for the program to recognize the button, it must be in a while loop. As you can imagine, the program ends up in an infinite loop and the integer values end up somewhere near 4,000.
task autonomous()
{
while(true)
{
if(SensorValue[positionSelectButton] == 1)
{
positionSelect = positionSelect + 1;
wait1Msec(0350);
}
}
}
I've managed to get the value by using a wait, but I do NOT want to do this. Is there any other way I can approach this?
assuming that the SensorValue comes from a physical component that is asynchronous to the while loop, and is a push button (i.e. not a toggle button)
task autonomous()
{
while(true)
{
// check whether
if(current_time >= next_detect_time && SensorValue[positionSelectButton] == 1)
{
positionSelect = positionSelect + 1;
// no waiting here
next_detect_time = current_time + 0350;
}
// carry on to other tasks
if(enemy_is_near)
{
fight();
}
// current_time
current_time = built_in_now()
}
}
Get the current time either by some built-in function or incrementing an integer and wrap around once reach max value.
Or if you are in another situation:
task autonomous()
{
while(true)
{
// check whether the flag allows incrementing
if(should_detect && SensorValue[positionSelectButton] == 1)
{
positionSelect = positionSelect + 1;
// no waiting here
should_detect = false;
}
// carry on to other tasks
if(enemy_is_near)
{
if(fight() == LOSING)
should_detect = true;
}
}
}
Try remembering the current position of the button, and only take action when its state changes from off to on.
Depending on the hardware, you might also get a signal as though it flipped back and forth several times in a millisecond. If that's an issue, you might want to also store the timestamp of the last time the button was activated, and then ignore repeat events during a short window after that.
You could connect the button to an interrupt and then make the necessary change in the interrupt handler.
This might not be the best approach, but it will be the simplest.
From The Vex Robotics catalogue :
(12) Fast digital I/O ports which can be used as interrupts
So, most probably which ever micro-controller of Vex you are using will support Interrupts.
Your question is a bit vague
I m not sure why u need this variable to increment and how things exactly work...but i ll make a try.Explain a bit more how things work for the robot to move...and we will be able to help more.
task autonomous()
{
int buttonPressed=0;
while(true)
{
if(SensorValue[positionSelectButton] == 1)
{
positionSelect = positionSelect +1;
buttonPressed=1;
}
else{
buttonPressed = 0;
}
//use your variables here
if( buttonPressed == 1){
//Move robot front a little
}
}
}
The general idea is :
First you detect all buttons pressed and then you do things according to them
All these go in your while loop...that will(and should) run forever(at least as long as your robot is alive :) )
Hope this helps!

Resources