Class Monitor

Class Monitor

Σχεδιάζουμε και δημιουργούμε έναν σταθμό ο οποίος θα μετράει τις συνθήκες στις σχολικές τάξεις και θα τις καταγράφει σε μια διαδικτυακή βάση δεδομένων. Ο σταθμός θα μπορεί να βρίσκεται σε κάθε σχολική αίθουσα και να καταγράφει συνθήκες όπως:

  • Θερμοκρασία (βαθμοί κελσίου)
  • Υγρασία (ποσοστό %)
  • Φωτεινότητα χώρου (Lux)
  • Αιωρούμενα μικροσωματίδια (µg/m³)

Τα δεδομένα θα καταγράφονται ανά 10 λεπτά σε διαδικτυακή βάση δεδομένων (ThingSpeak) ενώ θα αναπτύξουμε και εφαρμογή για κινητά τηλέφωνα η οποία θα μας δίνει τη δυνατότητα να παρακολουθούμε τα δεδομένα από όλες τις σχολικές αίθουσες που έχουν εγκαταστήσει το Class Monitor.

Εκπαιδευτικοί Στόχοι

  1. Εισαγωγή στις Βασικές Έννοιες της Μετρητικής Τεχνολογίας
    • Οι μαθητές θα εξοικειωθούν με τις έννοιες της μέτρησης φυσικών παραμέτρων, όπως η θερμοκρασία, η υγρασία, η φωτεινότητα και τα αιωρούμενα μικροσωματίδια.
  2. Καλλιέργεια Ψηφιακών Δεξιοτήτων
    • Οι μαθητές θα αποκτήσουν γνώσεις σχετικά με τη χρήση αισθητήρων, μικροελεγκτών και IoT πλατφορμών για τη συλλογή και επεξεργασία δεδομένων.
  3. Ενίσχυση της Επίλυσης Προβλημάτων μέσω Τεχνολογίας
    • Οι μαθητές θα σχεδιάσουν, θα κατασκευάσουν και θα προγραμματίσουν ένα σύστημα παρακολούθησης, ενισχύοντας τη δημιουργική σκέψη και την ικανότητα επίλυσης προβλημάτων.
  4. Ανάπτυξη Δεξιοτήτων Συνεργασίας
    • Μέσω ομαδικής εργασίας, οι μαθητές θα συνεργαστούν για την ολοκλήρωση του project, καλλιεργώντας δεξιότητες επικοινωνίας και συντονισμού.
  5. Αύξηση της Περιβαλλοντικής Ευαισθητοποίησης
    • Οι μαθητές θα κατανοήσουν τη σημασία της ποιότητας του εσωτερικού περιβάλλοντος στη μάθηση και την υγεία, ενισχύοντας την ευαισθητοποίησή τους για περιβαλλοντικά θέματα.
  6. Εισαγωγή στις Βασικές Έννοιες Διαχείρισης Δεδομένων
    • Οι μαθητές θα μάθουν πώς να αποθηκεύουν και να αναλύουν δεδομένα χρησιμοποιώντας πλατφόρμες όπως το ThingSpeak, κατανοώντας τη σημασία της οπτικοποίησης δεδομένων.
  7. Ανάπτυξη Εφαρμογής για Κινητές Συσκευές
    • Οι μαθητές θα εξοικειωθούν με την ανάπτυξη εφαρμογών για κινητά τηλέφωνα, αποκτώντας πρακτική εμπειρία στη σύνδεση συσκευών IoT με φιλικές προς τον χρήστη εφαρμογές.
  8. Καλλιέργεια Επιστημονικής Σκέψης και Έρευνας
    • Οι μαθητές θα εφαρμόσουν επιστημονικές μεθόδους για τη συλλογή, ανάλυση και ερμηνεία δεδομένων, αξιολογώντας τον αντίκτυπο διαφορετικών παραμέτρων στις σχολικές συνθήκες.
  9. Προώθηση Καινοτομίας και Επιχειρηματικής Σκέψης
    • Οι μαθητές θα διερευνήσουν πώς η τεχνολογία IoT μπορεί να εφαρμοστεί σε πραγματικές συνθήκες, ενθαρρύνοντας τη σκέψη γύρω από καινοτόμες λύσεις.
  10. Υποστήριξη της Εννοιολογικής Κατανόησης STEM
    • Το project ενσωματώνει στοιχεία από τις θετικές επιστήμες (Φυσική, Μαθηματικά), την τεχνολογία, τη μηχανική και την επιστήμη των υπολογιστών, ενισχύοντας την πολύπλευρη μάθηση στο STEM.

