New to coding, need some advice on were to start on a project

Hello, I'm quite new to coding and I have a project I need some help with, I have looked around to see if I can find some premade code to fit the project I'm doing as I am too inexperienced to write something from scratch, but I have come up short.

The project:
I have 5 different coloured LEDs and 2 push buttons (button 1 and button 2). Code start, all LEDs off, pressing button 1 will go to LED 1, pressing button 1 again will go LED 2 and so on until it loops back to the start, pressing button 2 from the start will go to LED 5, pressing button 2 again will go to LED 4 and so on until it loops back to the start (so the reverse of button 1), the last thing I need it to do is when ether button is held for longer than 2sec that it jumps to LED 5.

These are my input and output pins
Button 1 = pin2
Button 2 = pin3
LED 1 = pin5
LED 2 = pin6
LED 3 = pin9
LED 4 = pin10
LED 5 = pin11

If someone could point me to some code that might fit my project or help me write something I would be very grateful.

Thanks, Chris.

Don't bother looking for prewritten code, learn to write your own. That way you will understand what it does

You will get plenty of help here but you must start by writing some code yourself

Do you know how to detect when the state of a pin is LOW and print a message saying so ?

Do you know how to detect when the state of a pin becomes LOW and print a message saying so ?

How about doing the same with 2 inputs ?

Do you know what an array is and have you used them ?

Do you know what the millis() function does ?

When is our assignment due to be handed in ?

Start with the examples. start to understand the basics of code.

the example debounce has a good starting point for your code.

press the button and it changes state.
press once, light goes ON
press again, light goes OFF

what you could do is to increment a counter if the old state was OFF and the new state is ON, increment a counter.

since you are a beginner, it might be that a lot of if() statements will get you there.

if (counter==2) {
LED1status=0;
LED2status=1;
LED3status=0;
LED4status=0;
LED5status=0;
}

and at the end of loop()
and instead of doing it in the if() statements
do the output only once.

digitalWrite(LED1,LED1status);
digitalWrite(LED2,LED1status);
digitalWrite(LED3,LED1status);
digitalWrite(LED4,LED1status);
digitalWrite(LED5,LED1status);

a note about the counter
you can have a simple
if(counter=5){
counter=0;
}

so as it counts up, it only ever goes 0-4 for 5 states.

good luck and have some fun. please read the forum guidelines about how to post code using code tags. so when you do post code it will be in the correct format.

[ edit: the OP will have to figure some things out for themselves.
0 or 1 to turn ON an LED
that 0 to 4 is 1 to 5
Learn by doing

Hi UKHeliBob,
I agree, learning to write it from scratch would be far more beneficial.

Would that be checking that the pin state is LOW?

and this would be checking the pin has gone from a HIGH to LOW state?

I believe so, but after playing with the debounce example I was unable to make it work with two buttons.

No, I'm not sure.

Again, not sure.

I have around 2 weeks, but I could probably get an extension if I can show some results.

Thanks, Chris.

Try to make the assignment easier to start and iterate towards the full thing.

Start with one button & one led. When you can control that, (debounce mostly) add a led. Rinse and repeat.

By the time you have five leds working with the first button, adding the second should feel trivial.

Hi dave-in-nj,

Thank you for your advice, I have started to play around with the debounce example and will try to implement a second input and a counter, I'll let you know how I get on.

Thanks, Chris.

Well, here is some code that actually does something different, but contains all the button management in a concise fashion.

// Multiple toggles!
const int led1Pin =  3;    // LED pin number
const int button1 =  2;
const int led2Pin =  5; 
const int button2 =  4;
const int led3Pin =  6;
const int button3 =  7;
const int led4Pin =  9;
const int button4 =  8;
char bstate1 = 0;
char bstate2 = 0;
char bstate3 = 0;
char bstate4 = 0;
unsigned long bcount1 = 0; // button debounce timer.  Replicate as necessary.
unsigned long bcount2 = 0;
unsigned long bcount3 = 0;
unsigned long bcount4 = 0;

char led1State = LOW;        // initialise the LED
char led2State = LOW;
char led3State = LOW;
char led4State = LOW;

// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check
// Routines by Paul__B of Arduino Forum
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) { 
    *marker += interval;    // move on ready for next interval
    return true;       
  } 
  else return false;
}

// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
// Routines by Paul__B of Arduino Forum
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, >= 2 if debounce in progress
  case 0: // Button up so far, 
    if (button == HIGH) return false; // Nothing happening!
    else { 
      *butnstate = 2;                 // record that is now pressed
      *marker = millis();             // note when was pressed
      return false;                   // and move on
    }

  case 1: // Button down so far, 
    if (button == LOW) return false; // Nothing happening!
    else { 
      *butnstate = 3;                 // record that is now released
      *marker = millis();             // note when was released
      return false;                   // and move on
    }

  case 2: // Button was up, now down.
    if (button == HIGH) {
      *butnstate = 0;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 1;               // jackpot!  update the state
        return true;                  // because we have the desired event!
      }
      else 
        return false;                 // not done yet; just move on
    }

  case 3: // Button was down, now up.
    if (button == LOW) {
      *butnstate = 1;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 0;               // Debounced; update the state
        return false;                 // but it is not the event we want
      }
      else 
        return false;                 // not done yet; just move on
    }
  default:                            // Error; recover anyway
    {  
      *butnstate = 0;
      return false;                   // Definitely false!
    }
  }
}

