// **********************************************************************************************************
// ESP32-S3 44pin, connected to OLED display, sensor data DHT22 (on I2C?), LED Alarm
//
// Hardware: ESP32-S3 44pin, OLED Display 128x64 I2C, DHT22 temp. hum. sensor analog, LED,
// External libraries: u8g2lib.h,
// Processor selection in Arduino IDE: ESP32S3 Dev Module
// Possible Touch Pins for ESP32S3 with 44 pins: GPIO #: 1 2 3 4 5 6 7 8 9 10 11 12 13 14
// Possible Output Pins for ESP32S3 with 44 pins: GPIO #: 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 46
// 0 1 2 19 20 21 35 36 37 38 39 40 41 42 43 44 45 47 48 48 (or38?): internal RGB LED
// What it does:
// -
// -
// -
// to be added:
// -
// -
// Dec.2023
// **********************************************************************************************************
// **************************************************************************************************
// D E F I N I T I O N S *
// **************************************************************************************************
#include "U8g2lib.h" // include u8g2 library for drawing on the OLED display
#include "DHTesp.h" // include sensor library for DHT22 with ESP32
DHTesp dhtSensor; // start library
// ===== LEFT ROW: INPUTS/OUTPUTS for ESP32-S3 44pin ==================================
// 3.3V
// 3.3V
// RST
const int DHT_PIN = 4; // GPIO04 touch
// GPIO05 touch
// GPIO06 touch for SCD41 sensor
const int buttonPin = 7; // GPIO07 touch for SCD41 sensor
// GPIO15
// GPIO16
// GPIO17
// GPIO18
//#define SDA 8 // GPIO08 touch
// GPIO03 touch
// GPIO46
//#define SCL 9 // GPIO09 touch SPI BUSY Busy
// GPIO10 touch SPI CS chip select
// GPIO11 touch SPI DIN/SDI MOSI Hardware data!
// GPIO12 touch SPI CLK SCLK Hardware clock!
// GPIO13 touch SPI RST Reset
// GPIO14 touch SPI DC D/C data command
// 5.0V
// GND
// ===== RIGHT ROW: INPUTS/OUTPUTS ===================================
// GND
// GPIO43 TX CLK1 SPI?
// GPIO44 RX CLK2 I2C?
const int ledPin1 = 1; // GPIO01 touch
const int ledPin2 = 2; // GPIO02 touch
// GPIO42 for u8g2 constructor for OLED data
// GPIO41 for u8g2 constructor for OLED clock
// GPIO40
// GPIO39
// GPIO38 RGB LED
// GPIO37
// GPIO36
// GPIO35
// GPIO00
// GPIO45
// GPIO48
// GPIO47 define LED output touchPinB
// GPIO21 define LED output touchPinA
// GPIO20 define output pin for LED Alarm CO2
// GPIO19 Servo signal pin, must be PWM
// GND
// GND
// ===== CONSTRUCTOR for OLED display with u8g2 library, SCL clock and SDA data pins defined above
//U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, SCL, SDA, U8X8_PIN_NONE); // constructor for 0.96" OLED I2C display 0x3C SSD1306 (or SSD1315), display name "displayOLED"
//U8G2_SSD1309_128X64_NONAME0_F_SW_I2C u8g2_2(U8G2_R0, SCL2, SDA2, U8X8_PIN_NONE); // constructor for 2.42" OLED I2C display SSD1309, display name "display2"
//U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, SCL, SDA, U8X8_PIN_NONE); // constructor for 0.96" OLED I2C display 0x3C SSD1306 (or SSD1315), display name "display"
// ===== Constructor in Wokwi apparently needs Hardware pins 8 (data) and 9 (clock):
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0); // ["F" = full framebuffer, size = 1024 bytes, hardware I2C connection]
// ===== VARIABLES: =====
int ledState1 = LOW; // ledState used to set the LED
int ledState2 = LOW; // ledState used to set the LED
int buttonState = LOW; // variable for reading the button status
// Generally, you should use "unsigned long" for variables that hold time, The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time LED was updated
const long interval = 500; // interval at which to blink (milliseconds), this is a constant
byte audio_bar_height[7]; // sizes for the individual bars
byte audio_bar_peak[7]; // positions for the individual peaks (lines over the bars)
// **************************************************************************************************
// S E T U P *
// **************************************************************************************************
void setup()
{
u8g2.begin(); // start the u8g2 library/display
//u8g2.setColorIndex(1); // set the color to white
Serial.begin(115200); // for DHT22 results on serial monitor
dhtSensor.setup(DHT_PIN, DHTesp::DHT22); // setup DHT22 sensor with the input pin defined above
pinMode(ledPin1, OUTPUT); // set the digital pin as output
pinMode(ledPin2, OUTPUT); // set the digital pin as output
//pinMode(buttonPin, INPUT); // pin as input -> working with 3.3V to pin4 -> NOT working pin4 to GND
pinMode(buttonPin, INPUT_PULLUP); // pin as input_pullup -> NOT working with 3.3V to pin4 -> inverse working pin4 to GND
//pinMode(buttonPin, INPUT_PULLDOWN); // pin as input_pulldown -> working with 3.3V to pin4 -> NOT working pin4 to GND
}
// **************************************************************************************************
// F U N C T I O N S *
// **************************************************************************************************
// **************************************************************************************************
// L O O P *
// **************************************************************************************************
void loop()
{
unsigned long currentMillis = millis(); // time to blink the LED? difference between current time and last time the LED blinked is bigger than the blink interval
if (currentMillis - previousMillis >= interval)
{ previousMillis = currentMillis; // save the last time you blinked the LED
if (ledState1 == LOW) // if the LED is off turn it on and vice-versa:
{ ledState1 = HIGH; }
else
{ ledState1 = LOW; }
digitalWrite(ledPin1, ledState1); // set the LED with the ledState of the variable:
}
/*
digitalWrite(1, HIGH); // Classic turn on/off LED with delay() function
delay(500);
digitalWrite(1, LOW);
delay(500);
*/
/* if input button with INPUT_PULLDOWN (or just INPUT) connected to 3.3V: normally LOW, HIGH if pressed
//int buttonState = digitalRead(buttonPin); // read the state of the button
buttonState = digitalRead(buttonPin); // read the state of the button
if (buttonState == HIGH)
{ digitalWrite(ledPin2, HIGH); } // set the LED with the ledState of the variable:
else { digitalWrite(ledPin2, LOW); }
*/
// if input button with INPUT_PULLUP inverted logic is needed, as input pin is normally HIGH, then LOW if pressed
buttonState = digitalRead(buttonPin); // read the state of the button
if (buttonState == HIGH)
{ digitalWrite(ledPin2, LOW); } // set the LED with the ledState of the variable:
else { digitalWrite(ledPin2, HIGH); }
//
// Read DHT22 sensor for temperature and humidity, show on serial monitor
TempAndHumidity data = dhtSensor.getTempAndHumidity();
Serial.println("Temp: " + String(data.temperature, 2) + "°C");
Serial.println("Humidity: " + String(data.humidity, 1) + "%");
Serial.println("---");
//delay(2000); // Wait for a new reading from the sensor (DHT22 has ~0.5Hz sample rate)
u8g2.clearBuffer(); // clear buffer for storing display content in RAM
for (int i=0; i<7; i++) // loop for every fraquency (63Hz, 160Hz, 400Hz, 1kHz, 2.5kHz, 6.25kHz and 16kHz)
{
int random_value = random(1024); // calculate random value between 0-1024
audio_bar_height[i] = audio_bar_height[i] + ((map(random_value, 0, 1024, 0, 53) - audio_bar_height[i]) / 4.0); // update the bar with a new value (slowly)
// calculate the peak position
if (audio_bar_peak[i] < audio_bar_height[i]) // if the peak is below the current bar size
{ audio_bar_peak[i] = audio_bar_height[i]; } // move peak to the new max. position (i.e. size of the bar)
else
if (audio_bar_peak[i] > audio_bar_height[i]) // if the bar is lower than the peak
{ audio_bar_peak[i]--; } // slowly move the peak down, one pixel every frame
u8g2.drawBox(2 + i*19, 53-audio_bar_height[i], 10, audio_bar_height[i]); // draw bar
u8g2.drawBox(2 + i*19, 53-audio_bar_peak[i], 10, 1); // draw peak
}
// draw the individual labels
u8g2.setFont(u8g2_font_nerhoe_tr); // set font
u8g2.drawStr( 2, 64, "63");
u8g2.drawStr( 19, 64, "160");
u8g2.drawStr( 37, 64, "400");
u8g2.drawStr( 60, 64, "1K");
u8g2.drawStr( 75, 64, "2.5K");
u8g2.drawStr( 95, 64, "6.3K");
u8g2.drawStr(115, 64, "16K");
u8g2.sendBuffer(); // send buffer from RAM to display controller
}