PLEASE HELP A BEGINNER

Hi everyone,

I´m new to this forum and using arduino. Can somebody please help me with the following issue:

When I press a button, and hold it down (HIGH) (attached to pin2) I want Output (pin13) to go HIGH for 15 seconds, and after 15 seconds to go LOW. And when I release the button, I want Output (pin13) to stay LOW, and (pin12) to go HIGH for 15 seconds, and then go LOW after 15 seconds. Both outputs CANT be HIGH at the same time !

Consider the button as a ON/OFF switch, and when the condition changes, the board should do what explained earlier. So when changed from OFF to ON, the circuit should do the same as in reverse..

Here is my code that I tried, but something sucks:

int buttonPin = 2; // the number of the pushbutton pin
int ledPin_1 = 13; // the number of the LED pin
int ledPin_2 = 12;

// variables will change:
int buttonState = 0; // variable for reading the pushbutton status

void setup() {
// initialize the LED pin as an output:
pinMode(ledPin_1, OUTPUT);
pinMode(ledPin_2, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}

void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);

// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (buttonState == HIGH) {
// turn LED on:
digitalWrite(ledPin_1, HIGH);
delay(3000);
digitalWrite(ledPin_1, LOW);
} else {
// turn LED off:
digitalWrite(ledPin_1, LOW);
}
if (buttonState == LOW) {
// turn LED on:
digitalWrite(ledPin_2, HIGH);
delay(3000);
digitalWrite(ledPin_2, LOW);
} else {
// turn LED off:
digitalWrite(ledPin_2, LOW);
}

Whats wrong with my code ?

Please help me understand this..

You probably should look at the state change detection example, to see how to do something when a switch BECOMES pressed, rather than trying to do something when the switch IS pressed.

You should be recording WHEN the switch becomes pressed, so you can turn the LED on and off relative to that time, as shown in the Blink Without Delay example.

3000 !-= 15 seconds.

How IS your switch wired? Using INPUT_PULLUP makes for much easier wiring - just connect one leg to the pin and the other to ground. Then, LOW means pressed and HIGH means released.

Before we can explain why the code doesn't do what you want, you need to explain what the code actually does, and how that differs from what you want.

Hi,

The arduino Micro board is wired as shown in the attachment.

the code complies and uploads with mo problems..

3000ms is only to check the functionality without having to wait 15 seconds..

The arduino Micro board is wired as shown in the attachment.

That is a useless picture. No one can tell anything about which wires go where. Draw a schematic - by hand is fine.

SWITCH (NO):

1-> ARDUINO 5V pin
2-> ARDUINO Pin2 + other end connected to ground thru 10k resistor

LED1 connected to ARDUINO Pin13 with 470k serial resistor
LED2 connected to ARDUINO Pin12 with 470k serial resistor

as you can see in the code.

Can You send me a working example maybe?, or Im just so stupid that nobody wants to help..

thanks in advance.

  • Jarno

Anyone ? Please give me a working example. This cant be so difficult for you guys…

or Im just so stupid that nobody wants to help…

You misspelled impatient. Some of us have jobs to attend to and lives to live.

Pull the switch wiring. Put the resistors away. Connect one leg of the switch to the digital pin. Connect the other leg to ground. Use INPUT_PULLUP in the pinMode() call.

Have you looked at the state change detection example? Doesn’t it make sense to act when the switch BECOMES pressed, or BECOMES released, rather than when the switch IS pressed or IS released?

Hi,

I did look at it, but I dont understand what is in the code, and I dont know how to edit in such a way that my circuit would work.

Sorry, but I´m a beginner from Finland, and i thought this forum was about to help people on these projects. I would just apreciate an working example. I cant learn this unless I have something to start with.. A blinking led isnt just enough for me..

Sorry.

I would just apreciate an working example.

The state change detection example IS a working example.

It read the state of the pin on this pass through loop(), and compares it to the state on the previous pass. If they are different, the switch has become pressed, or has become released, so a state change has occurred.

The current state defines whether the switch has become pressed or has become released, so you can do something when the change you care about happens.

Modify the example to turn an LED on when the switch becomes pressed. Turn the LED off when the switch becomes released.

Then, turn things around. The LED should be on until the switch becomes pressed, when it should go off. When the switch becomes released, the LED should turn back on.

You'll learn a lot be spending half an hour experimenting.

