Help pulling data out of a seperate void function and turning it into variables.

Hello all, I am currently working with the NewPing library, and using the example to interface multiple sensors seems to work fine, however I need to do some extra math, not just display the individual output distance, and I don’t know how to.

// ---------------------------------------------------------------------------
// This example code was used to successfully communicate with 15 ultrasonic sensors. You can adjust
// the number of sensors in your project by changing SONAR_NUM and the number of NewPing objects in the
// "sonar" array. You also need to change the pins for each sensor for the NewPing objects. Each sensor
// is pinged at 33ms intervals. So, one cycle of all sensors takes 495ms (33 * 15 = 495ms). The results
// are sent to the "oneSensorCycle" function which currently just displays the distance data. Your project
// would normally process the sensor results in this function (for example, decide if a robot needs to
// turn and call the turn function). Keep in mind this example is event-driven. Your complete sketch needs
// to be written so there's no "delay" commands and the loop() cycles at faster than a 33ms rate. If other
// processes take longer than 33ms, you'll need to increase PING_INTERVAL so it doesn't get behind.
// ---------------------------------------------------------------------------
#include <NewPing.h>

#define SONAR_NUM     2 // Number or sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 500 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).

unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM];         // Where the ping distances are stored.
uint8_t currentSensor = 0;          // Keeps track of which sensor is active.

NewPing sonar[SONAR_NUM] = {     // Sensor object array.
  NewPing(2, 8, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
  NewPing(3, 9, MAX_DISTANCE)
};

void setup() {
  Serial.begin(115200);
  pingTimer[0] = millis() + 75;           // First ping starts at 75ms, gives time for the Arduino to chill before starting.
  for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
    pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
}

void loop() {
  for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
    if (millis() >= pingTimer[i]) {         // Is it this sensor's time to ping?
      pingTimer[i] += PING_INTERVAL * SONAR_NUM;  // Set next time this sensor will be pinged.
      if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
      sonar[currentSensor].timer_stop();          // Make sure previous timer is canceled before starting a new ping (insurance).
      currentSensor = i;                          // Sensor being accessed.
      cm[currentSensor] = 0;                      // Make distance zero in case there's no ping echo for this sensor.
      sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
    }
  }
  // The rest of your code would go here.
}

void echoCheck() { // If ping received, set the sensor distance to array.
  if (sonar[currentSensor].check_timer())
    cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
}

void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
  for (uint8_t i = 0; i < SONAR_NUM; i++) {
    Serial.print(i);
    Serial.print("=");
    Serial.print(cm[i]);
    Serial.print("cm ");
  }
  Serial.println();
}

The part at the bottom, void oneSensorCycle is where I would get the information I need, specifically the “cm” value, however, I am not sure how I would be able to pull that out and in the end, display it on an LCD. I have the basic outline of the part of the script to do it but since it prints the value from each ultrasonic sensor at the same time I don’t know how to use that information. Here’s what I will be doing with it.

int distance = (cm1 + cm - sizeofbox); <sizeofbox is just to take the distance between the sensors out of the final distance.
Convert it to meters/feet, I’ll figure that out later
lcd.setcursor(0, 0);
lcd.print("Distance = ")’
lcd.print(distance);

So, how would I go about doing this? I figure it needs a new void operation, or maybe if it is easy to get that information into their own variables I can just do it in the regular loop.

Your question is not that clear and your code does not seem to be complete.

All the distance values are stored in an array called cm. so cm[0] is the first, cm[1] is the second, etc. The cm array declared with global scope which is ok given your intended use.

marco_c:
Your question is not that clear and your code does not seem to be complete.

All the distance values are stored in an array called cm. so cm[0] is the first, cm[1] is the second, etc. The cm array declared with global scope which is ok given your intended use.

The thing is, the CM value changes quickly from the first ultrasonic to the second, the cm value is only used for the serial output, it displays the first cm value then the second on the same line very quickly. I’m not sure how I would be able to take it’s value and assign it to it’s own variable for the regular loop. If I just used the cm value I would not be able to tell which sensor it is for.

