Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Herstellungsprozess

LoRa-basierte Smart City-Luftqualitätsüberwachung

Komponenten und Verbrauchsmaterialien

Arduino UNO
× 1
Seeed Base Shield V2
× 1
NodeMCU ESP8266 Breakout Board
× 1
Seeed Loudness Sensor
× 1
Seeed Grove - Luftqualitätssensor v1.3
× 1
Seeed Grove - Temperatur- und Feuchtigkeitssensor (DHT11)
× 1
Reyax LoRa-Modul
× 1
Seeed Small Solar Panel 80x100mm 1W
× 1
Seeed LiPo Rider Pro
× 1
Akku, 3,7 V
× 1

Notwendige Werkzeuge und Maschinen

3D-Drucker (generisch)

Apps und Onlinedienste

Arduino-IDE
Grandeur
Grandeur Canvas

Über dieses Projekt

Smart City &Luftqualität

Die Weltbank definiert eine Smart City als eine technologieintensive Stadt. Dies bedeutet hocheffiziente öffentliche Dienste.

Eine der grundlegenden Eigenschaften von Smart Cities ist die Bereitstellung einer nachhaltigen Umwelt. Für eine nachhaltige Umwelt ist es notwendig, die Umweltbedingungen zu überwachen, um die Verschmutzungsquellen zu identifizieren und diese zu mindern. In diesem Zusammenhang werden Tausende von Luftqualitätssensoren platziert, um der Regierung und den Bürgern gleichermaßen Echtzeitinformationen bereitzustellen. Diese Daten können in nützliche Informationen umgewandelt werden, die es uns ermöglichen, bessere Entscheidungen zu treffen – sei es bei der Verkehrsplanung oder der besten Route zur Arbeit.

Die Luftqualitätsmessung passt gut zur Vision der Smart City – Bereitstellung von Informationen über eine Stadt, die zuvor nicht verfügbar waren, und ermöglicht es den Menschen, Entscheidungen zu treffen, die ihre Lebensqualität verbessern können.

Problem &Lösung

Die zunehmende Luftverschmutzung in Großstädten ist aufgrund des Risikos für die menschliche Gesundheit zu einem großen Problem geworden. In diesem Zusammenhang hat sich die Technologie zu einem sehr nützlichen Instrument bei der Überwachung der Kontamination und der möglichen Eindämmung ihrer Auswirkungen entwickelt. Insbesondere gibt es verschiedene Vorschläge, die das Internet der Dinge (IoT)-Paradigma verwenden, das miteinander verbundene Sensoren verwendet, um verschiedene Schadstoffe zu messen. Zur Überwachung der Luftqualität und meteorologischer Parameter kann ein Netzwerk kostengünstiger Sensorknoten zur Luftqualitätsüberwachung eingesetzt werden. Daher kann die Stadt durch die Erkennung von Schadstoffquellen Korrekturmaßnahmen ergreifen und ihre Umweltgesundheit verbessern. Durch die Installation von Katastrophenerkennungssystemen wie Überschwemmungs- und Niederschlagsüberwachungslösungen in Ihrer Umgebung. die Bürger können im Katastrophenfall vorab alarmiert werden. Eine ganzheitliche Sicht ist ableitbar, die es den Behörden ermöglicht, datengesteuerte Infrastruktur- und Politikplanungsentscheidungen zu treffen.

Der Projektplan

In diesem Projekt werden wir einige der wichtigsten Umweltparameter wie Lärm, Temperatur, Luftfeuchtigkeit und Luftqualität überwachen. Es überträgt Echtzeitdaten über ein drahtloses Kommunikationsprotokoll an eine Cloud-Plattform. Das Gerät wird vollständig mit Solarstrom mit Batterie-Backup betrieben. Die Daten des Geräts sind über ein Dashboard zugänglich, das die Daten in den gewünschten Formaten visualisiert und analysiert.

Für die Überwachung der Luftqualität in einer Smart City müssen Sie Sensorknoten an verschiedenen Orten platzieren. In Bezug auf Stromverbrauch und Kosten ist es keine gute Idee, jeden Sensorknoten einzeln mit der Cloud zu verbinden. Vielmehr ist es eine gute Idee, Daten von allen Sensorknoten eines kleinen Bereichs zu sammeln und alle Daten von einem einzigen Gateway in die Cloud zu veröffentlichen. LoRa kann uns diesen Vorteil verschaffen und deshalb habe ich LoRa für mein Projekt gewählt.

