Void loop and if else not looping

I hope i have this in the right place.

So this is my 1st project. it works 99%, just 1 issue.

Board is a Nano clone.

It's intended to turn on pin 7 if either pin 10 or 11 are HIGH
and not turn on if pin 12 is HIGH

then wait for a timeout and do it again

no pin High is by design a fast loop where nothing happens.
Most of the code is for the LCD display which ok and works just as intended

The issue is the last "esle if"



#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);

//Declare pins
int ledPin = 13;     //Pin to trigger external LED
int triggerPin = 7;  //Pin to trigger external device
int skipPin = 12;    //Pin to read for high status to set skip
int run10Pin = 11;
int run15Pin = 10;

//Declare counts
int count = 0;      //Initial event count
int skipCount = 0;  //Count of skipped activations

//Declare LCD outputs
int countPos = 14;   //Position of event counter
int countLine = 2;   //Line for event count
int statusPos = 11;  //Position of Status output
int statusLine = 1;  //Line For status output
int skipPos = 10;    //Position of Status output
int skipLine = 3;    //Line For status output

//Declare general
int run10On = 600000;     // 10 minutes
int run10Test = 20000;    // shorter test
int run10Off = 85800000;  //23hrs 50 Min
int test10Off = 30000;
int run15On = 900000;     // 15 minutes
int run15Test = 20000;    //shorter time for testing
int run15Off = 85500000;  //23hrs 45 Min
int test15Off = 50000;
int skipTime = 864000000;  // 24 hour skip time
int skipTest = 30000;      // 1 min skip for testing


void setup() {
  //start Serial Monitor
  Serial.begin(9600);
  // Controller setup, to run once:
  pinMode(triggerPin, OUTPUT);    //Set Pin to trigger output
  pinMode(ledPin, OUTPUT);        //Set Pin to trigger LED
  pinMode(skipPin, INPUT);        //Set pin to read for setting skip state
  pinMode(run10Pin, INPUT);       //Set pin to read for setting 10 min run
  pinMode(run15Pin, INPUT);       //Set pin to read for setting 15 min run
  lcd.init();                     // initialize the lcd
  lcd.backlight();                // Turn on backlight
  lcd.print("    Magic Bucket");  // Print a message to the LCD
  digitalWrite(triggerPin, LOW);  //set device status to off
  digitalWrite(ledPin, LOW);      //set LED status to off
}

void loop() {
  // main device code, to run repeatedly:
  Serial.println("top of loop");
  lcd.setCursor(0, 1);  // set the cursor to column 0, line 1
  lcd.print("Water is :");
  lcd.setCursor(0, 2);  // set the cursor to column 0, line 1
  lcd.print("Activations :");
  lcd.setCursor(0, 3);  // set the cursor to column 0, line 1
  lcd.print("Skipped : ");

  if (digitalRead(skipPin) == HIGH) {      //Check if Skip pin is set high
    skipCount++;                           // Increment skipped counter
    digitalWrite(triggerPin, LOW);         //turn device off
    digitalWrite(ledPin, LOW);             //turn LED off
    lcd.setCursor(statusPos, statusLine);  // set the cursor to column 12, line 1
    lcd.print("Skipped");
    lcd.setCursor(skipPos, skipLine);  // set the cursor to counter position.
    lcd.print(skipCount);              //print count of skipped activations
    delay(skipTest);                   //SKIP Runtime
    //delay(skipTime); //SKIP Runtime
    Serial.println("end of skip");
  } else if (digitalRead(run10Pin) == HIGH) {
    digitalWrite(triggerPin, HIGH);        //turn device on
    digitalWrite(ledPin, HIGH);            //turn device on
    count++;                               // Increment counter
    lcd.setCursor(statusPos, statusLine);  // set the cursor to column 12, line 1
    lcd.print("On - 10m ");
    lcd.setCursor(countPos, countLine);  // set the cursor to counter position.
    lcd.print(count);                    //print count of activations
    delay(run10Test);                    // 10 test runtime
    //delay(run10On); //ON Runtime
    //set off time
    lcd.setCursor(statusPos, statusLine);  // set the cursor to column 12, line 1
    digitalWrite(triggerPin, LOW);         //turn device off
    digitalWrite(ledPin, LOW);             //turn LED off
    lcd.print("Off      ");
    delay(test10Off);  //test10Off time
    //delay(run10Off); //run10 time off
    Serial.println("end of 10delay");
  } else if (digitalRead(run15Pin) == HIGH) {
    digitalWrite(triggerPin, HIGH);        //turn device on
    digitalWrite(ledPin, HIGH);            //turn device on
    count++;                               // Increment counter
    lcd.setCursor(statusPos, statusLine);  // set the cursor to column 12, line 1
    lcd.print("On - 15m ");
    lcd.setCursor(countPos, countLine);  // set the cursor to counter position.
    lcd.print(count);                    //print count of activations
    delay(run15Test);                    // 15 test Runtime
    //delay(run15On); //ON Runtime
    //set off time
    lcd.setCursor(statusPos, statusLine);  // set the cursor to column 12, line 1
    digitalWrite(triggerPin, LOW);         //turn device off
    digitalWrite(ledPin, LOW);             //turn LED off
    lcd.print("Off      ");
    Serial.println("start of 15delay");
    delay(test15Off);  //test10Off time
    //delay(run15Off); //run10 time off
    Serial.println("end of 15delay");
  } else {
    Serial.println("final else");
  }
}

