// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// ESP32-S3 44pin, connected to OLED display, sensor data DHT22, LED noDelay, button, Pot, Software
//
// 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:
// - DHT22 date is now shown on ESP32s3 after connecting pin17 instead of 4. Data can be altered by clicking on sensor while running
// -
// -
// to be added: onboard LED or RGB is not working!
// -
// -
// 07.01.24 last (start 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
#define DHT22_PIN 17 // oder const int DHT22_PIN 4
DHTesp DHT; // start library
// ===== LEFT ROW: INPUTS/OUTPUTS for ESP32-S3 44pin =================================================
// 3.3V
// 3.3V
// RST
//const int DHT22_PIN = 4; // GPIO04 touch
const int potPin = 5; // GPIO05 touch
// GPIO06 touch
const int buttonPin = 7; // GPIO07 touch
// GPIO15
// GPIO16
// GPIO17
// GPIO18
//#define SDA 8 // GPIO08 touch HW I2C SDA data
// GPIO03 touch
// GPIO46 - SPI BLK? SPI: BLK
//#define SCL 9 // GPIO09 touch - SPI BUSY Busy, HW I2C SCL clock SPI: DC (14)
// GPIO10 touch SPI CS chip select = SPI: CS
// GPIO11 touch SPI DIN/SDI MOSI Hardware data! = SPI: MOSI
// GPIO12 touch SPI CLK SCLK Hardware clock! = SPI: CLK
// 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
// GPIO41
const int ledPin3 = 40; // GPIO40
const int ledPin4 = 39; // GPIO39
// GPIO38 RGB LED
// GPIO37
// GPIO36
// GPIO35
// GPIO00
// GPIO45
// GPIO48
const int ledPin5 = 47; // GPIO47
// GPIO21
// GPIO20
const int buzzerPin = 19; // GPIO19
// 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 ESP32S3: 8 SDA, 9 CLK]
// ===== 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()
{ Serial.begin(115200); // for DHT22 results on serial monitor
u8g2.begin(); // start the u8g2 library/display
//u8g2.setColorIndex(1); // set the color to white
//dhtSensor.setup(DHT_PIN, DHTesp::DHT22); // setup DHT22 sensor with the input pin defined above
DHT.setup(DHT22_PIN, DHTesp::DHT22); // setup DHT22 sensor with the input pin defined above
//pinMode(DHT22_PIN, INPUT);
pinMode(buttonPin, INPUT_PULLUP); // pin as INPUT_PULLUP -> pin set to 3.3V, button connected to GND -> goes LOW (GND) if pressed
//pinMode(buttonPin, INPUT); // pin as INPUT or INPUT_PULLDOWN -> pin set to GND, button connected to 3.3V -> goes HIGH (3.3V) if pressed
pinMode(potPin, INPUT); // pin for potentiometer as input
pinMode(ledPin1, OUTPUT); // set the digital pin as output
pinMode(ledPin2, OUTPUT); // set the digital pin as output
pinMode(ledPin3, OUTPUT); // set the digital pin as output
pinMode(ledPin4, OUTPUT); // set the digital pin as output
pinMode(ledPin5, OUTPUT); // set the digital pin as output
pinMode(RGB_BUILTIN, OUTPUT); // onboard RGB as output pin 38/48? (ESP32: LED_BUILTIN = GPIO2)
pinMode(LED_BUILTIN, OUTPUT); // onboard LED as output pin 38/48? (ESP32: LED_BUILTIN = GPIO2)
pinMode(42, OUTPUT); // exp: pin 42 as output for speaker/buzzer
Serial.print("RGB_BUILTIN on GPIO#:... "); // check the GPIO# of the onboard RGB LED on the serial monitor
Serial.print(RGB_BUILTIN);
Serial.println();
Serial.print("LED_BUILTIN on GPIO#:... "); // check the GPIO# of the onboard LED on the serial monitor
Serial.print(LED_BUILTIN);
Serial.println();
}
// **************************************************************************************************
// F U N C T I O N S *
// **************************************************************************************************
// **************************************************************************************************
// L O O P *
// **************************************************************************************************
void loop()
{
// ===== LED 1 should blink with millis() function without delay()
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);
*/
// ===== LED 2 should light when button pressed
// 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); }
//
/* 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); }
*/
// ===== LED 3 should be on with PWM depending on potentiometer
int potValue = analogRead(potPin); // give input of potentiometer a value, analog 16bit 0..1023
analogWrite(ledPin3, potValue/4); // analog output for LED, 8 bit 0..255 (1024/4 = 256 )
// ===== LED 4 should be on/off with software
//digitalWrite(ledPin4, HIGH);
//digitalWrite(ledPin4, LOW);
analogWrite(ledPin4, 55); // analog from 0..255
// ===== LED 5 should be on/off with millis() function
// Using millis() function, returing the number of milliseconds since the program has started running. Divided 1000 -> number of seconds passed so far.
// Calculate the remainder of dividing by two, using the modulus (%) operator. -> Returns 0 for even numbers and 1 for odd numbers:
// In other words, we repeatedly take the number of seconds passed since the program started running, and set the value of the LED based on that: ON if the number if currently odd, OFF if it is currently even. This is how we achieve the desired blink.
//digitalWrite(ledPin5, (millis() / 1000) % 2); // blink every second: millis()/1000 %2
//digitalWrite(ledPin5, (millis() / 2000) % 2); // blink every two seconds: millis()/2000 %2
digitalWrite(ledPin5, (millis() / 200) % 2); // blink every 200 ms: millis()/200 %2
// ===== Builtin RGB-LED should be on/off with software
digitalWrite(RGB_BUILTIN, HIGH);
//delay(100);
//digitalWrite(RGB_BUILTIN, LOW);
//delay(100);
//analogWrite(RGB_BUILTIN, 100); // analog from 0..255
digitalWrite(LED_BUILTIN, HIGH); // try out different pins to see if this is the onboard LED 97, 18, 38, 48, ...
// ===== Read DHT22 sensor for temperature and humidity, show on serial monitor
TempAndHumidity data = DHT.getTempAndHumidity();
Serial.print ("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)
/* ===== writing to OLED
u8g2.clearBuffer(); // clear buffer for storing display content in RAM
u8g2.setFont(u8g2_font_nerhoe_tr); // set font
u8g2.drawStr( 0, 10, "Messwerte DHT22"); // draw String
u8g2.drawStr( 0, 30, "Temperatur"); // draw String
u8g2.setCursor(80,30);
u8g2.print(data.temperature, 2);
//u8g2.drawStr(data.temperature, 2);
u8g2.drawRFrame(2, 50, 100, 14, 3); // draw rounded empty rectangle x,y, width, height, radius
u8g2.drawFrame(5, 45, 80, 12); // draw empty rectangle x,y, width, height
u8g2.drawBox(10, 40,50, 10); // draw filled rectangle x,y, width, height
u8g2.sendBuffer(); // send buffer from RAM to display controller
*/
// ===== writing to OLED
u8g2.clearBuffer(); // clear buffer for storing display content in RAM
u8g2.setFont(u8g2_font_nerhoe_tr); // set font
u8g2.drawStr( 0, 10, "Data of DHT22"); // draw String
u8g2.setCursor(80,10);
u8g2.print("Value:"); // w/o F: ?
u8g2.setFont(u8g2_font_profont10_tr); // font for the small label
u8g2.drawStr( 0, 25, "Temperature"); // draw String
u8g2.setCursor(80,25);
u8g2.print(data.temperature, 2);
u8g2.drawStr( 0, 35, "Humidity"); // draw String
u8g2.setCursor(80,35);
u8g2.print(data.humidity, 1);
//u8g2.drawStr(data.temperature, 2);
u8g2.drawRFrame(0, 50, 128, 14, 3); // draw rounded empty rectangle x,y, width, height, radius
//u8g2.drawFrame(5, 45, 80, 12); // draw empty rectangle x,y, width, height
int barWidth = map(data.temperature, -40, 80, 0, 124); // mapping the temp. range 20..60°C to bar width from 0..120
u8g2.drawBox(2, 52, barWidth, 10); // draw filled rectangle x,y, width, height
u8g2.sendBuffer(); // send buffer from RAM to display controller
//
delay(3000);
// BUZZER: operation mode: "smooth" or "accurate" std. "smooth" Volume (loudness) of the sound, between "0.01" and "1.0" "1.0"
tone(buzzerPin, 262, 250); // Plays 262Hz tone for 0.250 seconds on pin 19 Buzzer
if (buttonState == HIGH) // Button gedrückt = LOW nicht gedrückt = HIGH
{ digitalWrite(42, LOW); } // set the LED with the ledState of the variable:
else
{ digitalWrite(42, HIGH);
tone(42, 500, 250); // Plays 500Hz tone for 0.250 seconds on a pin
}
}
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/*
Why the heart icon? Because I thought it was cool
and I want to use it in the future with some heartbeat sensor.
I needed to keep it somewhere and it was here. ;)
*/
/*
#include <dht.h>
#include <TinyWireM.h>
#include <Tiny4kOLED.h>
#define DHT22_PIN PB1
const unsigned char img_heart_small[] PROGMEM = {
0x00, 0x00, 0xc0, 0xe0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x80, 0xc0, 0xe0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00
};
const unsigned char img_heart_big[] PROGMEM = {
0xe0, 0xf0, 0xf8, 0xf8, 0xf8, 0xf8, 0xf0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf8, 0xf8, 0xf8, 0xf8, 0xf0, 0xe0, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00
};
const unsigned char img_thermometer[] PROGMEM = {
0x00, 0xfe, 0x03, 0xfe, 0x50,
0x00, 0xff, 0x00, 0xff, 0x55,
0x60, 0x9f, 0x80, 0x9f, 0x65,
};
dht DHT;
void splash() {
oled.clear();
oled.setCursor(15, 1);
oled.print(F("ATtiny85+SSD1306"));
oled.setCursor(42, 3);
oled.print(F("Example"));
oled.setCursor(35, 7);
oled.print(F("wokwi.com"));
}
void heartBeat() {
static char big = 1;
static long startTime = 0;
long currentTime;
// Get current time
currentTime = millis();
// Update if 200ms passed
if ((currentTime - startTime) > 200) {
startTime = currentTime;
big = 1 - big;
if (big) {
oled.bitmap(20, 4, 37, 6, img_heart_big);
} else {
oled.bitmap(20, 4, 37, 6, img_heart_small);
}
}
}
void prepareDisplay() {
unsigned int i, k;
unsigned char ch[5];
oled.clear();
oled.begin();
oled.setCursor(20, 1);
oled.print(F("ATtiny85+SSD1306"));
oled.setCursor(3, 2);
oled.print(F("temperature|humidity"));
oled.bitmap(105, 4, 110, 7, img_thermometer);
oled.setCursor(57, 4);
oled.print(F("24.0C"));
oled.setCursor(57, 5);
oled.print(F("40.0%"));
oled.bitmap(10, 5, 17, 2, img_heart_small);
}
float getTemperature() {
return DHT.temperature;
}
float getHumidity() {
return DHT.humidity;
}
void setup() {
pinMode(DHT22_PIN, INPUT);
oled.begin(128, 64, sizeof(tiny4koled_init_128x64br), tiny4koled_init_128x64br);
// Two fonts are supplied with this library, FONT8X16 and FONT6X8
oled.setFont(FONT6X8);
// To clear all the memory
oled.clear();
oled.on();
splash();
delay(3000);
prepareDisplay();
}
void loop() {
static long startTime = 0;
long currentTime;
DHT.read22(DHT22_PIN);
// Get current time
currentTime = millis();
// Checks 1 second passed
if ((currentTime - startTime) > 1000) {
startTime = currentTime;
// Update temperature
float temperature = getTemperature();
// Set cursor
oled.setCursor(57, 4);
// Print to display
oled.print(temperature, 1);
oled.print("C ");
// Update humidity
float humidity = getHumidity();
// Set cursor
oled.setCursor(57, 5);
// Print to display
oled.print(humidity, 1);
oled.print("% ");
oled.bitmap(105, 4, 110, 7, img_thermometer);
}
heartBeat();
}
*/