Für den Cloud-Dienst verwende ich Grandeur für mein Projekt. Grandeur ist eine vergleichsweise neue, herstellerfreundliche IoT-Plattform, auf der wir unsere Daten speichern und die Daten visualisieren können, indem wir Diagramm-Widgets per Drag-and-Drop erstellen. Sie bieten auch Arduino-, JavaScript- und Python-SDK mit Beispielcode. So kann man sich einfach über Arduino, NodeMCU und Raspberry Pi mit ihrem Dienst verbinden.

Die beste Möglichkeit, einen Sensorknoten mit Strom zu versorgen, ist die Verwendung eines Solarpanels. Da die Sensorknoten an einem anderen entfernten Ort platziert sind und die Batterie häufig gewechselt oder Strom aus einer Stromquelle bereitgestellt werden kann, ist es nicht immer möglich. Ich versorge meinen Sensor Note über das Solarpanel und den Lithium-Ionen-Akku mit Strom.

Herstellung des Sensorknotens

Ich möchte Luftqualität, Geräuschpegel, Temperatur und Luftfeuchtigkeit überwachen. Also habe ich den Grove-Luftqualitätssensor, den Grove-Geräuschsensor und den Grove DHT11-Temperatur- und Feuchtigkeitssensor verwendet. Eine gute Sache an Grove-Sensoren ist, dass Sie alle Grove-Sensoren mit dem Grove-Basisschild ohne Löten an Arduino anschließen können.

Für die Stromversorgung der Schaltung habe ich Grove 1W Solarpanel und Li-Ion-Akku verwendet. Zum Aufladen des Akkus mit dem Solarpanel habe ich das Solarladegerät Seeed LiPo Rider Pro verwendet, das über einen eingebauten 5V-Boost-Konverter verfügt. So können wir Arduino einfach mit dem Ausgang des LiPo Rider ausführen.

Die meisten der hier verwendeten Komponenten sind auf Seeedstudio.com verfügbar. Das folgende Bild zeigt eine Plug-and-Play-Testverbindung für alle Komponenten des Sensorknotens.

Für die Übertragung der Sensordaten an das IoT-Gateway habe ich den Reyax LoRa-Transceiver verwendet. Das folgende Bild zeigt das Reyax RYLR998 Lora Modul mit dem Pin-Diagramm.

Vorbereiten der Reyax RYLR998 LoRa Engine für die Verbindung mit dem Arduino Base Shield

Der RYLR998 hat einen 5-poligen Ausgang und ist nicht mit Grove Base Shield kompatibel. Für den Anschluss an Grove Shield habe ich ein Grove-Kabel in ein Perfboard mit einer 5-Pin-Buchse gelötet. Die Schaltungsverbindung ist wie folgt:

Das RYLR998 LoRa-Modul kann bis zu 3,6 V sicher betrieben werden. Der Arduino TX-Pin erzeugt einen 5V-Ausgang, der für den LoRa nicht sicher ist. Also habe ich einen Spannungsteiler verwendet, um 3,4 V vom Arduino TX-Pin zu erhalten. Auf der anderen Seite funktioniert der Arduino RX-Pin perfekt mit 3,3-V-Logik. Also habe ich den TX-Pin des LoRa direkt mit dem RX-Pin des Arduino verbunden. Für den normalen Betrieb sollte der RST-Pin des LoRa im High-Zustand sein.

Jetzt kann das obige LoRa-Modul einfach mit der folgenden Konverterschaltung an den Basisschirm angeschlossen werden.

Aber bevor Sie das Modul an die Basisabschirmung anschließen, stellen Sie sicher, dass sich der Netzschalter der Basisabschirmung in der 3,3-V-Position befindet, wie in der Abbildung unten gezeigt.

Nach dem Anschließen des LoRa-Moduls an das Basisschild können wir testen, indem wir einen AT-Befehl von Arduino an das Modul senden.

Kommunikation mit RYLR896 LoRa-Transceiver

