Stop arduino loop when a condition is active - c++

I need my code to stop in the loop, i have tried to put in a break but the method sendToGCM() continues. I only want the method to be executed once, the stop while the condition
void loop()
{
// Other code here giving temp a value
if (temp > 22)
{
status = false;
value["status"] = status;
while (temp > 22)
{
sendToGCM(); // Sends push notification
break;
}
}
else
{
status = true;
value["status"] = status;
}
}

So if I understood you correctly, if the temperature goes 22 degrees you want to send a message, but only the first time. If you break the loop, you still enter it if you the loop() function is executed again.
In order to achieve what you want to do, you code will need to look something like this
boolean message_sent;
void loop() {
...
if(temperature > 22 && !message_sent) {
sendToGCM();
message_sent = true;
}
}
If you want to send a message every time the temperature rises over 22 degrees you would need something like this
boolean message_sent;
boolean was_under_22;
void setup() {
...
was_under_22 = function_that_checks_if_temp_is_under_22();
...
}
void loop() {
...
if(temperature > 22 && was_under_22) {
if(!message_sent) {
sendToGCM();
message_sent = true;
was_under_22 = false;
}
} else {
was_under_22 = true;
message_sent = false;
}
}
EDIT: slightly adapted the code in response to Patrick Trentin's comment. The code assumes you only want to capture if the temperature rises above 22 degrees and that if the Arduino starts with over 22 degrees then no message is sent.

Your problem is that you are setting temp, then entering the loop that checks that value. A simple solution would be to update the temp value inside the while loop, to give the application a chance to break out of the while loop.
Example:
void loop()
{
// Other code here giving temp a value
if (temp > 22)
{
status = false;
value["status"] = status;
while (temp > 22)
{
sendToGCM(); // Sends push notification
//Additional code to set the value of temp, allowing the value to
//be greater than 22.
}
}
else
{
status = true;
value["status"] = status;
}
}
Please note that the above example is intended to continuously send the push notification while the temp value is over 22. If that's not the intention, just remove the sendToGCM() from the while loop. You will still only send it if the temp is greater than 22, since you have the if check.

Related

Global variable doesn't update prior to next loop

