Is this "while" not endless?

This is part of the given example code for reading a DHT11 digital humidity and temperature sensor

void start_test()
{
	// bus down, send start signal;
	digitalWrite(SENSOR_PIN, LOW); 
	// delay > 18ms, so DHT11 start signal can be detected;
	delay(30); 
	digitalWrite(SENSOR_PIN, HIGH);
	// Wait DHT11 response;
	delayMicroseconds(40); 
	pinMode(SENSOR_PIN, INPUT);

	while (digitalRead(SENSOR_PIN) == HIGH);

I do not understand the function of the last line shown. I thought it would stall the code action until SENSOR_PIN is written LOW. Apparently not.

How does this line work?

Thanks

Why don’t you put in some Serial.println(…) statements and show us the output in Serial monitor:

void start_test()
{
	// bus down, send start signal;
	digitalWrite(SENSOR_PIN, LOW);
	// delay > 18ms, so DHT11 start signal can be detected;
	delay(30);
	digitalWrite(SENSOR_PIN, HIGH);
	// Wait DHT11 response;
	delayMicroseconds(40);
	pinMode(SENSOR_PIN, INPUT);
Serial.println(F("1111111"));
	while (digitalRead(SENSOR_PIN) == HIGH);

Serial.println(F("22222222"));

Here is the full code

/*
-- filename   : temperatureAndHumidity.ino
--
-- purpose    :  demonstrate readint temperature and humidity
--                using a DHT11 sensor (Jaycar XC4520)
--
-- derivation : https://www.wiltronics.com.au/product/9236/dht11-digital-temperature-humidity-sensor-module/
--
-- version    : 0.0
--
-- date       : February 12, 2018
--
01234567890123456789012345678901234567890123456789012345678901234567890
__________1         2         3         4         5         6         7
*/

// constants
const int SENSOR_PIN = 8;

// global variables
int sensorOutput[5];


// forward declarations
int read_data();
void start_test();


// the setup function runs once when you press reset or 
//  power the board
void setup()
{
	Serial.begin(9600);
	pinMode(SENSOR_PIN, OUTPUT);
}  //  end setup()

// the loop function runs over and over again until power 
//  down or reset
void loop()
{
	start_test();
	Serial.print("Current humdity = ");
	// display the humidity-bit integer;
	Serial.print(sensorOutput[0], DEC); 
	Serial.print('.');
	// display the humidity decimal places;
	Serial.print(sensorOutput[1], DEC); 
	Serial.println('%');
	Serial.print("Current temperature = ");
	// display the temperature of integer bits;
	Serial.print(sensorOutput[2], DEC); 
	Serial.print('.');
	// display the temperature of decimal places;
	Serial.print(sensorOutput[3], DEC); 
	Serial.println('C');
	Serial.println();
	delay(5000);
}  //  end loop()


int read_data()
{
	int data;
	for (int i = 0; i < 8; i++) {
		if (digitalRead(SENSOR_PIN) == LOW) {
			while (digitalRead(SENSOR_PIN) == LOW);
			// wait for 50us;
			delayMicroseconds(30);
			// determine the duration of the high level to 
			//  determine the data is '0 'or '1';
			if (digitalRead(SENSOR_PIN) == HIGH)
				// high front and low in the post;
				data |= (1 << (7 - i)); 
			// data '1 ', wait for the next one receiver;
			while (digitalRead(SENSOR_PIN) == HIGH); 
		}
	}
	return data;
}  //  end read_data


void start_test()
{
	// bus down, send start signal;
	digitalWrite(SENSOR_PIN, LOW); 
	// delay > 18ms, so DHT11 start signal can be detected;
	delay(30); 
	digitalWrite(SENSOR_PIN, HIGH);
	// Wait DHT11 response;
	delayMicroseconds(40); 
	pinMode(SENSOR_PIN, INPUT);

	while (digitalRead(SENSOR_PIN) == HIGH);

	// DHT11 a response, pulled the bus 80us;
	delayMicroseconds(80); 
	if (digitalRead(SENSOR_PIN) == LOW);
	// DHT11 80us after the bus pulled to start sending data;
	delayMicroseconds(80); 

	// receives temperature and humidity data, 
	//  the parity bit is not considered;
	for (int i = 0; i < 4; i++)
		sensorOutput[i] = read_data();
	pinMode(SENSOR_PIN, OUTPUT);
	// sending data once after releasing the bus, 
	//wait for the host to open the next Start signal;
	digitalWrite(SENSOR_PIN, HIGH);
}  //  end start_test

and the output

Opening port
Port open
Current humdity = 43.0%
Current temperature = 24.0C

Current humdity = 43.0%
Current temperature = 24.0C

Current humdity = 43.0%
Current temperature = 24.0C

Why don't you read the DHT11 datasheet to find out how the sensor actually communicates with the Arduino?

MorganS:
Why don’t you read the DHT11 datasheet to find out how the sensor actually communicates with the Arduino?

  1. At my stage of electronics understanding most of this datasheet might as well be written in Chinese (I can get one that is, if that helps you :wink: )
  2. I cannot see any explanation of the function of this line of code
    while (digitalRead(SENSOR_PIN) == LOW);
    and that is all I am asking here.

I thought it would stall the code action until SENSOR_PIN is written LOW. Apparently not.

What symptoms of it "not working" do you get ?
What happens if you spread the code over several lines

while (digitalRead(SENSOR_PIN) == LOW)
{
  Serial.println(digitalRead(SENSOR_PIN));
}

UKHeliBob:
What symptoms of it "not working" do you get ?
What happens if you spread the code over several lines

Code stanza now reads

  Serial.println("Checking SENSOR_PIN");
	while (digitalRead(SENSOR_PIN) == HIGH)
	{
	  Serial.print("SENSOR_PIN reads ");
    Serial.println(digitalRead(SENSOR_PIN));
	}
	}

It shows no effect in output

Checking SENSOR_PIN
Current humdity = 164.0%
Current temperature = 100.1C

Checking SENSOR_PIN
Current humdity = 164.0%
Current temperature = 100.1C

Checking SENSOR_PIN
Current humdity = 164.0%
Current temperature = 100.1C

Print the state of the sensor pin before entering the while loop. It looks like it is LOW. How is it wired and what provides its input ?

UKHeliBob:
Print the state of the sensor pin before entering the while loop.

  Serial.println("Checking SENSOR_PIN");
  Serial.print("Before loop SENSOR_PIN reads ");
    Serial.println(digitalRead(SENSOR_PIN));
	while (digitalRead(SENSOR_PIN) == HIGH)
	{
	  Serial.print("SENSOR_PIN reads ");
    Serial.println(digitalRead(SENSOR_PIN));
	}

gets me

Checking SENSOR_PIN
Before loop SENSOR_PIN reads 1
Current humdity = 224.3%
Current temperature = 32.8C

Checking SENSOR_PIN
Before loop SENSOR_PIN reads 1
Current humdity = 224.3%
Current temperature = 32.8C

Checking SENSOR_PIN
Before loop SENSOR_PIN reads 1
Current humdity = 224.3%
Current temperature = 32.8C

so SENSOR_PIN is definitely HIGH.

( I note the temperature and humidity are up a bit, but that's another problem. :wink: )

UKHeliBob:
It looks like it is LOW. How is it wired and what provides its input ?

It's just run off the UNO - 5V, GND and D8.

It certainly looks like it should stick in the while loop.

How about writing a small sketch that simple implements the while loop with your hardware.

Hi,
When you read the sensorpin for the print statement, that is not the same sensorpin state when the while statement uses it .
Try this;

Serial.println("Checking SENSOR_PIN");
Serial.print("Before loop SENSOR_PIN reads ");
bool sensorPinstate = digitalRead(SENSOR_PIN);  // read the sensor
Serial.println(sensorPinstate);
while (sensorPinState == HIGH)  // decide if sensor is HIGH or LOW
{
  Serial.print("SENSOR_PIN in the loop reads ");  // drop into loop if HIGH
  sensorPinstate = digitalRead(SENSOR_PIN);  // check sensor to see  stateLOW or HIGH before looping back to while.
  Serial.println(sensorPinstate);
}
Serial.print("After loop SENSOR_PIN reads ");
Serial.println(sensorPinstate);

Tom... :slight_smile:

FTR: I removed all the modifications to the original code

//  Serial.println("Checking SENSOR_PIN");
//  Serial.print("Before loop SENSOR_PIN reads ");
//  Serial.println(digitalRead(SENSOR_PIN));
  while (digitalRead(SENSOR_PIN) == HIGH);
//  {
//    Serial.print("SENSOR_PIN reads ");
//    Serial.println(digitalRead(SENSOR_PIN));
//  }

and the temperature and humidity returned to something more temperate

Current humidity = 40.0%
Current temperature = 24.0C

Current humidity = 40.0%
Current temperature = 24.0C

Current humidity = 40.0%
Current temperature = 24.0C

Current humidity = 40.0%
Current temperature = 24.0C

although UKHeliBob mightn't call that temperate :wink:

UKHeliBob:
It certainly looks like it should stick in the while loop.

At a C++ forum I find. "while (true) means that the loop will iterate forever, unless some command inside the loop forces the loop to end" which reinforces my original thinking. So, why does the flow of control not stall at that point?

UKHeliBob:
How about writing a small sketch that simple implements the while loop with your hardware.

I'll have a crack at that in the morning.

UKHeliBob:
It certainly looks like it should stick in the while loop.

How about writing a small sketch that simple implements the while loop with your hardware.

This code will not stick because the while statement reads the input state directly from the input pin at the top of each loop

  Serial.println("Checking SENSOR_PIN");
  Serial.print("Before loop SENSOR_PIN reads ");
    Serial.println(digitalRead(SENSOR_PIN));
	while (digitalRead(SENSOR_PIN) == HIGH)  <===================================
	{
	  Serial.print("SENSOR_PIN reads ");
    Serial.println(digitalRead(SENSOR_PIN));
	}

Tom… :slight_smile:

Hi TomGeorge

I suspected that - it's probably why I got the strange temperature and humidity readings.

That's something else I'll get to in the morning.

Hi,
Why aren't you using a DHT11 library?

Tom.. :slight_smile:

vagulus:
2. I cannot see any explanation of the function of this line of code
while (digitalRead(SENSOR_PIN) == LOW);
and that is all I am asking here.

Because the line above sets that pin to be an input. This loop waits until the input is no longer LOW.

This code will not stick because the while statement reads the input state directly from the input pin at the top of each loop

Why not ?

This works fine for me

void setup()
{
  Serial.begin(115200);
  pinMode(A1, INPUT_PULLUP);
  while (digitalRead(A1) == HIGH);
  Serial.println("A1 gone LOW");
}

void loop()
{
}

Surely the whole point of a while loop is that the condition is tested each time through the loop and the associated code block is execute if the condition returns true.

UKHeliBob:
Why not ?

This works fine for me

void setup()

{
 Serial.begin(115200);
 pinMode(A1, INPUT_PULLUP);
 while (digitalRead(A1) == HIGH);
 Serial.println(“A1 gone LOW”);
}

void loop()
{
}




Surely the whole point of a while loop is that the condition is tested each time through the loop and the associated code block is execute if the condition returns true.

But some do this and get caught in the loop;

void setup()
{
  Serial.begin(115200);
  pinMode(A1, INPUT_PULLUP);
  bool status = digitalRead(A1);
  while (status == HIGH)
{
  Serial.println("A1 gone HIGH");
}
}
void loop()
{
}

To fix it so you don’t get caught in the loop you have to add this line;

void setup()
{
  Serial.begin(115200);
  pinMode(A1, INPUT_PULLUP);
  bool status = digitalRead(A1);
  while (status == HIGH)
{
  Serial.println("A1 gone HIGH"); 
  status = digitalRead(A1);  //<====
}
}
void loop()
{
}

In your code you read the actual input pin each time the while does the comparison.
(Where are your { } and are your HIGH and LOW correct?) :slight_smile:

In the next code, read the input into a variable, but don’t update it,so it is locked in the loop.

The last code updates the input status inside the loop so that the while comparison is done to the latest input status.

Tom… :slight_smile:

(Where are your { } and are your HIGH and LOW correct?)

{} not needed, and for the sake of the OP I chose to use his/her style and, yes, my HIGH and LOW are correct :stuck_out_tongue:

vagulus:
2. I cannot see any explanation of the function of this line of code
while (digitalRead(SENSOR_PIN) == LOW);
and that is all I am asking here.

Oh, ok.

What you might be missing is that in C, a semicolon by itself is a do-nothing statement; and that a while statement is [b]while([i]condition[/i]) [i]statement[/i][/b]. If we expand out the formatting, this line is the same thing as

while (digitalRead(SENSOR_PIN) == LOW)
  ; // do nothing

A while keyword controls one statement, but that statement is allowed to be a block enclosed in braces, which is what you usually see. Here, they are just using the semicolon by itself as the statement.

This line will cause the sketch to halt at that point until there is a +5v on SENSOR_PIN. I mean - it’s not actually halted: it’s executing a tight loop. But in effect it’s halted.