Λίστα υλικών

Σκοπεύουμε να εγκαταστήσουμε αρχικά 5 μονάδες Class Monitor σε 2 διαφορετικά σχολεία της Φλώρινας. Για την υλοποίηση του κάθε σταθμού μέτρησης θα χρειαστούμε τα παρακάτω υλικά:

  • ESP32 Development Board – Κόστος 10 ευρώ
  • Αισθητήρας θερμοκρασίας – υγρασίας DHT11 – Κόστος 2 ευρώ
  • Αισθητήρας σωματιδίων Sharp GP2Y1010AU0F – Κόστος 18 ευρώ
  • Αισθητήρας φωτεινότητας I2C – TSL25911 – Κόστος 5 ευρώ
  • Τροφοδοτικό USB – Κόστος 10 ευρώ

Για την εκτύπωση των περιβλημάτων θα χρειαστούμε και 1kg PLA με κόστος 20 ευρώ.

Το συνολικό κόστος για τους 5 σταθμούς θα είναι: 5 Χ 45 + 20 = 245 ευρώ.

Εγκατάσταση βιβλιοθηκών

Αρχικά θα πρέπει να εγκαταστήσουμε στο Arduino IDE τα ESP32 boards
Επίσης θα χρειαστούμε την βιβλιοθήκη DHT11 για τον αισθητήρα θερμοκρασίας και υγρασίας

Προγραμματισμός

// Libraries for ESP
#include <WiFi.h>
#include <HTTPClient.h>

// Library for DHT11 sensor
#include <DHT11.h>

// Libraries for Light sensor
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_TSL2591.h"

//DHT11 object
DHT11 dht11(2);

//Light sensor object
Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591); // pass in a number for the sensor identifier (for your use later)

//Constants for Dust Sensor
#define COV_RATIO 0.2      
#define NO_DUST_VOLTAGE 400
#define SYS_VOLTAGE 3300           
const int iled = 23;
const int vout = 0;  

//Wifi settings
const char *ssid = "wifi ssd";
const char *password = "wifi password";

// ThingSpeak settings
const char* server = "http://api.thingspeak.com";
const char* apiKey = "Thing Speak API"; // Replace with your ThingSpeak Write API Key

//Variables for dust sensor
float density, voltage;
int adcvalue;


/**************************************************************************/
/*
    Displays some basic information on this sensor from the unified
    sensor API sensor_t type (see Adafruit_Sensor for more information)
*/
/**************************************************************************/
void displaySensorDetails(void)
{
  sensor_t sensor;
  tsl.getSensor(&sensor);
  Serial.println(F("------------------------------------"));
  Serial.print  (F("Sensor:       ")); Serial.println(sensor.name);
  Serial.print  (F("Driver Ver:   ")); Serial.println(sensor.version);
  Serial.print  (F("Unique ID:    ")); Serial.println(sensor.sensor_id);
  Serial.print  (F("Max Value:    ")); Serial.print(sensor.max_value); Serial.println(F(" lux"));
  Serial.print  (F("Min Value:    ")); Serial.print(sensor.min_value); Serial.println(F(" lux"));
  Serial.print  (F("Resolution:   ")); Serial.print(sensor.resolution, 4); Serial.println(F(" lux"));  
  Serial.println(F("------------------------------------"));
  Serial.println(F(""));
  delay(500);
}

