Code to extend pulse on UNO pin

I've just started Arduino use so a complete beginner. Please bear with me.

I've created a break beam system base on the diode laser and photoresistor units. It works but the output produced to too short a pulse for my application. As you will see from my very basic code the output in on pin13. This is typically 10-15ms and I really need about a 500ms pulse. Putting a delay after the void loop digitalWrite doesn't work.

Any help would be greatly appreciated.

Alan


#include <TimerOne.h>

/*Laser module with Arduino.

#define laser 2 //or laser to Vcc
#define sensor 3
#define LED 13

void setup() {
Serial.begin(9600);
pinMode(laser, OUTPUT); //optional if laser on Vcc
pinMode(sensor, INPUT);
pinMode(LED, OUTPUT);

digitalWrite(laser, HIGH); //optional if laser on Vcc
}

void loop() {
bool value = digitalRead(sensor);

if (value == 0) {
digitalWrite(LED, HIGH);
} else {
digitalWrite(LED, LOW);
}
}

Welcome to the forum

Why did you post in the Uncategorised category of the forum ? Your topic has been moved to the Programming category

Please follow the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use code tags (the < CODE/ > icon above the compose window) to make it easier to read and copy for examination

https://forum.arduino.cc/t/how-to-get-the-best-out-of-this-forum

Sorry, didn't know how this site worked. I stand correceted

//#define laser 2 do not connect laser to arduino pin. 
#define sensor 3
#define LED 13

void setup() {
  pinMode(sensor, INPUT);// I suppose you using external pull up resistor
  pinMode(LED, OUTPUT);
}

void loop() {
  bool value = digitalRead(sensor);
  static uint32_t curMill = 0;

  if (!digitalRead(sensor) && !digitalRead(LED)) {
    digitalWrite(LED, HIGH);
    curMill = millis();
  }
  else {
    if (millis() - curMill >= 500 )digitalWrite(LED, LOW);
  }
}

Many thanks Kolaha, I'll give it a go. Sadly I don't understand a word of it though. It will, however, give me a great starting point to investigate the code. LED 13 pin goes to a relay.

Hi @alanlacey

welcome to the arduino-Forum.

In the electronics-world one term for what you want is a monoflop.
Here is a democode that does this.
I claim that the comments and the names that I use make it easier to understand.

Though this functionality that you want is medium advanced and requires quite some knowledge.
Read and post your very honest opinion and how much you did understand. It will be very interesting for me to read how much (or how less a real beginner understands)

My aim is to write demo-codes that shall be very easy to understand.
So the feedback and the questions of real beginners are the best possible feedback for this kind of improving

const byte triggerInputPin  = 3;
const byte triggerIsActive = LOW; // LOW or HIGH

const byte PinToSwitch  = 13;
const byte OutPutOn  = HIGH;
// the attention-mark ! is the not-operator which inverts the value
// !true = false  !false = true     !HIGH = LOW    !LOW = HIGH
const byte OutPutOff = !OutPutOn; 

// set InitialWaitTime to 0 if you don't want a delay between triggering and switching output
unsigned long InitialWaitTime = 0; // set to zero if you don't want an initial wait
unsigned long ActiveTime = 500;
unsigned long LockedTime = 0; // set to zero if you don't want a lock-time

unsigned long MonoFlopTimer; // variable used for non-blocking timing

// constants of the state-machine
const byte sm_Idling      = 0;
const byte sm_InitialWait = 1;
const byte sm_Activated   = 2;
const byte sm_Locked      = 3;

byte MonoFlopState = sm_Idling; // state-variable of the state-machine

unsigned long MyTestTimer = 0;                   // Timer-variables MUST be of type unsigned long
const byte    Heartbeat_LED = 10;


void setup() {
  Serial.begin(115200);
  Serial.println("Setup-Start");
  pinMode(triggerInputPin,INPUT_PULLUP); // INPUT_PULLUP
  digitalWrite(PinToSwitch,OutPutOff);
  pinMode(PinToSwitch,OUTPUT);
}


void loop() {
  BlinkHeartBeatLED(Heartbeat_LED, 250);

  // run down code of state-machine over and over again
  // all the logic for reading in sensor-signal and switching output ON/OFF 
  // is inside the function
  MonoFlopStateMachine(); 
}

void MonoFlopStateMachine() {

  switch (MonoFlopState) {

    case sm_Idling:
      // check if trigger-input reads triggering signal
      if (digitalRead(triggerInputPin) == triggerIsActive) {
        MonoFlopTimer = millis();       // make snapshot of time
        MonoFlopState = sm_InitialWait; // set next state of state-machine
        Serial.println( F("trigger-signal detected start inital wait") );
      }
      break; // IMMIDIATELY jump down to END OF SWITCH

    case sm_InitialWait:
      // wait until initial waittime has passed by
      if ( TimePeriodIsOver(MonoFlopTimer,InitialWaitTime) ) {
        // if waittime HAS passed by
        MonoFlopTimer = millis();           // make new snapshot of time
        digitalWrite(PinToSwitch,OutPutOn); // switch IO-Pin to activated state
        MonoFlopState = sm_Activated;       // set next state of state-machine
        Serial.println( F("InitialWaitTime is over switching output to ACTIVE") );
      }
      break; // IMMIDIATELY jump down to END OF SWITCH

    case sm_Activated:
      // check if time the IO-pin shall be active is over
      if ( TimePeriodIsOver(MonoFlopTimer,ActiveTime) ){
        // if activetime of IO-pin IS over
        MonoFlopTimer = millis();             // make new snapshot of time
        digitalWrite(PinToSwitch,OutPutOff);  // switch IO-pin to DE-activated state
        MonoFlopState = sm_Locked;            // set next state of state-machine
        Serial.println( F("Activetime is over switching output to IN-active") );
        Serial.println( F("and starting locktime") );
      }
      break; // IMMIDIATELY jump down to END OF SWITCH

    case sm_Locked:
      // check if time the logic shall be locked against too early re-triggering is over
      if ( TimePeriodIsOver(MonoFlopTimer,LockedTime) ){
        // if locked time IS over
        Serial.println( F("locktime is over change state to idling") );
        MonoFlopState = sm_Idling; // set state-machine to idle-mode
      }
      break; // IMMIDIATELY jump down to END OF SWITCH
  } // END OF SWITCH
}

// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - startOfPeriod >= TimePeriod ) {
    // more time than TimePeriod has elapsed since last time if-condition was true
    startOfPeriod = currentMillis; // a new period starts right here so set new starttime
    return true;
  }
  else return false;            // actual TimePeriod is NOT yet over
}


void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
  static unsigned long MyBlinkTimer;
  pinMode(IO_Pin, OUTPUT);

  if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
    digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
  }
}

best regards Stefan

Also known as a one-shot timer.
If this is your complete circuit function, you might want to consider a 555 timer circuit

Thanks Stefan. That will give me a lot to think about. I'll get back to you when I've partially digested all that new stuff.

I appreciate if you ask questions to whatever you want