How to generate two signals with time delay?

Hello forum. I would like to use Arduino Uno to generate two outputs from 2 pins to swith on two devices. I want to wait 10 seconds firstly. Then I start the first output which is a square or pic wave with a controllable frequency to set my camera. Then 5 seconds later the other output as a step signal is activated to start my motor. I want also try later to use a button on a breadboard to start and stop the whole code.

I have checked the forum a lot. But i didn't find an appropriate one with controlable time delay.
Could anyone give me some advice? Thanks in advance.

We get this question almost every day. You need to implement a state machine. The classic example is in the IDE examples folder and is called blink without delay. Also look at
http://www.thebox.myzen.co.uk/Tutorial/State_Machine.html

This will allow you to generate signals and delays that work independently.

1 Like

NOTE: there is some learning effort involved.
Some players come in hoping this a gift shop… it is, but we give you the knowledge so you can ‘nut it out’ yourself.

Nobody says it’s easy to get started, but as you learn more, you’ll realise what an amazing device a microcontroller really is, and writing your own programs is like magic.

1 Like

Hy-per, (short for Hi Hyper12) ;-))

welcome to the arduino-user-forum. Your first posting is pretty good as it describes the functionality you want to have with a medium grade of details.

Still I want to ask for some more details:
what do the words "pic wave" mean?

I know the term "square-wave"

What is used as the "standard"-device to "set my camera"
What happens if you "set your camera?"

What is the lowest and the highest frequency that this square-wave-signal needs to be?
Does the square-wave-signal has to have a certain-duty-cycle?

What kind of motor are you using? The words "step-signal" seem to be a hint it is a stepper-motor? Is it a stepper-motor or something different?

last but not least to be able to adapt answers to your knowledge-level
what is your experience with programming ?
How much do you know about the fundamentals of electronic?
What kind of measuring-equipment do you have?

best regards Stefan

Tks. It helps me a lot. I have just modified "used blink without delay" example and successed to have realized firstly the basic functionalities. I will continue with the link in your reply.

Yes of course efforts should be mad to achieve the goal. I just didn't know in which direction I shoud look into. Thanks for you comments.

Sorry for my bad English. More specifically, it should be pulse signal.
The square or pulse signal is used to control the camera. The sampling of the camera is activated by the rising edge of the square or the pulse signal. The frequency is between 0 and 250Hz.

For the motor, it's not the stepper DC motor. In fact the step signal is plugged into a PLC servo system and is just to used to activate the latter one. Then the PLC program takes the charge to set the motor motion.

I am a new commer about electronic programming. But the basic knowledge is OK for me and I used Mbed to construct my controller but now I determine to used Arduino which seems to have more libraries. I have experiences in other programs languages. So it may not be difficult for me to understand.

Thanks for your careful reading of my questions and give so many pertinent questions. Sorry for not being clear before.

If you find it difficult to write in english. Just use google-translate.
Write everything in your native language and let do google-translate the translation.
The grammar won't be brilliant but google will always find understandable words.

generating a frequency between 0 and 250 Hz could be done inside of loop or with the help of a timer-interrupt.

So do I understand right that the "PLC-signal" is just a single state-change LOW-HIGH and the rest is done by the PLC until you switch the signal back to LOW which makes the PLC stop the motor?

The waiting times 10 seconds and 5 seconds are a very typical case for non-blocking timing based on the function millis().

If you write down a step-by-step description what is happening one thing after the other, much more precise suggestions can be made

I try it with what I believe what I have understood so far.

everying is in an idle-mode waiting for a start-signal (what is it?)

start-signal is given => start a waiting period of 10 seconds
if waiting-time is over

    1. start outputting a pulse-train with a frequency between 0 and 250 Hz
    1. start a waiting-period of 5 seconds

if waiting-time is over

  • => switch PLC-Signal from LOW to HIGH to make PLC start moving the motor

  • if some other other event is occuring (what is it?) this event

  • => switches PLC-signal from HIGH to LOW

  • => puts code into idle-mode

This is a very classical application for a state-machine.

I have written a demo-code that shall explain how it works

I'm interested in feedback if it is easy to understand or what questions still arise

best regards Stefan

what do you mean by "pic"?

wouldn't the output simply need to be either ON or possibly a pulse?

Thanks Stefan.

Your step-by-step description is exactly what I meant. I will probably use a button to generate the start-signal waited by the idle-mode and the signal to put code into idle mode.
I will learn carefully your demo.

Best regards,