/**************************************************************************/
/*
    Configures the gain and integration time for the TSL2591
*/
/**************************************************************************/
void configureSensor(void)
{
  // You can change the gain on the fly, to adapt to brighter/dimmer light situations
  //tsl.setGain(TSL2591_GAIN_LOW);    // 1x gain (bright light)
  tsl.setGain(TSL2591_GAIN_MED);      // 25x gain
  //tsl.setGain(TSL2591_GAIN_HIGH);   // 428x gain
  
  // Changing the integration time gives you a longer time over which to sense light
  // longer timelines are slower, but are good in very low light situtations!
  //tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS);  // shortest integration time (bright light)
  // tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS);
  tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS);
  // tsl.setTiming(TSL2591_INTEGRATIONTIME_400MS);
  // tsl.setTiming(TSL2591_INTEGRATIONTIME_500MS);
  // tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS);  // longest integration time (dim light)

  /* Display the gain and integration time for reference sake */  
  Serial.println(F("------------------------------------"));
  Serial.print  (F("Gain:         "));
  tsl2591Gain_t gain = tsl.getGain();
  switch(gain)
  {
    case TSL2591_GAIN_LOW:
      Serial.println(F("1x (Low)"));
      break;
    case TSL2591_GAIN_MED:
      Serial.println(F("25x (Medium)"));
      break;
    case TSL2591_GAIN_HIGH:
      Serial.println(F("428x (High)"));
      break;
    case TSL2591_GAIN_MAX:
      Serial.println(F("9876x (Max)"));
      break;
  }
  Serial.print  (F("Timing:       "));
  Serial.print((tsl.getTiming() + 1) * 100, DEC); 
  Serial.println(F(" ms"));
  Serial.println(F("------------------------------------"));
  Serial.println(F(""));
}

/**************************************************************************/
/*
    Shows how to perform a basic read on visible, full spectrum or
    infrared light (returns raw 16-bit ADC values)
*/
/**************************************************************************/
void simpleRead(void)
{
  // Simple data read example. Just read the infrared, fullspecrtrum diode 
  // or 'visible' (difference between the two) channels.
  // This can take 100-600 milliseconds! Uncomment whichever of the following you want to read
  uint16_t x = tsl.getLuminosity(TSL2591_VISIBLE);
  //uint16_t x = tsl.getLuminosity(TSL2591_FULLSPECTRUM);
  //uint16_t x = tsl.getLuminosity(TSL2591_INFRARED);

  Serial.print(F("[ ")); Serial.print(millis()); Serial.print(F(" ms ] "));
  Serial.print(F("Luminosity: "));
  Serial.println(x, DEC);
}

/**************************************************************************/
/*
    Show how to read IR and Full Spectrum at once and convert to lux
*/
/**************************************************************************/
void advancedRead(void)
{
  // More advanced data read example. Read 32 bits with top 16 bits IR, bottom 16 bits full spectrum
  // That way you can do whatever math and comparisons you want!
  uint32_t lum = tsl.getFullLuminosity();
  uint16_t ir, full;
  ir = lum >> 16;
  full = lum & 0xFFFF;
  Serial.print(F("[ ")); Serial.print(millis()); Serial.print(F(" ms ] "));
  Serial.print(F("IR: ")); Serial.print(ir);  Serial.print(F("  "));
  Serial.print(F("Full: ")); Serial.print(full); Serial.print(F("  "));
  Serial.print(F("Visible: ")); Serial.print(full - ir); Serial.print(F("  "));
  Serial.print(F("Lux: ")); Serial.println(tsl.calculateLux(full, ir), 6);
}

/**************************************************************************/
/*
    Performs a read using the Adafruit Unified Sensor API.
*/
/**************************************************************************/
void unifiedSensorAPIRead(void)
{
  /* Get a new sensor event */ 
  sensors_event_t event;
  tsl.getEvent(&event);
 
  /* Display the results (light is measured in lux) */
  Serial.print(F("[ ")); Serial.print(event.timestamp); Serial.print(F(" ms ] "));
  if ((event.light == 0) |
      (event.light > 4294966000.0) | 
      (event.light <-4294966000.0))
  {
    /* If event.light = 0 lux the sensor is probably saturated */
    /* and no reliable data could be generated! */
    /* if event.light is +/- 4294967040 there was a float over/underflow */
    Serial.println(F("Invalid data (adjust gain or timing)"));
  }
  else
  {
    Serial.print(event.light); Serial.println(F(" lux"));
  }
}

int Filter(int m)
{
  static int flag_first = 0, _buff[10], sum;
  const int _buff_max = 10;
  int i;
  
  if(flag_first == 0)
  {
    flag_first = 1;
    for(i = 0, sum = 0; i < _buff_max; i++)
    {
      _buff[i] = m;
      sum += _buff[i];
    }
    return m;
  }
  else
  {
    sum -= _buff[0];
    for(i = 0; i < (_buff_max - 1); i++)
    {
      _buff[i] = _buff[i + 1];
    }
    _buff[9] = m;
    sum += _buff[9];
    
    i = sum / 10.0;
    return i;
  }
}