Um eine Kommunikation zwischen zwei LoRa-Modulen aufzubauen, müssen diese sich über eine Adresse finden können. Das Adressierungsschema des LoRa-Ökosystems hängt ein wenig von den Modulen und der Implementierung ab. Einfach gesagt ermöglicht uns das Modul, eine Netzwerk-ID und eine Adresse festzulegen. Module im gleichen Netzwerk (gleiche Netzwerk-ID) können miteinander kommunizieren. Jedes Modul soll innerhalb eines Netzwerks eine eindeutige ID (Adresse) haben. Wenn ein Modul die Adresse 0 hat, kann dieses Modul Daten von allen Geräten im Netzwerk empfangen.

Jedes Modul wird mit einer Standardfrequenz, Netzwerk-ID und Adresse geliefert, aber Sie müssen möglicherweise den Standardwert ändern. Die Standard-Netzwerk-ID für das obige Modul ist 18 und die Adresse 0.

Für unser Demoprojekt müssen wir derzeit nichts ändern. Wenn Sie jedoch einen Parameter ändern möchten, überprüfen Sie bitte das Datenblatt für die Details der AT-Befehle.

Um eine Nachricht zu senden (HALLO EMPFÄNGER!), müssen wir nur den Befehl „AT+SEND=0, 15, HALLO EMPFÄNGER!“ senden. am seriellen Anschluss des Moduls. Der erste Parameterwert ‚0‘ ist die Adresse des Empfängermoduls. Der nächste Wert ’15’ ist die Anzahl der zu sendenden Zeichen/Bytes. Der dritte Parameterwert ist die zu sendende Nachricht:„HALLO EMPFÄNGER!“ (15 Zeichen).

Code für Sensorknoten

Der folgende Code wird für den Sensorknoten entwickelt, um alle Sensordaten zu sammeln und an das IoT-Gateway zu übertragen.

#include "AirQuality.h" //grove Luftqualitätsbibliothek
#include "Arduino.h"
#include "DHT.h"

# definiere DHTPIN 4 // an welchen digitalen Pin der DHT-Sensor angeschlossen ist
#define DHTTYPE DHT11 // Modell des Sensors DHT11

DHT dht(DHTPIN, DHTTYPE);

AirQuality airqualitysensor;
int current_quality =-1;

const int sampleWindow =50; // Samplefensterbreite in mS (50 mS =20Hz)
unsigned int sample;
float noise;
float temp, feucht;
int airQuality;

//---------------------------------------------------------- ----------------------------------------------------------
// EINRICHTEN
//----------------------------------------- -------------------------------------------------- -
void setup()
{

Serial.begin(115200); //Seriennummer für Lora
airqualitysensor.init(14);
dht.begin();

}

//----- -------------------------------------------------- --------------------------------------
// HAUPTSCHLEIFE
/ /------------------------------------------------ -------------------------------------------------------

void loop()
{
noise =calcul_sound_in_db();
airQuality =calcul_air_quality();
calcul_temp_humid();

String temperature =String (temp);
Saitenfeuchte =Saite(feucht);
Saitenklang =Saite(Geräusch);
Saitenluft =String(airQuality);

Saitenwerte =String(Temperatur)+","+ String(Luftfeuchtigkeit)+","+ String(Sound)+","+ String(Luft);
String cmd ="AT+SEND=0,"+String (values.length())+","+values; //AT+SEND=,,
Serial.println (cmd); //an Lora gesendet

delay(15000);
}

