Invoke two events

jdickinsonarduino:
Yes, it works now as long as the threshold is less than 90.
but it's constantly looking...so the pins go low when value goes back up.

Perhaps there is a way once it goes low to STOP.??

Just so I'm clear: You want the alarm condition to be sticky? That is, if the value ever goes below the threshold you want the alarm to stay on no matter how high it goes again?

Blackfin:
Just so I'm clear: You want the alarm condition to be sticky? That is, if the value ever goes below the threshold you want the alarm to stay on no matter how high it goes again?

Yes, Exactly !

Try

const int ledPin =  LED_BUILTIN;
const int analogPin = A0;
const int threshold = 90;
const int ledAlarm = 6;

// Variables will change:
int ledState = LOW;


unsigned long previousMillis = 0;
unsigned long analogMillis;

const long interval = 1000;
void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(ledAlarm, OUTPUT);

  Serial.begin(9600);
}

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

  int analogValue = analogRead(analogPin);

  if (analogValue < threshold)
  {
    digitalWrite(ledAlarm, HIGH);

    if (currentMillis - previousMillis >= interval)
    {
      previousMillis = currentMillis;

      ledState = !ledState;
      digitalWrite(ledPin, ledState);
    }
  }

  if (currentMillis - analogMillis >= 500)
  {
    analogMillis = currentMillis;
    Serial.println(analogValue);
  }

} //END of loop()

larryd:
Try

const int ledPin =  LED_BUILTIN;

const int analogPin = A0;
const int threshold = 90;
const int ledAlarm = 6;

// Variables will change:
int ledState = LOW;

unsigned long previousMillis = 0;
unsigned long analogMillis;

const long interval = 1000;
void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(ledAlarm, OUTPUT);

Serial.begin(9600);
}

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

int analogValue = analogRead(analogPin);

if (analogValue < threshold)
  {
    digitalWrite(ledAlarm, HIGH);

if (currentMillis - previousMillis >= interval)
    {
      previousMillis = currentMillis;

ledState = !ledState;
      digitalWrite(ledPin, ledState);
    }
  }

if (currentMillis - analogMillis >= 500)
  {
    analogMillis = currentMillis;
    Serial.println(analogValue);
  }

} //END of loop()

Pretty much same scenario:

Both pins go High at instance below 90 and remain. However, If I hold my hand over the solar panel and don't remove it forcing the values to stay below 90, pin 13 blinks as it should and pin 6 remains HIGH

Try:

//#define DEV     1   //for dev

#ifndef DEV
const int ledPin =  LED_BUILTIN;// the number of the LED pin
#else
const int ledPin =  0;// the number of the LED pin
#endif

const int analogPin = A0;    // pin that the Solar panel is attached to
const int threshold = 90;   // The threshold level that is between the solar value readings when the laser is in contact vs when the laser is off.
                             // change threshold value to calabrate alarm system
const int ledAlarm = 6;

#define SAMPLE_INTERVAL     500
#define ALARM_TOGGLE        250

#define LOW_THRESH_FLG      0b00000001
#define ALARM_STATE         0b00000010
#define TAKE_SAMPLE_FLG     0b00000100
byte
    bFlags;

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long
    currentTime,
    last_AlarmTime,
    last_SampleTime;
    
void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
  pinMode(ledAlarm, OUTPUT);
  // initialize serial communications:
  Serial.begin(9600);
  while( !Serial ); //wait for console

  currentTime = millis();
  last_AlarmTime = currentTime;
  last_SampleTime = currentTime;
  bFlags = 0b00000000;
  
}
void loop() 
{
    //Serial.println(bFlags);
    Channel_Read();
    GeneralTimerUpdates();
    Output_Handler();

}//loop

void Channel_Read()
{
    int
        analogValue;

    if( !(bFlags & TAKE_SAMPLE_FLG) )
        return;        

    //if flag is already set, just leave
    if( bFlags & LOW_THRESH_FLG )
        return;

#ifndef DEV
    analogValue = analogRead(analogPin);
#else
    analogValue = 80;   //test value
#endif
    if( analogValue < threshold )
        bFlags |= LOW_THRESH_FLG;
    
    bFlags &= ~TAKE_SAMPLE_FLG;
        
}//Channel_Read

void GeneralTimerUpdates()
{
    currentTime = millis();

    //sample timer
    if( (currentTime - last_SampleTime) >= SAMPLE_INTERVAL )
    {
        bFlags |= TAKE_SAMPLE_FLG;
        last_SampleTime = currentTime;
            
    }//if

    //alarm timer
    if( (currentTime - last_AlarmTime) >= ALARM_TOGGLE )
    {
        //toggle ALARM flag in bFlags; alarm output will track it
        //if input is < threshold
        bFlags ^= ALARM_STATE;
        last_AlarmTime = currentTime;
            
    }//if
    
}//GeneralTimerUpdates

void Output_Handler()
{
    //if below threshold, alarm tracks ALARM_STATE bit
    //otherwise it's off
    //assumes HIGH turns on alarm
    digitalWrite( ledAlarm, (bFlags & LOW_THRESH_FLG) ? ((bFlags & ALARM_STATE)?HIGH:LOW):LOW );

    //if below threshold, LED is on solid
    //otherwise it's off
    //assumes HIGH turns on LED
    digitalWrite( ledPin, (bFlags & LOW_THRESH_FLG) ? HIGH:LOW );
    
}//Output_Handler

