Distillation sketch to function

I'm experimenting with it because it does not work in my project.
I'm not going to post the more than 600 lines for obvious reasons (i'm tired of discussing that topic).
Instead i'm going to post the very relevant and complete experimenting code in the three steps i'v tried (to find out why it doesn't work).
It is a attempt to convert an example sketch for the waterproof A02YYUW (UART) distance sensor to a function in my sketch. I'm using this library instead of writing/copying a piece of code because this lib is the only one that generates almost no errors.
The goal is to get the unsigned int 'dis' (distance) as a global variable in cm (the library 'DistanceSensor_A02YYUW' gives distance in mm; hence division by 10).
And yes, i know many of you would 'return' the value from the function but i want it globally defined so that it's more accessible for the other functions in my project code.

Why won't the distilled version of the sketch work like it should?

Step one: sketch that works (note: you see i'v changed the 'do/while' in a 'while' loop)

/*
 * 
 * Gets the distance from the sensor using a Software Serial every 1 second
 *
 */
#include <Wire.h>

#include <LiquidCrystal_I2C.h>

#include <DistanceSensor_A02YYUW.h>

#include <SoftwareSerial.h>

#define SOFTWARE_SERIAL_PIN_RX 11 //this is where the tx (white wire) of the sensor goes!!
#define SOFTWARE_SERIAL_PIN_TX 10

SoftwareSerial mySerial(SOFTWARE_SERIAL_PIN_RX, SOFTWARE_SERIAL_PIN_TX);
DistanceSensor_A02YYUW distanceSensor(&mySerial);
LiquidCrystal_I2C lcd(0x27, 16, 2);



void setup() {
  mySerial.begin(9600);
  Serial.begin(9600);
  	// initialize the LCD
	lcd.begin();

}

void loop() {
  DistanceSensor_A02YYUW_MEASSUREMENT_STATUS meassurementStatus;
  unsigned int dis = 0;

// Gets the distance from the sensor and if the measurement is wrong, it retries to get the distance
  while (meassurementStatus != DistanceSensor_A02YYUW_MEASSUREMENT_STATUS_OK) {
    lcd.backlight();
    meassurementStatus = distanceSensor.meassure();
    if (meassurementStatus == DistanceSensor_A02YYUW_MEASSUREMENT_STATUS_OK) {
      lcd.clear();
      lcd.setCursor(0, 0);
      dis = distanceSensor.getDistance()/10;
      lcd.print(dis);
      lcd.print(" cm");
      //Serial.print("Distance : ");
      //Serial.print(distanceSensor.getDistance()/10);
      //Serial.println(" cm");
    } else {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Error:");
      lcd.print(meassurementStatus);
      //Serial.print("Error:" );
      //Serial.println(meassurementStatus);
    }
  }

  /*// Gets the distance from the sensor and if the measurement is wrong, it retries to get the distance
  do {
    lcd.backlight();
    meassurementStatus = distanceSensor.meassure();

    if (meassurementStatus == DistanceSensor_A02YYUW_MEASSUREMENT_STATUS_OK) {
      lcd.clear();
      lcd.setCursor(0, 0);
      dis = distanceSensor.getDistance()/10;
      lcd.print(dis);
      lcd.print(" cm");
      //Serial.print("Distance : ");
      //Serial.print(distanceSensor.getDistance()/10);
      //Serial.println(" cm");
    } else {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Error:");
      lcd.print(meassurementStatus);
      //Serial.print("Error:" );
      //Serial.println(meassurementStatus);
    }
  } while (meassurementStatus != DistanceSensor_A02YYUW_MEASSUREMENT_STATUS_OK);
  */

  delay(1000);
}

Step two: The 'split-off' to a void function and unsigned int dis = 0; as global variable works

/*
 * 
 * Gets the distance from the sensor using a Software Serial every 1 second
 *
 */
#include <Wire.h>

#include <LiquidCrystal_I2C.h>

#include <DistanceSensor_A02YYUW.h>

#include <SoftwareSerial.h>

#define SOFTWARE_SERIAL_PIN_RX 11 //this is where the tx (white wire) of the sensor goes!!
#define SOFTWARE_SERIAL_PIN_TX 10

unsigned int dis = 0;

SoftwareSerial mySerial(SOFTWARE_SERIAL_PIN_RX, SOFTWARE_SERIAL_PIN_TX);
DistanceSensor_A02YYUW distanceSensor(&mySerial);
LiquidCrystal_I2C lcd(0x27, 16, 2);



void setup() {
  mySerial.begin(9600);
  Serial.begin(9600);
  	// initialize the LCD
	lcd.begin();

}

void loop() {
  distance ();
}

void distance() {
  DistanceSensor_A02YYUW_MEASSUREMENT_STATUS meassurementStatus;
  while (meassurementStatus != DistanceSensor_A02YYUW_MEASSUREMENT_STATUS_OK) {
    lcd.backlight();
    meassurementStatus = distanceSensor.meassure();
    if (meassurementStatus == DistanceSensor_A02YYUW_MEASSUREMENT_STATUS_OK) {
      lcd.clear();
      lcd.setCursor(0, 0);
      dis = distanceSensor.getDistance()/10;
      lcd.print(dis);
      lcd.print(" cm");
      //Serial.print("Distance : ");
      //Serial.print(distanceSensor.getDistance()/10);
      //Serial.println(" cm");
    } else {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Error:");
      lcd.print(meassurementStatus);
      //Serial.print("Error:" );
      //Serial.println(meassurementStatus);
    }
  }
    delay(1000);
}

Step three: Cutting away the printing balast in the void distance(); function and adding some printing balast to the loop() function doens't work (displays the variable 'dis' is 0 cm)

#include <Wire.h>

#include <LiquidCrystal_I2C.h>

#include <DistanceSensor_A02YYUW.h>

#include <SoftwareSerial.h>

#define SOFTWARE_SERIAL_PIN_RX 11 //this is where the tx (white wire) of the sensor goes!!
#define SOFTWARE_SERIAL_PIN_TX 10

unsigned int dis = 0;

SoftwareSerial mySerial(SOFTWARE_SERIAL_PIN_RX, SOFTWARE_SERIAL_PIN_TX);
DistanceSensor_A02YYUW distanceSensor(&mySerial);
LiquidCrystal_I2C lcd(0x27, 16, 2);



void setup() {
  mySerial.begin(9600);
  Serial.begin(9600);
  	// initialize the LCD
	lcd.begin();

}

void loop() {
  distance ();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(dis);
  lcd.print(" cm");
}

void distance() {
  DistanceSensor_A02YYUW_MEASSUREMENT_STATUS meassurementStatus;
  while (meassurementStatus != DistanceSensor_A02YYUW_MEASSUREMENT_STATUS_OK) {
    lcd.backlight();
    meassurementStatus = distanceSensor.meassure();
    if (meassurementStatus == DistanceSensor_A02YYUW_MEASSUREMENT_STATUS_OK) {
      dis = distanceSensor.getDistance()/10; //dis=global variable
    } 
  }
    delay(1000);
}

To be honest i, i don't exactly know what DistanceSensor_A02YYUW_MEASSUREMENT_STATUS meassurementStatus; does but i assume this is a variable created in the lib that gets renamed. Although i can't point my finger to, the trouble is mostly caused by something i don't really understand.
My apologies but i'm still having trouble naming everything with the right terms.

thx!

Why not begin at the real beginning. Where did you find this program and did the source state the program worked properly for them? Did it ever work properly for you?

Github. And 2x yes like stated in my text. First two work, third one not.

Then begin tracking the logic using serial.Print() to find where the error begins.

Might help if you initialize meassurementStatus to something other than 0 (which is the value of DistanceSensor_A02YYUW_MEASSUREMENT_STATUS_OK), otherwise the code within the while() may never execute. Local variables are created on the stack, and will have a random initial value. Would be better to use the original do/while() structure of the code, that way the value of meassurementStatus is set by the library function before testing it.

Nope. It is a local variable of type DistanceSensor_A02YYUW_MEASSUREMENT_STATUS, created within the scope of the function (see https://docs.arduino.cc/language-reference/en/variables/variable-scope-qualifiers/scope/ ) , and, since it is uninitialized, it may have garbage in it when it is next used in this line:

You should take care to initialize a variable before you use it, otherwise, you could get unpected behavior.

You may want to make it global, static, or maybe use a do {...} while(); control structure to make sure you set the variable before you reference it.

Normally i'm doing it that way but for some wrong reason in my head i thought that the I2C display disrupts the serial monitor and vise versa (i had trouble in the past but it was because push buttons where connected to A4&A5 pins = SDA & CLK).
Done. No real positive result but i can say now that the while loop is not be entered. It seems that; like already suggested below; it should revert to a do{}while() loop.
For me (with my limited knowledge) it doens't make sense that step two works although i'm working with the (sugested) wrongfully used while() loop (instead of do{}while() loop).

Like DaveX also stated, you guy's are right.
I'v found a (verry logical, after the tips) slight work around. Just reading the measurementStatus before using it in the while() loop. But you guy's are so very right to use a do{}while() loop. Now i'v learned the hard way why sometime i need to use do{}while() instead of while().
this is the work around that works :wink::

#include <Wire.h>

#include <LiquidCrystal_I2C.h>

#include <DistanceSensor_A02YYUW.h>

#include <SoftwareSerial.h>

#define SOFTWARE_SERIAL_PIN_RX 11 //this is where the tx (white wire) of the sensor goes!!
#define SOFTWARE_SERIAL_PIN_TX 10

unsigned int dis;

SoftwareSerial mySerial(SOFTWARE_SERIAL_PIN_RX, SOFTWARE_SERIAL_PIN_TX);
DistanceSensor_A02YYUW distanceSensor(&mySerial);
LiquidCrystal_I2C lcd(0x27, 16, 2);



void setup() {
  mySerial.begin(9600);
  Serial.begin(9600);
  	// initialize the LCD
	lcd.begin();

}

void loop() {
  distance ();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(dis);
  lcd.print(" cm");
  Serial.print("distance in main loop: ");
  Serial.print(dis);
  Serial.println("cm");
}

void distance() {
  DistanceSensor_A02YYUW_MEASSUREMENT_STATUS meassurementStatus;
  meassurementStatus = distanceSensor.meassure();
  while (meassurementStatus != DistanceSensor_A02YYUW_MEASSUREMENT_STATUS_OK) {
    lcd.backlight();
    Serial.println("meassurmentStatus = NOT OK");
    meassurementStatus = distanceSensor.meassure();
    if (meassurementStatus == DistanceSensor_A02YYUW_MEASSUREMENT_STATUS_OK) {
      dis = distanceSensor.getDistance()/10; //dis=global variable
      Serial.print("distance in distance function: ");
      Serial.println(dis);
      Serial.println("cm");
    } 
  }
    delay(1000);
}

That relies on distanceSensor.meassure() not returning DistanceSensor_A02YYUW_MEASSUREMENT_STATUS_OK.

The common reason for using a do...while instead of a while is that you want the code to execute at least once before the condition is tested.

If I want a function to work one time, work under certain conditions, or work always, I like to set a "oneTime" flag, then test the flag in an if() condition and clear the flag when necessary.

Indeed. Before searching a way to use a UART distance sensor (instead of the previously using the SR-04 sensor with trigger and pulse pins) i did it that way. Before i didn't know of the existence of the do{}while() loop. And that is why C++ is so difficult, many ways to the solution but for a beginner like me it creates to much question marks in my brain.
And that is the beauty of RISC assembler. Fewer instructions....but lots more brain work. Although RISC assembler language, once you have written code for different projects you can re-use and recycle everything.
But that was 25 years ago (long, long time) for a graduation project. Sins then no more electronics or programming.