void loop() is not looping

hello,
I am trying to program an automatic water level controller. I have used two arduino modules. One for the sensor side and another for the control side. The program for the control side:

#include <LiquidCrystal.h>
#define echo 0
#define motor 8
#define buzzer 12

LiquidCrystal lcd(2,3,4,5,6,7);

float distance=0;
int temp=0; 
void setup()
{
lcd.begin(16,2);
pinMode(echo,INPUT);
pinMode(motor, OUTPUT);
pinMode(buzzer, OUTPUT);
lcd.print("  Water Level ");
lcd.setCursor(0,1);
lcd.print("   Indicator  ");
Serial.begin(9600);
delay(2000);
}

void loop()
{
 while(Serial.available()>0){
 distance=Serial.parseFloat()-'0';}
 lcd.clear();
 lcd.print("Water Space In  ");
 lcd.setCursor(0,1);
 lcd.print("Tank is: ");
 lcd.print(distance);
 lcd.print("Cm");
 delay(1000);
if(distance<12 && temp==0)
{
    digitalWrite(motor, LOW);
    digitalWrite(buzzer, HIGH);
    lcd.clear();
    lcd.print("Water Tank Full ");
    lcd.setCursor(0,1);
    lcd.print("Motor Turned OFF");
    delay(2000);
    digitalWrite(buzzer, LOW);
    delay(3000);
    temp=1;
}

 else if(distance<12 && temp==1)
{
    digitalWrite(motor, LOW);
    lcd.clear();
    lcd.print("Water Tank Full ");
    lcd.setCursor(0,1);
    lcd.print("Motor Turned OFF");
    delay(5000);
}

else if(distance>30)
{
  digitalWrite(motor, HIGH);
  lcd.clear();
  lcd.print("LOW Water Level");
  lcd.setCursor(0,1);
  lcd.print("Motor Turned ON");
  delay(5000);
  temp=0;
}
}

The void loop is not looping. i get only one distance from the ultrasonic sensor. when the distance changes, it is not reflected on the code. can anyone guide me where i have gone wrong. Thanks in advance

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

