Hi everyone,
I am busy with a project that uses a button to change the behavior of a RGB LED. I have created several states that say what the led does:
State 1: led is off
State 2: led and vibration motor run a sequence
State 3: led is blue
I am quite new to this and I have used delays during the sequence. I figured that nothing will happen when you press the button during State 2 because of these delays and I have to change them to millis().
I want to change this so I have been doing a lot of research and studied the BlinkWithoutDelay. However, because I need multiple millis (for the vibration motor (which also has different times) and led), I cant figure out how to implement it correctly.
This is the code I have now (including delays):
#include <FastLED.h>
//connections of the ChainableLED
#define DATA_PIN 5
#define CLOCK_PIN 4
#define NUM_LEDS 1
// connections buzzer en button
int MoPin = 3;
const int button1Pin = 2; // the number of the pushbutton pin
boolean b1LastTimePressed = false;
//an array to hold the led data
CRGB leds[NUM_LEDS];
enum program_state{
// The state names are defined here. It helps to give them a descriptive name.
STATE1,
STATE2,
STATE3,
};
program_state current_state = STATE1; // This lines declares the variable that will hold the value of the state and defines an initial value.
void setup()
{
// This line tells the code to execute the function goToState. It is defined later in the code.
goToState(STATE1);
// initialize the buzzer pin as an output:
pinMode(MoPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(button1Pin, INPUT);
FastLED.addLeds<P9813, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
}
void loop()
{
switch(current_state){ // Depending on the value of current_state the switch will execute the corresponding section of code defined in the cases below. Each loop, the switch will check the value of current_state.
case STATE1 :
//turn LED off
leds[0].setRGB( 0, 0, 0);
FastLED.show();
if(button1Pressed()){
// Code that should run only once when moving to another state.
goToState(STATE2);
}
break; // end STATE1
case STATE2 :
// Turn LED to green
leds[0].setRGB( 0, 255, 0);
FastLED.show();
delay(5000);
// Turn LED to orange
leds[0].setRGB( 255, 50, 0);
FastLED.show();
//vibrate 2 times
digitalWrite(MoPin, HIGH);
delay(500);
digitalWrite(MoPin, LOW);
delay(500);
digitalWrite(MoPin, HIGH);
delay(500);
digitalWrite(MoPin, LOW);
delay(5000);
//vibrate
digitalWrite(MoPin,HIGH);
delay(500);
digitalWrite(MoPin,LOW);
delay(5000);
// turn LED to red
leds[0].setRGB( 255, 0, 0);
FastLED.show();
//vibrate 3 times
digitalWrite(MoPin,HIGH);
delay(500);
digitalWrite(MoPin,LOW);
delay(500);
digitalWrite(MoPin, HIGH);
delay(500);
digitalWrite(MoPin, LOW);
delay(500);
digitalWrite(MoPin, HIGH);
delay(500);
digitalWrite(MoPin, LOW);
delay(5000);
if(button1Pressed()){
// Code to run once when moving to STATE3
goToState(STATE3);
}
break; // end STATE2
case STATE3 :
// turn LED to blue
leds[0].setRGB( 0, 0, 255);
FastLED.show();
if(button1Pressed()){
// Code to run once when moving to STATE2
goToState(STATE2);
}
break; // end STATE3
}
}
// Function that checks if button1 is pressed while before not being pressed
boolean button1Pressed() {
boolean b1FirstTimePressed = false;
boolean b1Pressed = digitalRead(button1Pin);
if (b1Pressed && !b1LastTimePressed) {
b1FirstTimePressed = true;
}
b1LastTimePressed = b1Pressed;
return b1FirstTimePressed;
}
void goToState(program_state state){ // The goToState function takes one variable, the desired STATE. It changes the state and prints the current state to the serial monitor
current_state=state;
Serial.print("going to state:");
Serial.print('\t');
Serial.println(current_state);
}
I hope it is clear what I mean and somebody can explain to me how you can use different millis() in my code.
Thanks!
CodeV3.ino (3.4 KB)