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

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.

Related

handling when a button is pressed

I have the current code, and ive tried to add in a toggle_speed() function, this will be called in the main function in an if statement of, else if (button_pushed() == 2). What im trying to accomplished is that when the button is pressed it doubles the speed, but if it is pushed again the speed will go back to normal. This is the code I have, all help is appreciated, im quite new to this. We are programming this onto AVR working with ATmega324A. Basically, I need help in constructing a valid toggle_speed function as what ive done is most certai
You basically want something like this:
volatile uint32_t background_speed, alien_speed, projectile_speed;
...
void toggle_speed(void){
static int doublespeedactive;
doublespeedactive = !doublespeedactive;
if (doublespeedactive)
{
background_speed = 600;
alien_speed = 400;
projectile_speed = 300;
}
else
{
background_speed = 600 / 2;
alien_speed = 400 / 2;
projectile_speed = 300 / 2;
}
}
doublespeedactive is a state variable. If it's 1, then double speed is active, if it's 0, then normal speed is active.
doublespeedactive = !doublespeedactive; toggles the value of doublespeedactive from 1 to 0 or from 0 to 1.
Read about the ! operator.
However you don't call toggle_speed anywhere in the code you show in your question, so this answer is possibly incomplete.
Be aware that the volatile keyword is necessary if you intend to call toogle_speed from an ISR.

How do I correctly create a copy of an array in C or set a reference to one?

