Adding a Button on to my Knight Rider circuit

Hi, I have successfully made an circuit which I have made and it's called The Knight Rider. I am just wondering how and where to put a button on the breadboard. I don't know how to program properly - so I used one of the Arduino's tutorial's to help me out.

Here is the sketch of my circuit, it may be different in real life.

And here is the program which I want the button to be programmed in. Also, I want both of my programs together instead of separate.

Program #1

int pin2 = 2;
int pin3 = 3;
int pin4 = 4;
int pin5 = 5;
int pin6 = 6;
int pin7 = 7;
int timer = 100;

void setup(){
  pinMode(pin2, OUTPUT);
  pinMode(pin3, OUTPUT);
  pinMode(pin4, OUTPUT);
  pinMode(pin5, OUTPUT);
  pinMode(pin6, OUTPUT);
  pinMode(pin7, OUTPUT);
}

void loop() {
   digitalWrite(pin2, HIGH);
   delay(timer);
   digitalWrite(pin2, LOW);
   delay(timer);

   digitalWrite(pin3, HIGH);
   delay(timer);
   digitalWrite(pin3, LOW);
   delay(timer);

   digitalWrite(pin4, HIGH);
   delay(timer);
   digitalWrite(pin4, LOW);
   delay(timer);

   digitalWrite(pin5, HIGH);
   delay(timer);
   digitalWrite(pin5, LOW);
   delay(timer);

   digitalWrite(pin6, HIGH);
   delay(timer);
   digitalWrite(pin6, LOW);
   delay(timer);

   digitalWrite(pin7, HIGH);
   delay(timer);
   digitalWrite(pin7, LOW);
   delay(timer);

   digitalWrite(pin6, HIGH);
   delay(timer);
   digitalWrite(pin6, LOW);
   delay(timer);

   digitalWrite(pin5, HIGH);
   delay(timer);
   digitalWrite(pin5, LOW);
   delay(timer);

   digitalWrite(pin4, HIGH);
   delay(timer);
   digitalWrite(pin4, LOW);
   delay(timer);

   digitalWrite(pin3, HIGH);
   delay(timer);
   digitalWrite(pin3, LOW);
   delay(timer);
}

Program #2

int pinArray[] = {2, 3, 4, 5, 6, 7};
int count = 0;
int timer = 30;

void setup(){
  for (count=0;count<6;count++) {
    pinMode(pinArray[count], OUTPUT);
  }
}

void loop() {
  for (count=0;count<5;count++) {
   digitalWrite(pinArray[count], HIGH);
   delay(timer);
   digitalWrite(pinArray[count + 1], HIGH);
   delay(timer);
   digitalWrite(pinArray[count], LOW);
   delay(timer*2);
  }
  for (count=5;count>0;count--) {
   digitalWrite(pinArray[count], HIGH);
   delay(timer);
   digitalWrite(pinArray[count - 1], HIGH);
   delay(timer);
   digitalWrite(pinArray[count], LOW);
   delay(timer*2);
  }
}

Hi Benjamin123 and welcome.

We can't see your diagram. It is behind the school's firewall.

You can post it here on the forum by clicking "Additional options..." then "Choose file" underneith the box where you type your message.

Edit your post above and add the diagram that way. Also put code tags around your 2 sketches, using the # button above the box. It should then look like this:

your sketch appears here

Here is the sketch of my circuit, it may be different in real life.

If your sketch is different to real life, it won't be much help!

Paul

Okay. I have done it. Is the picture is visible for you?

Yes, thats ok now.

Looking at your 2 sketches, they seem to do almost the same thing. The second version is a bit more cleverly written. What is the difference you see when you run them and how do want the flasing to go when they are combined?

As for your button, just wire it to digital pin 8 and ground (0V). Then set it up with pinMode(8, INPUT_PULLUP) and read it with digitalRead( 8 ). The result will be LOW when the buttton is pressed.

In order for your button press to work well, you may want to get rid of the blocking delays in your Knight Rider example.

take a look at the attached and see if you understand what I did.

You should look at the BlinkWithoutDelay example in your IDE to get a grasp on how that works.

the button press state change example will explain that part of this (untested) sketch:

#define MAX_STATES 1

