Error when combining two simple sketches - range sensors and photocells

Hi all

I’m trying to modify the NewPing15Sensors Code to add some simple analogRead functions for photocells connected to a0-5 on my Arduino Uno. I’ve got two sketches that work great independently, but I’m having a newbie issue trying to combine the code. I get a nice serial.Print readout of my ultrasonic range sensors from the ping sketch and I’d like to serial.Print my photocell readouts on the next line. The problem is that they need to be timed exactly the same. Any help would be greatly appreciated!!

Here is my modified code from the NewPing15Sensors sketch. It works perfectly.

#include <NewPing.h>

#define SONAR_NUM     6 // Number or sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 20 // 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, 3, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
  NewPing(4, 5, MAX_DISTANCE),
  NewPing(6, 7, MAX_DISTANCE),
  NewPing(8, 9, MAX_DISTANCE),
  NewPing(10, 11, MAX_DISTANCE),
  NewPing(12, 13, 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();
}

And here is the very simple photocell code. Also works perfectly on its own

void setup() {
  Serial.begin(115200);
}

void loop()
{
  int p1read = analogRead (A0);
  int p2read = analogRead (A1);
  int p3read = analogRead (A2);
  int p4read = analogRead (A3);
  int p5read = analogRead (A4);
  int p6read = analogRead (A5);
  
    //Photocells
Serial.print ("photo ");
Serial.print (p1read);
Serial.write(32);
Serial.print (p2read);
Serial.write(32);
Serial.print (p3read);
Serial.write(32);
Serial.print (p4read);
Serial.write(32);
Serial.print (p5read);
Serial.write(32);
Serial.print (p6read);
Serial.println("");
delay (15);
}

Help me stick these two together!!!

Here is what I’ve been attempting. It will read both the range sensors and the photocells, but I get 5 readouts of photocells for every one read of range sensors.

Here’s the code

#include <NewPing.h>

#define SONAR_NUM     6 // Number or sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 20 // 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, 3, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
  NewPing(4, 5, MAX_DISTANCE),
  NewPing(6, 7, MAX_DISTANCE),
  NewPing(8, 9, MAX_DISTANCE),
  NewPing(10, 11, MAX_DISTANCE),
  NewPing(12, 13, 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).
    }
  }
  
 //Photocells
 
int p1read = analogRead (A0);
int p2read = analogRead (A1);
int p3read = analogRead (A2);
int p4read = analogRead (A3);
int p5read = analogRead (A4);
int p6read = analogRead (A5);
   
Serial.print ("photo ");
Serial.print (p1read);
Serial.write(32);
Serial.print (p2read);
Serial.write(32);
Serial.print (p3read);
Serial.write(32);
Serial.print (p4read);
Serial.write(32);
Serial.print (p5read);
Serial.write(32);
Serial.print (p6read);
Serial.println("");
delay (20);
}


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();
}

I’m thinking it has to do with this timing, but I can’t seem to get this to control my Serial.prints on the analog sensors

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 ");
  }

I'm finding it very hard to follow the logic through your code.

It seems that a ping interrupt calls echoCheck() - is that part working?

I can't see where oneSensorCycle() is called.

I don't understand your description of the problem. In each iteration of loop() you seem to be reading 6 sonar sensors in a FOR loop and the 6 analog pins without using a FOR loop. It also seems that the sonar sensor will only be read when some time has elapsed but the analog pins are read every time.

Perhaps it would help to post a sample of the output. I don't have a sonar device so I can't try your code.

...R