DO WHILE loop problem

Hello everybody,

I'm quite new in the programming but I'm trying to improve my skills.
I'm making a project for my greengarden. I'm making automatic irrigation boom contdolled by my Mega 2560 and Nextion display. The problem that I have is that the "DO ....WHILE" loop in the "void b1PushCallback(void *ptr) " exits for some reason even if the while statement is still true. The idea is to repeat the code inside the function until the boom is detected on the other end of the greenhouse. I'm doing something wrong but have no idea what. Inside of the loop the RPM of my motor are calculated and the PWM to the VFD is regulated to achive a constant speed of movement. I'm posing my code and I'm here for any additional information.

#include <Nextion.h>


int ambtemp; // ambient air temp
int shum; // soil humiduty
volatile byte tick; // counter for the motor wheel
unsigned int rpm;
unsigned long timeold;
int actualspeed;
int pwm;
int adjust = 5;



#define ssensor A0 // soil sensor pin
#define rpmsensor 21 // motor rpm sensor
#define startpos 22 // sensor for start
#define endpos 23 // sensor for end
#define forward 24 // forward direction of movement
#define reverse 25 // reverse direction of movement 
#define motor 2 // pwm for motor speed
#define pump 28 // pump relay



NexButton b1 = NexButton(3, 3, "b1");  // Button 5 l/dka
NexButton b2 = NexButton(3, 4, "b2");  // Button 10 l/dka
NexButton b3 = NexButton(3, 5, "b3");  // Button 15 l/dka
NexButton b0 = NexButton(7, 4, "b0"); // Stop Button


// Declare touch event objects to the touch event list:
// You just need to add the names of the objects that send a touch event.
// Format: &<object name>,

NexTouch *nex_listen_list[] =
{
  &b1,  // Button added
  &b2,  // Button added
  &b3,  // Button added
  &b0,
  NULL  // String terminated
};  // End of touch event list


void tick_count() {

  static unsigned long last_interrupt_time = 0;
  unsigned long interrupt_time = millis();
  // If interrupts come faster than 200ms, assume it's a bounce and ignore
  if (interrupt_time - last_interrupt_time > 200)
  {
    tick++;
  }
  last_interrupt_time = interrupt_time;
}

void RPM_calculation() {

  if (tick >= 3)                                    //Points to detect
  {
    rpm = 15 * 1000 / (millis() - timeold) * tick;
    timeold = millis();
    tick = 0;

  }

}
void pwmvalue1 () {
  if (rpm < 5) {
    if (pwm != 255) {
      pwm += adjust;
    }
  }
  if (rpm > 5) {
    if (pwm != 0) {
      pwm -= adjust;
    }
  }
}

void b1PushCallback(void *ptr)  // Press event for button 5 l/dka
{

  digitalRead(startpos);
  digitalRead(endpos);
  if (startpos == 0 && endpos == 1) {
    digitalWrite(reverse , HIGH);
  } else digitalWrite(forward , HIGH);

  do {
    RPM_calculation();
    Serial.print("rpm.val=");
    Serial.print(rpm);
    Serial.write(0xff);
    Serial.write(0xff);
    Serial.write(0xff);
    pwmvalue1 ();
    digitalWrite(pump , HIGH);
    analogWrite(motor , pwm);
  } while (startpos == 0);
}


//void b0PushCallback(void *ptr)  // Press event for back button
//{
//digitalWrite(pump , LOW);
//analogWrite(motor , 0);
//}






void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(ssensor , INPUT);
  pinMode(rpmsensor, INPUT_PULLUP);
  pinMode(startpos , INPUT);
  pinMode(endpos, INPUT);
  pinMode(forward , OUTPUT);
  digitalWrite(forward , LOW);
  pinMode(reverse, OUTPUT);
  digitalWrite(reverse , LOW);
  pinMode(motor , OUTPUT);
  attachInterrupt(digitalPinToInterrupt(rpmsensor), tick_count, FALLING);


  // Register the event callback functions of each touch event:
  // You need to register press events and release events seperatly.
  // Format for press events: <object name>.attachPush(<object name>PushCallback);
  // Format for release events: <object name>.attachPop(<object name>PopCallback);
  // b0.attachPush(b0PushCallback);  // Button press
  b1.attachPush(b1PushCallback);  // Button press
  // b2.attachPush(b2PushCallback);  // Button press
  // b3.attachPush(b3PushCallback);  // Button press

}




void loop() {
  // put your main code here, to run repeatedly:
  nexLoop(nex_listen_list);  // Check for any touch event
  digitalWrite(pump , LOW);
  analogWrite(motor , 0);
  shum = analogRead(ssensor);
  shum = map(shum, 550, 0, 0, 100);
  Serial.print("n7.val=");
  Serial.print(shum);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);

  delay(1000);



}

That do-while loop will exit only if startpos == 0 print it out to check.

#define startpos 22 // sensor for start
  digitalRead(startpos);
  digitalRead(endpos);
  if (startpos == 0 && endpos == 1)

Is startpos a pin number or the state of a pin ?

Hello MarkT - Thanks for you fast reply. Am I understanding wrong , the while statement must become false , then the loop will exit , isnt it. At least this is what I understand reading the while function explanation.

Hello UKHeliBob - 22 is a pin number to which one the proximty sensor is attached.

What do you think happens when these lines are executed?

digitalRead(startpos);
digitalRead(endpos);

.

larryd:
What do you think happens when these lines are executed?

digitalRead(startpos);
digitalRead(endpos);

.

hello larryd , I get what you mean. reading the current state is just nothing if it is not assigned to a variable that will keep it. Then I should check it.