Be honest: Is this for a class assignment? Keep in mind that teachers/professors can see this forum too :slight_smile:

Try and see if this works; if it does, try to make sense of it.

const int pinSwitch = 2;
const int pinLED1 = 13;
const int pinLED2 = 12;

int
    currSwitch,
    lastSwitch;
byte
    state;
unsigned long
    timeStart;
       
void setup() 
{
    pinMode( pinSwitch, INPUT );
    lastSwitch = digitalRead( pinSwitch );
    pinMode( pinLED1, OUTPUT );
    pinMode( pinLED2, OUTPUT );
    state = 0;
    
}//setup

void loop() 
{
    if( state == 0 )
    {
        //waiting for the button to transition from
        //low to high
        currSwitch = digitalRead( pinSwitch );
        if( currSwitch != lastSwitch )
        {
            if( currSwitch == HIGH )
            {
                //went from low to high
                //turn on the LED and get the millis count 
                digitalWrite( pinLED1, HIGH );
                timeStart = millis();
                //now move to the state where LED1 is timed
                state = 1;
            
            }//if
            //save this switch state as the last switch state
            lastSwitch = currSwitch;
            
        }//if
        
    }//if
    else if( state == 1 )
    {
        //wait until 15s has passed...
        if( millis() - timeStart >= 15000 )
        {
            //then turn off the LED and move to the state
            //where we look for a falling edge on the switch
            digitalWrite( pinLED1, LOW );
            state = 2;
             
        }//if
    }
    else if( state == 2 )
    {
        //looking for a falling edge...
        currSwitch = digitalRead( pinSwitch );
        if( currSwitch != lastSwitch )
        {
            if( currSwitch == LOW )
            {
                //got one. Turn on the 2nd LED, rinse and repeat
                digitalWrite( pinLED2, HIGH );
                timeStart = millis();
                state = 3;
            
            }//if

            lastSwitch = currSwitch;
            
        }//if 
               
    }//else if
    else
    {
        //once LED2 has timed out, set it low and 
        //go back to looking for a rising edge again
        if( millis() - timeStart >= 15000 )
        {
            digitalWrite( pinLED2, LOW );
            state = 0;
             
        }//if
        
    }//else
    

}//loop

Hi,

Thank you for this. Your example works just the way I wanted. Thank you wery much.

This is not a school thing. Im 34 year old electrical engineer from Finland, not a coder.

I try to multiple this working by 6 buttons and 12 outputs tomorrow.

Thanks again !!

JARNO_84:
Hi,

Thank you for this. Your example works just the way I wanted. Thank you wery much.

This is not a school thing. Im 34 year old electrical engineer from Finland, not a coder.

I try to multiple this working by 6 buttons and 12 outputs tomorrow.

Thanks again !!

What you see there is a crude and simplified "state machine." It could be refined and made more compact. If you start adding that many elements you're probably going to want to "architect" the code differently than that example.

Also, that code does pretty much exactly what you asked. If you lift the switch during the first LED timing, it won't be caught; to activate LED2 I think you'd need to push and release the switch so the logic sees that falling edge. Think about boundary conditions and how you code will handle things if inputs aren't exactly what you expect.

Hi,

do I just add more pinLed:s to the void setup, like pinLed3 to 12 ? and copy the rest of the code to the loop with corresponding pin numbers ? And ofcourse 5 more pinSwithes; pinSwitch to pinSwitch 5 on the start of the program ?

JARNO_84:
Hi,

do I just add more pinLed:s to the void setup, like pinLed3 to 12 ? and copy the rest of the code to the loop with corresponding pin numbers ? And ofcourse 5 more pinSwithes; pinSwitch to pinSwitch 5 on the start of the program ?

You could, if that’s what you’re comfortable doing.

Consider what you’re doing: Six things, all pretty much the same. Only things that are different are the pins for the switches and the LEDs. When you think about it like that you might think that arrays could be handy to cut down on the code bulk. It adds a bit of complexity to the syntax but the underlying logic is pretty much the same.

Consider this:

#define NUM_SWITCHES        6

//states used in state machine
#define INIT_STATE      0
#define TIME_LED        1

const int pinSwitch1 = 2;   //the pin assigments here are mostly arbitrary. Change to whatever you're using
const int pinSwitch2 = 3;
const int pinSwitch3 = 4;
const int pinSwitch4 = 5;
const int pinSwitch5 = 6;
const int pinSwitch6 = 7;