//diese Funktion berechnet den Schallpegel in dB
float compute_sound_in_db(){
unsigned long startMillis=millis(); // Beginn des Beispielfensters
float peakToPeak =0; // Spitze-zu-Spitze-Pegel

unsigned int signalMax =0; //Mindestwert
unsigned int signalMin =1024; //Maximalwert

// Daten für 50 mS sammeln
while (millis() - startMillis {
sample =analogRead(A1); // Messwert vom Mikrofon abrufen
if (sample <1024) // Störende Messwerte aussortieren
{
if (sample> signalMax)
{
signalMax =sample; // nur die maximalen Pegel speichern
}
else if (sample {
signalMin =sample; // nur die Mindestwerte speichern
}
}
}
peakToPeak =signalMax - signalMin; // max - min =Peak-Peak-Amplitude
//Serial.println(peakToPeak); // kalibrierte Dezibel schreiben
float db =map(peakToPeak,0,1000,48,120); // auf Dezibel kalibrieren
//Serial.print(db); // kalibrierte Dezibel schreiben
//Serial.println(" dB"); //Einheiten schreiben
return db;
}

int compute_air_quality(){
current_quality=airqualitysensor.slope();
/*
if (current_quality>=0)// wenn gültige Daten zurückgegeben wurden.
{
if (current_quality==0)
Serial.println("Hohe Verschmutzung! Force signal active");
else if (current_quality==1)
Serial.println("Hohe Verschmutzung!");
else if (current_quality==2)
Serial.println("Geringe Verschmutzung .) !");
else if (current_quality ==3)
Serial.println("Frische Luft");
}
*/
return current_quality;
}

voidcalcul_temp_humid(){
// Das Auslesen von Temperatur oder Luftfeuchtigkeit dauert ca. 250 Millisekunden!
// Sensormesswerte können auch bis zu 2 Sekunden alt sein ( es ist ein sehr langsamer Sensor)
float h =dht.readHumidity();
// Temperatur als Celsius lesen (Standard)
float t =dht.readTemperature();

// Prüfen, ob Lesevorgänge fehlgeschlagen sind und vorzeitig beenden (um es erneut zu versuchen).
if (isnan(h) || isnan(t)) {
//Serial.println("Fehler beim Lesen vom DHT-Sensor!");
return;
}

temp =t;
feucht =h;
/*
Seriendruck("Feuchtigkeit:");
Seriendruck(h);
Seriendruck("%\t");
Seriendruck("Temperatur:");
Seriendruck(t);
Seriendruck("*C");
*/
}

//Unterbreche Serviceroutine für Luftqualitätssensor
ISR(TIMER1_OVF_vect)
{
if(airqualitysensor.counter==61)//setze 2 Sekunden als erkannte Pflicht
{

airqualitysensor.last_vol=airqualitysensor.first_vol;
airqualitysensor.first_vol=analogRead(A0);
airqualitysensor.counter=0;
airqualitysensor.timer_index=1;
PORTB=PORTB^0x20;
}
else
{
airqualitysensor.counter++;
}
}

Der Code sendet die Sensordaten alle 15 Sekunden. Ändern Sie das Timing entsprechend Ihrer Anforderung.

Hochladen und testen

Schließen Sie nun alle Sensoren an, laden Sie den obigen Code hoch und testen Sie im seriellen Monitor. Die Quelldatei ist im Codeabschnitt angehängt.

Platzieren von Komponenten in der Box

Jetzt werden wir alle Sensoren und die Batterie in die Box legen. Drucken Sie zunächst die beiden STL-Dateien, die im Anhangsabschnitt angehängt sind, in 3D aus. Die gedruckten Bilder sehen wie das folgende Bild aus.

Die komplette Box sieht wie folgt aus. Je nach Qualität Ihres Druckers benötigen Sie möglicherweise eine gewisse Sendebasis.

Nach der Vorbereitung der Box befestigte zuerst das Solarpanel oben an der Box. Die Anschlussdrähte in der Box durch das obere Loch führen.

Dann platzieren Sie das Arduino mit dem angebrachten Basisschild zuerst mit etwas Heißkleber oder doppelseitigem Klebeband. Platzieren Sie die anderen Sensoren nacheinander und befestigen Sie sie mit etwas Heißkleber an einer festen Stelle.

Platzieren Sie Akku und Lipo Rider Pro und fügen Sie schließlich das LoRa-Modul hinzu.

Der Sensorknoten ist einsatzbereit.

Grandeur konfigurieren

Grandeur bietet einen Back-End-Dienst für IoT-Geräte, bei dem ein virtuelles Gerät-Benutzer-Paar erstellt wird. Das Gerätemodell wird bei der Erstellung als JSON-Objekt beschrieben, das verschiedene Variablen (in unserem Fall Temperatur, Feuchtigkeit, Geräuschpegel, Luftqualität) enthält, die gelesen und geschrieben werden können. Grandeur Canvas ist eine Web-App, mit der der Gerätezustand gekoppelter Geräte mithilfe von grafischen Widgets visualisiert werden kann.

Um den Grandeur nutzen zu können, müssen wir unser Konto erstellen und einige wichtige Konfigurationen auf der Plattform vornehmen. Schauen Sie auf deren Website https://grandeur.dev/ um ins Spiel zu kommen.

1. Nachdem Sie sich beim Root-Konto angemeldet haben, erstellen Sie ein neues Projekt :

2. Neues Benutzerkonto erstellen aus dem Konto hinzufügen Option auf der Registerkarte "Startseite" oder auf der Registerkarte "Konten". Wir werden uns später mit der E-Mail und dem Passwort, die wir jetzt erstellen, bei unserer App anmelden. Dies ist eine weitere coole Funktion von Grandeur:Mehrere Benutzer können Ihre App verwenden, indem sie sich mit ihren E-Mails und Passwörtern anmelden . Jeder Benutzer kann seine eigenen Geräte koppeln und das von einem Benutzer gekoppelte Gerät wird für andere nicht verfügbar. Die Authentifizierung ist das Herzstück von Grandeur. Die Benutzererstellung wird unten dargestellt:

3. Jetzt ein neues Gerät erstellen über die Registerkarte Geräte. Dieser Vorgang generiert eine neue eindeutige Geräte-ID, die wir beim Schreiben von Code für unsere Hardware verwenden, und diese Geräte-ID ist erforderlich, um eine Verbindung mit Grandure über die API herzustellen. Beim Erstellen eines Geräts wird auch ein accessToken generiert. Vergiss nicht, es zu kopieren und es wird im Hardwarecode verwendet und ist nach dem Schließen des Dialogfelds nicht mehr zugänglich . Sie müssen ein Gerätemodell hinzufügen, bevor Sie ein Gerät mit dem folgenden Verfahren hinzufügen. Ein Gerätemodell wird verwendet, um zu beschreiben, welche Variablen vom/an das Gerät kommuniziert werden können.

Klicken Sie bei den Modellen auf Hinzufügen und gib einen Modellnamen an. Geben Sie im Schema alle Variablen (4 in unserem Fall) im JSON-Format ein. Behalten Sie zu diesem Zeitpunkt den Wert 0 bei. Diese Variable wird automatisch aktualisiert, wenn wir Daten von unserem Geräteknoten senden.

 {"temp":0, "humid":0, "air":0, "noise":0} 

Klicken Sie nach dem Einfügen des Schemas auf Hinzufügen.

Nachdem Sie das Gerätemodell hinzugefügt haben, klicken Sie auf die Option Von Geräten hinzufügen und wählen Sie das gerade erstellte Modell aus, um das Modell mit dem Gerät zu verknüpfen.

Geben Sie eine Geräte-ID ein und klicken Sie auf Registrieren.

Kopieren Sie das Zugriffstoken und es wird im Hardwarecode verwendet und ist nach dem Schließen des Dialogfelds nicht mehr zugänglich.

Gerät wurde erfolgreich erstellt und notieren Sie sich auch die DEVICE ID. Es wird auch für die Codierung benötigt.

Ein Benutzer kann nicht mit einem Gerät interagieren, es sei denn, es ist damit gekoppelt. Es gibt zwei Möglichkeiten, Ihr Gerät zu koppeln :1) über das Cloud-Dashboard oder 2) über die Web-App mit pairDevice() Funktion der Geräte-API. Dieser zweite Weg hat eine sehr starke Bedeutung, wenn man ihn aus der Sicht der Produktion betrachtet. So können Sie jetzt Ihre Hardwareprodukte versenden, und Ihre Benutzer können sich bei Ihrer App anmelden und durch Koppeln das Eigentum an einer Hardware erklären. So können Sie Ihr Gerät über das Cloud-Dashboard mit einem Benutzer koppeln:

Um das Gerät zu koppeln, klicken Sie auf Koppeln und wählen Sie ein Konto aus. Sie sind bereit für den nächsten Schritt.

4. Wir werden jetzt eine Leinwand erstellen.

Klicken Sie im linken Menü des Dashboards auf Canvas oder gehen Sie zu https://canvas.grandeur.tech. Wenn Sie Canvas zum ersten Mal besuchen, eine Autorisieren Schaltfläche erscheint. Die Autorisierung gibt Canvas Zugriff auf die Benutzer und Geräte Ihres Projekts. Wenn Sie auf die Schaltfläche "Autorisieren" klicken, werden Sie zurück zum Grandeur-Dashboard geleitet, wo Sie aufgefordert werden, das Projekt auszuwählen, an das sich Canvas binden soll.

Wählen Sie ein Diagramm-Widget aus und klicken Sie darauf. Das Menü "Konfigurieren" wird angezeigt. Klicken Sie dann auf "Konfigurieren", um dem Diagramm einen Titel zu geben und die Variable einzustellen, deren Wert Sie in diesem Diagramm anzeigen möchten.

Klicken Sie auf Speichern.

Fügen Sie nach dem gleichen Verfahren 4 Diagramm-Widgets für die 4 Variablen hinzu.

Nachdem Sie Canvas mit Ihrem Projekt verbunden haben, wird möglicherweise ein Anmeldebildschirm angezeigt. Sie müssen sich hier als Benutzer Ihres zuvor angelegten Projekts anmelden, für das Sie in Ihrem Projekt ein Benutzerkonto erstellen müssen. Sie können dies tun, indem Sie die Kontenseite des Dashboards besuchen. Dann können Sie sich mit den Anmeldeinformationen dieses neuen Benutzers bei Canvas anmelden.