Delta_G:
What do you think are the chances that 22 will ever equal 0? That's pretty elementary math.

Wrong declaration of the pins. Stupidity is the word :slight_smile: I fixed that also.

Now the loop is running well and I can see readings for my pwm. For some reason it is changing too fast from 0 to 255 and vice versa. I'll try to figure that out also. If anybody can help it will be appreciated.

I don't know guys if that is the way how you help , just be a bit sarcastic instead of explaining what the idiots like me made wrong but it works for me , so thank you again :slight_smile:

Now the code looks like this and as I said any help for the pwm value will be appreciated:

#include <Nextion.h>


int ambtemp; // ambient air temp
int shum; // soil humiduty
volatile byte tick; // counter for the motor wheel
unsigned int rpm;
unsigned long timeold;
int actualspeed;
int pwm;
int adjust = 5;
int checkpos1;
int checkpos2;



const int ssensor = A0; // soil sensor pin
const int rpmsensor = 21; // motor rpm sensor
const int startpos = 22; // sensor for start
const int endpos = 23; // sensor for end
const int forward = 24; // forward direction of movement
const int reverse = 25; // reverse direction of movement 
const int motor = 2; // pwm for motor speed
const int pump = 28; // pump relay



NexButton b1 = NexButton(3, 3, "b1");  // Button 5 l/dka
NexButton b2 = NexButton(3, 4, "b2");  // Button 10 l/dka
NexButton b3 = NexButton(3, 5, "b3");  // Button 15 l/dka
NexButton b0 = NexButton(7, 4, "b0"); // Stop Button


// Declare touch event objects to the touch event list:
// You just need to add the names of the objects that send a touch event.
// Format: &<object name>,

NexTouch *nex_listen_list[] =
{
  &b1,  // Button added
  &b2,  // Button added
  &b3,  // Button added
  &b0,
  NULL  // String terminated
};  // End of touch event list


void tick_count() {

  static unsigned long last_interrupt_time = 0;
  unsigned long interrupt_time = millis();
  // If interrupts come faster than 200ms, assume it's a bounce and ignore
  if (interrupt_time - last_interrupt_time > 200)
  {
    tick++;
  }
  last_interrupt_time = interrupt_time;
}

int RPM_calculation() {

  if (tick >= 3)                                    //Points to detect
  {
    rpm = 15 * 1000 / (millis() - timeold) * tick;
    timeold = millis();
    tick = 0;

  }
return rpm;
}
int pwmvalue1 () {
  if (rpm < 5) {
    if (pwm != 255) {
      pwm += adjust;
    }
  }
  if (rpm > 5) {
    if (pwm != 0) {
      pwm -= adjust;
    }
  }
  return pwm;
}

void b1PushCallback(void *ptr)  // Press event for button 5 l/dka
{

  checkpos1 = digitalRead(startpos);
  checkpos2 = digitalRead(endpos);
  if (checkpos1 == 0 && checkpos2 == 1) {
    digitalWrite(reverse , HIGH);
  } else digitalWrite(forward , HIGH);

  do {
    RPM_calculation();
    Serial.print("rpm.val=");
    Serial.print(rpm);
    Serial.write(0xff);
    Serial.write(0xff);
    Serial.write(0xff);
    pwmvalue1 ();
    digitalWrite(pump , HIGH);
    analogWrite(motor , pwm);
  } while (checkpos1 == 0);
}


//void b0PushCallback(void *ptr)  // Press event for back button
//{
//digitalWrite(pump , LOW);
//analogWrite(motor , 0);
//}






void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(ssensor , INPUT);
  pinMode(rpmsensor, INPUT_PULLUP);
  pinMode(startpos , INPUT);
  pinMode(endpos, INPUT);
  pinMode(forward , OUTPUT);
  digitalWrite(forward , LOW);
  pinMode(reverse, OUTPUT);
  digitalWrite(reverse , LOW);
  pinMode(motor , OUTPUT);
  attachInterrupt(digitalPinToInterrupt(rpmsensor), tick_count, FALLING);


  // Register the event callback functions of each touch event:
  // You need to register press events and release events seperatly.
  // Format for press events: <object name>.attachPush(<object name>PushCallback);
  // Format for release events: <object name>.attachPop(<object name>PopCallback);
  // b0.attachPush(b0PushCallback);  // Button press
  b1.attachPush(b1PushCallback);  // Button press
  // b2.attachPush(b2PushCallback);  // Button press
  // b3.attachPush(b3PushCallback);  // Button press

}




void loop() {
  // put your main code here, to run repeatedly:
  nexLoop(nex_listen_list);  // Check for any touch event
  digitalWrite(pump , LOW);
  analogWrite(motor , 0);
  shum = analogRead(ssensor);
  shum = map(shum, 550, 0, 0, 100);
  Serial.print("n7.val=");
  Serial.print(shum);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);

  delay(1000);



}

Ok , may be I did not use the exact wotd saying sarcastic. What I'm pointing is that if I knew what I'ce done wrong , I will never ask. Mostly the people around ask because they DO NOT KNOW what exactly they mess up. I'm not feeling bad or stupid , not at all . Also I respect people like you Delta_G because of their knowledge. I respect also that you're spending time here to help people like me. What I saying is that a simple explanation will do much more than the rhetorical questions. I wish to became good in this , as good as you are. Up to know , I'm a good mechanical engineer and I grow very nice onions , cabbage and carrots. No offense to you or anybody around :slight_smile:

On the the problems with the programming - I manage to fix also the change of the pwm value adding a short period before every change (about 250 ms ) and know the regulation is much more precise.
For now it seems that the things are going to the right direction. Thank you all again for the help.