void sendDataToThingSpeak(float temperature, float humidity, float lux, float dustConcentration) {
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    String url = String(server) + "/update?api_key=" + apiKey +
                 "&field1=" + String(temperature) +
                 "&field2=" + String(humidity) +
                 "&field3=" + String(lux) +
                 "&field4=" + String(dustConcentration);

    http.begin(url);
    int httpResponseCode = http.GET();

    if (httpResponseCode > 0) {
      Serial.print("ThingSpeak Response: ");
      Serial.println(httpResponseCode);
    } else {
      Serial.print("Error sending data: ");
      Serial.println(http.errorToString(httpResponseCode).c_str());
    }

    http.end();
  } else {
    Serial.println("WiFi Disconnected. Unable to send data to ThingSpeak.");
  }
}


void setup() {
  //Set the mode of the led pin of the dust sensor to output
  pinMode(iled, OUTPUT);
  digitalWrite(iled, LOW);

  //Start serial communication for debugging
  Serial.begin(115200);

  // First step is to configure WiFi STA and connect in order to get the current time and date.
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" CONNECTED");

  //Start the light sensor
  Serial.println(F("Starting Adafruit TSL2591 Test!"));
  if (tsl.begin()) {
    Serial.println(F("Found a TSL2591 sensor"));
  } else {
    Serial.println(F("No sensor found ... check your wiring?"));
    while (1);
  }
  // Display some basic information on this sensor 
  displaySensorDetails();
  // Configure the light sensor 
  configureSensor();
}



void loop() {
  //Run every 10 minutes
  delay(600000);
  
  // Get light data
  uint32_t lum = tsl.getFullLuminosity();
  uint16_t ir = lum >> 16;
  uint16_t full = lum & 0xFFFF;
  float lux = tsl.calculateLux(full, ir);

  // Get temperature and humidity
  int temperature = 0, humidity = 0;
  int result = dht11.readTemperatureHumidity(temperature, humidity);

  // Get dust concentration
  digitalWrite(iled, HIGH);
  delayMicroseconds(280);
  adcvalue = analogRead(vout);
  digitalWrite(iled, LOW);

  adcvalue = Filter(adcvalue);
  voltage = (SYS_VOLTAGE / 1024.0) * adcvalue * 11;
  if (voltage >= NO_DUST_VOLTAGE) {
    voltage -= NO_DUST_VOLTAGE;
    density = voltage * COV_RATIO;
  } else {
    density = 0;
  }

  // Print data to Serial Monitor
  Serial.print("Temperature: "); Serial.print(temperature-2); Serial.print(" °C\t");
  Serial.print("Humidity: "); Serial.print(humidity); Serial.print(" %\t");
  Serial.print("Lux: "); Serial.print(lux); Serial.print(" lx\t");
  Serial.print("Dust: "); Serial.print(density); Serial.println(" µg/m³");

  // Send data to ThingSpeak
  if (result == 0) {
    sendDataToThingSpeak(temperature-2, humidity, lux, density);
  } else {
    Serial.println("Error reading DHT11 sensor data.");
  }  

}

Δεδομένα

Αυτή τη στιγμή έχουμε εγκαταστήσει ένα Class Monitor στο εργαστήριο ρομποτικής “Μικροί Χάκερ” του Πειραματικού Δημοτικού Σχολείου Φλώρινας το οποίο μετράει τα δεδομένα κάθε 10 λεπτά. Σημειώνουμε πως ο αισθητήρας αιωρούμενων σωματιδίων προς το παρόν δεν μας επιστρέφει δεδομένα λόγω κάποιου τεχνικού προβλήματος που προσπαθούμε να λύσουμε. Μπορείτε να δείτε τα δεδομένα εδώ: https://thingspeak.mathworks.com/channels/2813296

Σχόλια

Δεν υπάρχουν ακόμη σχόλια. Γιατί δεν ξεκινάτε τη συζήτηση;

Αφήστε μια απάντηση