It would be so much easier to read or copy and paste your code if you used
```
~~[/s]

code tags

[s]~~
```
, (which you're always supposed to do when posting code).
Even better if you hit Ctrl-T or ">Tools Auto format" in the IDE to correctly format your code before posting it.
It was done for you.

In your diagram, the Arduinos aren't connected to GND.

Why do you subtract '0' here?:-
distance=Serial.parseFloat()-'0';

Edit: And perhaps you should show the other half of the code - the sender.
Also, is 'distance' really a 'float'?

When I remove the -'0' that I mentioned and change all of the 'lcd.print()' statements to 'Serial.print()' or 'Serial.println()', then enter values in the serial monitor, I get this output:-
(I removed some of the repeated lines.)

Water Space In  Tank is: 0.00Cm
Water Tank Full 
Motor Turned OFF
Water Space In  Tank is: 31.00Cm
LOW Water Level
Motor Turned ON
Water Space In  Tank is: 15.00Cm
Water Space In  Tank is: 15.00Cm
Water Space In  Tank is: 15.00Cm
Water Space In  Tank is: 18.00Cm
Water Space In  Tank is: 18.00Cm
Water Space In  Tank is: 18.00Cm
Water Space In  Tank is: 10.00Cm
Water Tank Full 
Motor Turned OFF

N.B. I hate those 'delay()'s.
'millis()'-based timing would be much nicer. :slight_smile:

Can we see that sender code please?

hi,
Thanks for the reply. Here is the sender code:

#define trigger 10
#define echo 11
#define transmit 1
#define receive 0
 
float time=0,distance=0;
int temp=0; 
void setup()
{
 pinMode(trigger,OUTPUT);
 pinMode(echo,INPUT);
 pinMode(transmit, OUTPUT);
 pinMode(receive, INPUT);
 Serial.begin(9600);
 delay(1000);
}
 
void loop()
{
 digitalWrite(trigger,LOW);
 delayMicroseconds(2);
 digitalWrite(trigger,HIGH);
 delayMicroseconds(10);
 digitalWrite(trigger,LOW);
 delayMicroseconds(2);
 time=pulseIn(echo,HIGH);
 distance=time*340/20000;
 digitalWrite(receive,LOW);
 Serial.println(distance);
 }

I simulated the circuit in protheus. It assumes that the power and ground is already connected.

You don't need to define 'transmit' and 'receive' pins, then make them output and input respectively.
The hardware serial library takes care of all that stuff.
edit: And why do you do this?:-

digitalWrite(receive,LOW);

Next, 'pulseIn()' returns an unsigned long, not a float. And you'll never end up with better than 1cm accuracy, so why use float at all? You could just declare distance as 'int' or 'long' and time as 'unsigned long'.

Then, instead of this:-

distance=time*340/20000;

(I think you need a .0 in there somewhere.)
this is better:-

distance = time / 29 / 2;

But I'd recommend the "NewPing" library anyway, which does the conversion automatically if you use 'ping_cm()', as well as having other features.


Just testing a moment ago, if I send with a newline line ending character, no value is printed at the receiving end.

On the sender, try changing the 'println()' to 'print()', so that no '\n' character is sent.
And get rid of that -'0' on the receiving end.

Also, on the receiving end, 'echo' is never used, so you can get rid of it and the associated 'pinMode()' line.

Edit2: You might want to send values from the 'ping' sensor a little less often, too. Your receiving code can't process it at the rate that you're sending, especially with all of those delays at the receiving end.
Even ignoring that, you need some time between cycles of the 'ping' sensor. The HC-SR04 datasheet recommends measurement cycles larger than 60mS.
You'll need considerably longer than that for your receiving code to keep up though.

I made some changes in the program as suggested.
Sender code:

#define trigger 10
#define echo 11
float time=0,distance=0;
int temp=0; 
void setup()
{
 pinMode(trigger,OUTPUT);
 pinMode(echo,INPUT);
 Serial.begin(9600);
 delay(1000);
}
 
void loop()
{
 digitalWrite(trigger,LOW);
 delayMicroseconds(2);
 digitalWrite(trigger,HIGH);
 delayMicroseconds(10);
 digitalWrite(trigger,LOW);
 delayMicroseconds(2);
 time=pulseIn(echo,HIGH);
 distance=time/29/2;
 Serial.println(distance);
 }

Receiver code:

#include <LiquidCrystal.h>
#define motor 8
#define buzzer 12
 
LiquidCrystal lcd(2,3,4,5,6,7);
 
int distance=0;
int temp=0; 
void setup()
{
 lcd.begin(16,2);
 pinMode(motor, OUTPUT);
 pinMode(buzzer, OUTPUT);
 lcd.print("  Water Level ");
 lcd.setCursor(0,1);
 lcd.print("   Indicator  ");
 Serial.begin(9600);
 delay(2000);
}
 
void loop()
{
  while(Serial.available()==0){}
  distance=Serial.parseInt();
  lcd.clear();
  lcd.print("Water Space In  ");
  lcd.setCursor(0,1);
  lcd.print("Tank is: ");
  lcd.print(distance);
  lcd.print("Cm");
  delay(2000);
 if(distance<12 && temp==0)
 {
     digitalWrite(motor, LOW);
     digitalWrite(buzzer, HIGH);
     lcd.clear();
     lcd.print("Water Tank Full ");
     lcd.setCursor(0,1);
     lcd.print("Motor Turned OFF");
     delay(2000);
     digitalWrite(buzzer, LOW);
     delay(3000);
     temp=1;
 }
 
  else if(distance<12 && temp==1)
 {
     digitalWrite(motor, LOW);
     lcd.clear();
     lcd.print("Water Tank Full ");
     lcd.setCursor(0,1);
     lcd.print("Motor Turned OFF");
     delay(5000);
 }
 
 else if(distance>30)
 {
   digitalWrite(motor, HIGH);
   lcd.clear();
   lcd.print("LOW Water Level");
   lcd.setCursor(0,1);
   lcd.print("Motor Turned ON");
   delay(5000);
   temp=0;
 }
}

In the screenshots, it can be seen that when the program started, distance was 33cm. When the distance became 44cm, the lcd still shows 33cm only. the receiving side program does not read the next incoming values. i tried using Serial.print(distance) instead of Serial.println(distance) on the sending side. it did not work. The lcd displayed something like 3348cm and the motor remained turned on.

Well, you took notice of a couple of the things I said and ignored the rest.

I won't repeat everything that I said. It's far easier if you go back and read my suggestions again, then rewrite your code to suit. Go over my replies point-by-point. Take your time. This isn't a race. (If it is, I won, :smiley: )

As I showed earlier with the prints to the serial monitor, when the sending is done properly, everything works fine.

You'd be making a big step forward if you took the time to learn 'millis()'-based timing, too, instead of using all of those horrible 'delay()' statements

If you want to make it more bulletproof, use start and end markers for your serial communications. You're getting the "3348cm" because you're sending a second value before your receiver delays have ended, so the two values are concatenated.
Perhaps if you Google "serial input basics", and read the relevant forum thread?

And on an aside, I'm not a big fan of Arduino simulations. It's far better to build real test circuits.