PLC pulse command equivalence

I assume there is no simple pulse command as used in ladder for PLC's which is something I use often. I figure I have to use interrupts.
I have hunted through forums & looked at projects but cannot find what I thought would be a commonly used feature with a timer.

I have a photo-electric beam which I want to give a 1 second output to a piezzo buzzer, but I don't want the buzzer to sound again for another 5 minutes. My problem is if the photo-electric beam is broken (ie a car parks in front of it) the buzzer will continue to sound.

This is very simple to program until a car parks in front of the beam then the buzzer continues to sound, now this is where I get stuck.
I have spent way too much time trying to get this to work. Any help greatly appreciated.

Learn BlinkWithoutDelay. (except make all the time variables unsigned long)

It's in your IDE under File->Examples->02.Digital->BlinkWithoutDelay
There isn't 20 lines of actual code.

You can time as many dynamic events as you can have a 32-bit start time and a 32-bit interval for, or 16 bit vars if you're only timing short intervals or 64 bit unsigned long long if you want to time micros over huge intervals....

There's even a Timer Library you can use if you want, and note that the only hardware timer used is the one running the millis() clock. 1 clock to time as many events as you can fit.

Thanks GoForSmoke, but there is no input with this program for the relay contacts of the Photo-electric beam to connect to.

What does that have to do with generating a timed pulse?
Are you answering a different thread?

I am trying to end up with a buzzer which sounds for 1 second then is silent for 5 minutes after receiving an input from the relay output of the Photo electric beam, that can’t be done with the blink without delay. I can write that sketch, but I don’t know how to apply that sketch to what I am trying to achieve. It is very simple using PLC ladder logic.

that can't be done with the blink without delay.

Why not ?

Does the beam output relay pulse when an object (car) triggers it or does the relay stay energized until the object clears the beam?
If the relay stays energized while the beam is broken then altering your code so the buzzer will not arm to sound again until the relay opens should be easy(ish).
If it pulses then does it keep pulsing at fixed intervals until beam is restored? This could also be covered by noting time of last trigger and ignoring other triggers in the interval window.

theautomationguy:
I am trying to end up with a buzzer which sounds for 1 second then is silent for 5 minutes after receiving an input from the relay output of the Photo electric beam, that can't be done with the blink without delay. I can write that sketch, but I don't know how to apply that sketch to what I am trying to achieve. It is very simple using PLC ladder logic.

It can be done using the principle that BWD teaches, how to use time.

The process below will do what you want and let you add many other "simultaneous" functions.
You could do something simpler that would block other code but I'm guessing that you don't want that.

You have a buzzer that should only sound under certain conditions:

  • waiting for the button to be pushed, no sound ------- call this state 10, the default state
  • when the button is pushed, sound for a time period -- call this state 20
  • after that time period the buzzer is not to sound for another time period -- call this state 30

So you have an input, the button, and an output, the buzzer.

-- The button code should include debouncing and set or clear a button pushed flag after debounce. It should not change the state, the button may be pressed at any time. My favorite debounce is simply checking for change every time through loop and if it stays the same for 5 ms and is different than the button flag, change button flag but not until then. Yes, that means keeping track of the last pin read for the button.

-- The buzzer code should keep track of buzzer on/off and start the buzzer when (the state is 20 and the buzzer is off) else stop the buzzer when (the state is not 20 and the buzzer is on).

-- There should be a switch-case on state with time checks inside

case 10, if button pressed; set state to 20, set start time to millis(), set interval to 1000UL (1 second).
break
case 20, if the interval is up; set state to 30, set start time to millis(), set interval to 5 mins.
break
case 30, if the interval is up; set state to 10.

That's it. Each piece should be short, not interleave the logic of other pieces and easy to debug.
You could even tie leds to the states as process status indicators but give that a separate code block.

@ UKHeliBob, there is no input for the relay contacts to connect to.
@ Riva when the PE beam is broken the relay contacts change state until the beam is unbroken (for the use of a better word). Usually it is momentary as people & vehicles pass thru it, but occasionally a vehicle parks in front of it which means the contacts stay closed / open. I can't remember which way it is wired.
@ GoForSmoke you are onto it, but how do I go about doing that please?
What / who is BWD/ I googled it but came up with no results?

