Bug when using the arduino new ping library

If you use 10 ultrasonic sensors in the newping library, the "String" content will disappear.
However, if I change it to use 7, the contents of the "String" remain, so what's the problem?

see below please

#include <Adafruit_SSD1306.h>
#include <NewPing.h> // Ultrasound Sensor
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

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

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
int distance;
// OLED λ””μŠ€ν”Œλ ˆμ΄ 객체 생성
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40);

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.

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

// OLED λ””μŠ€ν”Œλ ˆμ΄μ— ν…μŠ€νŠΈμ™€ μ‹€μˆ˜ν˜• λ³€μˆ˜ 좜λ ₯ν•˜λŠ” ν•¨μˆ˜
void OLED_display(float voltage, float current, float power, float energy, int unit, int funct) { //λ””μŠ€ν”Œλ ˆμ΄
  // OLED λ””μŠ€ν”Œλ ˆμ΄ μ΄ˆκΈ°ν™”
  display.setTextSize(1);
  display.setTextColor(WHITE);
  unsigned long time = millis() / 1000;
  String timestr = String(time);

  // μ‹€μˆ˜ν˜• λ³€μˆ˜λ₯Ό λ¬Έμžμ—΄λ‘œ λ³€ν™˜ν•˜μ—¬ OLED λ””μŠ€ν”Œλ ˆμ΄μ— 좜λ ₯
  char voltageStr[8];
  char currentStr[8];
  char powerStr[8];
  char energyStr[8];
  char timeStr[8];
  dtostrf(voltage, 6, 2, voltageStr);
  dtostrf(current, 6, 2, currentStr);
  dtostrf(power, 6, 2, powerStr);
  dtostrf(energy, 6, 2, energyStr);
  String functstr;
  if (funct == 0){
    functstr = "function 1";
  }
  else if (funct == 1){
    functstr = "function 2";
  }
  else if (funct == 2){
    functstr = "function 3";
  }

  // 좜λ ₯ ν˜•μ‹ κ²°μ •
  String unitStr;
  if (unit == 0) {
    display.clearDisplay();
    display.setCursor(0, 0);   
  //  display.println(voltageStr + " V " + currentStr + " mA " + powerStr + " W");
    display.println(currentStr);
    display.setCursor(0, 10);
    display.println(functstr);
    display.display();
  } else if (unit == 1) {
    display.clearDisplay();
    display.setCursor(0, 0);
//    display.println(voltageStr + " V " + currentStr + " mA " + energyStr + " Wh ");
    display.setCursor(0, 10);
    display.println(functstr+ " " + timeStr + " s ");
    display.display();
  }
   Serial.println(voltageStr);
   Serial.println(currentStr);
   Serial.println(powerStr);
   Serial.println(energyStr);
   Serial.println(timeStr);
//   Serial.println(funct);

}

int readSwitchOnPin11() { //μŠ€μœ„μΉ˜ κΈ°λŠ₯
  static int globalstate1 = 0;
  if (digitalRead(11) == HIGH){
    if(globalstate1 == 0){
      globalstate1 = 1;
    }
    else if(globalstate1 == 1){
      globalstate1 = 2;
    }
    else if(globalstate1 == 2){
      globalstate1 = 0;
    }
  }
  if(globalstate1 == 0){
    return 0;
    }
  else if(globalstate1 == 1){
    return 1;
  }
  else if(globalstate1 == 2){
    return 2;
  }
}

int readSwitchOnPin12() { //μŠ€μœ„μΉ˜ κΈ°λŠ₯
  static int globalstate2 = 0;
  if (digitalRead(12) == HIGH){
    if(globalstate2 == 0){
      globalstate2 = 1;
    }
    else if(globalstate2 == 1){
      globalstate2 = 0;
    }
  }
  if(globalstate2 == 0){
    return 0;
    }
  else if(globalstate2 == 1){
    return 1;
  }
}

float currentsens(){//μ „λ₯˜ κ°’ λ°˜ν™˜
  float a[500];
  float ivalue = 0;
  float ivalue_avg = 0;
  for (int i = 0; i<500; i++){
      a[i]= (analogRead(A3) - 5)/3;
      ivalue = ivalue + a[i];
  }
  ivalue_avg = ivalue / 500;
  return ivalue_avg;
}

