warning
This commit is contained in:
parent
eba13c6181
commit
fa6c2a753a
50
README.md
50
README.md
@ -1,11 +1,10 @@
|
|||||||
# ESP32 Washing Machine Activity Notifier
|
# ESP32 Dual Machine Activity Notifier
|
||||||
|
|
||||||
This project turns an ESP32 into a smart device that monitors a washing machine's activity using vibration and light sensors and sends notifications when a cycle starts and finishes. It also displays the current status on an OLED display.
|
This project turns an ESP32 into a smart device that monitors two machines (e.g., washer and dryer) using light sensors and sends notifications when a cycle starts and finishes. It also displays the current status on an OLED display.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- **Vibration Sensing:** Detects machine operation by monitoring vibrations.
|
- **Dual Light Sensing:** Monitors two separate devices using two BH1750 light sensors.
|
||||||
- **Light Sensing:** Detects the machine's internal light to determine if the door is open.
|
|
||||||
- **Status Display:** Shows real-time sensor data and device status on a small OLED display.
|
- **Status Display:** Shows real-time sensor data and device status on a small OLED display.
|
||||||
- **Notifications:** Sends start and stop notifications to a `ntfy.sh` topic.
|
- **Notifications:** Sends start and stop notifications to a `ntfy.sh` topic.
|
||||||
- **WiFi Connectivity:** Connects to your local WiFi network.
|
- **WiFi Connectivity:** Connects to your local WiFi network.
|
||||||
@ -13,33 +12,31 @@ This project turns an ESP32 into a smart device that monitors a washing machine'
|
|||||||
## Hardware Requirements
|
## Hardware Requirements
|
||||||
|
|
||||||
- ESP32 development board
|
- ESP32 development board
|
||||||
- SW-420 vibration sensor module (or similar)
|
- 2x BH1750 light sensor modules
|
||||||
- BH1750 light sensor module
|
|
||||||
- SSD1306 128x64 OLED display (I2C)
|
- SSD1306 128x64 OLED display (I2C)
|
||||||
- Breadboard and jumper wires
|
- Breadboard and jumper wires
|
||||||
|
|
||||||
## Pinout
|
## Pinout
|
||||||
|
|
||||||
| Component | Pin on ESP32 |
|
| Component | Pin on ESP32 | Notes |
|
||||||
| ------------------- | ------------ |
|
| ------------------- | ------------ | ----- |
|
||||||
| Vibration Sensor | GPIO 4 |
|
| I2C SCL (OLED, Sensors)| GPIO 22 | Shared bus |
|
||||||
| I2C SCL (OLED, BH1750) | GPIO 22 |
|
| I2C SDA (OLED, Sensors)| GPIO 21 | Shared bus |
|
||||||
| I2C SDA (OLED, BH1750) | GPIO 21 |
|
|
||||||
|
|
||||||
### Wiring Diagram
|
### Wiring Diagram
|
||||||
|
|
||||||
```
|
```
|
||||||
+-----------------+ +-----------------+ +-----------------+ +-----------------+
|
+-----------------+ +-----------------+ +-----------------+
|
||||||
| ESP32 Dev Board | | Vibration Sensor| | BH1750 Sensor | | OLED Display |
|
| ESP32 Dev Board | | BH1750 Sensor | | OLED Display |
|
||||||
+-----------------+ +-----------------+ +-----------------+ +-----------------+
|
+-----------------+ +-----------------+ +-----------------+
|
||||||
| 3.3V |----->| VCC |----->| VCC |----->| VCC |
|
| 3.3V |---------->| VCC |----->| VCC |
|
||||||
| GND |----->| GND |----->| GND |----->| GND |
|
| GND |---------->| GND |----->| GND |
|
||||||
| GPIO 4 |----->| OUT | | | | |
|
| | | | | |
|
||||||
| | +-----------------+ | | | |
|
| GPIO 22 (SCL) |---------->| SCL |----->| SCL |
|
||||||
| GPIO 22 (SCL) |------------------------------>| SCL |----->| SCL |
|
| GPIO 21 (SDA) |---------->| SDA |----->| SDA |
|
||||||
| GPIO 21 (SDA) |------------------------------>| SDA |----->| SDA |
|
|
||||||
+-----------------+ +-----------------+ +-----------------+
|
+-----------------+ +-----------------+ +-----------------+
|
||||||
```
|
```
|
||||||
|
**Note:** For Sensor 1, connect the ADDR pin to GND (or leave floating if default is low). For Sensor 2, connect the ADDR pin to 3.3V to change its I2C address to 0x5C.
|
||||||
|
|
||||||
## Setup & Usage
|
## Setup & Usage
|
||||||
|
|
||||||
@ -61,19 +58,16 @@ This project turns an ESP32 into a smart device that monitors a washing machine'
|
|||||||
- Click the upload button.
|
- Click the upload button.
|
||||||
|
|
||||||
4. **Deploy the Device:**
|
4. **Deploy the Device:**
|
||||||
- Place the vibration sensor on the washing machine where it can detect vibrations from the spin cycle.
|
- Place Sensor 1 inside the first machine (e.g., Washer) to detect internal light.
|
||||||
- Place the light sensor inside the machine's drum to detect the internal light.
|
- Place Sensor 2 inside the second machine (e.g., Dryer) to detect internal light.
|
||||||
|
|
||||||
## Code Explanation
|
## Code Explanation
|
||||||
|
|
||||||
The code is structured as follows:
|
The code is structured as follows:
|
||||||
|
|
||||||
- **Includes and Definitions:** Includes the necessary libraries for WiFi, I2C devices, and the display. It also defines pins, thresholds, and other constants.
|
- It continuously reads the values from both light sensors.
|
||||||
- **`setup()`:** Initializes serial communication, I2C, sensors, the OLED display, and connects to WiFi.
|
- It implements a non-blocking logic using `millis()` to check if the sensors have been in a certain state (light level high) for a continuous period.
|
||||||
- **`loop()`:** This is the main part of the program.
|
- It updates the overall device states (`isDevice1Active`, `isDevice2Active`) based on the individual sensor states.
|
||||||
- It continuously reads the values from the vibration and light sensors.
|
|
||||||
- It implements a non-blocking logic using `millis()` to check if the sensors have been in a certain state (e.g., vibration active or light level high) for a continuous period of 5 seconds.
|
|
||||||
- It updates the overall device state (`isDeviceActive`) based on the individual sensor states.
|
|
||||||
- If the device state changes, it calls `sendNotification()`.
|
- If the device state changes, it calls `sendNotification()`.
|
||||||
- It calls `updateDisplay()` to show the latest data.
|
- It calls `updateDisplay()` to show the latest data.
|
||||||
- **`sendNotification()`:** Sends a POST request to the configured `ntfy.sh` topic with a message.
|
- **`sendNotification()`:** Sends a POST request to the configured `ntfy.sh` topic with a message.
|
||||||
|
|||||||
@ -34,11 +34,8 @@ const char* WIFI_PASSWORD = SECRET_WIFI_PASSWORD;
|
|||||||
const char* NTFY_TOPIC = SECRET_NTFY_TOPIC;
|
const char* NTFY_TOPIC = SECRET_NTFY_TOPIC;
|
||||||
|
|
||||||
// Device Names
|
// Device Names
|
||||||
const char* DEVICE1_NAME = "Dryer"; // Monitored by Vibration
|
const char* DEVICE1_NAME = "Wash"; // Monitored by Light 1 (0x23)
|
||||||
const char* DEVICE2_NAME = "Washer"; // Monitored by Light
|
const char* DEVICE2_NAME = "Dry "; // Monitored by Light 2 (0x5C)
|
||||||
|
|
||||||
// Pin definitions
|
|
||||||
const int VIBRATION_PIN = 4;
|
|
||||||
|
|
||||||
// OLED display settings
|
// OLED display settings
|
||||||
#define SCREEN_WIDTH 128
|
#define SCREEN_WIDTH 128
|
||||||
@ -51,19 +48,19 @@ Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
|||||||
|
|
||||||
// Light sensor
|
// Light sensor
|
||||||
#ifdef ENABLE_SENSORS
|
#ifdef ENABLE_SENSORS
|
||||||
BH1750 lightMeter;
|
BH1750 lightMeter1(0x23);
|
||||||
|
BH1750 lightMeter2(0x5C);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Thresholds
|
// Thresholds
|
||||||
const float LIGHT_ACTIVATION_THRESHOLD = 50.0;
|
const float LIGHT_ACTIVATION_THRESHOLD = 50.0;
|
||||||
const unsigned long WINDOW_DURATION = 10000; // 10 seconds
|
const unsigned long WINDOW_DURATION = 10000; // 10 seconds
|
||||||
const int REQUIRED_CONSECUTIVE_WINDOWS = 6;
|
const int REQUIRED_CONSECUTIVE_WINDOWS = 6;
|
||||||
const unsigned long VIBRATION_ACTIVE_THRESHOLD = 100000;
|
|
||||||
const unsigned long WARMUP_DURATION = 30000; // 20 seconds warmup
|
const unsigned long WARMUP_DURATION = 30000; // 20 seconds warmup
|
||||||
|
|
||||||
// Device state
|
// Device state
|
||||||
bool isVibrationActive = false;
|
bool isDevice1Active = false;
|
||||||
bool isLightActive = false;
|
bool isDevice2Active = false;
|
||||||
|
|
||||||
// Time tracking for sensor states
|
// Time tracking for sensor states
|
||||||
unsigned long lastWindowStartTime = 0;
|
unsigned long lastWindowStartTime = 0;
|
||||||
@ -88,29 +85,13 @@ QueueHandle_t notificationQueue;
|
|||||||
volatile bool isNetworkActive = false;
|
volatile bool isNetworkActive = false;
|
||||||
|
|
||||||
#ifdef ENABLE_SENSORS
|
#ifdef ENABLE_SENSORS
|
||||||
unsigned long vibrationTotalLow = 0;
|
int light1ConsecutiveOn = 0;
|
||||||
int vibConsecutiveOn = 0;
|
int light1ConsecutiveOff = 0;
|
||||||
int vibConsecutiveOff = 0;
|
float maxLight1InWindow = 0.0;
|
||||||
int lightConsecutiveOn = 0;
|
|
||||||
int lightConsecutiveOff = 0;
|
|
||||||
float maxLightInWindow = 0.0;
|
|
||||||
volatile unsigned long lastChangeTime = 0;
|
|
||||||
volatile unsigned long lowTimeAccumulator = 0;
|
|
||||||
volatile unsigned long highTimeAccumulator = 0;
|
|
||||||
|
|
||||||
void IRAM_ATTR onChange() {
|
int light2ConsecutiveOn = 0;
|
||||||
unsigned long now = micros();
|
int light2ConsecutiveOff = 0;
|
||||||
unsigned long duration = now - lastChangeTime;
|
float maxLight2InWindow = 0.0;
|
||||||
lastChangeTime = now;
|
|
||||||
|
|
||||||
if (digitalRead(VIBRATION_PIN) == HIGH) {
|
|
||||||
// Changed to HIGH, so previous state was LOW
|
|
||||||
lowTimeAccumulator += duration;
|
|
||||||
} else {
|
|
||||||
// Changed to LOW, so previous state was HIGH
|
|
||||||
highTimeAccumulator += duration;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_WIFI
|
#ifdef ENABLE_WIFI
|
||||||
@ -180,14 +161,13 @@ void setup() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_SENSORS
|
#ifdef ENABLE_SENSORS
|
||||||
// Initialize vibration sensor pin
|
// Initialize light sensors
|
||||||
pinMode(VIBRATION_PIN, INPUT_PULLUP);
|
if (!lightMeter1.begin(BH1750::CONTINUOUS_HIGH_RES_MODE, 0x23)) {
|
||||||
lastChangeTime = micros();
|
Serial.println(F("Could not find valid BH1750 sensor at 0x23, check wiring!"));
|
||||||
attachInterrupt(digitalPinToInterrupt(VIBRATION_PIN), onChange, CHANGE);
|
while (1) { }
|
||||||
|
}
|
||||||
// Initialize light sensor
|
if (!lightMeter2.begin(BH1750::CONTINUOUS_HIGH_RES_MODE, 0x5C)) {
|
||||||
if (!lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) {
|
Serial.println(F("Could not find valid BH1750 sensor at 0x5C, check wiring!"));
|
||||||
Serial.println(F("Could not find a valid BH1750 sensor, check wiring!"));
|
|
||||||
while (1) { }
|
while (1) { }
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -202,8 +182,17 @@ void setup() {
|
|||||||
display.setTextSize(1);
|
display.setTextSize(1);
|
||||||
display.setTextColor(WHITE);
|
display.setTextColor(WHITE);
|
||||||
display.setCursor(0, 0);
|
display.setCursor(0, 0);
|
||||||
display.println(F("Initializing..."));
|
display.println(F("Hello!"));
|
||||||
display.display();
|
display.display();
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
#ifdef ENABLE_WIFI
|
||||||
|
display.clearDisplay();
|
||||||
|
display.setCursor(0, 0);
|
||||||
|
display.println(F("WiFi:"));
|
||||||
|
display.println(WIFI_SSID);
|
||||||
|
display.display();
|
||||||
|
delay(1000);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_WIFI
|
#ifdef ENABLE_WIFI
|
||||||
@ -234,6 +223,13 @@ void setup() {
|
|||||||
delay(1000);
|
delay(1000);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
display.clearDisplay();
|
||||||
|
display.setCursor(0, 0);
|
||||||
|
display.println(F("Topic:"));
|
||||||
|
display.println(NTFY_TOPIC);
|
||||||
|
display.display();
|
||||||
|
delay(1000);
|
||||||
|
#endif
|
||||||
|
|
||||||
Serial.println("Setup finished.");
|
Serial.println("Setup finished.");
|
||||||
}
|
}
|
||||||
@ -245,83 +241,70 @@ void loop() {
|
|||||||
|
|
||||||
// Sensor readings
|
// Sensor readings
|
||||||
#ifdef ENABLE_SENSORS
|
#ifdef ENABLE_SENSORS
|
||||||
float currentLightLevel = lightMeter.readLightLevel();
|
float currentLight1 = lightMeter1.readLightLevel();
|
||||||
if (currentLightLevel > maxLightInWindow) {
|
if (currentLight1 > maxLight1InWindow) maxLight1InWindow = currentLight1;
|
||||||
maxLightInWindow = currentLightLevel;
|
|
||||||
}
|
float currentLight2 = lightMeter2.readLightLevel();
|
||||||
|
if (currentLight2 > maxLight2InWindow) maxLight2InWindow = currentLight2;
|
||||||
#else
|
#else
|
||||||
float currentLightLevel = 0.0;
|
float currentLight1 = 0.0;
|
||||||
|
float currentLight2 = 0.0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool previousVibrationState = isVibrationActive;
|
bool previousDevice1State = isDevice1Active;
|
||||||
bool previousLightState = isLightActive;
|
bool previousDevice2State = isDevice2Active;
|
||||||
|
|
||||||
// Window Logic
|
// Window Logic
|
||||||
if (currentTime - lastWindowStartTime >= WINDOW_DURATION) {
|
if (currentTime - lastWindowStartTime >= WINDOW_DURATION) {
|
||||||
lastWindowStartTime = currentTime;
|
lastWindowStartTime = currentTime;
|
||||||
|
|
||||||
// 1. Process Vibration
|
// 1. Process Device 1 (Light 1)
|
||||||
#ifdef ENABLE_SENSORS
|
#ifdef ENABLE_SENSORS
|
||||||
noInterrupts();
|
bool light1WindowOn = (maxLight1InWindow > LIGHT_ACTIVATION_THRESHOLD);
|
||||||
unsigned long now = micros();
|
|
||||||
unsigned long duration = now - lastChangeTime;
|
|
||||||
lastChangeTime = now;
|
|
||||||
|
|
||||||
if (digitalRead(VIBRATION_PIN) == LOW) {
|
if (light1WindowOn) {
|
||||||
lowTimeAccumulator += duration;
|
light1ConsecutiveOn++;
|
||||||
|
light1ConsecutiveOff = 0;
|
||||||
} else {
|
} else {
|
||||||
highTimeAccumulator += duration;
|
light1ConsecutiveOff++;
|
||||||
|
light1ConsecutiveOn = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
vibrationTotalLow = lowTimeAccumulator;
|
if (light1ConsecutiveOn >= REQUIRED_CONSECUTIVE_WINDOWS && currentTime > WARMUP_DURATION) {
|
||||||
lowTimeAccumulator = 0;
|
isDevice1Active = true;
|
||||||
highTimeAccumulator = 0;
|
} else if (light1ConsecutiveOff >= REQUIRED_CONSECUTIVE_WINDOWS) {
|
||||||
interrupts();
|
isDevice1Active = false;
|
||||||
|
}
|
||||||
|
|
||||||
bool vibWindowOn = (vibrationTotalLow > VIBRATION_ACTIVE_THRESHOLD);
|
// 2. Process Device 2 (Light 2)
|
||||||
|
bool light2WindowOn = (maxLight2InWindow > LIGHT_ACTIVATION_THRESHOLD);
|
||||||
|
|
||||||
if (vibWindowOn) {
|
if (light2WindowOn) {
|
||||||
vibConsecutiveOn++;
|
light2ConsecutiveOn++;
|
||||||
vibConsecutiveOff = 0;
|
light2ConsecutiveOff = 0;
|
||||||
} else {
|
} else {
|
||||||
vibConsecutiveOff++;
|
light2ConsecutiveOff++;
|
||||||
vibConsecutiveOn = 0;
|
light2ConsecutiveOn = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vibConsecutiveOn >= REQUIRED_CONSECUTIVE_WINDOWS && currentTime > WARMUP_DURATION) {
|
if (light2ConsecutiveOn >= REQUIRED_CONSECUTIVE_WINDOWS && currentTime > WARMUP_DURATION) {
|
||||||
isVibrationActive = true;
|
isDevice2Active = true;
|
||||||
} else if (vibConsecutiveOff >= REQUIRED_CONSECUTIVE_WINDOWS) {
|
} else if (light2ConsecutiveOff >= REQUIRED_CONSECUTIVE_WINDOWS) {
|
||||||
isVibrationActive = false;
|
isDevice2Active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset Light Accumulators
|
||||||
|
maxLight1InWindow = 0.0;
|
||||||
|
maxLight2InWindow = 0.0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 2. Process Light
|
|
||||||
bool lightWindowOn = (maxLightInWindow > LIGHT_ACTIVATION_THRESHOLD);
|
|
||||||
|
|
||||||
if (lightWindowOn) {
|
|
||||||
lightConsecutiveOn++;
|
|
||||||
lightConsecutiveOff = 0;
|
|
||||||
} else {
|
|
||||||
lightConsecutiveOff++;
|
|
||||||
lightConsecutiveOn = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lightConsecutiveOn >= REQUIRED_CONSECUTIVE_WINDOWS && currentTime > WARMUP_DURATION) {
|
// Device 1 Notifications
|
||||||
isLightActive = true;
|
if (isDevice1Active != previousDevice1State) {
|
||||||
} else if (lightConsecutiveOff >= REQUIRED_CONSECUTIVE_WINDOWS) {
|
|
||||||
isLightActive = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset Light Accumulator
|
|
||||||
maxLightInWindow = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Device 1 (Vibration) Notifications
|
|
||||||
if (isVibrationActive != previousVibrationState) {
|
|
||||||
String message;
|
String message;
|
||||||
String title;
|
String title;
|
||||||
String priority;
|
String priority;
|
||||||
if (isVibrationActive) {
|
if (isDevice1Active) {
|
||||||
message = String(DEVICE1_NAME) + " started.";
|
message = String(DEVICE1_NAME) + " started.";
|
||||||
title = String(DEVICE1_NAME) + " START";
|
title = String(DEVICE1_NAME) + " START";
|
||||||
priority = "default";
|
priority = "default";
|
||||||
@ -349,18 +332,18 @@ void loop() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Device 2 (Light) Notifications
|
// Device 2 Notifications
|
||||||
if (isLightActive != previousLightState) {
|
if (isDevice2Active != previousDevice2State) {
|
||||||
String message;
|
String message;
|
||||||
String title;
|
String title;
|
||||||
String priority;
|
String priority;
|
||||||
if (isLightActive) {
|
if (isDevice2Active) {
|
||||||
message = String(DEVICE2_NAME) + " active.";
|
message = String(DEVICE2_NAME) + " started.";
|
||||||
title = String(DEVICE2_NAME) + " ACTIVE";
|
title = String(DEVICE2_NAME) + " START";
|
||||||
priority = "default";
|
priority = "default";
|
||||||
} else {
|
} else {
|
||||||
message = String(DEVICE2_NAME) + " inactive.";
|
message = String(DEVICE2_NAME) + " finished.";
|
||||||
title = String(DEVICE2_NAME) + " INACTIVE";
|
title = String(DEVICE2_NAME) + " END";
|
||||||
priority = "high";
|
priority = "high";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,10 +367,10 @@ void loop() {
|
|||||||
|
|
||||||
#ifdef ENABLE_DISPLAY
|
#ifdef ENABLE_DISPLAY
|
||||||
// Update display data
|
// Update display data
|
||||||
displayData[0] = String(DEVICE1_NAME) + ": " + (vibrationTotalLow > VIBRATION_ACTIVE_THRESHOLD ? "YES" : "NO");
|
displayData[0] = String(DEVICE1_NAME) + ": " + String(currentLight1, 0) + (currentLight1 > LIGHT_ACTIVATION_THRESHOLD ? " = ON" : " = OFF");
|
||||||
displayData[1] = "Vibra: " + String(isVibrationActive ? "OFF? " + String(vibConsecutiveOff) : "ON? " + String(vibConsecutiveOn)) + "/" + String(REQUIRED_CONSECUTIVE_WINDOWS);
|
displayData[1] = " " + String(isDevice1Active ? "OFF? " + String(light1ConsecutiveOff) : "ON? " + String(light1ConsecutiveOn)) + "/" + String(REQUIRED_CONSECUTIVE_WINDOWS);
|
||||||
displayData[2] = String(DEVICE2_NAME) + ": " + String(currentLightLevel, 0);
|
displayData[2] = String(DEVICE2_NAME) + ": " + String(currentLight2, 0) + (currentLight2 > LIGHT_ACTIVATION_THRESHOLD ? " = ON" : " = OFF");
|
||||||
displayData[3] = "Light: " + String(isLightActive ? "OFF? " + String(lightConsecutiveOff) : "ON? " + String(lightConsecutiveOn)) + "/" + String(REQUIRED_CONSECUTIVE_WINDOWS);
|
displayData[3] = " " + String(isDevice2Active ? "OFF? " + String(light2ConsecutiveOff) : "ON? " + String(light2ConsecutiveOn)) + "/" + String(REQUIRED_CONSECUTIVE_WINDOWS);
|
||||||
displayDataLines = 4;
|
displayDataLines = 4;
|
||||||
|
|
||||||
// Update display
|
// Update display
|
||||||
@ -426,7 +409,7 @@ void updateDisplay() {
|
|||||||
|
|
||||||
// Draw Device 1 Indicator (Top)
|
// Draw Device 1 Indicator (Top)
|
||||||
display.drawRect(rectX, rectY1, rectWidth, rectHeight, WHITE);
|
display.drawRect(rectX, rectY1, rectWidth, rectHeight, WHITE);
|
||||||
if (isVibrationActive) {
|
if (isDevice1Active) {
|
||||||
int innerWidth = rectWidth - 4;
|
int innerWidth = rectWidth - 4;
|
||||||
int step = (millis() / 150) % (innerWidth + 1);
|
int step = (millis() / 150) % (innerWidth + 1);
|
||||||
display.fillRect(rectX + 2, rectY1 + 2, step, rectHeight - 4, WHITE);
|
display.fillRect(rectX + 2, rectY1 + 2, step, rectHeight - 4, WHITE);
|
||||||
@ -434,7 +417,7 @@ void updateDisplay() {
|
|||||||
|
|
||||||
// Draw Device 2 Indicator (Bottom)
|
// Draw Device 2 Indicator (Bottom)
|
||||||
display.drawRect(rectX, rectY2, rectWidth, rectHeight, WHITE);
|
display.drawRect(rectX, rectY2, rectWidth, rectHeight, WHITE);
|
||||||
if (isLightActive) {
|
if (isDevice2Active) {
|
||||||
int innerWidth = rectWidth - 4;
|
int innerWidth = rectWidth - 4;
|
||||||
int step = (millis() / 150) % (innerWidth + 1);
|
int step = (millis() / 150) % (innerWidth + 1);
|
||||||
display.fillRect(rectX + 2, rectY2 + 2, step, rectHeight - 4, WHITE);
|
display.fillRect(rectX + 2, rectY2 + 2, step, rectHeight - 4, WHITE);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user