Help with Code and understanding.

So Like a lot of folks I am new to the world of arduino. While i understand some BASIC things about coding and have managed to make some simple projects for my Halloween props. This project I’m working on now was meant as a learning tool to try to understand more complicated stuff and I think I bit off more then I can chew.

Here is the rundown on what I am trying to do. This is basically a trophy of failure for my work. It has an LCD, LED’s, Smoke, and Sparks. The circuit board that sits on top of the box has a few LED’s on it that blink normal and the LCD displays their name and to press the button on the side. Once the button is pressed the LED’s begin blinking faster, the display starts blinking and the spark generator starts arcing and after a second or so the display and everything goes out and then smoke is released.

Now to me this all sounded simple till I started trying to work on the code and I’m lost now. The code I have written so far may be absolutely worthless for accomplishing this.

What it does now is the normal routine. LCD displays info and LED’s blink normally. When i press and hold the switch then the LCD goes off, the LED’s blink faster and the 2 relays turn on for the smoke and sparks. Let go of the button and everything goes back to normal.

Below is the code that i need help with. How do I get the button to stay latched for enough time to run through the rest of the routine as well as how to get the relays to come on in steps (relay 1 then half second then relay 2).

I’m still trying to understand even some of the code I have which has been cut and pasted from other code.

Thanks for any help and please excuse me if i ask a stupid question. I really want to understand this.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display

const int buttonPin = 4;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin
const int smoke = 6;     // the number of the relay output for the smoke
const int spark =  7;      // the number of the relay output for the spark


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


class Flasher
{
    // Class Member Variables
    // These are initialized at startup
    int ledPin;      // the number of the LED pin
    long OnTime;     // milliseconds of on-time
    long OffTime;    // milliseconds of off-time

    // These maintain the current state
    int ledState;                 // ledState used to set the LED
    unsigned long previousMillis;   // will store last time LED was updated

    // Constructor - creates a Flasher
    // and initializes the member variables and state
  public:
    Flasher(int pin, long on, long off)
    {
      ledPin = pin;
      pinMode(ledPin, OUTPUT);

      OnTime = on;
      OffTime = off;

      ledState = LOW;
      previousMillis = 0;
    }

    void Update()
    {
      // check to see if it's time to change the state of the LED
      unsigned long currentMillis = millis();

      if ((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
      {
        ledState = LOW;  // Turn it off
        previousMillis = currentMillis;  // Remember the time
        digitalWrite(ledPin, ledState);  // Update the actual LED
      }
      else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
      {
        ledState = HIGH;  // turn it on
        previousMillis = currentMillis;   // Remember the time
        digitalWrite(ledPin, ledState);   // Update the actual LED
      }
    }
};

// set flashing rate paramiters (PIN, ON, OFF - milis)
Flasher led1(8, 200, 400);  //green led
Flasher led2(9, 350, 350);  //green led
Flasher led3(10, 600, 200);  //red led
Flasher led4(13, 600, 600);  //push button led

// set flash parameters for when button is pushed
Flasher led5(8, 25, 30); //green
Flasher led6(9, 50, 25);  //green
Flasher led7(10, 100, 50);  //red
Flasher led8(13, 25, 50); //pushbutton

void setup()
{
  // initialize the lcd
  lcd.init();

  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);

  // initialize the LED pin as an output:
  pinMode(smoke, OUTPUT);

  // initialize the LED pin as an output:
  pinMode(spark, OUTPUT);
}


void loop()
{
  // set the amount of LED's to flash
  led1.Update();
  led2.Update();
  led3.Update();
  led4.Update();


  // What do you want the LCD to say
  // starting cursor position and line number
  lcd.setCursor(1, 0);
  // Text to be displayed
  lcd.print("Smoked Board Award");
  lcd.setCursor(5, 1);
  lcd.print("Joe Shmoe");
  lcd.setCursor(8, 2);
  lcd.print("2016");
  lcd.setCursor(2, 3);
  lcd.print("Press Button--->");




  // 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 relays on:
    digitalWrite(smoke, LOW);
    digitalWrite(spark, LOW);

    //turn LCD backlight off
    lcd.setBacklight(LOW);

    //blink LED's faster
    led5.Update();
    led6.Update();
    led7.Update();
    led8.Update();
  }
  else {
    // turn relays off:
    digitalWrite(smoke, HIGH);
    digitalWrite(spark, HIGH);
    //lcd backlight on
    lcd.setBacklight(HIGH);
  }
}