bool i2CAddrTest(uint8_t addr) {
  Wire.begin();
  Wire.beginTransmission(addr);
  if (Wire.endTransmission() == 0) {
    return true;
  }
  return false;
}

this is the serial output if pin 10 is high.
It activates, turns of and that's the last this it does, it never gets to the "end of 15delay" statement

23:02:12.646 -> top of loop
23:02:32.744 -> start of 15delay

This is the output from the other 2 activated modes. (Pin 12 and the Pin 11 HIGH) No issues at all

23:30:39.794 -> top of loop
23:31:09.887 -> end of skip
23:31:09.887 -> top of loop
23:31:39.957 -> end of skip
23:31:39.957 -> top of loop
23:32:29.998 -> end of 10delay
23:32:29.999 -> top of loop
23:33:20.123 -> end of 10delay
23:33:20.123 -> top of loop
23:34:10.168 -> end of 10delay
23:34:10.168 -> top of loop

I gather I'm missing something to do with the If/else framework, but I'd like to know why the 1st to sections work fine and the program runs continuously for days, but the run15 section literally runs once, then begins the delay and then everything stops

all times values are short testing values as this is intended to run once a day.

I'm sure somewhere in here "millis" should be used but i haven't got my head around this yet.

Any advice gratefully received.

Thank you

When I compile your code for a Leonardo (you don't state which board you're compiling for) this is the first warning (there are a few more like that)

C:\Users\bugge\AppData\Local\Temp\.arduinoIDE-unsaved202626-18328-10liu89.zlk4i\sketch_mar6a\sketch_mar6a.ino:24:15: warning: overflow in implicit constant conversion [-Woverflow]
 int run10On = 600000;     // 10 minutes

Not said that it's the cause of your problem but definitely an issue.

And there are a few like below as well

C:\Users\bugge\AppData\Local\Temp\.arduinoIDE-unsaved202626-18328-10liu89.zlk4i\sketch_mar6a\sketch_mar6a.ino:66:15: warning: operation on 'skipCount' may be undefined [-Wsequence-point]
     skipCount = ++skipCount;               // Increment skipped counter

Just use skipCount++.

Again not said that this is the cause of your problems but needs improvement/solving.


You're advised to set the Warning Level under preferences to All.

2 Likes

@traincoder - welcome to the forum.

How are your switches wired? Or at least say the inputs aren't floating wherever they come from.

Quick use the IDE Autoformat tool, copy the code and paste it over the code you posted! It will make reading your code easier for everyone including you.

TIA

a7

1 Like

What is the range of values for an int on a Nano clone? (hint - some of your values are out of range).

2 Likes

Thanks!

Ive updated the board (Nano) in the 1st post

And oh look at the warnings! lol definite overflow operations.
i need to look st that... convert to "long" jumps to mind

Currently just on a breadboard so nothing attached other than a jumper wire as i select them.
wanted to get the code running before breaking out the hardware box.

We have success!

Thanks. Much appreciated.

changes the delay time declarations to "long".

now its looping ok. but running tests for all settings.

also fixed the count increase, much simpler.

I need to look up things like the value ranges. i'm sure there is a data sheet somewhere.

Very happy now.

Thanks again

Change your pinMode()s to INPUT_PULLUP.

Then ground the inout pin to drive it LOW, if left open it will be pulled HIGH.

Your logic then may be upside down.

You might

