Edit Readme

This commit is contained in:
Joachim Hummel committed 2020-09-26 01:21:58 +02:00
1 parent 2ac8d08f44
commit e430cf4661
7 files changed
+222 -2

No files matched your search

Executable
+190
View File
@@ -0,0 +1,190 @@
/* This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. */
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Adafruit_NeoPixel.h>
#include <SparkFun_SCD30_Arduino_Library.h>
#include <Wire.h>
String matrixausgabe_text = " "; // Ausgabetext als globale Variable
volatile int matrixausgabe_index = 0;// aktuelle Position in Matrix
IPAddress myOwnIP; // ownIP for mDNS
//-------------- definition mqtt-object ueber WiFi
WiFiClient espClient;
PubSubClient mqttclient(espClient);
//--------- list of mqtt callback functions
#define MAX_MQTT_SUB 10 // maximal 10 subscriptions erlaubt
typedef void (*mqtthandle) (byte*,unsigned int);
typedef struct { // Typdeklaration Callback
String topic; // mqtt-topic
mqtthandle fun; // callback function
}
subscribe_type;
subscribe_type mqtt_sub[MAX_MQTT_SUB];
int mqtt_sub_count=0;
String MQTT_Rx_Payload = "" ;
//--------- mqtt callback function
void mqttcallback(char* to, byte* pay, unsigned int len) {
String topic = String(to);
String payload = String((char*)pay);
MQTT_Rx_Payload=payload.substring(0,len);
Serial.println("\ncallback topic:" + topic + ", payload:" + MQTT_Rx_Payload);
for (int i=0;i<mqtt_sub_count;i++) { // durchsuche alle subscriptions, bis topic passt
if (topic==mqtt_sub[i].topic)
mqtt_sub[i].fun(pay,len); // Aufruf der richtigen callback-Funktion
}
}
//------------ reconnect mqtt-client
void mqttreconnect() { // Loop until we're reconnected
if (!mqttclient.connected()) {
while (!mqttclient.connected()) {
Serial.print("Attempting MQTT connection...");
if (mqttclient.connect("CO2Ampel" , "user", "passwort" )) {
Serial.println("connected");
for (int i=0;i<mqtt_sub_count;i++) { // subscribe topic
mqttclient.subscribe(mqtt_sub[i].topic.c_str());
Serial.println("\nsubscribe");
Serial.print(mqtt_sub[i].topic);
}
}
else {
Serial.print("failed, rc=");
Serial.print(mqttclient.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
else {
mqttclient.loop();
}
}
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(2,13,NEO_GRBW + NEO_KHZ800);
//Reading CO2, humidity and temperature from the SCD30 By: Nathan Seidle SparkFun Electronics
//https://github.com/sparkfun/SparkFun_SCD30_Arduino_Library
SCD30 airSensorSCD30; // Objekt SDC30 Umweltsensor
int co2 = 0 ;
int temp = 0 ;
int hum = 0 ;
void setup(){ // Einmalige Initialisierung
Serial.begin(115200);
//----------------------------------MQTT-Client
mqttclient.setServer("192.168.1.XX", 1883);
mqttclient.setCallback(mqttcallback);
pixels.begin();//-------------- Initialisierung Neopixel
delay(1);
pixels.show();
pixels.setPixelColor(0,0,0,0,0); // alle aus
pixels.setPixelColor(1,0,0,0,0);
pixels.show(); // und anzeigen
Wire.begin(); // ---- Initialisiere den I2C-Bus
if (Wire.status() != I2C_OK) Serial.println("Something wrong with I2C");
if (airSensorSCD30.begin() == false) {
Serial.println("The SCD30 did not respond. Please check wiring.");
while(1) {
yield();
delay(1);
}
}
airSensorSCD30.setAutoSelfCalibration(false); // Sensirion no auto calibration
airSensorSCD30.setMeasurementInterval(2); // CO2-Messung alle 5 s
//------------ WLAN initialisieren
WiFi.persistent(false);
WiFi.mode(WIFI_STA);
delay(100);
Serial.print ("\nWLAN connect to:");
Serial.print("WIFI");
WiFi.begin("SSID","PASSWORD-XXX");
while (WiFi.status() != WL_CONNECTED) { // Warte bis Verbindung steht
delay(500);
Serial.print(".");
};
Serial.println ("\nconnected, meine IP:"+ WiFi.localIP().toString());
matrixausgabe_text = " Meine IP:" + WiFi.localIP().toString();
myOwnIP = WiFi.localIP();
matrixausgabe_index=0;
pixels.setPixelColor(0,40,0,0,0);
pixels.show();
delay( 3000 );
// Forced Calibration Sensirion SCD 30
airSensorSCD30.setAltitudeCompensation(545); // Altitude in m ü NN
airSensorSCD30.setForcedRecalibrationFactor(400); // fresh air
delay( 3000 );
Wire.setClock(100000L); // 100 kHz SCD30
Wire.setClockStretchLimit(200000L);// CO2-SCD30
}
void loop() { // Kontinuierliche Wiederholung
co2 = airSensorSCD30.getCO2() ;
temp = airSensorSCD30.getTemperature() ;
hum = airSensorSCD30.getHumidity() ;
if (( ( co2 ) < ( 700 ) ))
{
pixels.setPixelColor(0,0,30,0,0);
pixels.show();
}
else
{
if (( ( co2 ) > ( 700 ) ))
{
pixels.setPixelColor(0,30,30,0,0);
pixels.show();
if (( ( co2 ) > ( 1000 ) ))
{
pixels.setPixelColor(0,40,0,0,0);
pixels.show();
}
}
else
{
}
}
delay( 1000 );
mqttreconnect();
{
String pay=String(String(co2));
mqttclient.publish("sensor/CO2",pay.c_str());
Serial.print("\nmqtt publish: ");
Serial.print(pay);
};
mqttreconnect();
{
String pay=String(String(temp));
mqttclient.publish("sensor/temp",pay.c_str());
Serial.print("\nmqtt publish: ");
Serial.print(pay);
};
mqttreconnect();
{
String pay=String(String(hum));
mqttclient.publish("sensor/hum",pay.c_str());
Serial.print("\nmqtt publish: ");
Serial.print(pay);
};
delay( 6000 );
}
+31 -2
View File
@@ -1,3 +1,32 @@
# CO2-Ampel-Octopus
# CO2 Ampel mit Sensor SCD30 und Octopus als Mikrocontroller
## Bauteile die benötigt werden:
* https://www.tindie.com/products/FabLab/iot-octopus-badge-for-iot-evaluation/
* https://www.sensirion.com/de/umweltsensoren/kohlendioxidsensor/kohlendioxidsensoren-co2/
* Oder https://www.seeedstudio.com/Grove-CO2-Temperature-Humidity-Sensor-SCD30-p-2911.html
* (Optional) MQTT Broker
* (Optional) NodeRED auf einem Raspberry Pi oder anderen Rechner
## Datenblatt für den SCD30
* https://www.mouser.de/datasheet/2/682/Sensirion_CO2_Sensors_SCD30_Datasheet-1510853.pdf
## Enhalten sind in diesem Repository:
* INO-File für Ardunio IDE und zur Programmierung des Octopus
* NodeRED Flow zur Anzeige von CO2/Temperatur/Luftfeuchte inkl. Dashboard
## Weiterführende Informationen zu dem Projekt gibt es hier:
* https://www.umwelt-campus.de/forschung/projekte/iot-werkstatt/ideen-zur-corona-krise
* WICHTIG Kalibrierung des Sensor https://www.youtube.com/watch?v=od_XsBE6hU4
![Screenshot](https://git.unixweb.net/jhummel/CO2-Ampel-Octopus/raw/branch/master/images/Die-CO2-Ampel.jpg)
![Screenshot](https://git.unixweb.net/jhummel/CO2-Ampel-Octopus/raw/branch/master/images/SCD30-CO2-Ampel.jpg)
![Screenshot](https://git.unixweb.net/jhummel/CO2-Ampel-Octopus/raw/branch/master/images/CO2-Ampel-mit-NodeRED-Dashboard.png)
CO2 Ampel mit Octopus für SCD30 Sensor
+1
View File
@@ -0,0 +1 @@
[{"id":"a626e146.9703f","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"3c760bd.0ac9374","type":"group","z":"a626e146.9703f","name":"","style":{"fill":"#ffdf7f","label":true},"nodes":["d026c6fb.b11348","c5e8c171.0d50a","760bb096.befa98","fb9c00b8.11c3b"],"x":114,"y":539,"w":432,"h":162},{"id":"63e88d79.c39f2c","type":"group","z":"a626e146.9703f","name":"","style":{"fill":"#dbcbe7","label":true},"nodes":["97f2a75b.922c4","7c4cf6e5.41c988","428c7026.608bf8","f53b5921.66de88"],"x":614,"y":319,"w":392,"h":162},{"id":"70ac67cd.b523c","type":"group","z":"a626e146.9703f","name":"","style":{"fill":"#3f93cf","label":true},"nodes":["6e16a33b.01d084","6fd849e9.c40648","5fffdd84.13262c","85220a51.039b18"],"x":174,"y":319,"w":372,"h":162},{"id":"6e16a33b.01d084","type":"mqtt in","z":"a626e146.9703f","g":"70ac67cd.b523c","name":"","topic":"sensor/CO2","qos":"2","datatype":"auto","broker":"bf300e91.fe3f28","x":270,"y":360,"wires":[["6fd849e9.c40648","5fffdd84.13262c"]]},{"id":"6fd849e9.c40648","type":"ui_gauge","z":"a626e146.9703f","g":"70ac67cd.b523c","name":"","group":"1bb3cad0.b6922d","order":3,"width":0,"height":0,"gtype":"gage","title":"Co2","label":"units","format":"{{value}}","min":"300","max":"3000","colors":["#00b500","#e6e600","#ca3838"],"seg1":"701","seg2":"1000","x":450,"y":360,"wires":[]},{"id":"5fffdd84.13262c","type":"ui_chart","z":"a626e146.9703f","g":"70ac67cd.b523c","name":"","group":"1bb3cad0.b6922d","order":1,"width":0,"height":0,"label":"CO2 Trend","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":450,"y":420,"wires":[[]]},{"id":"d026c6fb.b11348","type":"mqtt in","z":"a626e146.9703f","g":"3c760bd.0ac9374","name":"","topic":"sensor/temp","qos":"2","datatype":"auto","broker":"bf300e91.fe3f28","x":210,"y":580,"wires":[["c5e8c171.0d50a","760bb096.befa98"]]},{"id":"97f2a75b.922c4","type":"mqtt in","z":"a626e146.9703f","g":"63e88d79.c39f2c","name":"","topic":"sensor/hum","qos":"2","datatype":"auto","broker":"bf300e91.fe3f28","x":710,"y":360,"wires":[["7c4cf6e5.41c988","428c7026.608bf8"]]},{"id":"c5e8c171.0d50a","type":"ui_gauge","z":"a626e146.9703f","g":"3c760bd.0ac9374","name":"","group":"419515a1.e9fa2c","order":2,"width":0,"height":0,"gtype":"gage","title":"Temp","label":"units","format":"{{value}}","min":"-25","max":"50","colors":["#00b500","#e6e600","#ca3838"],"seg1":"25","seg2":"30","x":410,"y":640,"wires":[]},{"id":"7c4cf6e5.41c988","type":"ui_gauge","z":"a626e146.9703f","g":"63e88d79.c39f2c","name":"","group":"787e5119.94bc1","order":4,"width":0,"height":0,"gtype":"gage","title":"Humidity","label":"units","format":"{{value}}","min":0,"max":"100","colors":["#00b500","#e6e600","#ca3838"],"seg1":"98","seg2":"99","x":880,"y":440,"wires":[]},{"id":"760bb096.befa98","type":"ui_chart","z":"a626e146.9703f","g":"3c760bd.0ac9374","name":"","group":"419515a1.e9fa2c","order":1,"width":0,"height":0,"label":"Temperature Trend","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":430,"y":580,"wires":[[]]},{"id":"428c7026.608bf8","type":"ui_chart","z":"a626e146.9703f","g":"63e88d79.c39f2c","name":"","group":"787e5119.94bc1","order":1,"width":0,"height":0,"label":"Humidity Trend","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":900,"y":360,"wires":[[]]},{"id":"85220a51.039b18","type":"comment","z":"a626e146.9703f","g":"70ac67cd.b523c","name":"CO2","info":"","x":260,"y":440,"wires":[]},{"id":"fb9c00b8.11c3b","type":"comment","z":"a626e146.9703f","g":"3c760bd.0ac9374","name":"Temperature","info":"","x":240,"y":660,"wires":[]},{"id":"f53b5921.66de88","type":"comment","z":"a626e146.9703f","g":"63e88d79.c39f2c","name":"Humidity","info":"","x":710,"y":440,"wires":[]},{"id":"bf300e91.fe3f28","type":"mqtt-broker","z":"","name":"","broker":"192.168.10.55","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"1bb3cad0.b6922d","type":"ui_group","z":"","name":"CO2","tab":"28Line truncated
Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB