Getting a switch to send only a pulse

Hi everyone,

I’m fairly new to Arduino and i recently started a new project trying to make a quickshifter for one of my motorcycles. I made a very simple script wich, for now, activates the led on the board (Pin 13) according to a button being pressed. When everything runs as it should i will try to link the output to a transistor to switch off the ignition of the motorcycle for a very short time.

As i said i have a very simple script wich seems to work fine. When the button is pressed the led on pin 13 luminates for the time that i have set in the script with a delay. The only problem that occours is that if i hold the button, the led stays luminated as well (as long as i hold the button, if i stop pressing the button than the delay starts ‘counting’ and the led goes out after the time set by the delay) wich isn’t convenient for this project.

my question here is; how is it possible to program the arduino so that the delay will start counting from the moment that the button is pressed instead of when the button is released? So if i keep pressing the button, the led will stop luminating anyway after the delaytime set.

Sorry for the (probably) nooby question but i didn’t manage to find the answer on the internet…

(I have attached the code in the attachments)

In the Arduino IDE, go to: File --> Examples --> 02.Digital --> StateChangeDetection

Exactly. State change detection.
In the loop() if you detect a change from "button not pressed" to "button pressed" you set a timer.
In the loop you also check that timer. If it has expired (your pulse width in mS) you set the pulse pin low otherwise you set the pulse pin high.

Cool project. I’m addicted to the QS on my Tuono. :slight_smile:

Here’s an example of code (compiles, not tested) from which you can take some ideas:

#define IGN_ENABLE              HIGH
#define IGN_DISABLE             LOW
#define CLUTCH_PULLED           LOW         //level pinClutch attains when clutch lever is pulled in
#define QS_ACTIVE               LOW         //rider's foot is upshifting

#define QS_IGNITION_KILL_TIME   80  //mS ignition kill time during upshifts
#define QS_BLANKING_TIME        250 //mS blanking time after shifter is released before we enable QS ign cut again

const byte pinQS = 2;
const byte pinClutch = 3;
const byte pinIgnControl = 4;
const byte pinDBG = LED_BUILTIN;

void setup() 
    pinMode( pinDBG, OUTPUT );
    digitalWrite( pinDBG, LOW );
    pinMode( pinQS, INPUT_PULLUP );
    lastQS = digitalRead( pinQS );
    pinMode( pinClutch, INPUT_PULLUP );
    pinMode( pinIgnControl, OUTPUT );
    digitalWrite( pinIgnControl, IGN_ENABLE );


void loop() 
    static unsigned long
    static bool
        bQSBlanking = false,            //true = blanking period active
        bIgnitionStatus = true;         //true = ignition is enabled

    //if ignition kill is being timed...
    if( bIgnitionStatus == false )
        //has kill-time expired?
        if( millis() - timeIgnKill < QS_IGNITION_KILL_TIME )
            return; //no, just leave
        //kill-timing has finished; restore ignition operation and reset flag
        digitalWrite( pinIgnControl, IGN_ENABLE );
        digitalWrite( pinDBG, LOW );   //debug for ignition cut
        bIgnitionStatus = true;
        //are we timing a blanking-period for the QS? ...
        if( bQSBlanking == true )
            //... yes; has blanking time expired?
            if( millis() - timeQSBlanking < QS_BLANKING_TIME )
                return; //no, just leave

            //blanking period has expired; clear flag
            //digitalWrite( pinDBG, LOW );   //debug for QS blanking
            bQSBlanking = false;
            //if clutch lever pulled now, disable QS checks and allow normal shifting w/out ignition kill
            if( pinClutch == CLUTCH_PULLED )
            //read the status of the QS input
            currQS = digitalRead( pinQS );
            //(can add some debounce if desired)
            //if it's not the same as last time...
            if( currQS != lastQS )
                //save this read as the last
                currQS = lastQS;

                //if QS has transitioned from inactive to active (so rider is pulling up on shift-lever)...
                if( currQS == QS_ACTIVE )
                    //...get the time now and disable the ignition                    
                    timeIgnKill = millis();
                    digitalWrite( pinIgnControl, IGN_DISABLE );    
                    digitalWrite( pinDBG, HIGH );   //debug
                    bIgnitionStatus == false;   //indicate we're timing ignition cut
                    //shift lever has been released; set up for QS blanking period
                    timeQSBlanking = millis();
                    //digitalWrite( pinDBG, HIGH );   //debug
                    bQSBlanking = true;
            }//if QS now != last QS
        }//else not blanking
    }//else ignition is enabled


This does (or is intended to do…) a few things:

  1. Detect when the clutch lever is pulled and if so, disables the ignition kill function to allow normal manual shifting.

  2. Is set up for an 80mS ignition kill. This is a #define at the top of the code; you can change to suit your own need. Your gearbox may need more unload time or, maybe, you can get away with less.

  3. Has a “blanking” feature that disables the QS ignition cut for a period of time after the shift lever is released. Right now it’s set to 250mS (another #define; you can set it to whatever you like).

I’ve added a debug LED that can be made to blink on when the ignition cut is active or when the blanking period is active. You just have to comment/uncomment a couple of lines of code.

Good luck and ride safe!