int pin2 = 2;
int pin3 = 3;
int pin4 = 4;
int pin5 = 5;
int pin6 = 6;
int pin7 = 7;
int buttonPin = 8;
int myPin = 2;
int state;
int oldButtonState;
int timer = 200;
unsigned long startTime;
//
void setup()
{
  pinMode(pin2, OUTPUT);
  pinMode(pin3, OUTPUT);
  pinMode(pin4, OUTPUT);
  pinMode(pin5, OUTPUT);
  pinMode(pin6, OUTPUT);
  pinMode(pin7, OUTPUT);
  pinMode(buttonPin,INPUT_PULLUP);
}
//
void loop() 
{
  int buttonState = digitalRead(buttonPin);
  if (buttonState == LOW)
  {
    if (oldButtonState == HIGH)
    {
      state++;
      if (state > MAX_STATES) state = 0;
    }
  }
  oldButtonState = buttonState;
  if (state == 0)
  {
    digitalWrite(13, HIGH); // lite the onboard led
  }
  if (state == 1)
  {
    digitalWrite(13, LOW); // off the onboard led
    myKnight();  //  change this line to: knightRider(); and experiment with your button pressing, noting the delayed effect on the button
  }
}
//
void myKnight()  
{
  if (millis() - startTime <= timer/2)
  {
    digitalWrite(myPin, HIGH);
  }
  else if (millis() - startTime <= timer)
  {
    digitalWrite(myPin, LOW);
  }
  else 
  {
    startTime += timer;
    myPin++;
    if (myPin > 7)
    {
      myPin = 2;
    }
  }
}
//
void knightRider()  // not using it but left it in for you to compare
{
  digitalWrite(pin2, HIGH);
  delay(timer);
  digitalWrite(pin2, LOW);
  delay(timer);

  digitalWrite(pin3, HIGH);
  delay(timer);
  digitalWrite(pin3, LOW);
  delay(timer);

  digitalWrite(pin4, HIGH);
  delay(timer);
  digitalWrite(pin4, LOW);
  delay(timer);

  digitalWrite(pin5, HIGH);
  delay(timer);
  digitalWrite(pin5, LOW);
  delay(timer);

  digitalWrite(pin6, HIGH);
  delay(timer);
  digitalWrite(pin6, LOW);
  delay(timer);

  digitalWrite(pin7, HIGH);
  delay(timer);
  digitalWrite(pin7, LOW);
  delay(timer);

  digitalWrite(pin6, HIGH);
  delay(timer);
  digitalWrite(pin6, LOW);
  delay(timer);

  digitalWrite(pin5, HIGH);
  delay(timer);
  digitalWrite(pin5, LOW);
  delay(timer);

  digitalWrite(pin4, HIGH);
  delay(timer);
  digitalWrite(pin4, LOW);
  delay(timer);

  digitalWrite(pin3, HIGH);
  delay(timer);
  digitalWrite(pin3, LOW);
  delay(timer);
}

Thanks Bulldog for the code, but there is a problem. When I insert the extra 2 wires to my circuit, the LED lights flash from bottom to top it wont bounce to side by side. Also, when I press the button - I doesn't seem to do anything, the program doesn't change.

I maybe want a four way for the switch

  1. LED's flash from bottom to top
  2. LED's flash side by side (slower)
  3. LED's flash side by side (quicker)
  4. LED's flash from both ends to the middle and back
    You could think for any more animations to go in to my program.

I do like the work so far, but I need to do a few fixes which I have suggested on this forum.

so try to get your state change working and then tweak each of your LED effects.

Here is an example of a state change sketch that allows you to advance the state with a button press or by simply entering a character into the serial monitor:

#include <math.h>
int ledPin = 11;
int buttonPin = 2;
int lastPressed;
int state = 0;
unsigned long startTime;

void setup() 
{                
  // initialize the digital pin as an output.
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);  
}

void loop()
{
  int pressed = digitalRead(buttonPin); 
  if (pressed == LOW)
  {
    if (pressed != lastPressed)
    {
      state++;
    }
  }
  lastPressed = pressed;
  if (Serial.available())
  {
    char myChar = Serial.read();
    state++;
  }
  if (state > 3) state = 0;// add more light tricks by adding states
  if (state == 0)
  {
    prettyCoolFade();
  }
  else if (state == 1)
  {
    blinkyLed();
  }
  else if (state == 2)
  {
    digitalWrite(ledPin, HIGH);
  }
  else if (state == 3)
  {
    digitalWrite(ledPin, LOW);
  }
}

void prettyCoolFade()
{
  float val = (exp(sin(millis()/2000.0*PI)) - 0.36787944)*108.0;
  analogWrite(ledPin, val);
}