so, I'm very new to C, coming from a Java/C# background and I can't quite wrap my head around it so far.
What I'm trying to do is program a microcontroller (Adafruit Feather running an atmega32u4 in this case) to pose as a USB-coupled controller for Nintendo Switch and run automated commands.
The project I'm trying to expand upon is using a struct array of commands like this:
typedef struct {
Buttons_t button;
uint16_t duration; // 1 equals 0.025s on ATmega32u4 => 1s = 40
} command;
static const command loop[] = {
// do stuff
{ NOTHING, 150 },
{ TRIGGERS, 15 }, { NOTHING, 150 },
{ TRIGGERS, 15 }, { NOTHING, 150 },
{ A, 5 }, { NOTHING, 250 }
};
Now initially this was all there was to it, the program would loop through the commands, send a button to the console and "hold" it for the defined period of time. When the program ran to the end of the array, it would simply reset the index and start anew.
Now I'm trying to send different commands to the console, based on a few easy if..else queries. Specifically, the program will start with a day, month and year variable (the date the Switch console is currently set to) and roll days forward individually to get to a set date in the future. To this end, I want to check at every 'step' if the date +1 day is valid as described in this tutorial and based on the result either roll one day, one day and one month or one day, one month and one year forward. Then I want it to end after a set amount of days.
I wrote several arrays of commands to represent the different steps needed for setting up the controller, moving to where it's supposed to loop, rolling a day, a month or a year like this:
static const command setupController[] = {
// Setup controller
...
};
static const command moveToLoop[] = {
// Go into date settings
...
};
static const command rollDay[] = {
//roll to next day
...
};
static const command rollMonth[] = {
//roll to next month
...
};
static const command rollYear[] = {
//roll to next year
...
};
And another array I want to copy those to like this:
#define COMMANDMAXSIZE 100
static command activeCommand[COMMANDMAXSIZE];
I know this is (extremely) wasteful of memory, but I'm definitely not good enough at C to come up with fancier, more conservative solutions yet.
Then I go into my program, which looks like this:
int main(void) {
SetupHardware(); //Irrelevant, because it is exactly like I downloaded it and it works even with the bumbling changes I've made
GlobalInterruptEnable(); //Ditto
RunOnce(setupController);
RunOnce(moveToLoop);
while (daysSkipped != stopDay)
{
if (datevalid((dayOfMonth + 1), month, year)) {
dayOfMonth++;
RunOnce(rollDay);
}
else if (datevalid(1, (month + 1), year)) {
dayOfMonth = 1;
month++;
RunOnce(rollMonth);
}
else if (datevalid(1, 1, (year + 1))) {
dayOfMonth = 1;
month = 1;
year++;
RunOnce(rollYear);
}
daysSkipped++;
}
}
and finally (I swear I'll be done soon), the start of RunOnce looks like this
void RunOnce(command stepsToRun[]) {
memcpy(activeCommand, stepsToRun, sizeof(activeCommand)); //set the setup commands to be active
activeBounds = sizeof(stepsToRun) / sizeof(stepsToRun[0]);
...
Later in the program, the task that translates commands into button presses for the console actually runs one fixed array, so I figured I'd just "mark" the commands to run as active, and only ever run the active array. Only, it doesn't work as expected:
The program runs, sets up the controller, moves to the date settings and indeed starts to roll a date, but then, regardless if the next day is valid or not, it rolls forward a month, then a year and then it gets stuck moving the simulated analog stick upwards and pressing A indefinitely.
I figure the problem lies in my memcpy to overwrite the active array with the steps I want to run next, but I can't think of a way to solve it. I tried writing a function that was supposed to overwrite the active array element by element using a for loop, but this way the controller wouldn't even set itself up correctly and effectively nothing happened. Usually with any kind of output capabilities I'd try to fit in prints at points of interest, but I have virtually no way of getting feedback on my microcontroller.
Any help would be greatly appreciated.
Ignoring that doing a hard copy of the data is incredibly slow and wasteful, it is also incorrect indeed.
memcpy(activeCommand, stepsToRun, sizeof(activeCommand));
Here you need to copy the size of the data you pass on, not the size of the target buffer! Right now you end up copying more data than you have, because all of these declarations static const command rollDay[] etc get a variable size depending on the number of items in the initializer list.
The quick & dirty fix to your immediate problem would be to pass along the size:
void RunOnce(size_t size, command stepsToRun[size])
{
memcpy(activeCommand, stepsToRun, size);
and then call this function with RunOnce(sizeof rollDay, rollDay); etc.
The activeBounds = sizeof(stepsToRun) / sizeof(stepsToRun[0]); part is also incorrect but not the immediate reason for the bug. See How to find the 'sizeof' (a pointer pointing to an array)? and What is array to pointer decay? etc.
When you pass array to function it decays to a pointer.
RunOnce(rollYear);
Thus
void RunOnce(command stepsToRun[]) {
memcpy(activeCommand, stepsToRun, sizeof(activeCommand)); //set the setup commands to be active
activeBounds = sizeof(stepsToRun) / sizeof(stepsToRun[0]);
}
sizeof(stepsToRun) doesn't yield the correct result as you expected, since it is now sizeof(pointer) in function.
You will have to pass the size of the array as an extra argument to RunOnce function.

Not getting proper time duration in 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);
}

Low Pass filter in C

I'm implementing a low pass filter in C wih the PortAudio library.
I record my microphone input with a script from PortAudio itself. There I added the following code:
float cutoff = 4000.0;
float filter(float cutofFreq){
float RC = 1.0/(cutofFreq * 2 * M_PI);
float dt = 1.0/SAMPLE_RATE;
float alpha = dt/(RC+dt);
return alpha;
}
float filteredArray[numSamples];
filteredArray[0] = data.recordedSamples[0];
for(i=1; i<numSamples; i++){
if(i%SAMPLE_RATE == 0){
cutoff = cutoff - 400;
}
data.recordedSamples[i] = data.recordedSamples[i-1] + (filter(cutoff)*(data.recordedSamples[i] - data.recordedSamples[i-1]));
}
When I run this script for 5 seconds it works. But when I try to run this for more then 5 seconds it fails. The application records everything, but crashes on playback. If I remove the filter, the application works.
Any advice?
The problem:
you are lowering the cutoff frequency by 400 Hz everytime i%SAMPLE_RATE == 0
never stop so you go below zero
this is not done once per second !!!
instead every time your for passes through second barrier in your data
that can occur more often then you think if you are not calling your calls in the right place
which is not seen in your code
you are filtering in wrong oorder
... a[i]=f(a[i],a[i-1]; i++;
that means you are filtering with already filtered a[i-1] value
What to do with it
check the code placement
it should be in some event like on packed done sompling
or in thread after some Sleep(...); (or inside timer)
change the cut off changing (handle edge cases)
reverse filter for direction
Something like this:
int i_done=0;
void on_some_timer()
{
cutoff-=400;
if (cutoff<1) cutoff=1; // here change 1 for limit frequency
if (numSamples!=i_done)
for (i=numSamples-1,i>=i_done;i--)
data.recordedSamples[i] = data.recordedSamples[i-1] + (filter(cutoff)*(data.recordedSamples[i] - data.recordedSamples[i-1]));
i_done=numSamples;
}
if your code is already OK (you did not post th whole thing so I can missing something)
then just add the if (cutoff<1) cutoff=1; after cutoff change

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