// ----------------------------- toggle ------------------------------------------
char toggle(char *flip) {   // Yes, it toggles the variable pointed to
  if (*flip == LOW) {
    *flip = HIGH;
  }
  else {
    *flip = LOW; 
  } 
  return *flip;
}

void setup() {
  pinMode(led1Pin, OUTPUT);      
  pinMode(button1, INPUT_PULLUP); 
  pinMode(led2Pin, OUTPUT);      
  pinMode(button2, INPUT_PULLUP);      
  pinMode(led3Pin, OUTPUT);      
  pinMode(button3, INPUT_PULLUP);      
  pinMode(led4Pin, OUTPUT);      
  pinMode(button4, INPUT_PULLUP);        
  digitalWrite (led1Pin, LOW);
  digitalWrite (led2Pin, LOW);
  digitalWrite (led3Pin, LOW);
  digitalWrite (led4Pin, LOW);
}

void loop() {
  // Toggle LED if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
    toggle(&led1State);
    digitalWrite(led1Pin, led1State);
  } 

  if (butndown(digitalRead(button2), &bcount2, &bstate2, 10UL )) {
    toggle(&led2State);
    digitalWrite(led2Pin, led2State);
  } 

  if (butndown(digitalRead(button3), &bcount3, &bstate3, 10UL )) {
    toggle(&led3State);
    digitalWrite(led3Pin, led3State);
  } 

  if (butndown(digitalRead(button4), &bcount4, &bstate4, 10UL )) {
    toggle(&led4State);
    digitalWrite(led4Pin, led4State);
  } 
}

If you add LED 5 and then work with the last part, you can use this as the basis for your own code.

Or maybe I might do it for you. :grin:

Hmmm. ...

Maybe not the last part.

Right! One of the "secrets" of programming is start with something simple and "develop" or "expand" from there. If you're a beginner that means adding one or two lines of code at a time, test-compiling and test-running as you go.

If you don't do that you can get many-many errors and the compiler can report errors that are hard to figure-out and sometimes useless*. And/or you can end-up with logic errors (not syntax errors) where the program compiles without errors but doesn't behave as you expect.

If you add a couple of lines and an error pops-up, at least you know where the error is. Of course, professional programmers working on bigger programs write more than one or two lines at a time but NOBODY writes the whole program without testing as they go.

It's also helpful to take advantage of the serial monitor to "print out" messages (like "button one pushed", or you an display variable values etc.) so you can "see" what your program is doing before you are done. Once your program is finished you can remove or comment-out that code. And if you have LEDs working you can take advantage of the LEDs also to "see" what your program is doing.

It's also often helpful to work on the input (buttons in your case) and output (LEDs in your case) separately. In your case, you might want to work on the LED sequences first since that can be done and tested with no input and maybe with no additional "test code".

It takes some practice to develop your code this way because you can't just start at the top and work down, like you're writing a story or something... For example, if you delete the bottom-half of a program it's not going to compile or run. The compiler has to see a "complete" program. It also takes some practice to write a section of code that you can test & debug independently from the rest of the program.

The two most important concepts in programming are conditional execution (if statements, etc.) and loops (doing something over-and-over, usually until some condition is reached). Once you understand those two concepts you can start to write logical-useful programs.

*I was once working on a rather large program, large for me, maybe 5000 lines of code (not an Arduino project) - I put one curly bracket in the wrong place and the compiler reported thousands of errors! None of those errors said "misplaced curly bracket". The complier was just confused because the program didn't "make sense" to it. It took me a few hours of commenting-out code to make something that would compile again and then eventually track-down the problem.

@silverchris
Have you heard the name of Flow Chart Programming? This programming art uses some predefined geometrical figures to visualize the behavior of the hardware circuit. After that it is an enjoyabe job through trials-and erros to write sketch/codes for the Flow Chart. The solution to your problem can be described by the flow chart of Fig-1.

For simplicity, let us use only two LEDs (LED1 and LED2) connected at DPin-13 and DPin-6. Button-1 and Button-2 are respeectively connected with DPin-2 and DPin-3 (Fig-2).


Figure-1:

sw2led2
Figure-2:

The Arduino Codes for the Flow Chart of Fig-1 using goto statement (tested in UNO). Why is goto statement? At the moment it is beyond my ability to develop the Control Program without using goto statement and also the code optimization.

#include <Debounce.h> //for button debouncing
Debounce Button1(2);
Debounce Button2(3);
byte LED1 = LED_BUILTIN;
byte LED2 = 6;
bool flag1 = false;
bool flag2 = false;