What / who is BWD/ I googled it but came up with no results?

BWD = blink without delay (one of the examples that comes with the IDE)

I wrote a more extensive example of the Blink Without Delay concept in this Thread. It includes taking input from a switch.

…R

It is very simple using PLC ladder logic.

Writing programs ( or "sketches", or "scripts" ) is a different concept to ladder logic. Not necessarily harder or less simple, just different. If you are unable or unwilling to adapt to a different way of doing things, then perhaps Arduinos is not for you.

It is a very simple matter to write a program which detects the state of a switch, or any other kind of sensor input, and take some action when that occurs.

@ UKHeliBob, there is no input for the relay contacts to connect to.

You obviously have at least 1 pin free because you intend to use it for an interrupt, or is that not what you meant ?

Take a look at this. It is not tested because I don’t have the same hardware as you, whatever that is, so I have made some assumptions.

const byte photoPin = A0;
const byte buzzerPin = 8;
byte state = 0;
unsigned long buzzerStart = 0;
unsigned long waitFiveMinsStart = 0;
unsigned long buzzerPeriod = 1000UL;
unsigned long fiveMinutePeriod = 300000UL;

void setup() 
{
  Serial.begin(115200);
  pinMode(buzzerPin, OUTPUT);
}

void loop() 
{
  switch (state)
  {
  case 0:                              //do nothing until the beam is broken
    if (analogRead(photoPin) <= 512)   //adjust value or change to digitalRead if appropriate
    {
      state = 1; 
      digitalWrite(buzzerPin, HIGH);   //turn on the buzzer
      buzzerStart = millis();  
    }
    break;

  case 1:                              //buzzer sounds for one second
    if (millis() - buzzerStart >= buzzerPeriod)
    {
      state = 2;
      digitalWrite(buzzerPin, LOW);    //turn off the buzzer
      waitFiveMinsStart = millis();
    }
    break;

  case 2:                              //do nothing until five minutes has elapsed
    if (millis() -  waitFiveMinsStart >= fiveMinutePeriod)
    {
      state = 0; 
    }
    break;  
  }
}

theautomationguy:
@ Riva when the PE beam is broken the relay contacts change state until the beam is unbroken (for the use of a better word). Usually it is momentary as people & vehicles pass thru it, but occasionally a vehicle parks in front of it which means the contacts stay closed / open. I can't remember which way it is wired.

If the relay state stays the same till the beam is unbroken then use a flag variable that is set when you activate the sounder for 1 second and does not reset until beam is unbroken. After your 5 minutes have passed if the flag is still set and the beam is still broken then don't sound again.

theautomationguy:
@ UKHeliBob, there is no input for the relay contacts to connect to.
@ Riva when the PE beam is broken the relay contacts change state until the beam is unbroken (for the use of a better word). Usually it is momentary as people & vehicles pass thru it, but occasionally a vehicle parks in front of it which means the contacts stay closed / open. I can’t remember which way it is wired.
@ GoForSmoke you are onto it, but how do I go about doing that please?
What / who is BWD/ I googled it but came up with no results?

Oh, it finally clicked for me what PLC is. Funny, I want to mess with AT16VB8’s as glue logic (they cost $1) and don’t know where to even get a start with them.

And I’m just getting that you may not know C at all?

We can walk through the pseudocode and turn it into code, yes. But I don’t want to get “out of sight” on you if you’re willing to learn, which would benefit you far more than a piece of code.

theautomationguy:
@ UKHeliBob, there is no input for the relay contacts to connect to.
@ Riva when the PE beam is broken the relay contacts change state until the beam is unbroken (for the use of a better word). Usually it is momentary as people & vehicles pass thru it, but occasionally a vehicle parks in front of it which means the contacts stay closed / open. I can't remember which way it is wired.
@ GoForSmoke you are onto it, but how do I go about doing that please?
What / who is BWD/ I googled it but came up with no results?

here is the concept.

is the beam broken ? no, add one second to the unbroken count. (make broken count 0, stop sounding horn )
if the count is 5 minutes, send a beep and re-set unbroken count to 0

//here is where a beep with delay would work well. no need to count and time the beep

