Problem with OLED and a function using ultrasonic.

Hey guys ive reached a roadblock and I cant seem to figure out the problem im have(not very good at code).
Anyways what im trying to do is use an HC-SR04 to measure height in a tank and display it on a SSD1306 OLED. My issue is that when I enable my function to get the measurement my OLED screen stays black. If I leave it commented out the display works perfect. I’ve tried it in the main loop and within my display function. What am i doing wrong?

I forgot to add that my “Serial.println(Menus[encoderPos]); Serial.println(TankLevelVal);” inside the OLED function does work and send the text through the serial monitor.

#include <Encoder.h>
#include <NewPing.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define MenuItems 4
//Encoder Pins
static int pinA = 2; // Our first hardware interrupt pin is digital pin 2
static int pinB = 3; // Our second hardware interrupt pin is digital pin 3
volatile byte aFlag = 0; // let's us know when we're expecting a rising edge on pinA to signal that the encoder has arrived at a detent
volatile byte bFlag = 0; // let's us know when we're expecting a rising edge on pinB to signal that the encoder has arrived at a detent (opposite direction to when aFlag is set)
volatile byte encoderPos = 0; //this variable stores our current value of encoder position. Change to int or uin16_t instead of byte if you want to record a larger range than 0-255
volatile byte oldEncPos = 0; //stores the last encoder position value so we can compare to the current reading and see if it has changed (so we know when to print to the serial monitor)
volatile byte reading = 0; //somewhere to store the direct values we read from our interrupt pins before checking to see if we have moved a whole detent
#define EncBTN 4

//Sonar Sensor pins / settings
#define TRIGGER_PIN  5  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     6  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 30 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
#define TANK_MAX 8      //Tank depth from sensor in cm when full
#define TANK_MIN 25     //Tank depth from sensor in cm when full
//Setup for OLED
#define OLED_MOSI   9
#define OLED_CLK   10
#define OLED_DC    11
#define OLED_CS    12
#define OLED_RESET 13
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);


byte Counter = 0;
byte BTNState = 0;
byte oldBTNState = 0;
float TankLevelVal = 0;
long oldPosition  = -999;
int DisplayInterval = 250;
unsigned long previousMillis = 0;

char* Menus[] = {"<  Menu  >", "<PullShot>", "< Steam  >", "<Settings>"};


NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);      // NewPing setup of pins and maximum distance.

void setup() {

  pinMode(EncBTN, INPUT_PULLUP);                         // enable pull-ups
  pinMode(pinA, INPUT_PULLUP); // set pinA as an input, pulled HIGH to the logic voltage (5V or 3.3V for most cases)
  pinMode(pinB, INPUT_PULLUP); // set pinB as an input, pulled HIGH to the logic voltage (5V or 3.3V for most cases)
  attachInterrupt(0, PinA, RISING); // set an interrupt on PinA, looking for a rising edge signal and executing the "PinA" Interrupt Service Routine (below)
  attachInterrupt(1, PinB, RISING); // set an interrupt on PinB, looking for a rising edge signal and executing the "PinB" Interrupt Service Routine (below)
  display.begin(); //SSD1306_SWITCHCAPVCC
  display.clearDisplay();
  Serial.begin(9600);
  Serial.println("starting");
  TankLevel() ;                                          //Get Tank Level
  Serial.println("...");
}


void loop() {

  if (oldEncPos != encoderPos) {
    oldEncPos = encoderPos;
  }
  // ButtonStatus();  // Check for user inputs
  //TankLevel() ; //Gets tank level in percent
  OLEDDisplay();
}



// Fuction calls

void OLEDDisplay() {

  unsigned long currentMillis = millis();

  Counter++;
  if (Counter ==40){
   // TankLevel() ;
    Counter = 0;
  }
  
  if (currentMillis - previousMillis >= DisplayInterval) {
    previousMillis = currentMillis;
    display.setCursor(0, 0); display.setTextColor(WHITE);  display.setTextSize(2);
    display.print(Menus[encoderPos]);
    display.setTextColor(WHITE);  display.setTextSize(1);
    display.print('\n'); display.print('\n'); display.print("Tank level: "); display.print(TankLevelVal); display.print("%");
    display.display();
    display.clearDisplay();
    Serial.println(Menus[encoderPos]); Serial.println(TankLevelVal);
  }

}