I'm trying to build a tachometer in C++ for my ESP32. When I uncomment Serial.printf("outside rev: %d \n", rev); outside of the conditional it works, but when I comment it I get values that are orders of magnitude greater than they should be (700 revolutions without, vs 7 revolutions with). My best guess is that the print statement is slowing the loop() down just enough for incrementRevolutions() to toggle the global variable passedMagnet from true to false before the next loop. That would make sense, since a delay in updating passedMagnet would allow newRevCount++; to be triggered multiple times. But this is obviously something I can't debug with either print statements or step-through debugging given the time-sensitive nature of the race condition.
bool passedMagnet = true;
int incrementRevolutions(int runningRevCount, bool passingMagnet)
{
// Serial.printf("passedMagnet: %d , passingMagnet %d , runningRevCount: %d \n", passedMagnet, passingMagnet, runningRevCount);
int newRevCount = runningRevCount;
if (passedMagnet && passingMagnet)
{ //Started a new pass of the magnet
passedMagnet = false;
newRevCount++;
}
else if (!passedMagnet && !passingMagnet)
{ //The new pass of the magnet is complete
passedMagnet = true;
}
return newRevCount;
}
unsigned long elapsedTime = 0;
unsigned long intervalTime = 0;
int rev = 0;
void loop()
{
intervalTime = millis() - elapsedTime;
rev = incrementRevolutions(rev, digitalRead(digitalPin));
// Serial.printf("outside rev: %d \n", rev);
if (intervalTime > 1000)
{
Serial.printf("rev: %d \n", rev);
rev = 0;
elapsedTime = millis();
}
}
Is this a known gotcha with Arduino or C++ programming? What should I do to fix it?
I think the test is to blame. I had to rename and move things a bit to visualize the logic, sorry about that.
bool magStateOld = false; // initialize to digitalRead(digitalPin) in setup()
int incrementRevolutions(int runningRevCount, bool magState)
{
int newRevCount = runningRevCount;
// detect positive edge.
if (magState && !magStateOld) // <- was eq. to if (magState && magStateOld)
// the large counts came from here.
{
newRevCount++;
}
magStateOld = magState; // record last state unconditionally
return newRevCount;
}
You could also write it as...
int incrementRevolutions(int n, bool magState)
{
n += (magState && !magStateOld);
magStateOld = magState;
return n;
}
But the most economical (and fastest) way of doing what you want would be:
bool magStateOld;
inline bool positiveEdge(bool state, bool& oldState)
{
bool result = (state && !oldState);
oldState = state;
return result;
}
void setup()
{
// ...
magStateOld = digitalRead(digitalPin);
}
void loop()
{
// ...
rev += (int)positiveEdge(digitalRead(digitalPin), magStateOld);
// ...
}
It's reusable, and saves both stack space and unnecessary assignments.
If you cannot get clean transitions from your sensor (noise on positive and negative edges, you'll need to debounce the signal a bit, using a timer.
Example:
constexpr byte debounce_delay = 50; // ms, you may want to play with
// this value, smaller is better.
// but must be high enough to
// avoid issues on expected
// RPM range.
// 50 ms is on the high side.
byte debounce_timestamp; // byte is large enough for delays
// up to 255ms.
// ...
void loop()
{
// ...
byte now = (byte)millis();
if (now - debounce_timestamp >= debounce_delay)
{
debounce_timestamp = now;
rev += (int)positiveEdge(digitalRead(digitalPin), magStateOld);
}
// ...
}

My game of Snake crashes when you eat an apple, and the apple spawns inside your body after picking a new position (C++, SDL)

I thought I'd attempt to make Snake since it is a pretty easy game to make. I was having an issue where the apple would spawn inside the snakes body, and so I came up with a way to prevent that from happening:
void getRandomApplePos() {
// variable that tells the while loop whether the moving of the apple was successful
bool success;
// variable that is set to false if the apple is inside the snakes body
bool appleNotInside;
// Tells the collision to stop testing for collision until the apple has successfully moved
bool appleHasMoved;
// sets the variables
success = false;
appleNotInside = false;
appleHasMoved = false;
// while the apple spawns inside the snake, it keeps generating new positions
while (!success) {
// random seed
srand((unsigned int)time(NULL));
// gets a random position
int randomX = rand() % 769;
int randomY = rand() % 673;
// resets the two variables if this while loop as ran again
apple.delta_pos_x = 0;
apple.delta_pos_y = 0;
// checks to see if the apple has spawned in the same exact position
while (apple.delta_pos_x == 0 && apple.delta_pos_y == 0) {
// gets the previous poition of the apple
apple.prevPos_x = apple.x;
apple.prevPos_y = apple.y;
// picks a new apple position
apple.x = round((randomX) / 32) * 32;
apple.y = round((randomY) / 32) * 32;
// gets the new apple position
apple.currentPos_x = apple.x;
apple.currentPos_y = apple.y;
// sets the difference between the positions, if it's 0, then it has spawned in the same exact location
apple.delta_pos_x = (float)(apple.currentPos_x - apple.prevPos_x);
apple.delta_pos_y = (float)(apple.currentPos_y - apple.prevPos_y);
}
// checks to see if the snake length is only one, as to make the list not go out of index
if (snake.bodyLength == 1) {
// if the apple happens to spawn inside the snake with a length of 1, it will add false to the appleInSnake vector, else it adds true
if (apple.x == snakeBody[0][0] && apple.y == snakeBody[0][1]) {
appleNotInside = false;
appleInSnake.push_back(appleNotInside);
}
else {
appleNotInside = true;
appleInSnake.push_back(appleNotInside);
}
}
else {
// if the apple happens to spawn inside the currently compared snakeBodyPosition, it will add false to the appleInSnake vector, else it adds true
for (int i = 0; i < snakeBody.size(); i++) {
if (apple.x == snakeBody[i][0] && apple.y == snakeBody[i][1]){
appleNotInside = false;
appleInSnake.push_back(appleNotInside);
}
else {
appleNotInside = true;
appleInSnake.push_back(appleNotInside);
}
}
}
// if false appears inside the appleInSnake vector at all, it sets success to false and goes through the loop again. Else it breaks out.
if (std::find(appleInSnake.begin(), appleInSnake.end(), false) != appleInSnake.end()) {
success = false;
}
else {
success = true;
}
//clears appleInSnake so that it can take in a new comparision
appleInSnake.clear();
}
// tells the collision to start back up again
appleHasMoved = true;
}
So, whenever the apple does end up spawning inside of the snakes body, it crashes, just outright. I suspect some kind of infinite loop, but I can't put my finger on why this happens.
You are initializing your random number generator within your loop.
Note that the RNG is deterministic. It means that you will end up drawing the same numbers all over again as in the previous loop.
Initialize the RNG once at the start of your program. This way, the numbers drawn may be expected to be different within every loop.
You might wonder, that the crude use of time() should prevent this. A typical implementation of time() will have the granularity of seconds. So you would only expect the return value to change once a second, hence, you get the same initialization over and over again in your loop.

How to get a input that continuously gives data to output a single digit integer value

To give a short summary of my project, it’s a smart parking system where I let a parking user know whether a parking lot is vacant or not. I’m implementing an XBee network containing 1 coordinator and 2 routers. I have two sensors, 1 sensor at the exit and 1 at the entrance. Those two sensors are the routers and whatever data they gather is being transmitted to the coordinator (output). The two routers have the same code which is:
INPUT CODE (TRANSMITTING):
#include<SoftwareSerial.h>
#define Sensor 8
void setup() {
pinMode(Sensor,INPUT);
Serial.begin(9600);
}
void loop()
{
bool Detection = digitalRead(Sensor);
int carexit=1;
if(Detection == HIGH)
{
Serial.println("Car Exit");
Serial.write(carexit);
}
if(Detection == LOW)
{
Serial.println("Clear");
}
}
It’s a very simple code where it detects a car coming in or out. Since the two routers are the same we’ll use the sensor for the cars exiting. When I open the serial monitor, the word “Clear” will keep on being outputted continuously nonstop until detection is found which will show an output of “Car Exit” for about 3 seconds and then return to “Clear” continuously. This data is being transmitted to the coordinator. What I’m trying to do is take that continuous data and have the serial monitor at the coordinator input a single integer value. For example, at the entrance, the sensor will sense the car and transmit the data to the coordinator where it'll increment. The result will show something like this if there’s only 1 vacant slot available:
Vacant slots: 1
and when the car exits the router at the exit, it will transmit a code to the coordinator decrementing it:
Vacant slots: 0
So, the input(router) would be transmitting continuous data while the output(transmitter) will detect it and just register it for a single-digit value. The output code(receiving) by the way is shown below:
OUTPUT CODE(RECEIVING):
#include "SoftwareSerial.h"
// RX: Arduino pin 2, XBee pin DOUT. TX: Arduino pin 3, XBee pin DIN
void setup()
{
Serial.begin(9600);
}
void loop()
{
if (Serial.available() > 0)
{
Serial.write(Serial.read());
}
}
The output code is pretty simple as well. Let me know if there’s any possible way to implement what I’m trying to do and if there are any other details I left out, let me know as well.
Thank you!
This is a very common problem, best solved at the source, in your sensor transmit code.
//...
bool PreviousDetection = false;
void loop()
{
bool Detection = digitalRead(Sensor);
// do not do anything when state hasn't changed.
if (Detection != PreviousDetection)
{
if (Detection)
Serial.println("Car Exit");
else
Serial.println("Clear");
}
PreviousDetection = Detection;
}
You may want to add some debouncing to reduce the risk of false readings.
//...
// Debounce thresholds the number depends on the frequency of readings,
// speeed of cars, sensitivity and placement of your sensor...
// Dirt, sun exposure, etc... may influence readings in the long term.
const int LowDebounceThreshold = 3;
const int HighDebounceThreshold = 3;
bool PreviousDetection = false;
int DebounceCounter = 0;
bool DebouncedPreviousDetection = false;
void loop()
{
bool Detection = digitalRead(Sensor);
//
if (Detection == PreviousDetection)
++DebounceCounter; // this will rollover, but will not affect
// DebouncedDetection in any meaningfull way.
else
DebounceCounter = 0;
PreviousDetection = Detection;
bool DebouncedDetection = PreviousDebouncedDetection;
if (Detection && DebounceCounter >= HighDebounceThreshold)
DebouncedDetection = true;
else if (!Detection && DebounceCounter >= LowDebounceThreshold)
DebouncedDetection = false;
if (DebouncedDetection != PreviousDebouncedDetection)
{
PreviousDebouncedDetection = DebouncedDetection;
if (DebouncedDetection)
Serial.println("Car Exit");
else
Serial.println("Clear");
}
}

Arduino can't get my boolean to work

I cant get my boolean to work I don't know what I'm doing wrong with it. Could anyone take a look at the code and give me a hint on what is wrong with it? I have tested different ways to write it but without success. The only time the boolean worked was when I put the code under void loop. But I can't use it there.
#include <RemoteReceiver.h>
boolean statusLed1 = false;
void setup() {
Serial.begin(115200);
// Initialize receiver on interrupt 0 (= digital pin 2), calls the callback "showCode"
// after 3 identical codes have been received in a row. (thus, keep the button pressed
// for a moment)
//
// See the interrupt-parameter of attachInterrupt for possible values (and pins)
// to connect the receiver.
RemoteReceiver::init(0, 3, showCode);
}
void loop() {
}
// Callback function is called only when a valid code is received.
void showCode(unsigned long receivedCode, unsigned int period) {
// Note: interrupts are disabled. You can re-enable them if needed.
// Print the received code.
Serial.print("Code: ");
Serial.print(receivedCode);
Serial.print(", period duration: ");
Serial.print(period);
Serial.println("us.");
if (receivedCode == 353805)
{
statusLed1 = true;
}
if (receivedCode == 352829)
{
statusLed1 = false;
}
if (statusLed1 = true) {
Serial.print("on");
}
if (statusLed1 = false){
Serial.print("off");
}
}
if (statusLed1 = true) {
Oldest gotcha in the book. = is assignment, == is equality comparison.
Also, don't compare against a boolean like this regardless.
if (statusLed1) {
change
if (statusLed1 = true) {
Serial.print("on");
}
if (statusLed1 = false){
Serial.print("off");
}
}
to
if (statusLed1 == true) {
Serial.print("on");
}
if (statusLed1 == false){
Serial.print("off");
}
}
or
if (statusLed1) {
Serial.print("on");
}
if (!statusLed1){
Serial.print("off");
}
}