is the beam broken ? yes ? add one second to the broken count count (make unbroken count 0 )
is the count 5 minutes ? then make broken count 5 minutes //stops from climbing, but will stay over 5 minutes
sound the horn

this would only ever see the beam break.
it would beep every 5 min with no break, and after a continuous break of 5 minutes, it would sound the horn.

blink without delay tells you how to count.

millis() comes from a running timer routine, that tells you how to count?

The heart of BWD is timing without blocking.

loop() checks if ( now - start >= interval ) is true, it is when the interval is up
and if it isn't then next time through loop() it checks again.

Both loop() and the time check go together and may incorporate other checks and conditions.

@ michinyon I struggled to get the concept of PLC's ladder logic in the beginning too, I am willing to learn that is why I am here. I have bought a few beginners books & have no trouble copying other peoples code & making adjustments to them, just trying to get to the next base and this forum is very helpful for that.

@ GoForSmoke Correct I don't know "C" Your sketch looks good and you are leading down the right path. I am using Freetronics Eleven (Uno clone, I believe) I have tried your sketch & made the changes but I am only guessing at some things which isn't good enough to make things work.

This is what I have done so far
but I have to head off to work but will spend more time on it when I get home.

const int photoPin = 2;
const byte buzzerPin = 12;
byte state = 0;
unsigned long buzzerStart = 0;
unsigned long waitFiveMinsStart = 0;
unsigned long buzzerPeriod = 1000UL;
unsigned long fiveMinutePeriod = 300000UL;

void setup() 
{
  Serial.begin(115200);
  pinMode(buzzerPin, OUTPUT);
  pinMode(photoPin, INPUT);
}

void loop() 
{

  switch (state)
{
  
  //case 0:                              //do nothing until the beam is broken
    if (photoPin, HIGH);   //adjust value or change to digitalRead if appropriate
    {
      state = 1; 
      digitalWrite(buzzerPin, HIGH);   //turn on the buzzer
      buzzerStart = millis();  
    }
   break;

  //case 1:                              //buzzer sounds for one second
    if (millis() - buzzerStart >= buzzerPeriod)
    {
      state = 2;
      digitalWrite(buzzerPin, LOW);    //turn off the buzzer
      waitFiveMinsStart = millis();
    }
   // break;

  //case 2:                              //do nothing until five minutes has elapsed
    if (millis() -  waitFiveMinsStart >= fiveMinutePeriod)
    {
      state = 0; 
    }
   // break;  
  }

I assume I don't need the serial.
State = 2 I am confused with this, 0 = LOW = Off, 1 = HIGH = On, is my understanding or is this referring to the case: which I put // in front of?

hi, if you want a plc with arduino you could to try ardbox from www.industrialshields.com
reguards

@ UKHeliBob, thanks so much for your help. I did a quick read of case instructions and changed the code as follows:

const int photoPin = 2; //byte or int for digital input???
const byte buzzerPin = 12;
byte state = 0;
unsigned long buzzerStart = 0;
unsigned long waitFiveMinsStart = 0;
unsigned long buzzerPeriod = 1000UL;
unsigned long fiveMinutePeriod = 10000UL; //changed to 10sec for testing

void setup() 
{
  Serial.begin(115200);// Delete?? Not required??
  pinMode(buzzerPin, OUTPUT);
  pinMode(photoPin, INPUT); // added to read photoPin 2
}

void loop() 
{
switch (state)
{
  
  case 0:                              //do nothing until the beam is broken
    if (photoPin, HIGH);   //adjust value or change to digitalRead if appropriate
    {
      state = 1; 
      digitalWrite(buzzerPin, HIGH);   //turn on the buzzer
      buzzerStart = millis();  
    }
   break;

  case 1:                              //buzzer sounds for one second
    if (millis() - buzzerStart >= buzzerPeriod)
    {
      state = 2;
      digitalWrite(buzzerPin, LOW);    //turn off the buzzer
      waitFiveMinsStart = millis();
    }
   // break;

  case 2:                              //do nothing until five minutes has elapsed
    if (millis() -  waitFiveMinsStart >= fiveMinutePeriod)
    {
      state = 0; 
    }
   // break;  
  }
}

It doesn't work properly I have added comments, but this looks like I am not far from achieving my goal.