How to provide a one second (LOW) output pulse, each time the input returns to normal state

Thread Starter

Brian Krupicka

Joined Nov 1, 2014
38
I am trying to provide a one second (LOW) output pulse, each time the input returns to normal state.
State Input Output
Normal LOW HIGH
State change HIGH HIGH
Normal LOW LOW (for 1 second)
Repeat
Any help would be grateful.
Brian K



C:
//BMK
//Wheel Test Code
//11/24/2019


int sensorPin = 0;    // select the input pin for the photocell
int ledPin = 11;      // select the pin for the LED
int sensorValue = 0;  // variable to store the value coming from the sensor

void setup() {
// declare the ledPin as an OUTPUT:
pinMode(ledPin, OUTPUT); 
Serial.begin(9600); 
}

void loop() {
// read the value from the sensor:
sensorValue = analogRead(sensorPin);   
Serial.print("Digital reading = ");
Serial.println(sensorValue);     // the raw analog reading
// turn the ledPin on
if (sensorValue < 700){
   digitalWrite(ledPin, LOW);
}else{
digitalWrite(ledPin,HIGH);
} 
// stop the program for <sensorValue> milliseconds:
delay(10);         
            
}
 
Last edited by a moderator:

dl324

Joined Mar 30, 2015
11,518
Your code will be easier to read with some formatting:
C:
int sensorPin = 0;      // select the input pin for the photocell
int ledPin = 11;        // select the pin for the LED
int sensorValue = 0;    // variable to store the value coming from the sensor

void setup() {          // declare the ledPin as an OUTPUT:
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {           // read the value from the sensor:
  sensorValue = analogRead(sensorPin);
  Serial.print("Digital reading = ");
  Serial.println(sensorValue); // the raw analog reading
  // turn the ledPin on
  if (sensorValue < 700){
    digitalWrite(ledPin, LOW);
  } else {
    digitalWrite(ledPin,HIGH);
  }
  // stop the program for <sensorValue> milliseconds:
  delay(10);
}
I am trying to provide a one second (LOW) output pulse, each time the input returns to normal state.
What does normal state mean?
 

dl324

Joined Mar 30, 2015
11,518
Normal state means the photocell is not blocked from a light source and the "A0" pin is pulled upped to plus (HIGH).
What does that mean with respect to your code?

If the sensor value is >= 700, you want the LED to be turned on for a second?

What happens if the sensor value drops below 700 while the LED is on?

Do you want the sensor to continue being read? Or can the pulse prevent further reads of the sensor?
 

Thread Starter

Brian Krupicka

Joined Nov 1, 2014
38
The LED only turns on for 1 second when the input sensor return to normal state.
Input sensor no light - LED off.
Input sensor with light on sensor - led off.
Input sensor returns to no light - led turns on for 1 second, then turn off.
The next time the input sensor see light the steps repeat themselves.
 

dl324

Joined Mar 30, 2015
11,518
The LED only turns on for 1 second when the input sensor return to normal state.
Input sensor no light - LED off.
Input sensor with light on sensor - led off.
Input sensor returns to no light - led turns on for 1 second, then turn off.
The next time the input sensor see light the steps repeat themselves.
I still can't understand.
 

Thread Starter

Brian Krupicka

Joined Nov 1, 2014
38
Step 1= If "A0" is LOW - Pin 11 is HIGH
Step 2 = If "A0" is HIGH - Pin 11 is HIGH for the amount of time "A0" is HIGH
Step 3 = When "A0" returns to LOW
Step 4 = Pin 11 is LOW for 1 second
Step 5 = If "A0" is LOW after 1 second - pin 11 is HIGH
Repeat
 

dl324

Joined Mar 30, 2015
11,518
What if after Step 3, A0 goes High and then Low again? Does the initial 1 second LOW for pin 11 restart? Or is it allowed to timeout regardless of what A0 does?
 

djsfantasi

Joined Apr 11, 2010
6,805
There are several ways to do this in your code.

Most require saving the previous state of your sensor. I’d add a line before when you read the sensor, like this:
Code:
int lastSensorValue = sensorvalue;
sensorvalue = analogRead(sensorPin);
Then, test for the condition you want:
Code:
if ((sensorvalue == HIGH) &&
    (lastSensorValue == LOW)) {
          // insert code to light LED for 1 sec.
          }
 

dl324

Joined Mar 30, 2015
11,518
No, It is part of a model railroad project.
There are many ways to do it. Here's one:
Code:
int sensorPin = 0;      // select the input pin for the photocell
int ledPin = 11;        // select the pin for the LED
int sensorValue = 0;    // variable to store the value coming from the sensor
byte lastState = LOW;   // save last state of A0

void setup() {          // declare the ledPin as an OUTPUT:
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);
  Serial.begin(9600);
}