strange segmentation fault during function return

I am running a program on 2 different machines. On one it works fine without issue. On the other it results in a segmentation fault. Through debugging, I have figured out where the fault occurs, but I can't figure out a logical reason for it to happen.
In one function I have the following code:
pass_particles(particle_grid, particle_properties, input_data, coll_eros_track, collision_number_part, world, grid_rank_lookup, grid_locations);
cout<<"done passing particles"<<endl;
The function pass_particles looks like:
void pass_particles(map<int,map<int,Particle> > & particle_grid, std::vector<Particle_props> & particle_properties, User_input& input_data, data_tracking & coll_eros_track, vector<int> & collision_number_part, mpi::communicator & world, std::map<int,int> & grid_rank_lookup, map<int,std::vector<double> > & grid_locations)
{
//cout<<"east-west"<<endl;
//east-west exchange (x direction)
map<int, vector<Particle> > particles_to_be_sent_east;
map<int, vector<Particle> > particles_to_be_sent_west;
vector<Particle> particles_received_east;
vector<Particle> particles_received_west;
int counter_x_sent=0;
int counter_x_received=0;
for(grid_iter=particle_grid.begin();grid_iter!=particle_grid.end();grid_iter++)
{
map<int,Particle>::iterator part_iter;
for (part_iter=grid_iter->second.begin();part_iter!=grid_iter->second.end();)
{
if (particle_properties[part_iter->second.global_part_num()].particle_in_box()[grid_iter->first])
{
//decide if a particle has left the box...need to consider whether particle was already outside the box
if ((part_iter->second.position().x()<(grid_locations[grid_iter->first][0]) && part_iter->second.position().x()>(grid_locations[grid_iter->first-input_data.z_numboxes()][0]))
|| (input_data.periodic_walls_x() && (grid_iter->first-floor(grid_iter->first/(input_data.xz_numboxes()))*input_data.xz_numboxes()<input_data.z_numboxes()) && (part_iter->second.position().x()>(grid_locations[input_data.total_boxes()-1][0]))))
{
particles_to_be_sent_west[grid_iter->first].push_back(part_iter->second);
particle_properties[particle_grid[grid_iter->first][part_iter->first].global_part_num()].particle_in_box()[grid_iter->first]=false;
counter_sent++;
counter_x_sent++;
}
else if ((part_iter->second.position().x()>(grid_locations[grid_iter->first][1]) && part_iter->second.position().x()<(grid_locations[grid_iter->first+input_data.z_numboxes()][1]))
|| (input_data.periodic_walls_x() && (grid_iter->first-floor(grid_iter->first/(input_data.xz_numboxes()))*input_data.xz_numboxes())>input_data.xz_numboxes()-input_data.z_numboxes()-1) && (part_iter->second.position().x()<(grid_locations[0][1])))
{
particles_to_be_sent_east[grid_iter->first].push_back(part_iter->second);
particle_properties[particle_grid[grid_iter->first][part_iter->first].global_part_num()].particle_in_box()[grid_iter->first]=false;
counter_sent++;
counter_x_sent++;
}
//select particles in overlap areas to send to neighboring cells
else if ((part_iter->second.position().x()>(grid_locations[grid_iter->first][0]) && part_iter->second.position().x()<(grid_locations[grid_iter->first][0]+input_data.diam_large())))
{
particles_to_be_sent_west[grid_iter->first].push_back(part_iter->second);
counter_sent++;
counter_x_sent++;
}
else if ((part_iter->second.position().x()<(grid_locations[grid_iter->first][1]) && part_iter->second.position().x()>(grid_locations[grid_iter->first][1]-input_data.diam_large())))
{
particles_to_be_sent_east[grid_iter->first].push_back(part_iter->second);
counter_sent++;
counter_x_sent++;
}
++part_iter;
}
else if (particles_received_current[grid_iter->first].find(part_iter->first)!=particles_received_current[grid_iter->first].end())
{
if ((part_iter->second.position().x()>(grid_locations[grid_iter->first][0]) && part_iter->second.position().x()<(grid_locations[grid_iter->first][0]+input_data.diam_large())))
{
particles_to_be_sent_west[grid_iter->first].push_back(part_iter->second);
counter_sent++;
counter_x_sent++;
}
else if ((part_iter->second.position().x()<(grid_locations[grid_iter->first][1]) && part_iter->second.position().x()>(grid_locations[grid_iter->first][1]-input_data.diam_large())))
{
particles_to_be_sent_east[grid_iter->first].push_back(part_iter->second);
counter_sent++;
counter_x_sent++;
}
part_iter++;
}
else
{
particle_grid[grid_iter->first].erase(part_iter++);
counter_removed++;
}
}
}
world.barrier();
mpi::request reqs_x_send[particles_to_be_sent_west.size()+particles_to_be_sent_east.size()];
vector<multimap<int,int> > box_sent_x_info;
box_sent_x_info.resize(world.size());
vector<multimap<int,int> > box_received_x_info;
box_received_x_info.resize(world.size());
int counter_x_reqs=0;
//send particles
for(grid_iter_vec=particles_to_be_sent_west.begin();grid_iter_vec!=particles_to_be_sent_west.end();grid_iter_vec++)
{
if (grid_iter_vec->second.size()!=0)
{
//send a particle. 50 will be "west" tag
if (input_data.periodic_walls_x() && (grid_iter_vec->first-floor(grid_iter_vec->first/(input_data.xz_numboxes()))*input_data.xz_numboxes()<input_data.z_numboxes()))
{
reqs_x_send[counter_x_reqs++]=world.isend(grid_rank_lookup[grid_iter_vec->first + input_data.z_numboxes()*(input_data.x_numboxes()-1)], grid_iter_vec->first + input_data.z_numboxes()*(input_data.x_numboxes()-1), particles_to_be_sent_west[grid_iter_vec->first]);
box_sent_x_info[grid_rank_lookup[grid_iter_vec->first + input_data.z_numboxes()*(input_data.x_numboxes()-1)]].insert(pair<int,int>(world.rank(), grid_iter_vec->first + input_data.z_numboxes()*(input_data.x_numboxes()-1)));
}
else if (!(grid_iter_vec->first-floor(grid_iter_vec->first/(input_data.xz_numboxes()))*input_data.xz_numboxes()<input_data.z_numboxes()))
{
reqs_x_send[counter_x_reqs++]=world.isend(grid_rank_lookup[grid_iter_vec->first - input_data.z_numboxes()], grid_iter_vec->first - input_data.z_numboxes(), particles_to_be_sent_west[grid_iter_vec->first]);
box_sent_x_info[grid_rank_lookup[grid_iter_vec->first - input_data.z_numboxes()]].insert(pair<int,int>(world.rank(),grid_iter_vec->first - input_data.z_numboxes()));
}
}
}
for(grid_iter_vec=particles_to_be_sent_east.begin();grid_iter_vec!=particles_to_be_sent_east.end();grid_iter_vec++)
{
if (grid_iter_vec->second.size()!=0)
{
//send a particle. 60 will be "east" tag
if (input_data.periodic_walls_x() && (grid_iter_vec->first-floor(grid_iter_vec->first/(input_data.xz_numboxes())*input_data.xz_numboxes())>input_data.xz_numboxes()-input_data.z_numboxes()-1))
{
reqs_x_send[counter_x_reqs++]=world.isend(grid_rank_lookup[grid_iter_vec->first - input_data.z_numboxes()*(input_data.x_numboxes()-1)], 2000000000-(grid_iter_vec->first - input_data.z_numboxes()*(input_data.x_numboxes()-1)), particles_to_be_sent_east[grid_iter_vec->first]);
box_sent_x_info[grid_rank_lookup[grid_iter_vec->first - input_data.z_numboxes()*(input_data.x_numboxes()-1)]].insert(pair<int,int>(world.rank(),2000000000-(grid_iter_vec->first - input_data.z_numboxes()*(input_data.x_numboxes()-1))));
}
else if (!(grid_iter_vec->first-floor(grid_iter_vec->first/(input_data.xz_numboxes())*input_data.xz_numboxes())>input_data.xz_numboxes()-input_data.z_numboxes()-1))
{
reqs_x_send[counter_x_reqs++]=world.isend(grid_rank_lookup[grid_iter_vec->first + input_data.z_numboxes()], 2000000000-(grid_iter_vec->first + input_data.z_numboxes()), particles_to_be_sent_east[grid_iter_vec->first]);
box_sent_x_info[grid_rank_lookup[grid_iter_vec->first + input_data.z_numboxes()]].insert(pair<int,int>(world.rank(), 2000000000-(grid_iter_vec->first + input_data.z_numboxes())));
}
}
}
counter=0;
for (int i=0;i<world.size();i++)
{
//if (world.rank()!=i)
//{
reqs[counter++]=world.isend(i,1000000000,box_sent_x_info[i]);
reqs[counter++]=world.irecv(i,1000000000,box_received_x_info[i]);
//}
}
mpi::wait_all(reqs, reqs + world.size()*2);
//receive particles
//receive west particles
for (int j=0;j<world.size();j++)
{
multimap<int,int>::iterator received_info_iter;
for (received_info_iter=box_received_x_info[j].begin();received_info_iter!=box_received_x_info[j].end();received_info_iter++)
{
//receive the message
if (received_info_iter->second<1000000000)
{
//receive the message
world.recv(received_info_iter->first,received_info_iter->second,particles_received_west);
//loop through all the received particles and add them to the particle_grid for this processor
for (unsigned int i=0;i<particles_received_west.size();i++)
{
particle_grid[received_info_iter->second].insert(pair<int,Particle>(particles_received_west[i].global_part_num(),particles_received_west[i]));
if(particles_received_west[i].position().x()>grid_locations[received_info_iter->second][0] && particles_received_west[i].position().x()<grid_locations[received_info_iter->second][1])
{
particle_properties[particles_received_west[i].global_part_num()].particle_in_box()[received_info_iter->second]=true;
}
counter_received++;
counter_x_received++;
}
}
else
{
//receive the message
world.recv(received_info_iter->first,received_info_iter->second,particles_received_east);
//loop through all the received particles and add them to the particle_grid for this processor
for (unsigned int i=0;i<particles_received_east.size();i++)
{
particle_grid[2000000000-received_info_iter->second].insert(pair<int,Particle>(particles_received_east[i].global_part_num(),particles_received_east[i]));
if(particles_received_east[i].position().x()>grid_locations[2000000000-received_info_iter->second][0] && particles_received_east[i].position().x()<grid_locations[2000000000-received_info_iter->second][1])
{
particle_properties[particles_received_east[i].global_part_num()].particle_in_box()[2000000000-received_info_iter->second]=true;
}
counter_received++;
counter_x_received++;
}
}
}
}
mpi::wait_all(reqs_y_send, reqs_y_send + particles_to_be_sent_bottom.size()+particles_to_be_sent_top.size());
mpi::wait_all(reqs_z_send, reqs_z_send + particles_to_be_sent_south.size()+particles_to_be_sent_north.size());
mpi::wait_all(reqs_x_send, reqs_x_send + particles_to_be_sent_west.size()+particles_to_be_sent_east.size());
cout<<"x sent "<<counter_x_sent<<" and received "<<counter_x_received<<" from rank "<<world.rank()<<endl;
cout<<"rank "<<world.rank()<<" sent "<<counter_sent<<" and received "<<counter_received<<" and removed "<<counter_removed<<endl;
cout<<"done passing"<<endl;
}
I only posted some of the code (so ignore the fact that some variables may appear to be undefined, as they are in a portion of the code I didn't post)
When I run the code (on the machine in which it fails), I get done passing but not done passing particles
I am lost as to what could possibly cause a segmentation fault between the end of the called function and the next line in the calling function and why it would happen on one machine and not another.
If you're crashing between the end of a function and the subsequent line in the caller, you're probably crashing in the destructor of a local variable. You need to run the program in a debugger to find out which object's destructor is crashing.
There are a couple of possibilities:
You actually are returning, but cout is buffered by the OS so you don't see "done passing particles" because the application crashes first.
You have some local class that has a destructor that is seg faulting.
Try running it in a debugger to find out where it is actually crashing.
Edit:
Since you've mentioned you're using gcc, add the -g flag and run it with gdb. Gdb will then tell you exactly where it's going wrong (probably a null dereference).
Just in case anyone comes back to this later. I updated to the newest version of boost mpi(at the time), 1.50 and this issue went away. Not much of a solution, but it worked.