jurs:
I'd say: Learning programming is best done by programming.
So I have the code ready:
#define INPUTMODE INPUT_PULLUP // INPUT or INPUT_PULLUP
#define BOUNCETIME 50 // bouncing time in milliseconds
byte buttonPins[]={2};// pin numbers of all buttons
#define NUMBUTTONS (sizeof(buttonPins))
#define LED 13
long ledOnTime, ledCycleTime;
boolean ledIsOn;
unsigned long lastPulseTime, lastLEDcycleStart;
byte buttonState[NUMBUTTONS]; // array holds the actual HIGH/LOW states
byte buttonChange[NUMBUTTONS]; // array holds the state changes when button is pressed or released
enum{UNCHANGED,BUTTONUP,BUTTONDOWN};
void input(){
// read the input state and state changes of all buttons
static unsigned long lastButtonTime; // time stamp for remembering the time when the button states were last read
memset(buttonChange,0,sizeof(buttonChange)); // reset all old state changes
if (millis()-lastButtonTime<BOUNCETIME) return; // within bounce time: leave the function
lastButtonTime=millis(); // remember the current time
for (int i=0;i<NUMBUTTONS;i++)
{
byte curState=digitalRead(buttonPins[i]); // current button state
if (INPUTMODE==INPUT_PULLUP) curState=!curState; // logic is inverted with INPUT_PULLUP
if (curState!=buttonState[i]) // state change detected
{
if (curState==HIGH) buttonChange[i]=BUTTONDOWN;
else buttonChange[i]=BUTTONUP;
}
buttonState[i]=curState; // save the current button state
}
}
void debugCycleTime()
{
Serial.print("Cycle time: ");
Serial.print(ledCycleTime);
Serial.print(" on time: ");
Serial.print(ledOnTime);
Serial.println();
}
void processing()
{
long nowMillis=millis();
if (buttonChange[0]==BUTTONDOWN)
{ // new pulse detected, recalculate the new ledCycleTime and ledOnTime
ledCycleTime= (nowMillis-lastPulseTime)/10;
ledOnTime=ledCycleTime/5;
lastPulseTime=nowMillis;
debugCycleTime();
}
if (nowMillis-lastLEDcycleStart>=ledCycleTime)
{
lastLEDcycleStart+=ledCycleTime;
}
if (nowMillis-lastLEDcycleStart<ledOnTime)
ledIsOn=true;
else
ledIsOn=false;
}
void output()
{
if (ledIsOn)
digitalWrite(LED,HIGH);
else
digitalWrite(LED,LOW);
}
void setup() {
Serial.begin(9600);
for (int i=0;i<NUMBUTTONS;i++)
{
pinMode(buttonPins[i],INPUTMODE);
}
pinMode(LED, OUTPUT);
Serial.println("Waiting for first pulse...");
do
{
input();
} while (buttonChange[0]!=BUTTONDOWN);
lastPulseTime=millis();
Serial.println("Waiting for second pulse...");
do
{
input();
} while (buttonChange[0]!=BUTTONDOWN);
long nowMillis=millis();
ledCycleTime= (nowMillis-lastPulseTime)/10;
ledOnTime=ledCycleTime/5;
lastPulseTime=nowMillis;
lastLEDcycleStart=nowMillis;
Serial.println("System up and running!");
debugCycleTime();
}
void loop() {
input();
processing();
output();
}
The "input()" function is a little bit complicated for reading just a single input, normally this function is what I use for reading multiple buttons. As your signal is very slow, I've set the possible bouncetime to a relatively high value of 50 milliseconds for debouncing.
On the other side the output function is very short, also the loop() function.
OK, so you will see just two debug messages on Serial "Waiting for first pulse..." before the first pulse and ""Waiting for second pulse..." before the loop() function starts running.
The current duty cycle is now set to 20% of the cycle time, by calculating:
ledOnTime=ledCycleTime/5;
If you need a fixed "on" time for the pulse generation, you can set it instead.
Implementing a "timeout" to stop the whole thing would be up to you. It's not included in my code.
Perhaps have a look.
You can test the code opening the Serial monitor and simulate your input pulses with a wire betwen GND and the input pin-2. The LED on pin-13 then starts pulsing 10 times as quickly as you simulate pulses.
So what about adding an LCD-keypad shield to control the pulse Rate and view data?