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.
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.
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) );
}
}