const int pinLED11 = 13;    //ditto...
const int pinLED12 = 12;
//
const int pinLED21 = 50;
const int pinLED22 = 49;
//
const int pinLED31 = 48;
const int pinLED32 = 47;
//
const int pinLED41 = 46;
const int pinLED42 = 45;
//
const int pinLED51 = 44;
const int pinLED52 = 43;
//
const int pinLED61 = 42;
const int pinLED62 = 41;

//an array of the switches
const int grSwitches[] =
{
    pinSwitch1,
    pinSwitch2,
    pinSwitch3,
    pinSwitch4,
    pinSwitch5,
    pinSwitch6
        
};

//an array of the LED1s
const int grLED1s[] =
{
    pinLED11,
    pinLED21,
    pinLED31,
    pinLED41,
    pinLED51,
    pinLED61
      
};

//an array of the LED2s
const int grLED2s[] =
{
    pinLED12,
    pinLED22,
    pinLED32,
    pinLED42,
    pinLED52,
    pinLED62
      
};

//an array of the last switch readings
int
    lastSwitch[6];
    
//an array of each switch's state in the state machine
byte
    state[6];

//an array of uls for timing each switch's LEDs
unsigned long
    timeStart[6];

//used to shorten the state machine
//when false, LED1 is being processed
//when true, LED2 is being processed
bool
    bledState[6];
       
void setup() 
{
    Serial.begin(9600);

    //arrays are pretty handy to tidy up pinModes etc
    for( int i=0; i<NUM_SWITCHES; i++ )
    {
        pinMode( grSwitches[i], INPUT );
        pinMode( grLED1s[i], OUTPUT );
        pinMode( grLED2s[i], OUTPUT ); 
        lastSwitch[i] = digitalRead( grSwitches[i] );
        bledState[i] = false;
        state[i] = INIT_STATE;
        
    }//for
        
}//setup

void StateMachine( void )
{
    int 
        currSwitch;
    static byte
        stateIndex = 0;

    //each pass through we look at a different switch
    //they could all be at different states in the statemachine
    //the arrays keep things separate for us
    switch( state[stateIndex] )
    {
        case    INIT_STATE:
            currSwitch = digitalRead( grSwitches[stateIndex] );
            if( currSwitch != lastSwitch[stateIndex] )
            {
                //when bledState is false we're looking for the rising edge of the switch
                //when false, the falling edge
                if( currSwitch == (bledState[stateIndex]==false)?HIGH:LOW )
                {
                    //turn on the LED according to bledState (1 if false, 2 if true)
                    if( bledState[stateIndex]==false )
                        digitalWrite( grLED1s[stateIndex], HIGH );
                    else
                        digitalWrite( grLED2s[stateIndex], HIGH );
                        
                    timeStart[stateIndex] = millis();
                    state[stateIndex] = TIME_LED;
            
                }//if
                
                lastSwitch[stateIndex] = currSwitch;
            
            }//if
            
        break;
        
        case    TIME_LED:
            if( millis() - timeStart[stateIndex] >= 15000ul )
            {
                //when the time is up, turn off the appropriate LED
                if( bledState[stateIndex]==false )
                    digitalWrite( grLED1s[stateIndex], LOW );
                else
                    digitalWrite( grLED2s[stateIndex], LOW );

                //toggle the led state boolean; was false, now is true so next pass through
                //we process other switch condition and LED
                bledState[stateIndex] ^= true;
                state[stateIndex] = INIT_STATE;
                 
            }//if

        break;
        
    }//switch

    //each pass through we bump which switch we're looking at.
    //the processor should be fast enough that you don't notice the processor
    //is only spending a short time on each switch
    stateIndex++;
    if( stateIndex == NUM_SWITCHES )
        stateIndex = 0;
        
}//StateMachine

void loop() 
{
    //the state machine takes care of everything. Generally want to call it very 
    //often so don't add blocking stuff like delay() calls etc here...
    StateMachine();
    
}//loop

This should do six of switch/LED combos you want (you’ll have to set the pins to whatever you’re using…) It relies heavily on arrays of “like” things; six switches (array); six LED1s (array); six LED2s (array); six states (array). I also shortened the state machine some by leveraging that LED1 and LED2 do the same thing just on different edges of the switch. Look and you’ll see a variable called bledState; see if you can follow what it’s doing.

I tried this on my Mega2560 here with only your original single LED pair and it seems to work.