Need Help Coding This..

I am trying to:

Program Arduino to cause LED to flash when the left whisker is pressed. The LED should flash at progressively faster rates(shorter and shorter on/off cycles) for each successive press-hold-release of the left whisker switch.Start with a cycle of 2 seconds on and 2 seconds off while the switch is being pressed, and reduce each timing length by one half for each consecutive left-whisker press (after it has been released and pressed again). When the right whisker switch is pressed, the on-off cycle should revert to the initial 2 seconds on and 2 seconds off cycle-length (i.e., resetting the cycle length). When the left whisker is not actively pressed, the LED should remain off.

Where my code is at now... What do I need to add to get it to do the above?

int LEDpin = 6;
int switchpin = 4;
int switchstatus;
int leftwhisker = 8;
int rightwhisker = 9;
int leftwhiskerstatus;
int rightwhiskerstatus;

void setup() {
pinMode(LEDpin, OUTPUT);
pinMode(switchpin, INPUT);
pinMode(8, INPUT);
pinMode(9, INPUT);
}

void loop() {
switchstatus = digitalRead(switchpin);
if (switchstatus==HIGH){
digitalWrite(LEDpin,LOW);
}
else {
digitalWrite(LEDpin, HIGH);
}
leftwhiskerstatus = digitalRead(leftwhisker);

if (leftwhiskerstatus==HIGH) {
digitalWrite(LEDpin, HIGH);
delay (500);
digitalWrite(LEDpin,LOW);
delay (500);
}
rightwhiskerstatus = digitalRead(rightwhisker);
if (rightwhiskerstatus==HIGH) {
digitalWrite(LEDpin, HIGH);
delay (1000);
digitalWrite(LEDpin,LOW);
delay (1000);
}
else {
digitalWrite(LEDpin, LOW);
}
}

You need to learn to avoid using the delay function. Look at the following example

File -> Examples -> 02.Digital -> BlinkWithoutDelay

Delay is a bad function. It just stops and wastes processor cycles. What you want to do is think about the loop function. It is executed again and again. Every time you execute it you look at your system and decide what the status needs to be.

Thanks @Klaus_K for the info, but that isnt what I'm asking about. I will fix the delay later once I understand arduino coding a bit better and after I review your link.

But first I need to get the red text above into code. Can you help with that?

“ I will fix the delay later once I understand arduino coding a bit better and after I review your link. ”

Do it now.

Stop using delay() in your sketches.

Never use delay() again.

Forget that delay() even exists.

delay() stops regular code execution for the delay interval.
You can replace delay() with a technique called Blink Without Delay, BWD.
When using BWD, your sketch can run other code during the delay time.
Read Robin2’s discussion, Demonstration code for several things at the same time:
https://forum.arduino.cc/index.php?topic=223286.0

What would / should happen if both were pressed, or does the physical layout make that physically impossible? (I'm picturing an actual cat, or a car, trying to go through too narrow an opening and touching both sides.)

What's switchPin for?- is that like an on/off "mains switch" which dictates if the whiskers are active? (Not clear from your existing code ehat it's supposed to do.)

But in any case, look at blink without delay (as others noted while I was typing), and put the code from there in a function, and make the interval a variable. Set the variable value as 500 or 1000 according to which switch is pressed, and only call your new function if either is pressed (subject to describing what switchPin is supposed to do.)

Side note: how are the switches wired? You're looking for them to go high, so probably wired pin to 5V? In which case do they have pull down resistors to hold them low when not pressed? Easier option is to wire the switch from pin to ground, and use INPUT_PULLUP in pinMode and dispense with external resistors. Then change the code's logic, to look for a low when pressed.

edit: Karma-- (if there was such a thing) for making a significant edit to the opening post while folk were responding. Most of the red wasn't there when I read it originally. So what I just typed might not be appropriate anymore.

spottieottie:
Program Arduino to cause LED to flash when the left whisker is pressed. The LED should flash at progressively faster rates(shorter and shorter on/off cycles) for each successive press-hold-release of the left whisker switch.Start with a cycle of 2 seconds on and 2 seconds off while the switch is being pressed, and reduce each timing length by one half for each consecutive left-whisker press (after it has been released and pressed again). When the right whisker switch is pressed, the on-off cycle should revert to the initial 2 seconds on and 2 seconds off cycle-length (i.e., resetting the cycle length). When the left whisker is not actively pressed, the LED should remain off.

Above for posterity is the current red text from the opening post (in case it gets changed again :wink: ) which afaiks still doesn't say what switchPin does?

The new spec means you need to look at the state change detect tutorial now also, and use that to halve the interval for each new press of the left whisker, or to reset it for a right press.

@fishbone and Larry- So not looking to fix something that isn't broke. Delay, although inefficient, works. What doesn't work is what I'm trying to figure out in red. Lets fix something that is actually broken right now please? Just looking for help not condescension or code shaming.

spottieottie:
but that isnt what I'm asking about.

The BlinkWithoutDelay is all you need to solve your issue. As you can see, some have strong feelings about this function. The reason is that it creates many issues in beginners projects. We have seen it many times. Once you understand how the example works it will help you again and again.

Seriously, this has nothing to do with code shaming.

We are giving very good advice.

Your requirement for this sketch is very easy, but first please take some direction or not . . .

The only way I see it working is to use state change detect as I said, else while you hold the left down to make it blink, the interval will halve every time through loop() but you need it to halve only on a new press.

My approach would be to put blink without delay in a function, with the interval as a variable. Halve the interval with each new left press, and reset it with each new right press. Only call the blink function while the left whisker is still pressed.

What must happen if the right whisker is pressed while the left is held, ie there's a blink in progress? Should the right press be ignored, should the interval change for the current blink, or should the interval change for the next left whisker release/press cycle?

