I have a vital infinite for loop that allows a sensor to keep updating its values. However I would like to break that for loop when another sensor brings in new values. How can I switch from one infinite for loop to another?
Current code:
for(;;){
SON_Start();
// Wait 65ms for max range time
delay10ms(7);
// Read Range
i = SON_Read(SON_ADDRESSES[sonarReading]);
// pause
delayMs(100);
if(i<15)
drive(200, RadCW);
}
What I would like to add:
If Sensor2 returns a reading (e.g. Sensor2 > 20), then I want to break the loop and goto another infinite for loop to begin a new function.
If you are looking for "switching between 2 infinite loops" it could be "wrapped" by third loop and this "switching" could be done by simple break.
But since you want your program to stop some day, this loop could be placed within the function and you could use return; for ending it:
void myMagicLoop()
{
for(;;)
{
for(;;)
{
if ( I should stop )
return;
if ( I should switch to second loop )
break;
}
for(;;)
{
if ( I should stop )
return;
if ( I should switch back to first loop)
break;
}
}
}
And somewhere you just call:
myMagicLoop();
Hope this helps.
This will switch between loop A and loop B.
for (;;)
{
// Loop A
for (;;)
{
if WANT_TO_SWITCH
{
break;
}
}
// Loop B
for (;;)
{
if WANT_TO_SWITCH
{
break;
}
}
}
You use break; to break a loop and pass control beyond its closing brace. For example
for(;;) {
if( whatever ) {
break;
}
}
//break gets you here
Alternatively you could consider rewriting this with an event-driven approach. This will of course depend on what your hardware is capable of, but at the very least you should be able to produce some timer events.
Then the code would go something like this:
static volatile bool sensor_1_ready;
static volatile bool sensor_2_ready;
for(;;)
{
switch(state_machine)
{
case READING_SENSOR_1:
if(sensor_2_ready)
{
state_machine = READING_SENSOR_2;
}
else if(sensor_1_ready)
{
process sensor 1
}
break;
case READING_SENSOR_2:
if(!sensor_2_ready && some_timeout_etc)
{
state_machine = READING_SENSOR_1;
}
else if(sensor_2_ready)
{
process sensor 2
}
break;
}
}
void callback_sensor_1 (void) // some sort of interrupt or callback function
{
sensor_1_ready = true;
}
void callback_sensor_2 (void) // some sort of interrupt or callback function
{
sensor_2_ready = true;
}
(Before commenting on the volatile variables, please note that volatile is there to prevent dangerous compiler optimizations and not to serve as some mutex guard/atomic access/memory barrier etc.)
The "break" command should do what you need?
The best way to do that is to change the for statement to something like:
for (; Sensor2 <= 20;) {
...
Alternatively you can change it from a for to a while statement:
while (Sensor2 <= 20) {
...
If that doesn't suite your needs you can always use a break instead.
Another option could be to use signals (SIGUSR1,SIGUSR2) to switch from one loop to another.
Something of this sort:
void sensor2(int signum)
{
for (; ;)
...
/* Need to process sensor 1 now */
kill(pid, SIGUSR1);
}
void sensor1(int signum)
{
for (; ;)
...
/* Need to process sensor 2 now */
kill(pid, SIGUSR2);
}
int main()
{
/* register the signal handlers */
signal(SIGUSR1, sensor1);
signal(SIGUSR2, sensor2);
...
}
Related
To simplify the problem as much as possible, I have two functions, a parent that calls the child. Everything executes okay till it gets to the return of the child function. After that I get a Bus Error.
int main () {
game();
// this doesn't get executed and program fails with bus error
printf("Execute 2");
return 1;
}
int game () {
game_t GameInfo = {.level = 1, .score = 0, .playerCh = 0, .playerX = 1, .playerY = 1};
gameLevel(&GameInfo);
mvprintw(1,1, "Executed");
// code works up to here and get's executed properly
return 1;
};
void gameLevel (game_t *GameInfo) {
// determine the size of the game field
int cellCols = COLS / 3;
int cellRows = (LINES / 3) - 2;
GameInfo -> playerX = 1;
GameInfo -> playerY = 1;
generateMaze(0);
int solved = 0;
int level = GameInfo -> level;
// default player position
getPlayerDefault(GameInfo);
pthread_t enemies_th;
pthread_create(&enemies_th, NULL, enemies, (void *)GameInfo);
// enemies(&level);
while (solved == 0 && GameInfo -> collision != 1) {
printGameInfo(GameInfo);
noecho();
char move = getch();
echo();
if (GameInfo -> collision != 1) {
if (checkMoveValidity(move, GameInfo) == 1) {
solved = movePlayer(move, GameInfo);
if (solved == 1) {
break;
}
}
} else {
break;
}
}
if (solved == 1) {
pthread_cancel(enemies_th);
GameInfo->level++;
gameLevel(GameInfo);
} else {
// game over
pthread_cancel(enemies_th);
return;
}
}
Now, the code is much more complicated than here, but I think that shouldn't have any influence on this (?) as it executes properly, until the return statement. There is also ncurses and multithreading, quite complex custom structures, but it all works, up until that point. Any ideas ?
Tried putting print statements after each segment of code, everything worked up until this.
pthread_cancel() doesn't terminate the requested thread immediately. The only way to know that a cancelled thread has terminated is to call pthread_join(). If the thread is left running, it will interfere with use of the GameInfo variable in the next level of the game if the current level is solved, or may use the GameInfo variable beyond its lifetime if the current level was not solved and the main thread returns back to the main() function.
To make sure the old enemies thread has terminated, add calls to pthread_join() to the gameLevel() function as shown below:
if (solved == 1) {
pthread_cancel(enemies_th);
pthread_join(enemies_th);
GameInfo->level++;
gameLevel(GameInfo);
} else {
// game over
pthread_cancel(enemies_th);
pthread_join(enemies_th);
return;
}
The use of tail recursion in gameLevel() seems unnecessary. I recommend returning the solved value and letting the game() function start the next level:
In game():
while (gameLevel(&GameInfo)) {
GameInfo.level++;
}
In gameLevel():
int gameLevel(game_t *GameInfo) {
/* ... */
pthread_cancel(enemies_th);
pthread_join(enemies_th);
return solved;
}
I'm in a pickle regarding concepts relating to timers. How can I can I operate a "delay" inside a timer? This is the best way I can frame the question knowing full well what I'm trying to do is nonsense. The objective is: I wish to test the pinState condition 2 times (once initially and then 4 seconds later) but this all needs to happen periodically (hence a timer).
The platform is NodeMCU running a WiFi (ESP8266 chip) and coding done inside Arduino IDE.
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
BlynkTimer timer;
char auth[] = "x"; //Auth code sent via Email
char ssid[] = "x"; //Wifi name
char pass[] = "x"; //Wifi Password
int flag=0;
void notifyOnFire()
{
int pinState = digitalRead(D1);
if (pinState==0 && flag==0) {
delay(4000);
int pinStateAgain = digitalRead(D1);
if (pinStateAgain==0) {
Serial.println("Alarm has gone off");
Blynk.notify("House Alarm!!!");
flag=1;
}
}
else if (pinState==1)
{
flag=0;
}
}
void setup()
{
Serial.begin(9600);
Blynk.begin(auth, ssid, pass);
pinMode(D1,INPUT_PULLUP);
timer.setInterval(1000L,notifyOnFire);
}
void loop()
{
//Serial.println(WiFi.localIP());
Blynk.run();
timer.run();
}
an easy fix would be to set the periodicity of the timer to be 4000L timer.setInterval(4000L,notifyOnFire); and in notifyOnFire use a static variable and toggle its value whenever notifyOnFire is called
void notifyOnFire()
{
static char state = 0;
if( state == 0)
{
/* Write here the code you need to be executed before the 4 sec delay */
state = 1;
}
else
{
/* Write here the code you need to be executed after the 4 sec delay */
state = 0;
}
}
The nice thing about static variables is that they are initialized only once at compile time and they retain their values after the scope of code changes (In this case function notifyOnFire exits).
I want a solution for this problem than disabling interrupts while if condition being executed. I'm working on pic16f877a. and want very simple and basic solution.
static int counter=0;
void main()
{
while(1)
{
if(counter)
{
counter--;
//code
}
}
InterruptSerial()
{
counter++;
//code
}
To execute counter--; it is translated into
load counter value
decrement loaded value
assign new value in counter register
If an interrupt happened while executing this code before reaching the assign instruction this will result in wrong behavior.
Normal solution will be
void main()
{
while(1)
{
if(counter)
{
disableInterrupts();
counter--;
//code
enableInterrupts();
}
}
How to solve this without disabling interrupts ?
Details:
I am implementing Peterson's Algorithm(below) to avoid race condition. The way I want to do it, is to declare a global integer variable, and create threads one and two. Whenever the thread one had access to the global variable it should print a and add one to the global variable counter. When the thread two have access to this global variable it should print b and add one to the global variable counter. This should continue until the global variable reaches a certain number(let's say 10). After that I want the thread(which ever of the two threads that makes the last addition to the global variable) to reset the global variable to 1 and both threads should exit. The code that I have implemented so far kinda does the job,it avoids race condition, but I can't exit both threads when counter reaches limit.
Question:
How can I quit both threads when the counter reaches a specific limit.
Whats the proper form of quitting a thread, right now I am using exit(), which I don't think is very efficient.
Peterson's Algorithm
boolean flag [2];
int turn;
void P0()
{
while (true) {
flag [0] = true;
turn = 1;
while (flag [1] && turn == 1) /* do nothing */;
/* critical section */;
flag [0] = false;
/* remainder */;
}
}
void P1()
{
while (true) {
flag [1] = true;
turn = 0;
while (flag [0] && turn == 0) /* do nothing */;
/* critical section */;
flag [1] = false;
/* remainder */
}
}
void main()
{
flag [0] = false;
flag [1] = false;
parbegin (P0, P1);
}
My Code:
EDIT: I realized that I have to put the if-statement, that is checking for the counter limit value, should be in the critical section(before it changes the flag to false).
#include<stdlib.h>
#include<stdio.h>
#include<pthread.h>
int counter = 0;
int flag[2];
int turn;
void *func1(void *);
void *func2(void *);
int main(int argc,char *argv[]){
pthread_t thread1,thread2;
//int rt1,rt2;
flag[0] = 0;
flag[1] = 0;
//rt1 = pthread_create(&thread1,NULL,&func1,"a");
//rt2 = pthread_create(&thread2,NULL,&func2,"c");
pthread_create(&thread1,NULL,&func1,"a");
pthread_create(&thread2,NULL,&func2,"b");
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
return 0;
}// End of main function
void *func1(void *message){
while(1){
flag[0] = 1;
turn = 1;
while(flag[1] && turn == 1);
printf("%s %d\n",(char *)message,counter);
counter++;
flag[0] = 0;
if(counter == 10){
counter = 1;
printf("exited at func1, with counter %d\n",counter);
exit(0);
}
}
return 0;
}
void *func2(void *message){
while(1){
flag[1] = 1;
turn = 0;
while(flag[0] && turn == 0);
printf("%s %d\n",(char *)message,counter);
counter++;
flag[1] = 0;
if(counter == 10){
counter = 1;
printf("exited at func2, with counter %d\n",counter);
exit(0);
}
}
return 0;
}
Obviously, when one thread resets the global counter, the other thread may never see the global counter reaching e.g.10, so it will never quit. What if you simply don't reset the global counter, and let it thread quit whenever it finds the global counter e.g. 10? If you really want to reset the counter, you do that in the parent (main) thread (which is also where you define the global counter).
As for quitting a thread, you can either simply return from the primary thread function (this will end the thread by itself), call pthread_exit from within the thread, or you can use phtread_cancel from the main function.
im trying to create something similar to "lost in migration" as a project for my finals but im having trouble with the randomization and the timer
how do i run two do while independently of each other
timer should not disappear, and must keep running until time is up, must run independently
randomization must not affect timer
bugs
imputing directional key does not display result
while (timer) once and go to the do while (randomization) and will keep looping at "randomize" and will not go back to the while (timer)
while (timer) is affected bu getch() and getche() pausing it
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<windows.h>
#include<time.h>
//******************************************//
// DEFAULT BUILT-IN CLOCK //
//******************************************//
void Wait(int seconds)
{
clock_t end wait;
endwait = clock () + seconds * CLK_TCK;
while (clock() < end wait) {}
}
//***********************************************************//
// DIRECTIONAL KEYS //
//***********************************************************//
#define LEFT 75
#define RIGHT 77
#define UP 72
#define DOWN 80
int rdtsc()
{
as m volatile("rdtsc");
}
int main()
{
char ans;
int image;
int loop=1;
int correct=0, total=0;
int sec=0, min=0;
//***********************************************************//
// TIMER //
//***********************************************************//
int x=1;
while(1==1)
{
Wait(1);
sec++;
if(sec==46)
{
loop=0;
}
printf("%i:%i\n\n", min, sec);
//***********************************************************//
// RANDOMIZED IMAGES //
//***********************************************************//
fflush(st din);
srand(rdtsc());
image=rand()%4;
do
{
if(image==0)
{
printf(">>IMAGE 1 CORRECT LEFT<<");
ans=getche();
if(ans==LEFT)
{
printf("\n\ncorrect!");
}
else
if(ans!=LEFT)
{
printf("\n\nwrong!");
}
}
else
if(image==1)
{
printf(">>IMAGE 2 CORRECT UP<<");
ans=getche();
if(ans==UP)
{
printf("\n\ncorrect!");
}
else
if(ans!=UP)
{
printf("\n\nwrong!");
}
}
else
if(image==2)
{
printf(">>IMAGE 3 CORRECT DOWN<<");
ans=getche();
if(ans==DOWN)
{
printf("\n\ncorrect!");
}
else
if(ans!=DOWN)
{
printf("\n\nwrong!");
}
}
else
if(image==3)
{
printf(">>IMAGE 4 CORRECT RIGHT<<");
ans=getche();
if(ans==RIGHT)
{
printf("\n\ncorrect!");
}
else
if(ans!=RIGHT)
{
printf("\n\nwrong!");
}
}
getch();
system("cls");
}
while(loop==1);
}
getch();
}
Create a state machine for each of the two tasks you're trying to accomplish.
Write the code to implement each state machine using a switch statement.
Place them sequentially within an outer loop.
for ( int i = 0; i < 100; i++ )
{
switch ( state1 )
{
case 0:
// do whatever you need for task 1
}
switch ( state2 )
{
case 0:
// do whatever you need for task 2
}
}