Award_Test_V2.ino (3.55 KB)

Why do you have two instances of Flasher for each of 4 pins?

Why are you unconditionally updating 4 of them, and conditionally updating 4 others?

Why does your code talk about LEDs while your post talks about relays? There is NOTHING magic about the name led. If you have a relay attached to the pin, use the name relay.

Since you are asking about switch issues, and are not using the internal pullup resistor, it is necessary for you to explain how you wired the switch and why the heck you choose to wire it the hard way.

One set flashes at one rate, the other set flashes at a faster rate and because that's what the tutorial said to do that i read online, oh and because I'm new at this.

I have no idea, its what the tutorial said to do. Hence why I stated i was new at this and that i didn't understand some of the code, that it was cut and pasted.

Uhm my post does mention LED's as well as relays. Press button, LEDS blink, relays click on...

Well apparently I'm not using the pull up resistor because, wait for it.. I'm NEW at this.. I wired it with a resistor tied to ground because that is how it was shown how to be done in the material i read from the web.

I'm sorry if i seem a little terse but it almost feels like I'm being badgered for being new and posting here. I clearly stated this fact and that I didn't understand some of the code and that i was probably doing something wrong. I would have expected a response that was less "why you doing this and this, why you doing this the hard way?" and more "here is what your doing wrong, this is why its wrong, this is how you fix it", but i apparently picked the wrong forum for that experience.

Thanks for the help...

Right now your code says if the button state is HIGH to do the sparky thing else do the normal thing. So when you let go of the button and it's not HIGH anymore, it goes to ding the normal thing.

Perhaps instead you should say that when the button BECOMES pressed (as in is pressed now but wasn't the last time you checked it (see the State Change Example with the IDE for inspiration)) then you set a boolean variable to true indicating that you are in sparky mode. Then, instead of doing the sparky thing when the button is pressed do it when that boolean is true.

You might need to debounce the button. Contact switches/buttons have a millisecond or so when the state changes rapidly between ON and OFF. During that time the state of the pin only reflects the user's desire about half the time. What I do is watch the pin for when it does not change for 2+ millis and only then is the state stable.

You can debounce the button with a capacitor placed across the button leads. Nick Gammon shows that in his tutorial on switches using IIRC a 1uF cap.

When using classes like this, I like to have setup() and loop() methods in them. That is: I suggest renaming update() to loop(). This is so that other arduino programmers understand what is going on: a class instance is a little sketch in its own right. You do the pinMode(OUTPUT) in the setup in the class, and call it from the main setup. Keeps everything consistent.

Rather than having two flashers on the pin and updating the one that you want updated, add a “flashFast” and a “flashSlow” method to the flasher. The constructor will take 5 values - the pin, and that two values for the fast and the slow times.

void flashSlow() {
  onTime = slowOnTime;
  offTime = slowOffTime;
}

As an exercise - you could do this by subclassing the flasher you already have, making a “Flasher (that has a fast and a slow time)”.

When updating the time for the flasher, rather than setting previousMillis to currentMillis, set it to previousMillis+(what I expected the flash time to be). This will result in a more consistent flash, because the timing becomes independent of any delays or skips if for some reason you happen to pause for a whole two millis() before calling Update() again.

Rather than having four flasher variables, have an array of them:

const int nFlashers = 4;

Flasher flasher[nFlashers] = {
  Flasher led1(8, 200, 400),  //green led 
  Flasher led2(9, 350, 350),  //green led
  Flasher led3(10, 600, 200),  //red led
  Flasher led4(13, 600, 600)  //push button led
};

Calling update is then a matter of

for(int i = 0; i<nFlashers; i++) {
   flasher[i].Update();
}

There’s probably no need to write to the LCD every time loop() executes. Just the once in setup() will do.

Your sketch has two states - before button is pressed, and after it is pressed. You’ll need to stuff that in a variable somewhere. Go from “ready!” state to “smokin!” state when the button goes from unpressed to pressed. And no way to go back again? You have to reset the board to go back into “Ready!” state? Consider adding a timer, a second button, or permitting a second ush of the button to put the board back into its starts state.

(EDIT) actually: a better way might be to use a slider rather than a pushbutton for ready/smokin. In the loop, you look at whether the slider’s current value is the same as it’s previous value, and act when it changes.