void loop() {           // read the value from the sensor:
  sensorValue = analogRead(sensorPin);
//  Serial.print("Digital reading = ");
//  Serial.println(sensorValue); // the raw analog reading
  // turn the ledPin on
  if (sensorValue < 700){
    if (lastState == HIGH) {
      digitalWrite(ledPin, LOW);
      delay(1000);
      digitalWrite(ledPin, HIGH);
    }
    lastState = LOW;
  } else {
    lastState = HIGH;
  }
  // stop the program for <sensorValue> milliseconds:
//  delay(10);
}
 

djsfantasi

Joined Apr 11, 2010
6,805
There are many ways to do it. Here's one:
Code:
int sensorPin = 0;      // select the input pin for the photocell
int ledPin = 11;        // select the pin for the LED
int sensorValue = 0;    // variable to store the value coming from the sensor
byte lastState = LOW;   // save last state of A0

void setup() {          // declare the ledPin as an OUTPUT:
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);
  Serial.begin(9600);
}

void loop() {           // read the value from the sensor:
  sensorValue = analogRead(sensorPin);
//  Serial.print("Digital reading = ");
//  Serial.println(sensorValue); // the raw analog reading
  // turn the ledPin on
  if (sensorValue < 700){
    if (lastState == HIGH) {
      digitalWrite(ledPin, LOW);
      delay(1000);
      digitalWrite(ledPin, HIGH);
    }
    lastState = LOW;
  } else {
    lastState = HIGH;
  }
  // stop the program for <sensorValue> milliseconds:
//  delay(10);
}
Pretty much what I said earlier, but dl324 went a little bit further by showing the entire program rather than just the necessary mods.
 

Thread Starter

Brian Krupicka

Joined Nov 1, 2014
38
Dennis
Thank you for your help so far.
The code still has one more issue, if you can be so kind to help.
When "A0" first goes < 700 the LED (pin 11) comes "on-delays-then off".
The LED at this point should not come "cycle".
The LED should only cycle when "A0" goes from < to >.
Brian K
 

dl324

Joined Mar 30, 2015
11,518
When "A0" first goes < 700 the LED (pin 11) comes "on-delays-then off".
The LED at this point should not come "cycle".
The LED should only cycle when "A0" goes from < to >.
Can you post a schematic of, or describe, how you have the LED connected? Your on and off and HIGH and LOW keep confusing me.

The code will hold ledPin low for 1 second on the HIGH (>= 700) to LOW (< 700) transition of A0.

EDIT: These requirements seem to be conflicting and that's what's confusing me.
Step 2 = If "A0" is HIGH - Pin 11 is HIGH for the amount of time "A0" is HIGH
Step 3 = When "A0" returns to LOW
Step 4 = Pin 11 is LOW for 1 second
Step 5 = If "A0" is LOW after 1 second - pin 11 is HIGH
This boils down to triggering on the falling edge of A0.
The LED should only cycle when "A0" goes from < to >.
This says the trigger is on the rising edge of A0.
 
Last edited:

Thread Starter

Brian Krupicka