I meant a square wave, not just an ON or a single pulse.

Hello Stefan,

I reorganise my program step by step.

=> everthing is in idle-mode with LED blink waiting for the first press button
=> first button press, note the instant and start two waiting periods (waitCameraOn=5s and waitPLCOn=7 seconds)
=> if waitCameraOn is over, start outputting a square train at 100Hz for my camera
=> if waitPLCOn is over, switch PLC-signal output from LOW to HIGH
=> second press,

  1. stop the square wave and just output LOW for camera
  2. switch PLC-signal from HIGH to LOW

=> third press, go back to idle-mode

I finished my code. The timing squence works pretty good but I can't get the predefined frequency. I attach my code below. I predefine 100 Hz for the square wave. but finally get 5/0.7=7.1 and the square width seems to increase in the beginning.(See the attached oscilloscope picture). The square width stablizes later.

I wonder if you or other forum users could give some advice.


// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;    // the number of the pushbutton pin
const int ledPin = 13;      // the number of the LED pin
const int plcPin = 6; // the number of the PLC pin
const int cameraPin = 9;

// Variables will change:
int ledState = LOW;         // the current state of the output pin
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = HIGH;             // the current reading from the input pin
int lastButtonState = HIGH;   // the previous reading from the input pin
// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
long int blinkInterval = 1000;

unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers
unsigned long currentMillis;
unsigned long StartWaiting;
unsigned long previousTime = 0;
unsigned long waitCameraOn = 5000; // duration from first press button to camera on
unsigned long waitPLCOn = 7000;  // duration from first press button on to PLC on
unsigned long halfcameraPeriod = 5000UL; // microseconds, x2=10ms => 100 HZ
unsigned long currentMicros;
unsigned long previousMicros;

void setup() {
  Serial.begin(9600);
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
  // set initial LED state
  digitalWrite(ledPin, ledState);
  pinMode(plcPin, OUTPUT);
  pinMode(cameraPin, OUTPUT);
  digitalWrite(plcPin, LOW);
  digitalWrite(cameraPin, LOW);
}

void loop() {
  currentMillis = millis();


  readButton();
  //  Serial.println(buttonPushCounter);

  switch (buttonPushCounter) {
    case 0:  // wait button press
      Serial.println(ledState);
      blinkLED();
      break;
    case 1:

      controlOn();
      break;
    case 2:
      digitalWrite(cameraPin, LOW);
      digitalWrite(plcPin, LOW);
      digitalWrite(ledPin, LOW);
      break;
  }
}

void controlOn () {
  currentMicros = micros();
  if (! waitDuration(waitCameraOn)) {
    previousMicros = currentMicros;  // update to generate sqaure wave after waitcamera
  } else {
    Serial.print( F("seconds waited(s):") );
    Serial.print( (currentMillis - StartWaiting) / 1000 );
    Serial.println();
    squareWave();
    Serial.print(F("Sqaure wave triggers camera(Hz):"));
    Serial.print( 1000 / halfcameraPeriod / 2);
    Serial.println();
  }
  if (waitDuration( waitPLCOn )) {
    Serial.print( F("seconds waited(s)") );
    Serial.print( (currentMillis - StartWaiting) / 1000 );
    Serial.println();
    digitalWrite(plcPin, HIGH);
    Serial.println("PLC on");
  }
}

void squareWave () {
  unsigned long elapsedMicros = currentMicros - previousMicros;
  if (elapsedMicros >= halfcameraPeriod) {
    PINB = PINB | 0b00000010; // toggle D9
    previousMicros = previousMicros + halfcameraPeriod;
  }
}

inline boolean  waitDuration(unsigned long Duration) {
  return (currentMillis - StartWaiting >= Duration);
}

void blinkLED() {
  // 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.
  if (currentMillis - previousTime >= blinkInterval) {
    // save the last time you blinked the LED
    previousTime = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

void readButton() {
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH), and you've waited long enough
  // since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;
      // only toggle the LED if the new button state is LOW
      if (buttonState == LOW) {
        buttonPushCounter++;
        buttonPushCounter %= 3;
        //       blinkInterval = blinkInterval* (buttonPushCounter + 1);
        Serial.println("on");
        Serial.print("number of button pushes: ");
        Serial.println(buttonPushCounter);
        StartWaiting = currentMillis;
      } else {
        // if the current state is HIGH then the button went from on to off:
        Serial.println("off");
      }
    }
  }
  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;
}

controlUnit.ino (5.1 KB)

Thanks and best regards