void blinkyLed()
{
  if (millis() - startTime >= 100UL)
  {
    digitalWrite(ledPin, !digitalRead(ledPin));
    startTime += 100UL;
  }
}

you should work to master the BlinkWithoutDelay example in order to prevent your button presses from being blocked.

and i fixed this for your Knight Rider without delay()

#define MAX_STATES 1
int pin2 = 2;
int pin3 = 3;
int pin4 = 4;
int pin5 = 5;
int pin6 = 6;
int pin7 = 7;

int buttonPin = 8;
int myPin = 2;
int state;
int ledState;
int oldButtonState;
int timer = 200;
unsigned long startTime;
//
void setup()
{
  pinMode(pin2, OUTPUT);
  pinMode(pin3, OUTPUT);
  pinMode(pin4, OUTPUT);
  pinMode(pin5, OUTPUT);
  pinMode(pin6, OUTPUT);
  pinMode(pin7, OUTPUT);
  pinMode(buttonPin,INPUT_PULLUP);
}
//
void loop() 
{
  int buttonState = digitalRead(buttonPin);
  if (buttonState == LOW)
  {
    if (oldButtonState == HIGH)
    {
      state++;
      if (state > MAX_STATES) state = 0;
    }
  }
  oldButtonState = buttonState;
  if (state == 0)
  {
    digitalWrite(13, HIGH); // lite the onboard led
  }
  if (state == 1)
  {
    digitalWrite(13, LOW); // off the onboard led
    myKnight();  //  change this line to: knightRider(); and experiment with your button pressing, noting the delayed effect on the button
  }
}
//
void myKnight()  
{
  if (ledState == 1)
  {
    if (millis() - startTime <= timer/2)
    {
      digitalWrite(myPin, HIGH);
    }
    else if (millis() - startTime <= timer)
    {
      digitalWrite(myPin, LOW);
    }
    else 
    {
      startTime += timer;
      myPin++;
      if (myPin > 7)
      {
        myPin = 7;
        ledState = !ledState;
      }
    }
  }
  if (ledState == 0)
  {
  if (millis() - startTime <= timer/2)
    {
      digitalWrite(myPin, HIGH);
    }
    else if (millis() - startTime <= timer)
    {
      digitalWrite(myPin, LOW);
    }
    else 
    {
      startTime += timer;
      myPin--;
      if (myPin < 2)
      {
        myPin = 2;
        ledState = !ledState;
      }
    }
  }
}

Bulldog is being very generous with helping you but the last 2 sketches have something missing: switch debouncing.

To implement this, you need to check that when you detect a button change, you must ignore it if another button change happened within, say, the last 50ms.

Without this, every time you press the button, the state will change several times over in less than the blink of an eye.

Paul

PaulRB:
Bulldog is being very generous with helping you but the last 2 sketches have something missing: switch debouncing.

To implement this, you need to check that when you detect a button change, you must ignore it if another button change happened within, say, the last 50ms.

Without this, every time you press the button, the state will change several times over in less than the blink of an eye.

Paul

never had a problem with this kind of code on a simple button press, but you can easily attach a little delay to allow for PaulRB's (wisely noted) debounce:

untested

void loop() 
{
  int buttonState = digitalRead(buttonPin);
  if (buttonState == LOW)
  {
    if (oldButtonState == HIGH)
    {
      state++;
      delay(50);
      if (state > MAX_STATES) state = 0;
    }
  }
  oldButtonState = buttonState;
  if (state == 0)
  {
    digitalWrite(13, HIGH); // lite the onboard led
  }
  if (state == 1)
  {
    digitalWrite(13, LOW); // off the onboard led
    myKnight();  //  change this line to: knightRider(); and experiment with your button pressing, noting the delayed effect on the button
  }
}

or start a timer, remembering to declare:

unsigned long debounceStart;

in your header.

void loop() 
{
  int buttonState = digitalRead(buttonPin);
  if (buttonState == LOW)
  {
    unsigned long elapsedTime = (millis() - debounceStart);
    if (oldButtonState == HIGH && elapsedTime > 50UL)
    {
      state++;
      debounceStart = millis();
      if (state > MAX_STATES) state = 0;
    }
  }
  oldButtonState = buttonState;
  if (state == 0)
  {
    digitalWrite(13, HIGH); // lite the onboard led
  }
  if (state == 1)
  {
    digitalWrite(13, LOW); // off the onboard led
    myKnight();  //  change this line to: knightRider(); and experiment with your button pressing, noting the delayed effect on the button
  }
}