Joined Nov 1, 2014
38
I am sorry if I did not express myself correctly.
The LED (Pin 11) should only trigger for (1 seccond) on the "fall edge" of "A0". The LED should not trigger on the "rising edge" of "A0".
Again sorry, I am not clear on how to express the conditions in programming language but I am learning.

I truly appreciate your continued support.

Brian K
 

dl324

Joined Mar 30, 2015
11,518
The LED (Pin 11) should only trigger for (1 seccond) on the "fall edge" of "A0". The LED should not trigger on the "rising edge" of "A0".
That's what the code should be doing.

This code initializes lastState to LOW and sets the LED pin to HIGH (LED off):
Code:
byte lastState = LOW;   // save last state of A0

void setup() {          // declare the ledPin as an OUTPUT:
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);
}
This code turns the LED on (LED pin LOW) for 1 second on the HIGH to LOW transition of A0:
Code:
if (sensorValue < 700) {
  if (lastState == HIGH) {
    digitalWrite(ledPin, LOW);
    delay(1000);
    digitalWrite(ledPin, HIGH);
  }
  lastState = LOW;
} else {
  lastState = HIGH;
}
Is this easier for you to undertand?
1574621160077.png
 

Thread Starter

Brian Krupicka

Joined Nov 1, 2014
38
The is the code as I have it.
Checkout the following video.... It explains the needed operation.

https://www.icloud.com/attachment/?u=https://cvws.icloud-content.com/B/AX6X5r6zR5JxPG-6N8c_mYCnvRldAW4cuXa7Tc_h2f9Yr7_ijSpaN-uw/${f}?o=ArY5EYXpFvax3JKEHBur0dv3ZPvmWgyTCL_nmEaFGUL9&v=1&x=3&a=CAogauzeBb_BaKhwMmuN1XnGaa-zZKAQNMAKW-niIbSqrhoSJxC7zvb36S0Yu97xy_MtIgEAKggByAD_aV_1ilIEp70ZXVoEWjfrsA&e=1577217453&k=${uk}&fl=&r=BCAECCD9-A205-4E95-B4A9-61EC6AB44462-1&ckc=com.apple.largeattachment&ckz=70822CD4-A385-4CCF-9093-D2BA15E152EC&p=57&s=LtyDVCUy_F1BQmTwxfbJXqNNMYg&uk=iS7TzH5S5PhT0HxzuJz7vQ&f=IMG_5197.MOV&sz=124868819

The flow chart was helpful....but not sure if I fully understand ALL the branches.

//BMK
//2-24-2019
// Wheel Test code

// Note: The photocell has a resistance of 120 ohms with lights applied. (normal mode) (HIGH to pin "A0").
// Note: The photocell has a resistance of 950 ohm when the light is blocked. (LOW to pin "A0").
// Note: It is when the light is REAPPLIED to the photocell, LED (pin 11) should light for one second.


int sensorPin = 0; // select the input pin for the photocell
int ledPin = 11; // select the pin for the LED
int sensorValue = 0; // variable to store the value coming from the sensor
byte lastState = LOW; // save last state of A0

void setup() { // declare the ledPin as an OUTPUT:
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
Serial.begin(9600);
}

void loop() { // read the value from the sensor:
sensorValue = analogRead(sensorPin);
if (sensorValue < 700) {
if (lastState == HIGH) {
digitalWrite(ledPin, LOW);
delay(1000);
digitalWrite(ledPin, HIGH);
}
lastState = LOW;
} else {
lastState = HIGH;
}
// stop the program for <sensorValue> milliseconds:
// delay(10);
}
 

djsfantasi

Joined Apr 11, 2010
6,805
I don’t understand why your toggling lastState that way. It might work but IMHO it’s non-intuitive.

“lastState” is exactly that. It is the last or previous state of your sensor. As in the sample code I’ve already provided, just before you determinebthe sensor state. I’d set lastState to the value of the sensor state just before it is overwritten.
 
Top