float energycalc(float voltage, float current) {//μ—λ„ˆμ§€ κ°’ λ°˜ν™˜
  static unsigned long startTime = 0;
  static float accumulatedEnergy = 0.0;
  static float accumulatedTime = 0.0;
  float energy = voltage * current / 1000;
  unsigned long currentTime = millis();
  
  if (digitalRead(14) == HIGH) { // λ””μ§€ν„Έ pin 14λ²ˆμ— high μ‹ ν˜Έκ°€ 듀어왔을 λ•Œ μ΄ˆκΈ°ν™”
    startTime = currentTime;
    accumulatedEnergy = 0.0;
    accumulatedTime = 0.0;
  }
  
  accumulatedEnergy += energy * (currentTime - startTime) / 100.0; // μ—λ„ˆμ§€ 적산
  accumulatedTime += (currentTime - startTime) / 100.0; // μ‹œκ°„ 적산
  
  float averagePower = 0.0;
  if (accumulatedTime > 0) {
    averagePower = accumulatedEnergy / accumulatedTime; // 평균 μ „λ ₯ 계산
  }
  
  return averagePower;
}

void setLEDs(int* ult_num, int enable, int cds_value) { // LEDλ₯Ό 켜고 λ„λŠ” ν•¨μˆ˜

  if (enable == 0) { //function 1 κΈ°λŠ₯ dimming off
    for (int i = 0; i < 10; i++) {
      pwm.setPWM(i, 0, 4095);
    }
  }

  else if (enable == 1){  //function 2 κΈ°λŠ₯ dimming on
    for (int i = 0; i < 10; i++) {
    /*  if (ult_num[i] <= 20) {
        pwm.setPWM(i-1, 0, 2047);      
        pwm.setPWM(i, 0, 4095);
        pwm.setPWM(i+1, 0, 2047);
      } else {
        pwm.setPWM(i, 0, 0);
      }
    }
    */
    pwm.setPWM(i, 0, 2000);      
    }
  }

  else if (enable == 2){ //function 3 κΈ°λŠ₯ cds on
    for (int i = 0; i < 10; i++) {
      pwm.setPWM(i, 0, 1000);      
    }
  }
}

void setup() {
  // OLED λ””μŠ€ν”Œλ ˆμ΄ μ΄ˆκΈ°ν™”
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.display();
  pinMode(11,INPUT);
  pinMode(12,INPUT);
  pwm.begin();
  pwm.setPWMFreq(10000); // Set the PWM frequency to 1000 Hz
  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;
}

int ult_distance() {
  static int distance[10];
  for (uint8_t i = 0; i < SONAR_NUM; i++) { 
    distance[i] = sonar[i].ping_cm();

  }
  return distance;
}

float voltage = 5.0;

void loop() {
  float current = currentsens();
  float power = voltage * current / 1000;
  float energy = energycalc(voltage, current);
  distance = ult_distance();
  int button1 = readSwitchOnPin11(); // LED 좜λ ₯ ν˜•νƒœ λ³€κ²½
  int button2 = readSwitchOnPin12(); // OLED ν‘œμ‹œ λ³€κ²½
  OLED_display(voltage, current, power, energy, button2, button1);
  setLEDs(5, button1, 0);
  Serial.println(button1);
}

Each sensor is pinged at 33ms intervals. So, one cycle of 15 sensors takes 495ms (33 * 15 = 495ms)

https://bitbucket.org/teckel12/arduino-new-ping/wiki/Help%20with%2015%20Sensors%20Example%20Sketch

When I compile your sketch I get a couple of warnings.