Thanks for the codes, but no of them work. I am stuck, because I don't know which hole on the breadboard to put the wires. Also, I have done the ports and the input/output. Do you think the switch needs to move?

Here are my real photos of what I have done, this is different to the sketch in earlier on in the post.

This will not help you with your current problem but you may be interested anyway. Here is a project that I did a while ago that has eight LED's controlled by a shift register with an LCD interface. I started out by having four different patterns including a knightrider one and eventually expanded it to eight different patterns with the LCD indicating the name of the pattern that was selected and also later a 7 segment LED that indicated the pattern number of between one and eight. The thread is here and if you look at one of the comments on the YouTube video you will find links to some code and a circuit diagram. The code and circuit diagram there are for the full eight LED patterns and also incorporate the 7 segment display connections. If you go the the Mediafire link to download the circuit diagram you will have to have the Tinycad program on your computer to view the circuit. This is all explained in the comments of the YouTube video. Pedro.

Benjamin123:
Thanks for the codes, but no of them work.

You can't just say "doesn't work". That gives us no clues to help you. You must describe what happens in more precise detail. If no leds are lighting up, say that.

Benjamin123:
I am stuck, because I don't know which hole on the breadboard to put the wires.

I can see some wires in your breadboard. So how did you know where to put them? Do you know which holes in the breadboard are connected to each other, underneath? You must do some of the work, we are not here to spoon-feed you!

Benjamin123:
Also, I have done the ports and the input/output.

Don't know what you mean.

Benjamin123:
Do you think the switch needs to move?

The switch is fine where it is, but you must connect some wires to it and to the arduino! See my earlier suggestion.

Benjamin123:
Here are my real photos of what I have done, this is different to the sketch in earlier on in the post.

Its not a great photo. We can't see which Arduino outputs those wires are connected to. Taking photos like this is not easy. There is no angle that gives a perfectly clear picture of the connections. Even from directly above, the wires will look a jumbled mess.

I don't know why so many people try to connect an Uno to a breadboard like this. Uno was designed to be used with shields. Other types of Arduino, like Nano, Mini and Micro are better for breadboards. This is how I like to wire up my Arduino on a breadboard: Useful circuit: Charlieplexed 4 x 7-Segment display - #2 by PaulRB - Exhibition / Gallery - Arduino Forum . Its still not perfect, its still hard to see where some of the wires go. That's why when you get more experienced you will understand the value of a proper schematic diagram.

Can you update your fritzing diagram to show how you have connected everything, including the switch?

Thanks Pedro147 for the YouTube link, but I do not recommend that kind of thing. All I wanted to is the program for the button to my 2 codes which I have put on this forum thread to operate the circuit.
If any one doesn't understand, I'll make it go back to my regular circuit with no button and just keep programming which one is my favourite. I just wanted, so that you I can change the pattern without programming it on the computer.

did you connect the pushbutton?

Yes. But I couldn't get it to work. Because I am new to Arduino. I have been learning the basics and I would like to build this circuit, because I find it fun for interest. Because it's like technology.

connect one side of the button to your buttonPin (as defined in my code I posted for you (pin8)

attach the other side of the switch to ground.

the switch will connect the pin to ground when pressed... you got it?

then test with this sketch:

int buttonPin = 8;
int ledPin = 13;
unsigned long duration = 5000UL; // five seconds
unsigned long startTime;
int lastButtonState;

void setup()
{
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
}
void loop()
{
 int buttonState = digitalRead(buttonPin);
 if (buttonState == LOW)
 {
   if (lastButtonState == HIGH)
   {
     startTime = millis();
     Serial.println(F("Button Pressed"));
   }
 }
 lastButtonState = buttonState;
 ledOn(startTime);
}

void ledOn(unsigned long myStart)
{
  if (millis() - myStart < duration)
  {
    digitalWrite(ledPin, HIGH);
  }
  else
  {
    digitalWrite(ledPin, LOW);
  }
}

the on-board led with lite for 5seconds each time you press the button...

not tested, but I think it will work for you

Thanks for the instructions, but it would be better if it would be better on a sketch diagram. You can copy my sketch diagram and edit it - so I can understand. Because, I do really understand where it goes. This is my first time doing this.

I have put on some more photos just give you guys some ideas. :slight_smile:
Some of the pictures can be blurry due to the shakiness of the camera which I was holding.