#include <LEDController.h> // controls the lights
#include <OLEDController.h> // controls the little screen
#include <sevSeg.h> // controls the seven segment/4 digit display
// -----------------------------
// auto on/off sensor
// -----------------------------
const int trigPin = 14;
const int echoPin = 12;
float duration, distance;
bool headPresent = false;
// -----------------------------
// ------- METER
// -----------------------------
int meter = 32; // set pin for meter (analog out)
unsigned long prevMeterMillis = 0; // set this for later
// -----------------------------
// ------- LIGHTS
// -----------------------------
int ledPins[] = { 15, 4, 16, 17, 5, 18, 19 }; // Array of pin numbers
#define NUM_LED (sizeof(ledPins) / sizeof(ledPins[0])) // Calculate the number of LEDs
LEDController ledController(ledPins, NUM_LED); // Create an array of pointers to ezLED objects
// -----------------------------
// ------- BUTTON
// -----------------------------
const int BUTTON_PIN = 25;
int lastButtonState = LOW; // the previous state of the button
int currentButtonState; // the current state of the button
bool systemOn = true; // using boolean instead of String for efficiency
// -----------------------------
// ------- PROGRAM
// -----------------------------
void setup() {
Serial.begin(115200);
// register the meter
pinMode(meter, OUTPUT);
// Start LED Animation
ledController.beginSequence();
// Start the sevseg display
randomSeed(analogRead(0));
sevSeg.begin();
sevSeg.setBrightness(4);
sevSeg.flipDisplay();
// start the oled
u8g2.begin();
// Start the button
pinMode(BUTTON_PIN, INPUT_PULLUP); // set button pin to input pull-up mode
// distance sensor
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
digitalWrite(trigPin, LOW);
digitalWrite(trigPin, HIGH);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration*.0343)/2;
Serial.print("Distance: ");
Serial.println(distance);
if(distance <= 80) {
headPresent = true;
} else {
headPresent = false;
}
// -----------------------------
// BUTTON
// -----------------------------
currentButtonState = digitalRead(BUTTON_PIN); // read new state
// Check for a button press (transition from HIGH to LOW)
if (lastButtonState == HIGH && currentButtonState == LOW) {
systemOn = !systemOn; // Toggle systemOn between true and false
//Serial.println("The button is pressed");
}
Serial.println(headPresent);
// Display system status
if (systemOn || headPresent) {
//Serial.println("System is On");
// -----------------------------
// METER
// -----------------------------
unsigned long meterCurMillis = millis(); // Current time
if (meterCurMillis - prevMeterMillis >= 250) { // if the time between now and the last time is more than the interval
prevMeterMillis = meterCurMillis; // reset the last time
int meterVal = random(0, 22); // get a random value for the power output value
analogWrite(meter, meterVal); // send random value to the meter
//Serial.println(meterVal);
}
// -----------------------------
// SHOW MESSAGE
// -----------------------------
// int randomIndex = random(arraySize);
// String displayNum = sciNums[randomIndex]; // Get the random string
// sevSeg.showString(displayNum.c_str());
bool isAnimationRunning = sevSeg.Animate();
if (!isAnimationRunning) {
sevSeg.startAnimation_P(ANIMATION, FRAMES(ANIMATION), TIME_MS(170));
}
// -----------------------------
// LOOP LIGHTS
// -----------------------------
ledController.start();
ledController.update();
// -----------------------------
// SHOW OLED ANIMATION
// -----------------------------
u8g2.clearBuffer(); // clear the internal memory
if (!isAnimating) {
int randNum = random(0, 70); // generate a random number from 0 to 29 (higher number lowers probability)
if (randNum == 0) {
//Serial.print("\n Blink! \n");
isAnimating = true;
counter = 0; // reset counter to start from the first frame
animationDirection = 1; // start by moving forward in the sequence
frameCount = 0; // reset frame count for the new animation cycle
}
}
// If in animation mode, cycle through frames 0-3-2-1-0
if (isAnimating) {
unsigned long currentMillis = millis(); // Current time
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
u8g2.drawXBMP(32, 0, 64, 64, blink_allArray[counter]); // Draw the current frame
counter += animationDirection; // Update the counter based on the current animation direction
if (counter == 3) { // Reverse the direction at the ends of the array (ping-pong effect)
animationDirection = -1; // start going backward
} else if (counter == 0 && animationDirection == -1) {
animationDirection = 1; // when back at 0, start going forward again
}
frameCount++; // increment the number of frames shown
if (frameCount >= totalFrames) { // End the animation after one full ping-pong cycle (7 frames)
isAnimating = false; // stop animating after the set number of frames
}
}
} else {
u8g2.drawXBMP(32, 0, 64, 64, blink_allArray[0]); // If not in animation mode, show frame 0
}
u8g2.sendBuffer(); // transfer internal memory to the display
} else {
//Serial.println("System is Off");
analogWrite(meter, 0); // kill the meter
sevSeg.clear(); // clear the closk display
u8g2.clear(); // clear the oled
if (ledController.isOn()) {
ledController.shutdown(); // kill the lights
}
}
lastButtonState = currentButtonState; // Save the current state as the last state for the next loop iteration
delay(120);
}