OLED Display and Hall sensor for shaft rpm

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
  }
}

Is there a need to toggle the "silencePressed flag? Do you see "Silenced" on the OLED?

I don't see any button debouncing code, if you have multiple buttons, a debouncing library like "bounce2" may be beneficial. It's in the IDE library manager.

This seems to be the debounce...

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.