Untitled
unknown
plain_text
5 months ago
7.5 kB
7
Indexable
#include <OneWire.h> // Library for talking to temp sensors #include <DallasTemperature.h> // Library for Dallas temp sensors #include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> // Graphics support for OLED #include <Adafruit_SSD1306.h> // OLED display library #include <math.h> // Math functions #define ONE_WIRE_BUS 2 // Pin for OneWire data OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); #define SCREEN_WIDTH 128 // OLED display width #define SCREEN_HEIGHT 32 // OLED display height #define OLED_RESET -1 // OLED reset pin (not used) #define SCREEN_ADDRESS 0x3C // OLED I2C address Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); unsigned long lastTempUpdateTime = 0; // Last time temp updated float temperature, celsius, fahrenheit; // Temp variables bool anomalies = false; // Flag for anomaly detection float baseline = 0; // Baseline temp to compare against int baselineCounter = 0; // Number of readings for baseline int sprayPin = 3; // Pin controlling spray mechanism bool configuring = true; // Flag for baseline config mode float temperatureReadings[10]; // Store last 10 temp readings int readingIndex = 0; // Index for temp readings bool readingsFilled = false; // Flag for when all reading slots filled void setup() { pinMode(sprayPin, OUTPUT); // Set spray pin as output Serial.begin(9600); // Start serial comm for debug sensors.begin(); // Init temp sensor if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { // Init display Serial.println(F("SSD1306 allocation failed")); // Print error if display init fails for (;;); // Loop forever if display fails } display.display(); // Show splash screen delay(2000); // Wait 2 secs display.clearDisplay(); // Clear splash screen display.setTextSize(3); // Set text size for initial screen display.setTextColor(SSD1306_WHITE); // Set text color to white display.setCursor(10, 0); // Set cursor position for display text } void loop() { unsigned long currentMillis = millis(); // Get current time in ms if (configuring) { // If in baseline config mode display.clearDisplay(); // Clear display before showing new text display.setTextSize(1); // Smaller text size for config msg display.setCursor(0, 0); // Set cursor pos for config msg display.print("CONFIGURING..."); // Display config msg display.setCursor(0, 20); // Set cursor for second line display.print("HANDS OFF"); // Display instructions during setup display.display(); // Update display with config msg int progress = (baselineCounter * 16) / 10; // Calc progress of config (scaled) for (int i = 0; i < progress; i++) { // Loop to show progress bar display.setCursor(i * 8, 30); // Set cursor for each progress step display.print("%"); // Show progress indicator } display.display(); // Update display with progress if (currentMillis - lastTempUpdateTime >= 1000) { // If 1 sec passed since update updateTemperatureReadings(); // Get new temp reading baseline += temperature; // Add current temp to baseline total baselineCounter++; // Increment baseline counter lastTempUpdateTime = currentMillis; // Update last temp time } if (baselineCounter == 10) { // If 10 readings taken baseline /= 10; // Calc avg baseline temp Serial.print("Baseline (K): "); // Print baseline temp to serial Serial.println(baseline, 2); // Print baseline value w/ 2 decimals configuring = false; // End config mode display.clearDisplay(); // Clear display after config } } else { // Normal operation mode if (currentMillis - lastTempUpdateTime >= 1000) { // If 1 sec passed since last update updateTemperatureReadings(); // Get new temp reading for (int i = 9; i > 0; i--) { // Shift readings in array to make room for new one temperatureReadings[i] = temperatureReadings[i - 1]; // Move previous reading to next index } temperatureReadings[0] = temperature; // Store latest temp at start of array if (readingIndex < 10) { // If readings array not full readingIndex++; // Increment reading index } else { readingsFilled = true; // Mark readings as filled if all slots used } lastTempUpdateTime = currentMillis; // Update last temp update time checkForAnomalies(); // Check for anomalies in temp readings } if (anomalies) { // If anomaly detected displayAnomalyScreen(); // Show anomaly info on screen } else { // If no anomaly displayTemperatureScreen(); // Show regular temp info } } delay(100); // Short delay to smooth loop, avoid rapid updates } // Function to update temp readings from sensor void updateTemperatureReadings() { sensors.requestTemperatures(); // Request temp from sensor celsius = sensors.getTempCByIndex(0); // Get temp in Celsius fahrenheit = sensors.getTempFByIndex(0); // Get temp in Fahrenheit temperature = celsius + 273.15; // Convert Celsius to Kelvin Serial.println(temperature); // Print temp (in Kelvin) for debug } // Function to check for anomalies in temp readings vs baseline void checkForAnomalies() { if (readingsFilled) { // Only check if all slots full float sum = 0; // Sum of temp readings float sumSquares = 0; // Sum of squares of temp readings for (int i = 0; i < 10; i++) { // Loop through all readings sum += temperatureReadings[i]; // Add each reading to sum sumSquares += pow(temperatureReadings[i], 2); // Add square of each reading } float mean = sum / 10; // Calc mean of readings float variance = (sumSquares / 10) - pow(mean, 2); // Calc variance float stdDeviation = sqrt(variance); // Calc standard deviation if (abs(temperature - baseline) > 2 * stdDeviation && temperature > baseline) { // If temp deviates a lot from baseline anomalies = true; // Set anomaly flag digitalWrite(sprayPin, 1); // Activate spray } else { // If no big deviation anomalies = false; // Clear anomaly flag digitalWrite(sprayPin, 0); // Deactivate spray } Serial.print("Anomaly: "); // Print anomaly status Serial.println(anomalies ? "True" : "False"); // Print if anomaly detected } } // Function to display current temp readings on screen void displayTemperatureScreen() { display.clearDisplay(); // Clear display before new info display.setTextSize(2); // Set text size for temp info display.setCursor(0, 0); // Set cursor for Kelvin info display.print("K:"); // Label for Kelvin temp display.print(temperature, 2); // Show temp in Kelvin w/ 2 decimals display.setCursor(0, 16); // Set cursor for Celsius info display.print("C:"); // Label for Celsius temp display.print(celsius, 2); // Show temp in Celsius w/ 2 decimals display.display(); // Update display with temp info } // Function to display anomaly info on screen void displayAnomalyScreen() { display.clearDisplay(); // Clear display before anomaly info display.setTextSize(1); // Set text size for anomaly display.setCursor(0, 0); // Set cursor for baseline display.print("Baseline:"); // Label for baseline temp display.print(baseline, 2); // Show baseline temp w/ 2 decimals display.setCursor(0, 16); // Set cursor for current display.print("->"); // Arrow pointing to current temp display.print(temperature, 2); // Show current temp w/ 2 decimals display.display(); // Update display with anomaly info }
Editor is loading...
Leave a Comment