void TankLevel() {

  int Reading[3];
  float AvgReading;

  for (int i = 0; i <= 3; i++) {
    unsigned long x = millis();
    Reading[i] = sonar.ping_cm();    // Send ping, get distance in cm and print result (0 = outside set distance range)
    while (millis() - x < 30) {      // Wait 30ms between pings 29ms is the min
    }
  }

  AvgReading = (Reading[1] + Reading[2] + Reading[3]) / 3 ; // Store Average result
  TankLevelVal = (AvgReading / (TANK_MIN - TANK_MAX)) * 100 ;   //Convert avg to percent
  TankLevelVal = 100 - TankLevelVal ;

  if (TankLevelVal < 0) {
    TankLevelVal = 0;
  }
  if (TankLevelVal > 100) {
    TankLevelVal = 100;
  }
}

void PinA() {
  cli(); //stop interrupts happening before we read pin values
  reading = PIND & 0xC; // read all eight pin values then strip away all but pinA and pinB's values
  if (reading == B00001100 && aFlag) { //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge
    encoderPos --; //decrement the encoder's position count
    if (encoderPos == 255) {
      encoderPos = 0;
    }
    bFlag = 0; //reset flags for the next turn
    aFlag = 0; //reset flags for the next turn
  }
  else if (reading == B00000100) bFlag = 1; //signal that we're expecting pinB to signal the transition to detent from free rotation
  sei(); //restart interrupts
}

void PinB() {
  cli(); //stop interrupts happening before we read pin values
  reading = PIND & 0xC; //read all eight pin values then strip away all but pinA and pinB's values
  if (reading == B00001100 && bFlag) { //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge
    encoderPos ++; //increment the encoder's position count
    if (encoderPos == 4) {
      encoderPos = 3;
    }
    bFlag = 0; //reset flags for the next turn
    aFlag = 0; //reset flags for the next turn
  }
  else if (reading == B00001000) aFlag = 1; //signal that we're expecting pinA to signal the transition to detent from free rotation
  sei(); //restart interrupts
}

void ButtonStatus() {

  unsigned long x = millis();
  unsigned long y = millis();
  unsigned long z = 0;

  while (digitalRead(EncBTN) == 0) {
    y = millis();
  }

  z = y - x;

  if (z < 50) {
    BTNState = 0;
  }
  if (z > 50) {
    BTNState = 1;
  }
  if (z > 2000) {
    BTNState = 2;
  }

  if (BTNState != oldBTNState) {
    oldBTNState = BTNState;
    Serial.println(BTNState);
  }
}

My issue is that when I enable my function to get the measurement my OLED screen stays black. If I leave it commented out the display works perfect. I've tried it in the main loop and within my display function. What am i doing wrong?

I would guess that you are trying to use the same pins for the OLED screen and the ping sensor. Post a link to the OLED display, so we can see what pins it uses.

The while loop in TankLevel() is a delay() in disguise.

It is hardly useful to use NewPing, which uses interrupts, so it can be non-blocking, in the same code that stuffs its head in the sand for 30 milliseconds at a time.

Array indices start at 0, not 1.

It is NOT necessary to store the individual readings in an array, just so you can add them up later.

It is annoying to put incredibly long single line comments on the same line as a statement. If you really need a novel to describe what a single statement is doing, put the novel on more than one line BEFORE the statement that needs explaining.

Thanks for the reply PaulS. I replaced the new ping code with an example i found that does not use it and all my issues are cleared now.

When you say this “It is NOT necessary to store the individual readings in an array, just so you can add them up later.” do you have some example for me to look at? Like i said im not very good at coding and I figured thats the proper way to do an average. I have removed that portion of the code but I am still curious.

That array indexing defiantly came back to haunt me but i figured it out when my menu was not behaving.

When you say this “It is NOT necessary to store the individual readings in an array, just so you can add them up later.” do you have some example for me to look at? Like i said im not very good at coding and I figured thats the proper way to do an average. I have removed that portion of the code but I am still curious.

Set average to 0 before the for loop. In the loop, increment average by the current reading. After the loop, divide average by the number of times the loop iterated, to get the real average. No need to store the readings.

  int average = 0;
  for(byte i=0; i<3; i++)
  {
     average += getDistance();
  }
  average /= 3;