#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ A4, /* data=*/ A5);
static const unsigned char image_Alert_9x8_bits[] U8X8_PROGMEM = {0x10,0x00,0x38,0x00,0x28,0x00,0x6c,0x00,0x6c,0x00,0xfe,0x00,0xee,0x00,0xff,0x01};
#define SENSOR_PIN A0
const int sampleWindow = 50; //Sensor speed
const int red_ledBulb = 9; // Analog connection of our LED bulb
const int yellow_ledBulb = 10; // Analog connection of our LED
const int green_ledBulb = 11; // Analog connection of our LED
const int buzzer = 8; // Analog connection of our buzzer
const int threshold = 80; //Variable (CAN BE CHANGED)
// Define your reference value for 0 dB (the maximum sensor value at reference sound level)
const float referenceValue = 0.0744; // Replace with the actual reference value
//DISPLAY VARIABLES + FRAME ANIMATION
char buffer[32];
/* DOCUMENTATION MAJOR (FORMULA)
(This formula is a LOGARITHMIC FORMULA, different from the VERSION 1 which has the Linear Equation)
(With regards to this "const float referenceValue = 0.0638;" - 0.0638 is computed using the following formula.)
BUT 0.0638 came from 638 (ANALOG READ) and was only given for SIMULATION PURPOSES ONLY!
- In order to find the right referenceValue, test the Noise sensor to be calibrated properly
- TAKE THE 10 SERIAL MONITOR READINGS ONLY and get the average (e.g 534 + 522 + 576 etc.. / 10)
- After obtaining the value (e.g 638 ave of 10 ANALOG READ) use 638 in the formula below.
LOGARITHMIC CONVERSION OF ANALOG READ to Db (NON ADAPTIVE to the PLACE):
To achieve dB values of 80 dB.
you will need to choose a reference value that corresponds to the
desired sound level when your sensor reads 638. In other words, you need
to set your reference value (Vr) such that:
dB = 20 * log10(Vs / Vr) ^ // (Vs = 638) implies your preferred ANALOG READ of when will the ALARM POWERS!
dB = 20 * log10(638 / Vr) // (Vr) is the reference value that you need to FIND!
Let's assume you want a reading of 638 to correspond to 80 dB. You can rearrange the formula to solve for Vr:
Vr = 638 / (10^(80 / 20))
Now, calculate the reference value:
Vr = 638 / (10^(4)) = 638 / 10000 = 0.0638
So, if you set your reference value to 0.638,
then when your sensor reads 638, you'll get a dB value of 80 dB.
- THIS METHOD NEEDS PROPER CALIBRATION OF OUR NOISE SENSOR!
- To make the sensor more sensitive and detects electric signal more often
- change the const int sampleWindow = 100; from 100 ms to 50ms (in this way it reads ANALOG DATA FASTER!)
(NON-FORMULA CHANGES)
- added an LED DISPLAY for NOISE and NOISE LEVEL BARS.
- addded warning sign for Noise values greater than the Threshold
*/
/* DOCUMENTATION MINOR
*Changes to source code 11/2/2023
- Red LED and Buzzer continuously ACTIVE
(can be interrupted when NOISE LEVEL reached SAFE ZONE such as LESS THAN 60 to 70)
(YELLOW - GREATER THAN 61 and LESS THAN 70 ONLY, GREEN - LESS THAN 60 ONLY)
- Added Serial Output for the peakToPeak Analog value var (Peak Analog)
- Added pinMode Functions:
pinMode(red_ledBulb, OUTPUT);
pinMode(yellow_ledBulb, OUTPUT);
pinMode(green_ledBulb, OUTPUT);
pinMode(buzzer, OUTPUT);
(To add real world compatibility with LED and BUZZER)
*/
void setup() {
u8g2.begin(); // start the u8g2 library
pinMode(SENSOR_PIN, INPUT);
pinMode(red_ledBulb, OUTPUT);
pinMode(yellow_ledBulb, OUTPUT);
pinMode(green_ledBulb, OUTPUT);
pinMode(buzzer, OUTPUT);
Serial.begin(115200);
}
void loop() {
// Read the analog sensor value
int sensorValue = analogRead(SENSOR_PIN); // Replace A0 with your actual sensor pin
u8g2.clearBuffer(); //LED Ini
unsigned long currentMillis = millis(); //frame animation for Warning SIGN
// Calculate dB using the reference value
double dB = 20 * log10(sensorValue /(double)referenceValue);
int dBLevel = dB;
if (dB <= 65) {
digitalWrite(green_ledBulb, HIGH);
digitalWrite(buzzer, LOW);
digitalWrite(red_ledBulb, LOW);
u8g2.setFont(u8g2_font_helvB08_tr);
u8g2.drawStr(68, 61, "LOW");
if (dB >= 40) {
u8g2.drawBox(58, 47, 6, 4);
}
if (dB >= 54){
u8g2.drawBox(66, 45, 6, 6);
}
if (dB >= 64){
u8g2.drawBox(74, 43, 6, 8);
}
} if (dB >= 65 && dB <= 80) {
digitalWrite(green_ledBulb, HIGH);
digitalWrite(yellow_ledBulb, HIGH);
digitalWrite(buzzer, LOW);
digitalWrite(red_ledBulb, LOW);
u8g2.setFont(u8g2_font_helvB08_tr);
u8g2.drawStr(59, 61, "MODERATE");
u8g2.drawBox(58, 47, 6, 4);
u8g2.drawBox(66, 45, 6, 6);
u8g2.drawBox(74, 43, 6, 8);
delay(100);
digitalWrite(red_ledBulb, LOW);
if (dB >= 65 ){
u8g2.drawBox(82, 41, 6, 10);
}
if (dB >= 75) {
u8g2.drawBox(90, 39, 6, 12);
}
if (dB >= 78) {
u8g2.drawBox(98, 37, 6, 14);
}
} if (dB >= 80 && dB >= threshold ) {
digitalWrite(red_ledBulb, HIGH);
digitalWrite(green_ledBulb, HIGH);
digitalWrite(yellow_ledBulb, HIGH);
digitalWrite(buzzer, HIGH);
u8g2.drawBox(58, 47, 6, 4);
u8g2.drawBox(66, 45, 6, 6);
u8g2.drawBox(74, 43, 6, 8);
u8g2.drawBox(82, 41, 6, 10);
u8g2.drawBox(90, 39, 6, 12);
u8g2.drawBox(98, 37, 6, 14);
u8g2.drawBox(106, 35, 6, 16);
if (dB > threshold + 1){
u8g2.drawXBMP( 114, 43, 9, 8, image_Alert_9x8_bits);
u8g2.setFont(u8g2_font_helvB08_tr);
u8g2.drawStr(20, 61, "ALARMING NOISE!");
} else {
u8g2.setFont(u8g2_font_helvB08_tr);
u8g2.drawStr(60, 61, "BE QUIET!");
}
}
delay(sampleWindow); // Adjust the delay as needed
/*LED DRAW SECTION for NOISE INFO*/
u8g2.setBitmapMode(1);
u8g2.drawFrame(0, 0, 128, 64);
u8g2.setFont(u8g2_font_helvB08_tr);
u8g2.drawStr(9, 23, "NOISE:");
u8g2.setFont(u8g2_font_profont22_tr);
sprintf(buffer,"%d dB", dBLevel);
u8g2.drawStr(58, 23, buffer);
u8g2.setFont(u8g2_font_helvB08_tr);
u8g2.drawStr(9, 51, "LEVEL:");
u8g2.sendBuffer();
// Print the dB value to the serial monitor
Serial.print("Analog Value: ");
Serial.print(sensorValue);
Serial.print(" | Decibels: ");
Serial.println(dB);
}