Monitoring Sketch

I have written the following sketch to monitor two sensors and when they read high I want to flash an LED for each one independently. Although it works by going through both if statements each pass, I feel that it is a bit clunky! I wondered if there is way for each sensor to trigger a flashing sub-routine? If there was a more efficient method of programming, it would help a future project. Thank you in advance for any help or advice offered.

int LED1 = 7;
int LED2 = 8;
int sensor1 = 9;
int sensor2 = 10;
int flash = 200;
int sensor1state;
int sensor2state;

void setup() {
  
  pinMode(sensor1, INPUT);
  pinMode(sensor2, INPUT);
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  
  digitalWrite(LED1, LOW);
  digitalWrite(LED2, LOW);
  
  
}

void loop() {
  
 sensor1state = digitalRead(sensor1); 
 sensor2state = digitalRead(sensor2);
    
  if (sensor1state == LOW){
    digitalWrite(LED1, LOW);
  }
  else {
    digitalWrite(LED1, HIGH);
    delay(flash);
    digitalWrite(LED1, LOW);
  }  
    
  if (sensor2state == LOW){
    digitalWrite(LED2, LOW);
  }
  else {
    digitalWrite(LED2, HIGH);
    delay(flash);
    digitalWrite(LED2, LOW); 
  }
    delay(flash);
}

Have a look at the blinkwithout delay example in the IDE (File- Examples- Digital iirc) and then put that code into 2 functions, remembering to double up the names like eg previousMillis1 and previousMillis2 or whatever.

Then call the appropriate function in the "if" of whichever sensor is over its limit; this delay()-less approach will work for both at once.

When a sensor is below its limit, explicitly turn its led off.

consider

#undef MyHW
#ifdef MyHW
const byte LED1 = 12;
const byte LED2 = 13;
const byte sensor1 = A1;
const byte sensor2 = A2;

#else
int LED1 = 7;
int LED2 = 8;
int sensor1 = 9;
int sensor2 = 10;
#endif

int sensor1state;
int sensor2state;

const unsigned long Flash = 200;
unsigned long msecLst;

enum { Off = HIGH, On = LOW };

void loop()
{
    unsigned long msec = millis ();

    if ( (msec - msecLst) > Flash)  {
        msecLst = msec;

        if (LOW == sensor1state)
            digitalWrite (LED1, ! digitalRead (LED1));
        else
            digitalWrite (LED1, Off);

        if (LOW == sensor2state)
            digitalWrite (LED2, ! digitalRead (LED2));
        else
            digitalWrite (LED2, Off);
    }

    sensor1state = digitalRead (sensor1);
    sensor2state = digitalRead (sensor2);
}


void setup() {
    pinMode(sensor1, INPUT_PULLUP);
    pinMode(sensor2, INPUT_PULLUP);
    pinMode(LED1, OUTPUT);
    pinMode(LED2, OUTPUT);
}

Many thanks for your speedy reply, i have tried that and although it compiles OK, it does not work. I am obviously missing something but can't see anything amiss! Hopefully someone can spot my error!

const int LED1 = 7;
const int LED2 = 8;
const int sensor1 = 9;
const int sensor2 = 10;
const long interval = 1000;           // interval at which to blink (milliseconds)
int sensor1state;
int sensor2state;
int LED1state = LOW;
int LED2state = LOW;
unsigned long previousMillis = 0;

void setup() {
  
  pinMode(sensor1, INPUT);
  pinMode(sensor2, INPUT);
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  
  digitalWrite(LED1, LOW);
  digitalWrite(LED2, LOW);  
}

void loop() {
  
 sensor1state = digitalRead(sensor1); 
 sensor2state = digitalRead(sensor2);
    
  if (sensor1state == LOW){
    digitalWrite(LED1, LOW);
  }
  else {
    
   void flashLED1(); 
}
    
  if (sensor2state == LOW){
    digitalWrite(LED2, LOW);
  }
  else {
    
    void flashLED2();

  }

}

void flashLED1() {

  // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (LED1state == LOW) {
      LED1state = HIGH;
    } else {
      LED1state = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(LED1, LED1state);
  }
}

void flashLED2() {
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (LED2state == LOW) {
      LED2state = HIGH;
    } else {
      LED2state = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(LED2, LED2state);
  }
}

Thank you for your reply, I have had a look at it but don't quite understand it. I will spend more time on it to see if I can get to grips with it.

These lines don't get the word "void" in front- that's for when you created a function, not when you call it.

I didn't check further once I saw that.

It's pretty much what you did in the functions, just "in line" shall we say.