void setup()
{
L0: Serial.begin(9600);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
L1: digitalWrite(LED1, LOW);
  digitalWrite(LED2, LOW);
L2: if (flag1 == true)
  {
    goto L9;
  }
L3:  chkButton1();    //for close codition
L4: digitalWrite(LED1, HIGH);
L5: chkButton1();
L6: digitalWrite(LED2, HIGH);
L7: chkButton1();
L8: flag1 = true;
  goto L1;
L9: if (flag2 == true)
  {
    goto L16;
  }
L10: chkButton2();   //for close condition
L11: digitalWrite(LED2, HIGH);
L12: chkButton2();
L13: digitalWrite(LED1, HIGH);
L14: chkButton2();
L15: flag2 = true;
  goto L1;
L16: chkButton1();
  Serial.println("L17:"); //debugg
L17: unsigned long pr1Millis = millis();
  while (millis() - pr1Millis <= 2000)
  {
    if (!Button1.read() != LOW)
    {
      Serial.print("open"); //debugg
      goto L20;
    }
  }
L18: digitalWrite(LED2, HIGH);
L19: while (1);
L20: Serial.println("HERE"); //debugg
chkButton2();
L21: unsigned long pr2Millis = millis();
  while (millis() - pr2Millis <= 2000)
  {
    if (!Button2.read() != LOW)
    {
      goto L16;
    }
  }
  goto L18;
}

void loop()
{

}

void chkButton1()  //for close condition
{
  while (!Button1.read() != HIGH) {} //to ensure that Button-1 is at open condition
  while (!Button1.read() != LOW) {}
}

void chkButton2()    //for close condition
{
  while (!Button2.read() != HIGH) {}
  while (!Button2.read() != LOW) {}
}

This thread is a hoot

Maybe someone will post the version using port manipulation?

And can someone post a version using ASM?

I would love to see the professors face when looking at these solutions.

Although I would hate to be in the shoes of the student asked to explain the code to the class.

This thread is like an inside joke.
And the full moon is not for another week.

Hi,
Welcome to the forum.

Can I suggest you get some of the hardware , if you haven't already, and build just the two press button part of your project.

Write some code, or try and we will help, that reads the buttons, using Serial.print.
Serial.print is essential in code debugging and developing.

That will get you started and we can assist with further developments.
Adding a couple of LEDs and their series resistors would be next.

Unfortunately code just doesn't materialize, it takes development.

What have you programmed on your Arduino so far?
What model Arduino is it?

Tom... :smiley: :+1: :coffee: :australia:

I'm back, thank you to everyone for your help on this project, I am still trying to wrap my head around the code but I thought I'd an update and see what to do next. I have made a test box, circuit diagram, a flow chart, and the beginnings of a program (the code compiles but does not work), see below.

const int button1 = 2;
const int button2 = 3;
const int red = 5;
const int green = 6;
const int blue = 9;
const int white = 10;
const int uv = 11; 

int buttonState1;
int buttonState2;  
int lastButtonState1 = HIGH;
int lastButtonState2 = HIGH; 
int counter = 0;
unsigned long lastDebounceTime = 0; 
unsigned long debounceDelay = 50; 

void setup() {
  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  pinMode(red, OUTPUT); digitalWrite(red, HIGH);
  pinMode(green, OUTPUT); digitalWrite(green, HIGH);
  pinMode(blue, OUTPUT); digitalWrite(blue, HIGH);
  pinMode(white, OUTPUT); digitalWrite(white, HIGH);
  pinMode(uv, OUTPUT); digitalWrite(uv, HIGH);
}

void loop() {
  int reading1 = digitalRead(button1);
  if (reading1 != lastButtonState1) {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading1 != buttonState1) {
      buttonState1 = reading1;

      if (buttonState1 == LOW) {
        counter++;
      }
    }
  }
  else if (counter == 0){
    digitalWrite(red, HIGH);
    digitalWrite(green, HIGH);
    digitalWrite(blue, HIGH);
    digitalWrite(white, HIGH);
    digitalWrite(uv, HIGH);
  }
  else if (counter == 1){
    digitalWrite(red, HIGH);
    digitalWrite(green, HIGH);
    digitalWrite(blue, HIGH);
    digitalWrite(white, LOW);
    digitalWrite(uv, HIGH);
  }
}

Thanks, Chris.

LED

You need current limiting resistors for the LEDs

Hello
Your flow chart is not clean and/or incomplete, see cutout.

grafik

It's on the 3.3V rail just for the test box, I know there a little overloaded but it should be fine for how long it's going to be used, the final design will be running 12v arrays via transistors.

Thanks, Chris.

Hi,

Its not a case of overloading the LEDs, its a case of overloading the Nano outputs.
Please fit current limit resistors.

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

Oh, I see, my bad :sweat_smile:

I'll do that now, and update the diagram later

Thanks, Chris. :grin:

else if (counter == 0){

Remove the else. All 5 should be simple if() statements.

And

if (buttonState1 == LOW) { counter++;

Needs to add
if(counter==5){
counter=0;
} /loop back to 0 with multiple button presses

If you don't want it to loop then

if (counter >= 4){ //allows for multiple excessive button presses

And counter could be locked at 4
Following counter++
if(counter>=5){ counter=4;