edit: still have no idea what switchPin's for.

You're doing a class assignment and asking for help. Does it really make sense to argue with those offering advice?

You say "So not looking to fix something that isn't broke. Delay, although inefficient, works."

People here are saying delay() won't produce good results for what you want here. In that respect, it is broken. It's not the right tool for the job.

The problem with trying to use delay here (and anywhere) is that it blocks. When you first press the left switch and start your 2-second delay (e.g. delay(2000)), there will be 2-seconds where the Arduino is dead to the outside world. It will not recognize if you've released the switch, or if you pressed the right etc for the entire 2-second duration of the delay. Indeed, if you code it so, you might make the thing dead for 4-seconds (e.g. LED on for 2-seconds, LED off for 2-seconds --> rest of loop.) It also makes it difficult to do other timing like switch debounce.

You don't have to use this but have a look anyway; millis() based timing that doesn't block the CPU along with a few other slightly more advanced concepts.

#define BLINK_BIT       0b00000001      //bitmask   flag indicating status of fast-blink
#define LEFT_BIT        0b00000010      //bitmask   flag indicating status of left switch
#define SW_INTERVAL     50ul            //mS        switch read interval
#define DEFAULT_BLINK   2000ul          //mS        default/initial blink rate
#define MIN_BLINK_TIME  25ul            //mS        minimum value for blink time (no more /2 at this point)

const byte pinLED = LED_BUILTIN;        //easy debug; use of LED mounted to board
//const byte pinLED = 6;
//const byte switchpin = 4; //?         //what is this for?
const byte pinLeftWhisker = 8;
const byte pinRightWhisker = 9;

unsigned long
    timeBlink;

byte
    bFlags,
    lastLeftWhisker,
    lastRightWhisker;

void setup() 
{
    pinMode( pinLED, OUTPUT );
    //pinMode(switchpin, INPUT);    //?
    pinMode( pinLeftWhisker, INPUT_PULLUP );        //see notes below about switch pin states
    pinMode( pinRightWhisker, INPUT_PULLUP );

    bFlags = 0;
    timeBlink = DEFAULT_BLINK;
    lastLeftWhisker = digitalRead( pinLeftWhisker );
    lastRightWhisker = digitalRead( pinRightWhisker );
    
}//setup

void doBlinkFlags( void )
{
    static unsigned long
        timeToggle;
    unsigned long
        timeNow;

    //get the millis count now
    timeNow = millis();
    
    //only time blinks when the left switch is pressed
    //makes the initial flash timing better
    if( !(bFlags & LEFT_BIT) )
    {
        //if button is not pressed, reset the toggle time and return
        timeToggle = timeNow;
        bFlags |= BLINK_BIT;        //makes sure LED turns on when switch closes
        
        return;
    }

    //if left is pressed, check the time; is it time to toggle the flag bit?
    if( timeNow - timeToggle >= timeBlink )
    {
        //yes; toggle the blink flag
        bFlags ^= BLINK_BIT;
        //and save the time for the next compare
        timeToggle = timeNow;
        
    }//if
    
}//doBlinkFlags

void pollSwitches( void )
{
    static unsigned long
        timeSwitch;
    unsigned long
        timeNow;
    byte
        swNow;

    //get the millis count
    timeNow = millis();
    
    //time to read the switches?
    if( timeNow - timeSwitch < SW_INTERVAL )
        return; //no just return

    //yes; save the time for the next polling
    timeSwitch = timeNow;

    //read the left whisker
    swNow = digitalRead( pinLeftWhisker );
    //if not the same as the last time the switch was read...
    if( swNow != lastLeftWhisker )
    {
        //switch was pushed or released; save the new value for next compare
        lastLeftWhisker = swNow;
        
        //is is high or low now?
        if( swNow == LOW )          //assume NO-MOM that, when pressed, grounds pin
            bFlags |= LEFT_BIT;     //if low now, switch is pressed so set the left flag
        else
        {
            //when the switch is released, we...
            bFlags &= ~LEFT_BIT;                //...clear the left switch flag and...
            //...if we're above the minimum blink time, divide the blink timer by two
            if( timeBlink > MIN_BLINK_TIME )
                timeBlink /= 2;
        }//else
        
    }//if

    //if right is pressed, reset the blink timer
    swNow = digitalRead( pinRightWhisker );
    if( swNow != lastRightWhisker )
    {
        lastRightWhisker = swNow;
        if( swNow == LOW )      //assume NO-MOM that, when pressed, grounds pin
            timeBlink = DEFAULT_BLINK;
        
    }//if
    
}//pollSwitches

void loop() 
{
    //every loop check the blink flags and switches    
    //timing logic in each function determines when actions happen
    doBlinkFlags();
    pollSwitches();

    //LEFT_BIT is set when left whisker switch is closed; if closed, enable LED blinking
    if( bFlags & LEFT_BIT )
        digitalWrite( pinLED, (bFlags & BLINK_BIT) ? HIGH:LOW );
    else
        digitalWrite( pinLED, LOW );    //switch is open; turn the LED off.
            
}//loop

larryd:
“ I will fix the delay later once I understand arduino coding a bit better and after I review your link. ”

Do it now.

One of the best reasons for doing this now is that the further in you get with delay() the harder it becomes to pull it out and change over to using millis(). Kind of a 'pay me now or pay me later' thing.

What is the behavior as is? This could be as simple as using INPUT_PULLUP.

OP I have written a sketch along the lines of what I described above. It doesn't use any showy Blackfinian "slightly more advanced concepts", and only uses the simple tutorial techniques of blink without delay and state change detect. I'll post it if you want it.