A few points:
(1) When entering code, please use the insert code menu item, so that it's properly formatted. You'll get less people helping if you make it hard for them to see your code properly.
(2) Your line checking for buttonState2 controls output 13, and your line checking button3 controls output12. That seems to be the opposite to what you want, so change the numbers on those lines.
(3) You've configured pins 12 and 13 to be outputs, yet you read them using digitalRead. I don't know if that is valid or not in Arduino world. It might be OK, but not all microcontrollers necessarily will report back what you expect, if you try to read an output pin. It might not be an issue, but personally I would not do this unless I was sure what the behavior was. If you're in any doubt, then simply create two variables, called (say) state12 and state13 (these are terrible names by the way, but it's the sort of convention you seem to be using, so I've stuck with it), then set your outputs either high or low at startup, as you desire, and set those state variables to match. Then, you never need to try to do a digitalRead on those outputs, you can simply check your variable state, and update that along with your digitalWrite commands.
Won't it be much easier to use interrupt rather than whatever this copy pasted code with absurd amount of blocking delay?
How AI would do it, with some prodding:
// toggle.ino // rev 0.1 // buttons with pull-downs on pins 2 and 3 are to toggle outputs on pins 12 and 13 respectively // buttons are connected to the microcontroller positive rail when pressed. Pull-down resistors are used. #include <Arduino.h> // define the pins #define BUTTONA 2 #define BUTTONB 3 #define OUTPUTA 12 #define OUTPUTB 13 // define the states #define OFF 0 #define ON 1 // define the states of the buttons int buttonAState = OFF; int buttonBState = OFF; // define the states of the outputs int outputAState = OFF; int outputBState = OFF; void setup() { // set the button pins as inputs pinMode(BUTTONA, INPUT); pinMode(BUTTONB, INPUT); // set the output pins as outputs pinMode(OUTPUTA, OUTPUT); pinMode(OUTPUTB, OUTPUT); // set the initial states of the outputs digitalWrite(OUTPUTA, outputAState); digitalWrite(OUTPUTB, outputBState); } // debounce the buttons void debounce(int button) { delay(50); while (digitalRead(button) == ON) { delay(50); } } void loop() { // read the buttons buttonAState = digitalRead(BUTTONA); buttonBState = digitalRead(BUTTONB); // if button A is pressed, toggle output A if (buttonAState == ON) { outputAState = !outputAState; digitalWrite(OUTPUTA, outputAState); debounce(BUTTONA); } // if button B is pressed, toggle output B if (buttonBState == ON) { outputBState = !outputBState; digitalWrite(OUTPUTB, outputBState); debounce(BUTTONB); } }
This is still not ideal, but has a chance of working (might need some mods, it is untested). I'd still do it differently, but this code should be easier to follow for a newcomer to Arduino.
I myself being a self admitted coding dunderhead, avoid the use of inversion in this case because its easy to overlook.
I'd use direct commands if buttonState3 == HIGH then {digitalWrite (12, LOW) ;} else {digitalWrite(12,HIGH);}
The time delays are for debouncing ? If so, as you add code, it ties up the IO scan time.
To make things more complicated, I'll edge detect, create a "last scan" value. If the value != last scan value ( state changes on an input), it then goes off to do the desired action without waiting a couple seconds. A time delay can be put elsewhere as needed.
I also dont like putting pin #s as a VARIABLE because I make an IO map assignment before I start a small project, altho a couple times would have been convenient. I acquiescence to software folks who want to smack me for even suggesting that party foul :-) In my defense, Im not writing 1000000 lines of code, not creating libraries, and dont code with team members :-)