Σχεδιάζουμε και δημιουργούμε έναν σταθμό ο οποίος θα μετράει τις συνθήκες στις σχολικές τάξεις και θα τις καταγράφει σε μια διαδικτυακή βάση δεδομένων. Ο σταθμός θα μπορεί να βρίσκεται σε κάθε σχολική αίθουσα και να καταγράφει συνθήκες όπως:
- Θερμοκρασία (βαθμοί κελσίου)
- Υγρασία (ποσοστό %)
- Φωτεινότητα χώρου (Lux)
- Αιωρούμενα μικροσωματίδια (µg/m³)
Τα δεδομένα θα καταγράφονται ανά 10 λεπτά σε διαδικτυακή βάση δεδομένων (ThingSpeak) ενώ θα αναπτύξουμε και εφαρμογή για κινητά τηλέφωνα η οποία θα μας δίνει τη δυνατότητα να παρακολουθούμε τα δεδομένα από όλες τις σχολικές αίθουσες που έχουν εγκαταστήσει το Class Monitor.
Εκπαιδευτικοί Στόχοι
- Εισαγωγή στις Βασικές Έννοιες της Μετρητικής Τεχνολογίας
- Οι μαθητές θα εξοικειωθούν με τις έννοιες της μέτρησης φυσικών παραμέτρων, όπως η θερμοκρασία, η υγρασία, η φωτεινότητα και τα αιωρούμενα μικροσωματίδια.
- Καλλιέργεια Ψηφιακών Δεξιοτήτων
- Οι μαθητές θα αποκτήσουν γνώσεις σχετικά με τη χρήση αισθητήρων, μικροελεγκτών και IoT πλατφορμών για τη συλλογή και επεξεργασία δεδομένων.
- Ενίσχυση της Επίλυσης Προβλημάτων μέσω Τεχνολογίας
- Οι μαθητές θα σχεδιάσουν, θα κατασκευάσουν και θα προγραμματίσουν ένα σύστημα παρακολούθησης, ενισχύοντας τη δημιουργική σκέψη και την ικανότητα επίλυσης προβλημάτων.
- Ανάπτυξη Δεξιοτήτων Συνεργασίας
- Μέσω ομαδικής εργασίας, οι μαθητές θα συνεργαστούν για την ολοκλήρωση του project, καλλιεργώντας δεξιότητες επικοινωνίας και συντονισμού.
- Αύξηση της Περιβαλλοντικής Ευαισθητοποίησης
- Οι μαθητές θα κατανοήσουν τη σημασία της ποιότητας του εσωτερικού περιβάλλοντος στη μάθηση και την υγεία, ενισχύοντας την ευαισθητοποίησή τους για περιβαλλοντικά θέματα.
- Εισαγωγή στις Βασικές Έννοιες Διαχείρισης Δεδομένων
- Οι μαθητές θα μάθουν πώς να αποθηκεύουν και να αναλύουν δεδομένα χρησιμοποιώντας πλατφόρμες όπως το ThingSpeak, κατανοώντας τη σημασία της οπτικοποίησης δεδομένων.
- Ανάπτυξη Εφαρμογής για Κινητές Συσκευές
- Οι μαθητές θα εξοικειωθούν με την ανάπτυξη εφαρμογών για κινητά τηλέφωνα, αποκτώντας πρακτική εμπειρία στη σύνδεση συσκευών IoT με φιλικές προς τον χρήστη εφαρμογές.
- Καλλιέργεια Επιστημονικής Σκέψης και Έρευνας
- Οι μαθητές θα εφαρμόσουν επιστημονικές μεθόδους για τη συλλογή, ανάλυση και ερμηνεία δεδομένων, αξιολογώντας τον αντίκτυπο διαφορετικών παραμέτρων στις σχολικές συνθήκες.
- Προώθηση Καινοτομίας και Επιχειρηματικής Σκέψης
- Οι μαθητές θα διερευνήσουν πώς η τεχνολογία IoT μπορεί να εφαρμοστεί σε πραγματικές συνθήκες, ενθαρρύνοντας τη σκέψη γύρω από καινοτόμες λύσεις.
- Υποστήριξη της Εννοιολογικής Κατανόησης 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 ευρώ.
Εγκατάσταση βιβλιοθηκών


Προγραμματισμός
// 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