# define PRESSED LOW

up top, then compare the digitalRead() to that defined value.

  bool switchState = digitalRead(somePin) == PRESSED;  // true is switch closed

It reads better, and lets you easily change your mind or adjust to however you end up wiring your switches.

a7

1 Like

Current the wiring connects the 5v pin direct to the input pin to go HIGH

Intention was just a basic 3 position switch.
but i get the idea if forcing the "off" state to be low or high to prevent erroneous inputs.

I'll do some study on those other statements. I'm very very green, this was just written after a few you tube videos and a search on the LCD controls code. learning as i go.

Have had it loop through all output options now and working just fine.

But I'll add in the INPUT_PULLUP section. makes sense.

Thanks again.

besides

  • usingunsigned long and L ahen specifying delay values
  • count++ instead of count = ++count;
  • bear in mind the INPUT_PULLUP pulls the pin HIGH, the pin needs to be pulled down to ground by a button or other source.
  • copy&paste is error prone and difficult to debug, use functions. look the following over
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd (0x27, 20, 4);

// Declare pins
int ledPin      = 13; // Pin to trigger external LED
int triggerPin  = 7;  // Pin to trigger external device
int skipPin     = 12; // Pin to read for high status to set skip
int run10Pin    = 11;
int run15Pin    = 10;

// Declare counts
int count       = 0; // Initial event count
int skipCount   = 0; // Count of skipped activations

// Declare LCD outputs
int countPos    = 14;   // Position of event counter
int countLine   = 2;    // Line for event count
int statusPos   = 11;   // Position of Status output
int statusLine  = 1;    // Line For status output
int skipPos     = 10;   // Position of Status output
int skipLine    = 3;    // Line For status output

// Declare general
#define Sec(n)   (n*1000L);
#define Min(n)   (n*Sec(60));
unsigned long run10Test   =      Sec(10);
unsigned long test10Off   =      Sec(3);
unsigned long run15Test   =      Sec(15);
unsigned long test15Off   =      Sec(5);
unsigned long skipTest    =      Sec(5);

enum { Off = LOW, On = HIGH };

// -----------------------------------------------------------------------------
void setup ()
{
    Serial.begin (9600);

    pinMode (triggerPin, OUTPUT);
    pinMode (ledPin, OUTPUT);
    pinMode (skipPin,  INPUT_PULLUP);
    pinMode (run10Pin, INPUT_PULLUP);
    pinMode (run15Pin, INPUT_PULLUP);

    lcd.init ();
    lcd.backlight ();
    lcd.print ("    Magic Bucket");

    digitalWrite (triggerPin, LOW);
    digitalWrite (ledPin,     LOW);
}

// -----------------------------------------------------------------------------
void turnOn  (
    const char    *status,
    unsigned long  msec1,
    unsigned long  msec2,
    const char    *trailer )
{
    Serial.print   ("tuenOn: ");
    Serial.println (status);

    if (0 < msec1)  {
        digitalWrite (triggerPin, On);
        digitalWrite (ledPin,     On);
    }

    lcd.setCursor (statusPos, statusLine); lcd.print (status);
    lcd.setCursor (countPos,  countLine);  lcd.print (count);
    lcd.setCursor (skipPos,   skipLine);   lcd.print (skipCount);

    delay (msec1);

    digitalWrite (triggerPin, Off);
    digitalWrite (ledPin,     Off);

    lcd.setCursor (statusPos, statusLine); lcd.print ("Off      ");

    delay (msec2);
    Serial.println (trailer);
}

// -----------------------------------------------------------------------------
void loop () {

    Serial.println ("top of loop");
    lcd.setCursor (0, 1); lcd.print ("Water is :");
    lcd.setCursor (0, 2); lcd.print ("Activations :");
    lcd.setCursor (0, 3); lcd.print ("Skipped : ");

    if (digitalRead (skipPin) == LOW) {
        skipCount++;
        turnOn ("skipped", 0, test10Off, "end of skip");
    }
    else if (digitalRead (run10Pin) == LOW) {
        count ++;
        turnOn("On - 10m ", run10Test, test10Off, "end of 10 test");
    }
    else if (digitalRead (run15Pin) == LOW) {
        count ++;
        turnOn("On - 15m ", run15Test, test15Off, "end of 15 test");
    }
}

I think i have a fair bit of study before i understand this.

have not got to functions yet.
I'll get there though.

Definitely looks nicer.

Thanks