Blackfin:
Try:

//#define DEV     1   //for dev

#ifndef DEV
const int ledPin =  LED_BUILTIN;// the number of the LED pin
#else
const int ledPin =  0;// the number of the LED pin
#endif

const int analogPin = A0;    // pin that the Solar panel is attached to
const int threshold = 90;  // The threshold level that is between the solar value readings when the laser is in contact vs when the laser is off.
                            // change threshold value to calabrate alarm system
const int ledAlarm = 6;

#define SAMPLE_INTERVAL    500
#define ALARM_TOGGLE        250

#define LOW_THRESH_FLG      0b00000001
#define ALARM_STATE        0b00000010
#define TAKE_SAMPLE_FLG    0b00000100
byte
    bFlags;

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long
    currentTime,
    last_AlarmTime,
    last_SampleTime;
   
void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
  pinMode(ledAlarm, OUTPUT);
  // initialize serial communications:
  Serial.begin(9600);
  while( !Serial ); //wait for console

currentTime = millis();
  last_AlarmTime = currentTime;
  last_SampleTime = currentTime;
  bFlags = 0b00000000;
 
}
void loop()
{
    //Serial.println(bFlags);
    Channel_Read();
    GeneralTimerUpdates();
    Output_Handler();

}//loop

void Channel_Read()
{
    int
        analogValue;

if( !(bFlags & TAKE_SAMPLE_FLG) )
        return;

//if flag is already set, just leave
    if( bFlags & LOW_THRESH_FLG )
        return;

#ifndef DEV
    analogValue = analogRead(analogPin);
#else
    analogValue = 80;  //test value
#endif
    if( analogValue < threshold )
        bFlags |= LOW_THRESH_FLG;
   
    bFlags &= ~TAKE_SAMPLE_FLG;
       
}//Channel_Read

void GeneralTimerUpdates()
{
    currentTime = millis();

//sample timer
    if( (currentTime - last_SampleTime) >= SAMPLE_INTERVAL )
    {
        bFlags |= TAKE_SAMPLE_FLG;
        last_SampleTime = currentTime;
           
    }//if

//alarm timer
    if( (currentTime - last_AlarmTime) >= ALARM_TOGGLE )
    {
        //toggle ALARM flag in bFlags; alarm output will track it
        //if input is < threshold
        bFlags ^= ALARM_STATE;
        last_AlarmTime = currentTime;
           
    }//if
   
}//GeneralTimerUpdates

void Output_Handler()
{
    //if below threshold, alarm tracks ALARM_STATE bit
    //otherwise it's off
    //assumes HIGH turns on alarm
    digitalWrite( ledAlarm, (bFlags & LOW_THRESH_FLG) ? ((bFlags & ALARM_STATE)?HIGH:LOW):LOW );

//if below threshold, LED is on solid
    //otherwise it's off
    //assumes HIGH turns on LED
    digitalWrite( ledPin, (bFlags & LOW_THRESH_FLG) ? HIGH:LOW );
   
}//Output_Handler

That worked :slight_smile:
Now I need to pay close attention to what you did and learn from it.
Thank you all...thx Blackfin

In your post #17

You have:
digitalWrite(ledAlarm, HIGH);

But you dont have a:
digitalWrite(ledAlarm, LOW);

What do you think needs to be done?

larryd:
In your post #17

You have:
digitalWrite(ledAlarm, HIGH);

But you dont have a:
digitalWrite(ledAlarm, LOW);

What do you think needs to be done?

Sounds like it should go LOW, but I want it to stay HIGH (constant) and blink the other

jdickinsonarduino:
That worked :slight_smile:
Now I need to pay close attention to what you did and learn from it.
Thank you all...thx Blackfin

A few thoughts:

  • maybe add a way to turn off the alarm (e.g. another button input)
  • maybe add some filtering to the input (e.g. 5 successive samples must be under the threshold before the flag/alarm is set; use a running average of the input etc)

Anyway, hope it helps you understand how you can do multiple things with millis().

Blackfin:
A few thoughts:

  • maybe add a way to turn off the alarm (e.g. another button input)
  • maybe add some filtering to the input (e.g. 5 successive samples must be under the threshold before the flag/alarm is set; use a running average of the input etc)

Anyway, hope it helps you understand how you can do multiple things with millis().

This is an incredible system.
I am so very excited to be learning and hopefully soon sharing my knowledge with others.
Happy New Year to all, thank you again.
I will be back, hopefully to just update how things are going.
Sincerely,
Jack

jdickinsonarduino:
Sounds like it should go LOW, but I want it to stay HIGH (constant) and blink the other

The point being, from you code in #17 once you set ledAlarm HIGH it will stay there since you have no code to ever make it go LOW.

No wonder ledAlarm would stay ON.

Looks like you have been given an example that you like.

BTW, the code I offered will print the reading every 500ms without using delay() and without blocking the sketch.

You must learn how to use the BWD technique if you ever want to proceed to more complicated coding.

larryd:
The point being, from you code in #17 once you set ledAlarm HIGH it will stay there since you have no code to ever make it go LOW.

No wonder ledAlarm would stay ON.

Looks like you have been given an example that you like.

BTW, the code I offered will print the reading every 500ms without using delay() and without blocking the sketch.

You must learn how to use the BWD technique if you ever want to proceed to more complicated coding.

I will learn it..., thank you Larry.
I appreciate and respect your knowledge and input.
Respectfully.
Jack