/*
* Gray_ButtonsAndSwitches
* Code by: Gray Mack
* Published at: N/A
* Description: A few switches, button, ws2812 8 pixel strip, piezo element or micro speaker
* Why I made this:
* Just playing around, quick demo of switches and activities
*
* License: MIT License
* https://choosealicense.com/licenses/mit/
* Created: 11/14/2022
* Board: Arduino Uno or compatible
* Select Board: Arduino Uno
* Processor: ATMEGA328p
*
* Connections:
* connect 3 toggle switches to 2,3,4 (use internal pullups) the other end to ground
* connect button to 6 (use internal pullups) the other end of switched so ground
* lighted safety toggle switch- This switch is tricky since it only has 3 leads
* one end to +5v which is led annode and switch input
* and the switch lead to pin 5 (use physical pull down 10k resistor)
* the switches LED should already have a resistor inside the switch, connect through pin 7
* pin 8 goes to WS2812 pixels. We should have no problem powering 8 through the regulator 5v supply. Ensure wires do not come out while powered which can damage pixels
* connect mini 16ohm speaker/piezo element to pin 9 (and the other lead to GND)
*
*
* 11/14/2022 initial code creation
* //2022
* //2022
* //2022
*/
// ----[ included libraries ]--------------------------------
#include <FastLED.h> // LED pixel library for neopixels
#include <Bounce2.h> // button debounce library v2.71 https://github.com/thomasfredericks/Bounce2/
// ----[ configuration ]------------------------------------
#define SerialBaud 9600
#define LED_COLOR_ORDER GRB
#define LED_CHIPSET WS2812
// ----[ pin definitions ]-----------------------------------
const int PIN_TOGGLE_ACC1 = 2;
const int PIN_TOGGLE_ACC2 = 3;
const int PIN_TOGGLE_ACC3 = 4;
const int PIN_TOGGLE_MAIN_SYSTEM = 5;
const int PIN_START_BUTTON = 6;
const int PIN_MAIN_SYSTEM_LED = 7;
const int PIN_PIXELS = 8;
const int PIN_SPEAKER = 9;
// LED_BUILTIN is internally defined as 13
// ----[ constants ]-----------------------------------------
const int NUM_LEDS = 8; // How many leds in your strip
const int LED_BRIGHTNESS = 220; // use 60 on real LEDs but need brighter for simulator
const int MAIN_SYSTEM_LED_ON = LOW;
const int MAIN_SYSTEM_LED_OFF = HIGH;
// ----[ predeclarations ]-----------------------------------
// ----[ global variables ]----------------------------------
CRGB leds[NUM_LEDS]; // Define the array of leds for FastLED
//Button2 ToggleAcc1, ToggleAcc2, ToggleAcc3;
//Button2 ToggleMainSystem;
//Button2 ButtonStart;
Bounce2::Button ToggleAcc1 = Bounce2::Button();
Bounce2::Button ToggleAcc2 = Bounce2::Button();
Bounce2::Button ToggleAcc3 = Bounce2::Button();
Bounce2::Button ToggleMainSystem = Bounce2::Button();
Bounce2::Button ButtonStart = Bounce2::Button();
int oldSwitchValue;
// ----[ code ]----------------------------------------------
void setup() {
Serial.begin(9600);
Serial.println("\nArduino reset");
ToggleAcc1.attach(PIN_TOGGLE_ACC1, INPUT_PULLUP);
ToggleAcc1.setPressedState(LOW);
ToggleAcc1.interval(100);
ToggleAcc2.attach(PIN_TOGGLE_ACC2, INPUT_PULLUP);
ToggleAcc2.setPressedState(LOW);
ToggleAcc2.interval(100);
ToggleAcc3.attach(PIN_TOGGLE_ACC3, INPUT_PULLUP);
ToggleAcc3.setPressedState(LOW);
ToggleAcc3.interval(100);
ToggleMainSystem.attach(PIN_TOGGLE_MAIN_SYSTEM, INPUT);
ToggleMainSystem.setPressedState(HIGH); // active low, needs external pulldown because of LED in switch
ToggleMainSystem.interval(100);
ButtonStart.attach(PIN_START_BUTTON, INPUT_PULLUP);
ButtonStart.setPressedState(LOW);
ButtonStart.interval(20);
pinMode(PIN_MAIN_SYSTEM_LED, OUTPUT);
digitalWrite(PIN_MAIN_SYSTEM_LED, MAIN_SYSTEM_LED_ON);
FastLED.addLeds<LED_CHIPSET, PIN_PIXELS, LED_COLOR_ORDER>(leds, NUM_LEDS);
FastLED.clear();
FastLED.setMaxPowerInVoltsAndMilliamps(5, 200);
FastLED.setBrightness(LED_BRIGHTNESS);
FastLED.show();
pinMode(PIN_SPEAKER, OUTPUT);
digitalWrite(PIN_SPEAKER, LOW); // caution mini speaker is a low ohm load, do not wright HIGH, tone command seems ok to use. Recommend piezo element instead.
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
}
void loop() {
ToggleAcc1.update();
ToggleAcc2.update();
ToggleAcc3.update();
ToggleMainSystem.update();
ButtonStart.update();
if(ToggleAcc1.changed() && ToggleAcc1.isPressed())
Serial.println("ACC1 on");
if(ToggleAcc2.changed() && ToggleAcc2.isPressed())
Serial.println("ACC2 on");
if(ToggleAcc3.changed() && ToggleAcc3.isPressed())
Serial.println("ACC3 on");
if(ToggleMainSystem.changed() && ToggleMainSystem.isPressed())
Serial.println("Main System on");
int switchValue = (ToggleAcc1.isPressed()? 1 : 0) +
(ToggleAcc2.isPressed()? 2 : 0) +
(ToggleAcc3.isPressed()? 4 : 0);
if(switchValue != oldSwitchValue)
{
oldSwitchValue = switchValue;
Serial.print("switchValue: ");
Serial.println(switchValue);
}
bool animating = false;
if(ToggleMainSystem.isPressed())
{
switch(switchValue)
{
case 0:
break;
case 1:
lightEffect1();
animating = true;
break;
case 2:
lightEffect2();
animating = true;
break;
case 3:
lightEffect3();
animating = true;
break;
case 4:
lightEffect4();
animating = true;
break;
case 5:
lightEffect5();
animating = true;
break;
case 6:
lightEffect6();
animating = true;
break;
case 7:
lightEffect7();
animating = true;
break;
}
}
if(!animating)
{
lightsOff();
}
BlinkLed();
if(ToggleMainSystem.isPressed() && ButtonStart.isPressed())
{
if(switchValue == 7)
soundEffect2();
else
soundEffect3();
}
if(ButtonStart.released() || ToggleMainSystem.released())
{
noTone(PIN_SPEAKER);
}
}
// ----[ support functions ]---------------------------------
void BlinkLed()
{
static int systemLedState = MAIN_SYSTEM_LED_OFF;
if(ToggleMainSystem.isPressed())
{
EVERY_N_MILLISECONDS(500)
{
systemLedState = !systemLedState;
}
}
else
{
systemLedState = MAIN_SYSTEM_LED_OFF;
}
digitalWrite(PIN_MAIN_SYSTEM_LED, systemLedState);
}
void soundEffect3()
{ // up/down frequency
const int lowTone = 31; // 31 is the minimum tone value
const int highTone = 100;
const int changeAmount = 6;
const int delayAmount = 50;
static int toneVal = lowTone;
static bool soundUp = true;
EVERY_N_MILLISECONDS(delayAmount)
{
tone(PIN_SPEAKER, toneVal);
if(soundUp)
{
toneVal+=changeAmount;
if(toneVal > highTone)
{
toneVal = highTone;
soundUp = false;
}
}
else // sound down
{
toneVal-=changeAmount;
if(toneVal < lowTone)
{
toneVal = lowTone;
soundUp = true;
}
}
}
}
void soundEffect2()
{
const int lowTone = 100;
const int highTone = 800;
const int changeAmount = 4;
const int delayAmount = 50;
static int toneVal = lowTone;
static bool toggle = false;
EVERY_N_MILLISECONDS(delayAmount)
{
if(toggle)
tone(PIN_SPEAKER, toneVal);
else
tone(PIN_SPEAKER, highTone-toneVal);
toggle = !toggle;
toneVal += changeAmount;
if(toneVal > highTone)
toneVal = lowTone;
}
}
void lightsOff()
{
FastLED.clear();
FastLED.show();
}
void lightEffect1() // red/blue/red/blue/red/blue
{
const int delayAmount = 1000/2;
static int counter = 0;
EVERY_N_MILLISECONDS(delayAmount)
{
FastLED.clear();
counter++;
if(counter%2==0)
{
leds[0] = CRGB::Red;
}
else
{
leds[7] = CRGB::Blue;
}
FastLED.show();
}
}
void lightEffect2() // back forth green
{
const int delayAmount = 1000/8;
static int counter = 0;
static int cdirection = 1;
EVERY_N_MILLISECONDS(delayAmount)
{
FastLED.clear();
counter+=cdirection;
if(counter >= NUM_LEDS)
{
cdirection = -1;
counter+=cdirection;
}
if(counter < 0)
{
cdirection = 1;
counter+=cdirection;
}
leds[counter] = CRGB::Green;
FastLED.show();
}
}
void lightEffect3() // center to outside on both sides
{
const int delayAmount = 1000/2;
static int counter = 0;
EVERY_N_MILLISECONDS(delayAmount)
{
FastLED.clear();
for(int i=counter; i<NUM_LEDS; i=i+2)
{
leds[i] = CRGB::Purple;
}
FastLED.show();
counter = (counter == 0) ? 1 : 0;
}
}
void lightEffect4() // center to outside on both sides
{
const int delayAmount = 1000/6;
static int counter = 0;
EVERY_N_MILLISECONDS(delayAmount)
{
FastLED.clear();
for(int i=0; i<counter%6; i++)
{
leds[3+i] = CRGB::Orange;
leds[4-i] = CRGB::Orange;
}
FastLED.show();
counter++;
}
}
void lightEffect5() // rainbow
{
const int delayAmount = 1000/20;
const int changeAmount = 4;
static byte counter = 0;
EVERY_N_MILLISECONDS(delayAmount)
{
for(int i=0; i<NUM_LEDS; i++)
leds[i] = CHSV((counter+i*20)%256, 255, 255);
FastLED.show();
counter+=changeAmount;
}
}
void lightEffect6() // not implemented yet
{
FastLED.clear();
leds[0] = CRGB::Cyan;
FastLED.show();
}
void lightEffect7() // random
{
const int delayAmount = 10;
EVERY_N_MILLISECONDS(delayAmount)
{
FastLED.clear();
int i = random(NUM_LEDS);
CRGB rcolor;
switch(random(3))
{
case 0: rcolor = CRGB::Red; break;
case 1: rcolor = CRGB::Green; break;
case 2: rcolor = CRGB::Blue; break;
}
leds[i] = rcolor;
FastLED.show();
}
}
// good alarm sounds 1, 4, 5, 22
// sound 9 is like rocket sound