Preparing IoT LoRa Gateway

In a simple way, an IoT Gateway is like home or office network router or gateway that connects sensors, IoT modules, and smart devices to the cloud. Such a gateway facilitates communication between your devices, maintains security, and provides an admin interface where you can perform basic functions.

A true IoT gateway contains communication technologies connecting end-devices (sensors, actuators, or more complex devices) and backend platforms (data, device, and subscriber management) to the gateway. It has a computing platform allowing pre-installed or user-defined applications to manage data (for routing and computing at the edge), devices, security, communication, and other aspects of the gateway.

Raspberry Pi can be a good option for a gateway with lots of flexibility but to keep it simple I am using Node MCU as a gateway for this project. Node MCU will receive the data from the LoRa module using UART. Then using Arduino SDK we will upload the data to the Grandeur cloud platform.

Firmware for the Gateway

The following code was developed for the gateway using Arduino SDK provided by Grandeur cloud. Data is received in string form from the LoRa using the UART port. Then the received data is processed to separate the individual variable from the comma-separated string value. The values are then sent to Grandeur using WiFi. The following function was used to separate the variables.

void process_received_data(){

start_pos =inputString.indexOf(start_val);
end_pos =inputString.indexOf(end_val);
String data_string =inputString.substring(start_pos+1, end_pos-1);
//Serial.println(data_string);
//identifying commas inn the string
int firstCommaIndex =data_string.indexOf(',');
int secondCommaIndex =data_string.indexOf(',', firstCommaIndex+1);
int thirdCommaIndex =data_string.indexOf(',', secondCommaIndex+1);
//seperating comma seperated value from the data string
String temperature =data_string.substring(0, firstCommaIndex);
String humidity =data_string.substring(firstCommaIndex+1, secondCommaIndex);
String noise_level =data_string.substring(secondCommaIndex+1, thirdCommaIndex);
String air_auality =data_string.substring(thirdCommaIndex+1);

//Serial.println(temperature);
//Serial.println(humidity);
//Serial.println(noise);
//Serial.println(air_auality);

temp =temperature.toFloat();
humid =humidity.toFloat();
noise =noise_level.toFloat();
air =air_auality.toFloat();

Serial.println(temp);
Serial.println(humid);
Serial.println(noise);
Serial.println(air);

inputString ="";
stringComplete =false;
}

The complete code is attached in the code section.

Data Visualization

Code

  • Code for Sensor Node
  • Code for Gateway