The thing is, the CM value changes quickly from the first ultrasonic to the second

I still don’t get what the problem is, sorry. I am not sure what you mean by an ‘ultrasonic’. do mean a reading or a sensor?

How many sensors do you have?

If this is the code you are using, what exactly are you trying to do in loop()? Whatever it is, just write the code - at least we will have a starting point.

marco_c:

The thing is, the CM value changes quickly from the first ultrasonic to the second

I still don’t get what the problem is, sorry. I am not sure what you mean by an ‘ultrasonic’. do mean a reading or a sensor?

How many sensors do you have?

If this is the code you are using, what exactly are you trying to do in loop()? Whatever it is, just write the code - at least we will have a starting point.

This script reads two ultrasonic sensors, and outputs them in the serial output like so “0 = 5cm 1 = 15cm” or whatever the value is.

This part of the script is what does that and what has the cm value.

void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
  for (uint8_t i = 0; i < SONAR_NUM; i++) {
    Serial.print(i);
    Serial.print("=");
    Serial.print(cm[i]);
    Serial.print("cm ");
  }
  Serial.println();
}

The problem is that it prints them out of the same line, so the value changes quickly. That makes it difficult to get the cm value for just one sensor, or to be sure it is one specific one.

I need a way to take the cm value for the individual sensors into their own separate variables so I can do whatever else I need with them, but the fact that it changes very quickly means that I don’t know how i can get the cm value for just one or the other because there is no delay in the void sensorloop before printing the cm value to the serial output

      sonar[currentSensor].timer_stop();          // Make sure previous timer is canceled before starting a new ping (insurance).
      currentSensor = i;                          // Sensor being accessed.
      cm[currentSensor] = 0;                      // Make distance zero in case there's no ping echo for this sensor.

Just before you set cm[currentSensor] back to 0 would be the time to use (print, text, copy, whatever) the data for the current sensor. Comment out the call to oneSensorCycle, and print the value of currentSensor and the value of cm[currentSensor].

XOIIO:
This script reads two ultrasonic sensors, and outputs them in the serial output like so “0 = 5cm 1 = 15cm” or whatever the value is.

This part of the script is what does that and what has the cm value.

The problem is that it prints them out of the same line, so the value changes quickly. That makes it difficult to get the cm value for just one sensor, or to be sure it is one specific one.

No. This part of the ‘script’ does not HAVE the cm value. It is the part of the program (or sketch, or code), that GETS the cm value that has been saved, and sends it out on the Serial port. The part of the code that has the cm value is the array called cm, which is declared globally (meaning that it’s declared outside any function).

So, if you don’t want to have the values printed out that way, DON’T CALL THAT FUNCTION.

If you want to do something else with those values, make a function to use them in whatever way you want to use them.

The cm array will have those values right after this loop:

  for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
    if (millis() >= pingTimer[i]) {         // Is it this sensor's time to ping?
      pingTimer[i] += PING_INTERVAL * SONAR_NUM;  // Set next time this sensor will be pinged.
      if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
      sonar[currentSensor].timer_stop();          // Make sure previous timer is canceled before starting a new ping (insurance).
      currentSensor = i;                          // Sensor being accessed.
      cm[currentSensor] = 0;                      // Make distance zero in case there's no ping echo for this sensor.
      sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
    }

I need a way to take the cm value for the individual sensors into their own separate variables so I can do whatever else I need with them, but the fact that it changes very quickly means that I don’t know how i can get the cm value for just one or the other because there is no delay in the void sensorloop before printing the cm value to the serial output

You already have those values in separate variables. After the loop I mentioned above, the first sensor’s cm value is in cm[0], and the second sensor’s cm value is in cm[1]. So right after the loop, use them. It’s just that simple.

If you don’t want the pings to be done that quickly, don’t call the routine that quickly.

From what I see of this thread and the previous one, you REALLY need to do some studying on writing C++ code (or even C code, which will be accepted by a C++ compiler).