|
32 | 32 | #include <WiFi.h>
|
33 | 33 | #include <WebServer.h>
|
34 | 34 |
|
35 |
| - // --------------------------------------------------------------------- |
36 |
| - // WIFI CREDENTIALS - EDIT THESE |
37 |
| - // --------------------------------------------------------------------- |
| 35 | + |
| 36 | + // WIFI CREDENTIALS - EDIT THESE |
38 | 37 | const char* ssid = "YOUR_SSID";
|
39 | 38 | const char* password = "YOUR_PASSWORD";
|
40 | 39 |
|
| 40 | + |
41 | 41 | // Create the WebServer on port 80
|
42 | 42 | WebServer server(80);
|
43 | 43 |
|
44 |
| - // --------------------------------------------------------------------- |
45 | 44 | // OLED SETUP
|
46 |
| - // --------------------------------------------------------------------- |
47 | 45 | #define SCREEN_WIDTH 128
|
48 | 46 | #define SCREEN_HEIGHT 64
|
49 | 47 | #define OLED_RESET -1 // Use -1 if no reset pin
|
|
53 | 51 | // Second OLED at address 0x3D (shows the graph/history)
|
54 | 52 | Adafruit_SSD1306 display2(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
55 | 53 |
|
56 |
| - // --------------------------------------------------------------------- |
57 | 54 | // PINS
|
58 |
| - // --------------------------------------------------------------------- |
59 | 55 | #define POT_PIN 34 // ADC input from potentiometer (for live target temperature)
|
60 | 56 | #define ONE_WIRE_BUS 4 // DS18B20 data line (temperature sensor)
|
61 | 57 | #define HEATER_PIN 26 // Output to control MOSFET that switches the heater
|
62 | 58 | #define BUTTON_1 13 // Button used to toggle lock/unlock mode
|
63 | 59 | #define BUTTON_2 12 // Used to toggle auto mode
|
64 | 60 |
|
65 |
| - // --------------------------------------------------------------------- |
66 | 61 | // DS18B20 SETUP
|
67 |
| - // --------------------------------------------------------------------- |
68 | 62 | OneWire oneWire(ONE_WIRE_BUS); // Initialize OneWire on the defined pin
|
69 | 63 | DallasTemperature sensors(&oneWire); // Pass OneWire to the DallasTemperature library
|
70 | 64 |
|
71 |
| - // --------------------------------------------------------------------- |
72 | 65 | // 6-HOUR HISTORY (1080 points => 6hr, 1 every 20s)
|
73 |
| - // We'll only show last 30 min = 90 points on OLED #2 |
74 |
| - // --------------------------------------------------------------------- |
75 | 66 | static const int HISTORY_LEN = 1080;
|
76 | 67 | static const int OLED_HISTORY_LEN = 90; // Last 30 minutes
|
77 | 68 |
|
|
89 | 80 | // For button debouncing (to detect state changes)
|
90 | 81 | static bool lastButtonState = true;
|
91 | 82 |
|
92 |
| - // --- SHT30 object --- |
93 | 83 | // Object for the SHT30 sensor that reads ambient temperature and humidity.
|
94 | 84 | Adafruit_SHT31 sht3x = Adafruit_SHT31();
|
95 | 85 |
|
|
106 | 96 | bool enableWifi = false;
|
107 | 97 |
|
108 | 98 |
|
109 |
| - // --------------------------------------------------------------------- |
| 99 | + |
110 | 100 | // Draw text center with a box on the OLED display
|
111 |
| - // --------------------------------------------------------------------- |
112 | 101 | void drawTextCenterWithBox(Adafruit_SSD1306 &disp, int16_t y, const char *text, uint8_t size)
|
113 | 102 | {
|
114 | 103 | disp.setTextSize(size);
|
|
126 | 115 | disp.print(text);
|
127 | 116 | }
|
128 | 117 |
|
129 |
| - // --------------------------------------------------------------------- |
| 118 | + |
| 119 | + |
130 | 120 | // STAR FIELD (for splash animation)
|
131 |
| - // --------------------------------------------------------------------- |
132 | 121 | #define NUM_STARS 30
|
133 | 122 | static int starX[NUM_STARS]; // X coordinates for stars
|
134 | 123 | static int starY[NUM_STARS]; // Y coordinates for stars
|
|
144 | 133 | }
|
145 | 134 |
|
146 | 135 |
|
147 |
| - // Draw star field and optional splash text on a display |
| 136 | + |
| 137 | + // Draw star field and splash text on a display |
148 | 138 | void drawStarsAndSplash(Adafruit_SSD1306 &disp, bool drawSplash, int offset)
|
149 | 139 | {
|
150 | 140 | disp.clearDisplay();
|
|
167 | 157 | }
|
168 | 158 | }
|
169 | 159 |
|
170 |
| - // A similar splash function for the second OLED with different text |
| 160 | + |
| 161 | + |
| 162 | + // Second OLED splash function |
171 | 163 | void drawStarsAndSplash2(Adafruit_SSD1306 &disp, bool drawSplash, int offset)
|
172 | 164 | {
|
173 | 165 | disp.clearDisplay();
|
|
186 | 178 | }
|
187 | 179 | }
|
188 | 180 |
|
189 |
| - // --------------------------------------------------------------------- |
| 181 | + |
| 182 | + |
190 | 183 | // GRAPH CONSTANTS (for OLED #2: graphing the last 30 min data)
|
191 |
| - // --------------------------------------------------------------------- |
192 | 184 | static const int GRAPH_LEFT = 20;
|
193 | 185 | static const int GRAPH_RIGHT = 127;
|
194 | 186 | static const int GRAPH_TOP = 9;
|
|
214 | 206 | return (int)(y + 0.5f);
|
215 | 207 | }
|
216 | 208 |
|
217 |
| - // --------------------------------------------------------------------- |
| 209 | + |
| 210 | + |
218 | 211 | // WEB HANDLERS
|
219 |
| - // --------------------------------------------------------------------- |
220 | 212 |
|
221 | 213 | // Handler to set the target temperature from the browser
|
222 | 214 | void handleSetTarget() {
|
|
237 | 229 | server.send(400, "text/plain", "Missing 'temp' parameter!");
|
238 | 230 | }
|
239 | 231 | }
|
240 |
| - |
| 232 | + |
241 | 233 | // Main webpage handler: Displays system status and sensor readings.
|
242 | 234 | void handleRoot()
|
243 | 235 | {
|
|
498 | 490 | }
|
499 | 491 |
|
500 | 492 |
|
501 |
| - // --------------------------------------------------------------------- |
| 493 | + |
502 | 494 | // SETUP
|
503 |
| - // --------------------------------------------------------------------- |
504 | 495 | void setup()
|
505 | 496 | {
|
506 | 497 | Serial.begin(115200); // Start serial communication for debugging
|
|
515 | 506 | while(true);
|
516 | 507 | }
|
517 | 508 |
|
518 |
| - // --------------- |
519 | 509 | // WiFi Selection
|
520 |
| - // --------------- |
521 | 510 | pinMode(BUTTON_1, INPUT_PULLUP);
|
522 | 511 | pinMode(BUTTON_2, INPUT_PULLUP);
|
523 | 512 |
|
|
651 | 640 |
|
652 | 641 | Wire.begin(); // Start I2C for OLEDs and SHT30
|
653 | 642 |
|
654 |
| - // --- NEW: SHT30 begin --- |
655 | 643 | // Try to initialize the SHT30 sensor at its default address (0x44); if it fails, try 0x45.
|
656 | 644 | if(!sht3x.begin(0x44)) {
|
657 | 645 | Serial.println("SHT30 not found at 0x44? Trying 0x45...");
|
|
708 | 696 | Serial.println("ESP32 setup complete.");
|
709 | 697 | }
|
710 | 698 |
|
711 |
| - // --------------------------------------------------------------------- |
| 699 | + |
| 700 | + |
712 | 701 | // LOOP
|
713 |
| - // --------------------------------------------------------------------- |
714 | 702 | void loop()
|
715 | 703 | {
|
716 | 704 | // Process any incoming web requests
|
|
764 | 752 | dewPointF = -999.0;
|
765 | 753 | }
|
766 | 754 |
|
| 755 | + |
767 | 756 | // --- AUTO MODE BUTTON HANDLING ---
|
768 | 757 | // Read the auto button state
|
769 | 758 | bool currentAutoButtonState = digitalRead(BUTTON_2);
|
|
811 | 800 | lastSampleTime = now;
|
812 | 801 | }
|
813 | 802 |
|
814 |
| - // ----------------------- |
| 803 | + |
815 | 804 | // OLED #1: Display the target and current DS18B20 temperature,
|
816 | 805 | // plus the lock status, auto mode indicator, and heater state.
|
817 |
| - // ----------------------- |
818 | 806 | display1.clearDisplay();
|
819 | 807 | // Draw a vertical divider between the left (target) and right (current) sections
|
820 | 808 | display1.drawLine(59, 0, 59, 33, WHITE);
|
|
866 | 854 | display1.display();
|
867 | 855 |
|
868 | 856 |
|
869 |
| - // ----------------------- |
| 857 | + |
870 | 858 | // OLED #2: Display the last 30 minutes of temperature history as a graph.
|
871 |
| - // ----------------------- |
872 | 859 | display2.clearDisplay();
|
873 | 860 | display2.setTextSize(1);
|
874 | 861 | display2.setCursor(20, 0);
|
|
0 commit comments