I am trying to make a project where I use the hall sensor to measure shaft rpm and display it on the OLED display. If the rpm drops below a threshold that you can change with buttons, it will set off a buzzer and flash an LED. Additionally, I want a function to where I can silence the buzzer/led and unsilence them. So far, this is my code, but it keeps counting down the threshold when the buzzer is active and will not let me unsilence the buzzer.
#include <Wire.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.
// On an Arduino UNO: A4(SDA), A5(SCL)
// On an Arduino MEGA 2560: 20(SDA), 21(SCL)
// On an Arduino LEONARDO: 2(SDA), 3(SCL), ...
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const int hallSensorPin = 2; // Hall sensor input pin (change to your pin)
const int buzzerPin = 9; // Buzzer output pin (change to your pin)
const int ledPin = 13; // LED output pin (change to your pin)
const int buttonSilencePin = 7; // Button to silence the buzzer
const int buttonDecreaseThresholdPin = 10; // Button to decrease threshold
const int buttonIncreaseThresholdPin = 11; // Button to increase threshold
volatile unsigned long lastTime = 0;
volatile unsigned long lastPulseTime = 0;
volatile unsigned long lastSpeedCheckTime = 0;
volatile unsigned int pulseCount = 0;
volatile float rpm = 0;
bool soundEnabled = true;
bool buttonSilenceState = false;
bool lastButtonSilenceState = false;
bool buttonDecreaseState = false;
bool lastButtonDecreaseState = false;
bool buttonIncreaseState = false;
bool lastButtonIncreaseState = false;
bool silencePressed = false; // Flag to track silence button press
bool unsilencePressed = false; // Flag to track unsilence button press
bool silenced = false; // Flag to track if the buzzer is silenced
bool lastButtonSilenceReleased = false; // Flag to track if silence button is released
unsigned long lastButtonPressTime = 0;
const unsigned long buttonPressWindow = 200; // 0.2 seconds button press window
int threshold = 50; // Initial threshold value
int previousThreshold = threshold; // Store the previous threshold for comparison
bool displaySilencedMessage = false;
int buttonstate10;
int buttonstate11;
enum DisplayMode {
RPM,
THRESHOLD
};
DisplayMode currentDisplayMode = RPM;
unsigned long displayChangeTime = 0;
const unsigned long displayChangeDuration = 1000; // 1 second display duration for threshold
void hallSensorInterrupt()
{
// This function is called whenever the Hall sensor detects a magnetic field change
pulseCount++;
}
void setup()
{
pinMode(hallSensorPin, INPUT_PULLUP); // Configure Hall sensor pin as input with pull-up resistor
pinMode(buzzerPin, OUTPUT);
pinMode(ledPin, OUTPUT); // Configure LED pin as output
pinMode(buttonSilencePin, INPUT_PULLUP); // Configure button to silence the buzzer
pinMode(buttonDecreaseThresholdPin, INPUT_PULLUP); // Configure button to decrease threshold
pinMode(buttonIncreaseThresholdPin, INPUT_PULLUP); // Configure button to increase threshold
attachInterrupt(digitalPinToInterrupt(hallSensorPin), hallSensorInterrupt, FALLING);
Serial.begin(9600);
// Initialize the OLED display with I2C communication
if (!display.begin(0x3C))
{
Serial.println(F("SSD1306 allocation failed"));
for (;;)
;
}
display.display();
delay(2);
display.setTextColor(SSD1306_WHITE);
display.setTextSize(3.5);
display.setCursor(0, 0);
// Display scrolling message for a few seconds during startup
display.setTextSize(2);
display.setCursor(0, 0);
display.startscrollright(0x00, 0x0F); // Scroll display to the right
display.display();
delay(5000); // Display scrolling message for 5 seconds
display.stopscroll();
display.clearDisplay();
// Display initial RPM value
currentDisplayMode = RPM;
displayChangeTime = millis();
}
void loop()
{
unsigned long currentTime = millis(); // Define currentTime at the start of the loop
// Calculate RPM
unsigned long timeElapsed = currentTime - lastSpeedCheckTime;
if (timeElapsed >= 1000) // Update RPM every 1000 ms (1 second)
{
rpm = (float)pulseCount * (60000.0 / (float)timeElapsed);
pulseCount = 0;
lastSpeedCheckTime = currentTime;
display.clearDisplay();
display.setCursor(0, 0);
// Display based on the current display mode
switch (currentDisplayMode) {
case RPM:
display.setTextSize(3.5);
display.println(rpm);
break;
case THRESHOLD:
display.setTextSize(2);
display.println("Threshold: " + String(threshold));
break;
}
display.display();
}
buttonSilenceState = digitalRead(buttonSilencePin);
buttonDecreaseState = digitalRead(buttonDecreaseThresholdPin);
buttonIncreaseState = digitalRead(buttonIncreaseThresholdPin);
if (buttonSilenceState != lastButtonSilenceState)
{
if (buttonSilenceState == LOW && (currentTime - lastButtonPressTime >= buttonPressWindow))
{
// Check if the silence button was pressed and if it's outside the time window
soundEnabled = !soundEnabled;
silencePressed = !silencePressed; // Toggle silencePressed flag
lastButtonPressTime = currentTime;
if (silencePressed) {
silenced = true; // Silence the buzzer
// Display silenced message
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0, 0);
display.println("Silenced");
display.display();
displaySilencedMessage = true;
noTone(buzzerPin); // Turn off the buzzer when silenced
} else {
silenced = false; // Unsilence the buzzer
displaySilencedMessage = false;
}
} else if (buttonSilenceState == HIGH && silencePressed) {
lastButtonSilenceReleased = true; // Silence button released
}
lastButtonSilenceState = buttonSilenceState;
}
// Check if the silence button is released and silencePressed is true
if (lastButtonSilenceReleased && silencePressed) {
silencePressed = false;
lastButtonSilenceReleased = false;
}
// Check if the unsilence button is pressed
if (unsilencePressed) {
if (buttonSilenceState == LOW && (currentTime - lastButtonPressTime >= buttonPressWindow)) {
// Unsilence the buzzer
unsilencePressed = false; // Stop tracking unsilence button press
silenced = false;
displaySilencedMessage = false;
}
}
// Check if the decrease threshold button is pressed
if (buttonDecreaseState == LOW)
{
threshold -=5;
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(2);
display.println("Threshold: " + String(threshold));
display.display();
delay(250);
display.clearDisplay();
}
// Check if the increase threshold button is pressed
if (buttonIncreaseState == LOW)
{
threshold +=5;
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(2);
display.println("Threshold: " + String(threshold));
display.display();
delay(250);
display.clearDisplay();
}
// Check if the shaft stopped and the buzzer hasn't sounded yet
if (!silenced && rpm <= threshold && soundEnabled)
{
// Turn on the buzzer when the shaft stops
digitalWrite(ledPin, HIGH); // Turn on the LED when the buzzer sounds
tone(buzzerPin, 650); // Send 800Hz sound signal...
}
else
{
digitalWrite(buzzerPin, LOW); // Turn off the buzzer when the shaft is moving
digitalWrite(ledPin, LOW); // Turn off the LED when the buzzer is off or the shaft is moving
}
}