C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2023421-9256-9jjpok.eg5nj\sketch_may21a\sketch_may21a.ino: In function 'void setLEDs(int*, int, int)':
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2023421-9256-9jjpok.eg5nj\sketch_may21a\sketch_may21a.ino:192:19: warning: unused parameter 'ult_num' [-Wunused-parameter]
 void setLEDs(int* ult_num, int enable, int cds_value)
                   ^~~~~~~
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2023421-9256-9jjpok.eg5nj\sketch_may21a\sketch_may21a.ino:192:44: warning: unused parameter 'cds_value' [-Wunused-parameter]
 void setLEDs(int* ult_num, int enable, int cds_value)
                                            ^~~~~~~~~
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2023421-9256-9jjpok.eg5nj\sketch_may21a\sketch_may21a.ino: In function 'int ult_distance()':
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2023421-9256-9jjpok.eg5nj\sketch_may21a\sketch_may21a.ino:251:10: warning: invalid conversion from 'int*' to 'int' [-fpermissive]
   return distance;
          ^~~~~~~~
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2023421-9256-9jjpok.eg5nj\sketch_may21a\sketch_may21a.ino: In function 'void loop()':
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2023421-9256-9jjpok.eg5nj\sketch_may21a\sketch_may21a.ino:265:24: warning: invalid conversion from 'int' to 'int*' [-fpermissive]
   setLEDs(5, button1, 0);
                        ^
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2023421-9256-9jjpok.eg5nj\sketch_may21a\sketch_may21a.ino:192:6: note:   initializing argument 1 of 'void setLEDs(int*, int, int)'
 void setLEDs(int* ult_num, int enable, int cds_value)
      ^~~~~~~
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2023421-9256-9jjpok.eg5nj\sketch_may21a\sketch_may21a.ino: In function 'int readSwitchOnPin11()':
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2023421-9256-9jjpok.eg5nj\sketch_may21a\sketch_may21a.ino:125:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2023421-9256-9jjpok.eg5nj\sketch_may21a\sketch_may21a.ino: In function 'int readSwitchOnPin12()':
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2023421-9256-9jjpok.eg5nj\sketch_may21a\sketch_may21a.ino:149:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^

You can ignore the first two, the others might be (and I suspect that they are) the cause of your problem.

It seems like a memory issue. What is a board you use?

2 Likes

FYI, it compiles to around 836 bytes RAM for an Uno; that will exclude the memory for the display so you have a very valid point :+1:

1 Like

The board I'm using is an Arduino Uno.
I thought it might be a memory issue, do you think it's a memory issue?
If you know how I can fix this memory issue, I would appreciate your advice.

It definitely is; I had another look at your code

So it compiles to 836 bytes. Your display required 128x64 bits which is equal to 1kByte of RAM; so now you are at 1860 bytes. This might already be critical or you might get away with it.

But this is the killer; you're lucky that you managed 7 sensors.

float currentsens()
{  //μ „λ₯˜ κ°’ λ°˜ν™˜
  float a[500];

That requires 2K of RAM at the moment that you call currentsense().

A solution: probably use a Mega if you want to keep that float array with a size of 500 bytes. Further you can consider a library that only supports text and not graphics (I think it's u8g2).

There might be a few other ones that at to your problem.

The code above is an example of inefficiency and waste of memory.
Firstly, to store data from an analog port, a float is not required, the int type is enough - and this immediately reduces the memory requirements by half.
And secondly - if you look closely - this array of 500 values is used only to calculate the average, it is not used in the program.
So why keep it at all?

Lets use ONLY ONE float to keep the sum of analog values and calculate the average:

float currentsens()  {
  float ivalue = 0;
  for (int i = 0; i<500; i++){
      ivalue += (analogRead(A3) - 5)/3;
     }
  ivalue = ivalue / 500;
  return ivalue;
}

and reduce the memory requirements from 2008 to only 4 bytes

I tried following your advice, but it's still not working with the same problem.
I guess I'll have to look for another way.
Thank you very much for your help.

Hi, @jihwanlee
What is the application that requires 10 ultrasonic sensors?

Thanks... Tom... :grinning: :+1: :coffee: :australia:

This is a small project to control street lights.
Fortunately, it's working well because I'm not using a library and I'm controlling it myself.
Thanks for your interest.

Hi,
So you have an ultrasonic sensor at each street light, one controller for all?.
How far between lights, that is what cabling?

Can you please post your working solution?

Thanks.. Tom.. :grinning: :+1: :coffee: :australia:

Hi
We will create a model of the road with an ultrasonic sensor assigned to each streetlight. Additionally, we plan to use one Arduino Uno for every 10 streetlights. The distance between each streetlight in the mockup will be approximately 10 to 20 centimeters, although the exact distance is still being determined as I continue working on the mockup. So far, it seems that all the issues I encountered have been resolved. Thank you.

Hi,
To help others how may be trying to use so many sensors, and in the process of the forum, can you please post your working code?

Thanks.. Tom... :grinning: :+1: :coffee: :australia:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.