Programming A Duel Delay

Hi There,

Im very new to arduino units and am wanting to do a knock sensor so that on the first knock it will delay 30 seconds and second knock will delay 60 seconds and 3rd knock will completely disabled. i have been able as a very new comer to write as far as this first delay but am stumped on a further step. If its a possibility to help me out and guide me through my next steps so that i may try myself. sorry if makes no sense.

const int sensorPin=A0;
const int ledPin= 13;
const int threshold= 100;

void setup()
{
pinMode(ledPin, OUTPUT);
}

void loop()
{
int val= analogRead(sensorPin);
if (val >= threshold)
{
digitalWrite(ledPin, HIGH);
delay(30000);
digitalWrite(ledPin, LOW);
}
else
digitalWrite(ledPin, LOW);

}

Add a Counter. Set it initially to Zero.

When the analog goes over the threshhold, increment the Counter.

If the Counter is now 1, do the 30 seconds.

If the Counter is 2, do the second delay.

If the Counter is now 3, reset it back to Zero.

Amazing thank you so much for the help

Possibly a counter and the use of a Boolean state for delay A and delay B. That way they won't fight each other depending on the state value.

Yes, to keep the delays from "clashing" or "compounding"

Can you clarify what this project is supposed to do?

What kind of knocks? Could they happen before your timeouts/delays expire? If so, what happens? Are delays additive or timed from the first knock?

Oh... :smiley:

essentially i am setting up a system for remote controlled tanks, i have three piezos sensors above the tracks on either side and i wish that during the first impact the track motor is taken out for a 30 second delay, the 2nd time the tracks are hit the motor shuts down for a 60 second delay and the third time the track is completely disabled, each tank is airsoft allowing for the knock against the sensor

Thanks

This might get you closer to what you want.

(YMMV; compiles for a Mega2560 but not tested; also not coded to super-duper ISO MISRA C- or CPP standards; may offend those who make a living coding...)

const int sensorPin=A0;
const int ledPin= 13;

#define NO_HIT_CHECKTIME    2L          //checks between no-hits is 2mS
#define POST_HIT_CHECKTIME  10L         //after a hit, next check is 10mS to allow for sensor settling/noise abatement
#define HIT_THRESHOLD       100

#define TRACK_REPAIR_TIME   30000L      //mS
#define ENGINE_REPAIR_TIME  60000L      //mS

//tank status states
#define HEALTHY             0
#define TANK_HIT            1
#define TANK_REPAIR         2
#define TANK_DEAD           3

int
    hitCount;

void setup()
{
    pinMode(ledPin, OUTPUT);
    hitCount = 0;
    
}//setup

void loop()
{
    AssessHits();
    DamageHandler();

}//loop

void AssessHits()
{
    static unsigned long
        hitCheckInterval = millis() + NO_HIT_CHECKTIME;
    unsigned long
        timeNow;

    //reads sensors every HIT_CHECK_TIME mS
    //may want to add some filtering or additional time after a hit for sensor settling etc
    timeNow = millis();
    if( timeNow >= hitCheckInterval )
    {
        if( analogRead( sensorPin >= HIT_THRESHOLD ) )
        {
            hitCount++;
            hitCheckInterval = timeNow + POST_HIT_CHECKTIME;
        }
        else
            hitCheckInterval = timeNow + NO_HIT_CHECKTIME;
        
    }//if
        
}//AssessHits

void DamageHandler()
{
    static int
        lastHitCount;
    static unsigned long
        timeRecovery;
    static byte
        damageState = HEALTHY;
        
    switch( damageState )
    {
        case    HEALTHY:
            if( hitCount )
            {
                //tank hit
                digitalWrite(ledPin, HIGH);
                damageState = TANK_HIT;
            }//if
            else
                //not hit detected
                digitalWrite(ledPin, LOW);
        break;

        case    TANK_HIT:
            lastHitCount = hitCount;
            //first hit damaged tracks
            timeRecovery = millis() + TRACK_REPAIR_TIME;
            damageState = TANK_REPAIR;
        break;

        case    TANK_REPAIR:
            if( hitCount == lastHitCount )
            {
                //have not been hit since last hit; keep repairing existing damage
                if( millis() >= timeRecovery )
                {
                    //time of repair has finished; tank is healthy
                    hitCount = 0;
                    damageState = HEALTHY;
                    
                }//if
                        
            }//if
            else
            {
                //crap...tank has been hit again; is this 1-2 (engine damage now) or 2-3 (dead)?
                if( hitCount == 2 )
                {
                    //took another hit when still repairing first; reset repair timer to "engine" time
                    timeRecovery = millis() + ENGINE_REPAIR_TIME;
                    lastHitCount = hitCount;
                    
                }//if
                else
                {
                    //tank has taken three hits before repairs completed; dead
                    damageState = TANK_DEAD;
                    
                }//else
            }
 
        break;
                
        case    TANK_DEAD:
            //there's no recovery from dead
            //though you could add a reset switch or something to get out of this state...
            
        break;
        
    }//switch
    
}//DamageHandler

Thank you for all the help, definitely sent me on the right path!