Code for Sensor NodeArduino
This code is for the sensor device that collects sensors data and sent the data to the IoT gateway using LoRa.
#include "AirQuality.h" //grove air quality library#include "Arduino.h"#include "DHT.h"#define DHTPIN 4 // what digital pin DHT sensor connected to#define DHTTYPE DHT11 // model of the sensor DHT11 DHT dht(DHTPIN, DHTTYPE);AirQuality airqualitysensor;int current_quality =-1;const int sampleWindow =50; // Sample window width in mS (50 mS =20Hz)unsigned int sample;float noise;float temp, humid;int airQuality; //-------------------------------------------------------------------------------------------- // SETUP //--------------------------------------------------------------------------------------------void setup() { Serial.begin(115200); //Serial for lora airqualitysensor.init(14); dht.begin();} //--------------------------------------------------------------------------------------------// MAIN LOOP//-------------------------------------------------------------------------------------------- void loop() { noise =calculate_sound_in_db(); airQuality =calculate_air_quality(); calculate_temp_humid(); String temperature =String(temp); String humidity =String(humid); String sound =String(noise); String air =String(airQuality); String values =String(temperature)+","+ String(humidity)+","+ String(sound)+","+ String(air); String cmd ="AT+SEND=0,"+String(values.length())+","+values; //AT+SEND=
,, Serial.println(cmd); //sent to lora delay(15000);}//this function calculate sound level in dBfloat calculate_sound_in_db(){ unsigned long startMillis=millis(); // Start of sample window float peakToPeak =0; // peak-to-peak level unsigned int signalMax =0; //minimum value unsigned int signalMin =1024; //maximum value // collect data for 50 mS while (millis() - startMillis signalMax) { signalMax =sample; // save just the max levels } else if (sample =0)// if a valid data returned. { if (current_quality==0) Serial.println("High pollution! Force signal active"); else if (current_quality==1) Serial.println("High pollution!"); else if (current_quality==2) Serial.println("Low pollution!"); else if (current_quality ==3) Serial.println("Fresh air"); } */ return current_quality;}void calculate_temp_humid(){ // Reading temperature or humidity takes about 250 milliseconds! // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) float h =dht.readHumidity(); // Read temperature as Celsius (the default) float t =dht.readTemperature(); // Check if any reads failed and exit early (to try again). if (isnan(h) || isnan(t)) { //Serial.println("Failed to read from DHT sensor!"); Rückkehr; } temp =t; humid =h; /* Serial.print("Humidity:"); Serial.print(h); Serial.print(" %\t"); Serial.print("Temperature:"); Serial.print(t); Serial.print(" *C "); */}//interrupt service routine for air quality sensorISR(TIMER1_OVF_vect){ if(airqualitysensor.counter==61)//set 2 seconds as a detected duty { airqualitysensor.last_vol=airqualitysensor.first_vol; airqualitysensor.first_vol=analogRead(A0); airqualitysensor.counter=0; airqualitysensor.timer_index=1; PORTB=PORTB^0x20; } else { airqualitysensor.counter++; }}
Code for GatewayArduino
Receives data from the sensor nodes, process the data and sends to Grandeur cloud
/* Including the SDK and WiFi library */#include #include #include SoftwareSerial LORA(D7, D8);/* Configurations */String deviceID ="your device id";String apiKey ="your api key";String token ="your device token";/* WiFi credentials */String ssid ="your wifi ssid";String password ="your wifi password";/* Create variable to hold project and device */Grandeur::Project project;Grandeur::Project::Device device;/* Variable to keep track of connection state and time */int connected =0;uint32_t lastUpdate =0;String inputString =""; // a string to hold incoming databoolean stringComplete =false; // whether the string is complete//:and % was set from the transmitter node for the eage of data separationchar start_val =':';char end_val ='%';int start_pos =0;int end_pos =0;float temp =0;float humid =0;float air =0;float noise =0;/* Function to check device's connection status */void onConnection(bool status) { switch(status) { case CONNECTED:Serial.println("Device is connected to the cloud."); /* Record connection state and time */ connected =1; lastUpdate =millis(); Rückkehr; case DISCONNECTED:Serial.println("Device is disconnected from the cloud."); connected =0; Rückkehr; }}/* Function to connect to WiFi */void connectWiFi() { /* Set mode to station */ WiFi.mode(WIFI_STA); /* Connect using the ssid and password */ WiFi.begin(ssid, password); /* Block till the WiFi is connected */ while (WiFi.status() !=WL_CONNECTED) { delay(500); Serial.print("."); } /* Print message */ Serial.println(""); Serial.println("WiFi connected"); /* And IP address */ Serial.println(WiFi.localIP());}/* Function to confirm that data has been updated */void dataCallback(const char* code, Var res) { /* If the update was recorded successfully */ if(code =="DEVICE-DATA-UPDATED") { //Serial.println("Updated DATA"); /* Get data */ double temp_data =(double) res["update"]["temp"]; double humid_data =(double) res["update"]["humid"]; double noise_data =(double) res["update"]["noise"]; double air_data =(double) res["update"]["air"]; /* Print */ Serial.printf("Temperature:%f Humidity:%f Noise Level:%f Air Quality:%f\n", temp_data, humid_data, noise_data, air_data); Rückkehr; } /* If the summary could not be updated. */ Serial.println("Failed to Update DATA"); return;}/* Function to send updated current and power readings */void sendUpdate() { Var data; //JSON data format set in Grandeur:{"temp":0, "humid":0, "air":0, "noise":0} data["temp"] =temp; data["humid"] =humid; data["noise"] =noise; data["air"] =air; /* Record update */ //device.data().set("", data, dataCallback); //send JSON device.data().set("temp", temp, dataCallback); device.data().set("humid", humid, dataCallback); device.data().set("noise", noise, dataCallback); device.data().set("air", air, dataCallback); //delay(2000);}void setup() { /* Begin the serial */ Serial.begin(9600); LORA.begin(115200); inputString.reserve(200); /* Connect to WiFi */ connectWiFi(); /* Initializes the global object "grandeur" with your configurations. */ project =grandeur.init(apiKey, token); /* Get reference to device */ device =project.device(deviceID); /* Sets connection state update handler */ project.onConnection(onConnection);}void loop() { serialEvent(); project.loop(WiFi.status() ==WL_CONNECTED); /* Send update to server */ if (stringComplete) { process_received_data(); if (connected) sendUpdate(); }}void serialEvent() { while (LORA.available()) { // get the new byte:char inChar =(char)LORA.read(); // if the incoming character is a newline, set a flag // so the main loop can do something about it:if (inChar =='\n') { stringComplete =true; } else // add it to the inputString:inputString +=inChar; }}void process_received_data(){ start_pos =inputString.indexOf(start_val); end_pos =inputString.indexOf(end_val); String data_string =inputString.substring(start_pos+1, end_pos-1); //Serial.println(data_string); //identifying commas inn the string int firstCommaIndex =data_string.indexOf(','); int secondCommaIndex =data_string.indexOf(',', firstCommaIndex+1); int thirdCommaIndex =data_string.indexOf(',', secondCommaIndex+1); //seperating comma seperated value from the data string String temperature =data_string.substring(0, firstCommaIndex); String humidity =data_string.substring(firstCommaIndex+1, secondCommaIndex); String noise_level =data_string.substring(secondCommaIndex+1, thirdCommaIndex); String air_auality =data_string.substring(thirdCommaIndex+1); //Serial.println(temperature); //Serial.println(humidity); //Serial.println(noise); //Serial.println(air_auality); temp =temperature.toFloat(); humid =humidity.toFloat(); noise =noise_level.toFloat(); air =air_auality.toFloat(); Serial.println(temp); Serial.println(humid); Serial.println(noise); Serial.println(air); inputString =""; stringComplete =false; }

Custom parts and enclosures

Schematics


Herstellungsprozess

  1. Fortschrittliche Sensortechnologien ermöglichen eine personalisierte Überwachung der Luftqualität
  2. Luftqualitätssensor integriert KI-Funktionen
  3. Luftqualitätssensorplattform erhält eingebettete KI
  4. Messen der Luftqualität auf OpenSensors
  5. Luftverschmutzungsdetektor
  6. Helium-Luftqualitätssensor
  7. Verbesserte Überwachung der Luftverschmutzung mit IoT-Sensoren
  8. Vorteile eines IoT-basierten Systems zur Überwachung der Umgebungsluftqualität
  9. Anwendungen von industriellen IoT-infundierten Luftqualitätsüberwachungssystemen
  10. Kohlenstoffbasierter Luftqualitätssensor