Great, that did the trick! I am running it on a simulator and one of the LEDs is flashing considerably slower, but I think that is down to the simulator. I will rig a physical one up and try that. Thanks for your help, it is much appreciated.

OK thanks, I will look at it later.

Hello SierraGolfMike
Yes, there is. The magic word is OOP.
Below you will see a simple example to do this with several objects and a service that handle the button and blink business.

/* BLOCK COMMENT
  ATTENTION: This Sketch contains elements of C++.
  https://www.learncpp.com/cpp-tutorial/
  Many thanks to LarryD
  https://europe1.discourse-cdn.com/arduino/original/4X/7/e/0/7e0ee1e51f1df32e30893550c85f0dd33244fb0e.jpeg
  https://forum.arduino.cc/t/monitoring-sketch/996076
  Tested with Arduino: Mega[ ] - UNO [ ] - Nano [ ]
*/
#define ProjectName "Monitoring Sketch"
// HARDWARE AND TIMER SETTINGS
// YOU MAY NEED TO CHANGE THESE CONSTANTS TO YOUR HARDWARE AND NEEDS
constexpr byte ButtonPins[] {A0,A1,A2};      // portPin o---|button|---GND
constexpr byte LedPins[] {9, 10, 11};        // portPin o---|220|---|LED|---GND
constexpr unsigned long BlinkRate[] {100,500,1000}; 
#define OutPutTest
constexpr  unsigned long OutPutTestTime {1000};
// CONSTANT DEFINITION
enum {One, Two, Three};
// VARIABLE DECLARATION AND DEFINITION
unsigned long currentTime;
enum {Stop, Start, Blink};
enum {Released, Pressed};
struct TIMER {              // has the following members
  unsigned long duration;   // memory for interval time
  unsigned long stamp;      // memory for actual time
  int onOff;               // control for stop/start/blink
};
struct BUTTON {             // has the following members
  byte pin;                 // port pin
  bool statusQuo;           // current state
  TIMER scan;               // see timer struct
};
struct MONITOR {
  byte led;
  BUTTON knop;
  TIMER flash;
} monitors[] {
  {LedPins[One],   ButtonPins[One],   false, 20, 0, Blink, BlinkRate[One], 0, false},
  {LedPins[Two],   ButtonPins[Two],   false, 20, 0, Blink, BlinkRate[Two], 0, false},
  {LedPins[Three], ButtonPins[Three], false, 20, 0, Blink, BlinkRate[Three],  0, false},
};
// time handler
bool timerEvent (TIMER &timer) {
  bool reTurn = currentTime - timer.stamp >= timer.duration && timer.onOff;
  if (reTurn) timer.onOff == Blink ? timer.stamp = currentTime : timer.onOff = Stop;
  return reTurn;
}
// -------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  Serial.println(F("."));
  Serial.print(F("File   : ")), Serial.println(__FILE__);
  Serial.print(F("Date   : ")), Serial.println(__DATE__);
  Serial.print(F("Project: ")), Serial.println(ProjectName);
  pinMode (LED_BUILTIN, OUTPUT);  // used as heartbeat indicator
  //  https://www.learncpp.com/cpp-tutorial/for-each-loops/
  for (auto monitor : monitors) pinMode(monitor.knop.pin, INPUT_PULLUP);
  for (auto monitor : monitors) pinMode(monitor.led, OUTPUT);
#ifdef OutPutTest
  // check outputs
  for (auto monitor : monitors) digitalWrite(monitor.led, HIGH), delay(OutPutTestTime);
  for (auto monitor : monitors) digitalWrite(monitor.led, LOW), delay(OutPutTestTime);
#endif
}
void loop () {
  currentTime = millis();
  digitalWrite(LED_BUILTIN, (currentTime / 500) % 2);
  for (auto &monitor : monitors) {
    if (timerEvent (monitor.knop.scan)) {
      int stateNew = !digitalRead(monitor.knop.pin);
      if (monitor.knop.statusQuo != stateNew) {
        monitor.knop.statusQuo = stateNew;
        switch (stateNew) {
          case Pressed:
            digitalWrite(monitor.led, HIGH);
            monitor.flash.stamp = currentTime;
            monitor.flash.onOff = Blink;
            break;
          case Released:
            digitalWrite(monitor.led, LOW);
            monitor.flash.onOff = Stop;
            break;
        }
      }
      if (timerEvent (monitor.flash))  digitalWrite(monitor.led, !digitalRead(monitor.led));
      }
  }
}

Have a nice day and enjoy coding in C++.
Дайте миру шанс!

really ??

.... as adafruit say "Put some oop in your loop" :wink:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.