Explorar el Código

Pocobo 2 sketch

Arduino Sketch for Pocobo 2
gerfried hace 5 meses
padre
commit
f27b0d5dd3
Se han modificado 1 ficheros con 775 adiciones y 0 borrados
  1. 775 0
      Pocobo_2.ino

+ 775 - 0
Pocobo_2.ino

@@ -0,0 +1,775 @@
+/*Pocobo 2- Pollution Collecting Bottle 2
+ * 
+ * v1.0
+ * 
+ * Devices & Parts: 
+ * - Arduino MKR NB 1500 (https://www.arduino.cc/en/Guide/MKRNB1500, https://store.arduino.cc/products/arduino-mkr-nb-1500?_gl=1%2Ajmo3e2%2A_ga%2AMTgyMjQxNTg5MC4xNjM3MTQ1NTIw%2A_ga_NEXN8H46L5%2AMTYzNzc0NjM2My4yLjEuMTYzNzc0NjYwOS4w)
+ * - Sensirion SEN54 PM Sensor (https://www.sensirion.com/products/catalog/SEN54)
+ * - Adafruit Mini GPS PA1010D Module (https://learn.adafruit.com/adafruit-mini-gps-pa1010d-module)
+ * - Dipole Pentaband Waterproff antenna (https://store.arduino.cc/en-at/products/dipole-pentaband-waterproof-antenna?queryID=undefined
+ * - Eckstein  3.7V, 2000mAh Battery (https://eckstein-shop.de/LiPo-Akku-Lithium-Ion-Polymer-Batterie-37V-2000mAh-mit-JST-PHR-2-Stecker-LP803860)
+ * - Adafruit Powerboost 500 Charger (https://www.adafruit.com/product/1944) (needed because the Arduino MKR NB can only charge batteries from 700-1500mAh; see also (scroll down): https://store.arduino.cc/products/arduino-mkr-nb-1500?_gl=1%2Ads0y0w%2A_ga%2AMTgyMjQxNTg5MC4xNjM3MTQ1NTIw%2A_ga_NEXN8H46L5%2AMTYzODQ1MzI5My4xNy4xLjE2Mzg0NTUwMzkuMA..)
+ * - Adafruit RGB On/Off Switch (https://www.adafruit.com/product/3426)
+ * 
+ * 
+ * 
+ * Infos & Libraries: 
+ * - Arduino MKR NB Library:https://www.arduino.cc/en/Reference/MKRNB
+ * - Arduino MKR NB Features: https://docs.arduino.cc/hardware/mkr-nb-1500
+ * - Sensirion SEN54 Library Github: https://github.com/Sensirion/arduino-i2c-sen5x
+ * - Sensirion SEN54 Library Arduino: https://www.arduino.cc/reference/en/libraries/sensirion-i2c-sen5x/
+ * - Comparison for PM2.5 values: https://kachelmannwetter.com/de/luftqualitaet/wien-umgebung/pm25-feinstaub/20211126-1100z.html
+ * - Comparison for PM10 values: https://kachelmannwetter.com/de/luftqualitaet/wien-umgebung/pm10-feinstaub/20211126-1100z.html
+ * - Available Radio Access Technology: https://www.gsma.com/iot/deployment-map/
+ * - Sparkfun_I2C_GPS_Arduino_Library: For using TinyGPS++ Library with I2C
+ * - Tiny GPS++ Library: http://arduiniana.org/libraries/tinygpsplus/
+ * - Switch with Powerboost 500: https://learn.adafruit.com/adafruit-powerboost-500-plus-charger/on-slash-off-switch
+ * - Wiring the Button: https://learn.adafruit.com/ambient-color-controller/build-the-circuit
+ * - Example for lighting the button LED: https://create.arduino.cc/projecthub/102550/rgb-light-control-with-arduino-9979df
+ * - Read Battery voltage on MKR Board: https://docs.arduino.cc/tutorials/mkr-wifi-1010/mkr-battery-app-note
+ * - TinyGPS++ i2c example: https://github.com/sparkfun/SparkFun_GPS_Breakout_XA1110_Qwiic/blob/master/Libraries/SparkFun%20I2C%20GPS/examples/Example2-TinyGPS/Example2-TinyGPS.ino
+ 
+
+ * 
+ * WIRING:
+ *  Arduino                     SCL  <->   SCL    Adafruit Mini GPS, SEN54 (4, yellow)
+ *  Arduino                     SDA  <->   SDA    Adafruit Mini GPS, SEN54 (3, green)
+ *  Arduino                     VIN  <->   5V
+ *  Arduino                     GND  <->   GND
+ *  SEN54 (1, white)            VCC  <->   5V
+ *  SEN54 (2, blue)             GND  <->   GND
+ *  SEN54 (5, black)            SEL  <->   GND
+ *  Adafruit Mini GPS           VIN  <->   5V
+ *  Adadruit Mini GPS           GND  <->   GND
+ *  Adafruit Power Boost 500    5V   <->   5V   
+ *  Adafruit Power Boost 500    GND  <->   GND
+ *  Adafruit Power Boost 500    LBO  <->   5      Arduino //DOES NOT REALLY WORK CHECK WIRING AND FUNCTIONALITY
+ *  Adafruit RGB ON/OFF Switch  C+   <->   5V          
+ *  Adafruit RGB ON/OFF Switch  C    <->   GND
+ *  Adafruit RGB ON/OFF Switch  R    <->   6      Arduino   
+ *  Adafruit RGB ON/OFF Switch  G    <->   7      Arduino
+ *  Adafruit RGB ON/OFF Switch  B    <->   8      Arduino
+ *  Adafruit RGB ON/OFF Switch  NC   <->   EN     Adafruit Power Boost 500
+ *  
+ * Wiring Button (Colors)
+ * R = Orange
+ * G = Grey
+ * B = Violett
+ * C+ = White
+ * C = Blue
+ * NC = Yellow
+ * NO (Center) = Green
+
+ * Wiring 22mm Button
+ * 1 -> EN
+ * 2 -> GND
+ * 
+ * 
+ * Challenges, Problems, Errors, etc.
+ * - SOLVED:  Standard SoftwareSerial Library does not work with SAMD Controllers. (Serial1 is now passing through)
+ * - SOLVED:    HTTP Post: https://forum.arduino.cc/t/mkr-nb-1500-http-post/680965
+ *            -> SIM-Card does not support NB-IoT: https://www.a1.net/nb-iot
+ *            -> Sending SMS works, but no GPRS connection via NB-IoT.
+ * - SOLVED:  GPS needs 3minutes to get a fix. (Using TinyGPS++ Library)
+ * - SOLVED:  Arduino does not work with battery (Use Power Boost 500 Module)
+ * - SOLVED:  Button LED is not lighting correct if system runs on battery (arduino not connect to Power via USB).
+ *            -> it's color is white ??? WHY; Turns green if arduino is connected to USB
+ *            -> Moved activation of Button to the top of setup()
+              -> see aml_pocobo2_testledbutton.ino
+ * - OPEN:    LED stays green for a long time if sensor is inside (NO GPS).
+ * - OPEN:    Indicating low battery level by use of LBO pin
+ *            -> https://forums.adafruit.com/viewtopic.php?f=19&p=757864
+              -> How to use the LB Pin on the Power boost?
+              -> https://forums.adafruit.com/viewtopic.php?f=19&t=58281
+              -> https://forums.adafruit.com/viewtopic.php?f=19&t=80260
+              -> https://forums.adafruit.com/viewtopic.php?p=379644
+              -> https://forum.arduino.cc/t/adafruit-powerboost-500c-arduino-micro-lbo/251123
+              -> https://electronics.stackexchange.com/questions/334472/general-electrical-question-with-regards-to-the-lbo-pin-on-the-adafruit-boost-5
+              
+ * - SOlVED:  After switching OFF and ON again, the SEN54 delivers nan results
+ *            -> works after uploading the code, but not after switching OFF and ON again with the button.
+ * - SOLVED:    LED Works correctly with battery if Arduino is powered via VCC 
+              -> This should not be correct, as this is the 3.3v Power I/O
+              -> Check wiring
+              = Works also via VIN 9.1.24
+ * - TODO:    Send status messages to the Datahub.
+ * - TODO:    Get Battery status
+ * - SOLVED:     Device restarts every 20 secs (sampling interval)
+              - Battery is charged
+              - LED is connected to the LBO
+ * - SOLVED:   GPS sends only two decimals
+              - https://forum.arduino.cc/t/tinygpsplus-gives-out-the-location-only-up-to-two-decimals/601442 
+              - String function seems to cut decimals: String(double) https://forum.arduino.cc/t/string-function-seems-to-be-rounding-doubles/642177
+              - include numer of decimals (6) when casting to String.
+ * - BUG:     After putting sensor inside (no gps, LED green) and then outside again pocobo does not send data to server. gets stuck
+              - does not get accross this line in sendtodatahub: if (client.connect(server, port))   
+ * TODO:      If an error occurs update the led immediately. (and make sure it is not overridden);      
+              
+
+ *         
+ *
+ *
+ *
+ *
+ * 
+ * SOURCE TOKENS:
+ *    POCOBO 2 - 0: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjE5LCJpYXQiOjE2Mzc5MzIzMjF9.fGMMPIMp-yHKX7yqddMKU3ItpcwiGD4srkY1-vj0Pz4
+      POCOBO 2 - 1: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjIxLCJpYXQiOjE3MTIwNjc4NTZ9._YmIoqeE98XWNu629MFS1OOGGzWxPnKH-zI06zFWOnI
+      POCOBO 2 - 2: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjIzLCJpYXQiOjE3NDUzMTgxOTJ9.n2c2huqnC5p4MRaBf-NksLlNKcW976t1mwZMOPhiBa4
+      Pocobo 2 - 3: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI0LCJpYXQiOjE3NDY3MDgxOTJ9.pKcHaTF88j6usI55lnWdgdXk9PESK4mGbKn6nf9Vv7A
+      Pocobo 2 - 4: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI1LCJpYXQiOjE3NDY3MDgyNzF9.UzfhKlXXXO8uFUsBgvVkLg19dRZBHP5rjXvncYZ2JeA
+ *    
+ */
+
+
+
+#include <MKRNB.h>
+#include <TinyGPS++.h>
+#include <SparkFun_I2C_GPS_Arduino_Library.h>
+#include <RGBLed.h>
+#include <Arduino.h>
+#include <SensirionI2CSen5x.h>
+#include <Wire.h>
+
+// The used commands use up to 48 bytes. On some Arduino's the default buffer
+// space is not large enough
+#define MAXBUF_REQUIREMENT 48
+
+#if (defined(I2C_BUFFER_LENGTH) && (I2C_BUFFER_LENGTH >= MAXBUF_REQUIREMENT)) || (defined(BUFFER_LENGTH) && BUFFER_LENGTH >= MAXBUF_REQUIREMENT)
+#define USE_PRODUCT_INFO
+#endif
+
+
+
+#define rLEDPIN 6  // Pin for red Button LED
+#define gLEDPIN 7  // Pin for green Button LED
+#define bLEDPIN 8  // Pin for blue Button LED
+#define batPin 5   // Pin to detect if battery gets low
+
+RGBLed ledButton(rLEDPIN, gLEDPIN, bLEDPIN, RGBLed::COMMON_ANODE);
+byte curR = 0;
+byte curG = 0;
+byte curB = 0;
+
+SensirionI2CSen5x sen5x;
+
+// The TinyGPS++ object
+I2CGPS myI2CGPS;  //Hook object to the library
+TinyGPSPlus gps;
+boolean encodeGPSAgain = false;
+
+
+//Connection to DATAhub
+//NBClient client(false);
+//Otherwise the NBClient.connect() method waits until the internet connection gets ready, if you explicitly prohibit this it will wait forever.
+NBClient client(false);
+GPRS gprs;
+NB nbAccess;
+boolean connected = false;
+
+//Forwarder address for non SSL: http://forwarder.aml.media.tuwien.ac.at:11313/receive-reading/{token}
+// URL, path and port (for example: example.org
+// URL DATAHUB = "http://aml.media.tuwien.ac.at:11312/api/sensordata/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI0LCJpYXQiOjE3NDY3MDgxOTJ9.pKcHaTF88j6usI55lnWdgdXk9PESK4mGbKn6nf9Vv7A";
+char server[] = "aml.media.tuwien.ac.at";
+//char server[] = "forwarder.aml.media.tuwien.ac.at";
+// IMPORTANT: Place correct source Token here: THIS IS POCOBO 2 - 3
+char path[] = "/api/sensordata/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI0LCJpYXQiOjE3NDY3MDgxOTJ9.pKcHaTF88j6usI55lnWdgdXk9PESK4mGbKn6nf9Vv7A";
+int port = 11312;  // port 80 is the default for HTTP
+
+
+//Measured Data
+float lastPM1 = 0;
+float lastPM25 = 0;
+float lastPM4 = 0;
+float lastPM10 = 0;
+float lastHumidity = 0;
+float lastTemperature = 0;
+float lastVocIndex = 0;
+float lastNoxIndex = 0;
+
+
+//Timing
+unsigned long currentMillis = 0;
+
+uint32_t printTimer = millis();  //Just a timer for printing out values
+
+unsigned long sendToDATAhubInterval = 20000;  //20sek; Interval for sending data to webservice = Data sampling interval
+unsigned long lastSendToDATAhub = 0;
+
+//String URL = "http://aml.media.tuwien.ac.at:11312/api/sensordata/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjE0LCJpYXQiOjE2MDA4NDY0MDR9.0BPUK7NVTlqi7i9QFx9kcVY55jsn0qskPWDL1PKyKec";
+
+
+// Sensor Status
+// used for the LED
+// 0 = Startup
+// 1 = Sensor Running / Everything is fine
+// 2 = Measuring Data (Optional)
+// 3 = No GPS
+// 4 = No cell network
+// 5 = Battery Low
+// 6 = Sensor Error
+// 7 = Testoutput
+byte statusInfo = 0;
+
+//int sendcount = 0;
+
+
+
+/********************************************* SETUP *********************************************************/
+void setup() {
+
+  updateLED(statusInfo);
+
+  pinMode(batPin, INPUT_PULLUP);
+
+  Serial.begin(115200);
+  Serial1.begin(9600);
+
+  //sendcount = 0;
+
+  //while(!Serial);                  // UNCOMMENT(remove)
+
+
+  // CONNECT Cell network
+  //Serial.println("Starting connection to NB-IOT Service (A1)");
+  // connection state
+  //updateLED(4);
+
+  connected = false;
+
+    // After starting the modem with NB.begin()
+  // attach to the GPRS network with the APN, login and password
+  connectToNetwork();
+  updateLED(statusInfo);
+
+
+  Wire.begin();
+
+  //Connect GPS to I2C
+  //updateLED(3);
+  if (myI2CGPS.begin() == false) {
+    //Serial.println("GPS Module failed to respond. Please check wiring.");
+    statusInfo = 3;
+    updateLED(statusInfo);
+    while (1)
+      ;  //Freeze!
+  }
+
+  encodeGPS();
+  updateLED(statusInfo);
+
+
+  // Init SEN54
+  //updateLED(6);
+
+
+  sen5x.begin(Wire);
+
+  uint16_t error;
+  char errorMessage[256];
+  error = sen5x.deviceReset();
+  if (error) {
+    //Serial.print("Error trying to execute deviceReset(): ");
+    errorToString(error, errorMessage, 256);
+    //Serial.println(errorMessage);
+    statusInfo = 6;
+    updateLED(statusInfo);
+  }
+
+
+  // set a temperature offset in degrees celsius
+  // Note: supported by SEN54 and SEN55 sensors
+  // By default, the temperature and humidity outputs from the sensor
+  // are compensated for the modules self-heating. If the module is
+  // designed into a device, the temperature compensation might need
+  // to be adapted to incorporate the change in thermal coupling and
+  // self-heating of other device components.
+  //
+  // A guide to achieve optimal performance, including references
+  // to mechanical design-in examples can be found in the app note
+  // “SEN5x – Temperature Compensation Instruction” at www.sensirion.com.
+  // Please refer to those application notes for further information
+  // on the advanced compensation settings used
+  // in `setTemperatureOffsetParameters`, `setWarmStartParameter` and
+  // `setRhtAccelerationMode`.
+  //
+  // Adjust tempOffset to account for additional temperature offsets
+  // exceeding the SEN module's self heating.
+  float tempOffset = 0.0;
+  error = sen5x.setTemperatureOffsetSimple(tempOffset);
+  if (error) {
+    //Serial.print("Error trying to execute setTemperatureOffsetSimple(): ");
+    errorToString(error, errorMessage, 256);
+    //Serial.println(errorMessage);
+    statusInfo = 6;
+    updateLED(statusInfo);
+
+  } else {
+    //Serial.print("Temperature Offset set to ");
+    //Serial.print(tempOffset);
+    //Serial.println(" deg. Celsius (SEN54/SEN55 only");
+  }
+
+
+  //Do an initial reading
+  readSEN();
+  updateLED(statusInfo);
+
+  if (statusInfo == 0) statusInfo = 1;  //Init finished without error. Statusinfo is still 0
+
+  updateLED(statusInfo);
+
+}
+
+
+
+/********************************************* LOOP *********************************************************/
+void loop() {
+
+  //updateLED(7);
+
+
+  //Sending to DATAhub
+  currentMillis = millis();
+
+  if ((currentMillis - lastSendToDATAhub >= sendToDATAhubInterval)) {
+
+    lastSendToDATAhub = currentMillis;
+
+    updateLED(2);
+
+    Serial.println("start sending");
+
+    
+
+
+    //TODO: Do this in a certain time interval
+    //Serial.println("Start checking battery!");
+    //checkBattery(); //does not really work ???
+
+    //Encode GPS
+    //Serial.println("Start encoding gps!");
+    encodeGPS();
+
+    //Read Sensor Data
+    //INFO: Perhaps better to put in a timed interval; Also see sds.setCustomWorkingPeriod
+    //Serial.println("Start reading sensor data!");
+    readSEN();
+    //Serial.println("After Sensor read; before DELAY");
+    delay(1000);
+
+    //Sending data to DATAhub Webservice
+    //Serial.print("Start sending to DATAhub. statusInfo: ");
+    //Serial.println(statusInfo);
+    /*if (!gps.location.isUpdated()) {
+      Serial.println("ERROR: GPS data not updated (no new signal)");
+      statusInfo = 3;
+      updateLED(statusInfo);
+    }*/
+
+    int satNum = gps.satellites.value();
+    Serial.println("Satellites: " + String(satNum));
+
+    //encodeGPS();  //Encode again
+    if (statusInfo != 3 && statusInfo != 4 && statusInfo != 6) {  //no gps, mobile connection and sensor error -> send
+
+      sendToDATAhub();
+    }
+    
+    //sendToDATAhub();
+
+    updateLED(statusInfo);
+  }
+}
+
+/********************************************* sendToDATAhub *********************************************************/
+void sendToDATAhub() {
+
+
+
+  //Serial.println("connecting to DATAhub...");
+  //Serial.println("Getting geo json datastring");
+  String dataString = getGeoJSONDataString();
+  //Serial.println("GOT Geo json datastring");
+
+  unsigned int len = dataString.length() + 1;
+  char data[len];
+  dataString.toCharArray(data, len);
+  
+  //Serial.println("Transformed geo json data string to char array.");
+  Serial.println("Server: " + String(server) + " Port: " + String(port));
+  // if you get a connection, report back via serial:
+  if (client.connect(server, port)) {
+    
+    Serial.println("connected to server -> YAY I CAME ACROSS THE CONNECTION PART!");
+    
+    //if (statusInfo != 3 && statusInfo != 4 && statusInfo != 6) {
+      // Make a HTTP request:
+      client.print("POST ");
+      client.print(path);
+      client.println(" HTTP/1.1");
+      client.print("Host: ");
+      client.println(server);
+      client.println("Content-Type: text/plain");
+      client.print("Content-Length: ");
+      client.println(strlen(data));
+      client.println();
+      client.println(data);
+      client.println("Connection: close");
+      client.println();
+    //}
+
+    Serial.println("...sent to DATAhub!");
+
+    if(statusInfo ==2) statusInfo = 1;
+    
+
+  } else {
+    // if you didn't get a connection to the server:
+    Serial.println("sendToDATAhub: connection failed");
+    statusInfo = 4;
+    updateLED(statusInfo);
+    connected = false;
+    Serial.println("Shutting down the modem");
+    nbAccess.shutdown();   //restart the modem
+    delay(5000);
+    connectToNetwork();
+    
+    
+  }
+}
+
+void connectToNetwork() {
+    // After starting the modem with NB.begin()
+  // attach to the GPRS network with the APN, login and password
+  //&& (gprs.attachGPRS() == GPRS_READY)
+  while (!connected) {
+    
+    
+    Serial.println("Connecting to network!");
+    
+    if ((nbAccess.begin() == NB_READY)) {
+      Serial.println("Connected to NB-IOT Service (A1)");
+      connected = true;
+      if(statusInfo ==2) statusInfo = 1;
+    } else {
+      Serial.println("Not connected to NB-IOT Service (A1)");
+      delay(1000);
+      statusInfo = 4;
+      updateLED(statusInfo);
+    }
+  }
+}
+
+/********************************************* encodeGPS *********************************************************/
+void encodeGPS() {
+
+  unsigned long start = millis();
+  // For one second we parse GPS data and report some key values
+  for (start; millis() - start < 1000;) {
+    while (myI2CGPS.available()) {  //available() returns the number of new bytes available from the GPS module
+      gps.encode(myI2CGPS.read());  //Feed the GPS parser
+    }
+  }
+
+  //Debugging
+  //if we haven't seen lots of data in 5 seconds, something's wrong.
+  if (start > 5000 && gps.charsProcessed() < 10) {
+    //Serial.println("ERROR: Not getting any GPS data! Encoding again");
+    statusInfo = 3;
+    updateLED(statusInfo);
+    encodeGPS();                         //Encode again
+  } else if (!gps.location.isValid()) {  //also add timer for circumstances when there is definately no signal to find
+    Serial.println("ERROR: GPS Data not valid! Encoding again");
+    statusInfo = 3;
+    updateLED(statusInfo);
+    encodeGPS();  //Encode again
+  } else if (gps.satellites.value() < 3) {
+    Serial.println("ERROR: Not enough GPS satellites");
+    statusInfo = 3;
+    updateLED(statusInfo);
+    //encodeGPS();  //Encode again
+  } else {
+    if(statusInfo ==2) statusInfo = 1; //no error occured
+  }
+
+
+  //printGPSData();
+}
+
+/********************************************* PrintGPSDATA *********************************************************/
+void printGPSData() {
+
+  //We have new GPS data to deal with!
+  Serial.println();
+
+  if (gps.time.isValid()) {
+    Serial.print(F("Date: "));
+    Serial.print(gps.date.month());
+    Serial.print(F("/"));
+    Serial.print(gps.date.day());
+    Serial.print(F("/"));
+    Serial.print(gps.date.year());
+
+    Serial.print((" Time: "));
+    if (gps.time.hour() < 10) Serial.print(F("0"));
+    Serial.print(gps.time.hour());
+    Serial.print(F(":"));
+    if (gps.time.minute() < 10) Serial.print(F("0"));
+    Serial.print(gps.time.minute());
+    Serial.print(F(":"));
+    if (gps.time.second() < 10) Serial.print(F("0"));
+    Serial.print(gps.time.second());
+
+    Serial.println();  //Done printing time
+  } else {
+    Serial.println(F("Time not yet valid"));
+  }
+
+  if (gps.location.isValid()) {
+    Serial.print("Location: ");
+    Serial.print(gps.location.lat(), 6);
+    Serial.print(F(", "));
+    Serial.print(gps.location.lng(), 6);
+    Serial.println();
+  } else {
+    Serial.println(F("Location not yet valid"));
+  }
+}
+
+/********************************************* readSEN *********************************************************/
+void readSEN() {
+  
+  
+
+  // Start Measurement //TODO: Remove from setup()?
+  uint16_t error;
+  char errorMessage[256];
+  error = sen5x.startMeasurement();
+  if (error) {
+    //Serial.print("Error trying to execute startMeasurement(): ");
+    errorToString(error, errorMessage, 256);
+    //Serial.println(errorMessage);
+    statusInfo = 6;
+    updateLED(statusInfo);
+  }
+
+  error = sen5x.readMeasuredValues(
+    lastPM1, lastPM25, lastPM4,
+    lastPM10, lastHumidity, lastTemperature, lastVocIndex,
+    lastNoxIndex);
+
+  if (error) {
+    //Serial.print("Error trying to execute readMeasuredValues(): ");
+    errorToString(error, errorMessage, 256);
+    //Serial.println(errorMessage);
+    statusInfo = 6;
+    updateLED(statusInfo);
+  } else {
+    //printSen54Data();
+    if(statusInfo ==2) statusInfo = 1;
+    
+  }
+
+  //status = 7;
+
+
+
+
+
+
+  delay(1000);
+
+  //updateLED(statusInfo);
+}
+
+/********************************************* printSEN54DATA *********************************************************/
+void printSen54Data() {
+
+  Serial.print("PM 1.0: ");
+  Serial.print(lastPM1);
+  Serial.print("\t");
+  Serial.print("PM 2.5: ");
+  Serial.print(lastPM25);
+  Serial.print("\t");
+  Serial.print("PM 4.0: ");
+  Serial.print(lastPM4);
+  Serial.print("\t");
+  Serial.print("PM 10.0: ");
+  Serial.print(lastPM10);
+  Serial.print("\t");
+  Serial.print("Humidity: ");
+  if (isnan(lastHumidity)) {
+    Serial.print("n/a");
+  } else {
+    Serial.print(lastHumidity);
+  }
+  Serial.print("\t");
+  Serial.print("Temperature: ");
+  if (isnan(lastTemperature)) {
+    Serial.print("n/a");
+  } else {
+    Serial.print(lastTemperature);
+  }
+  Serial.print("\t");
+  Serial.print("VocIndex: ");
+  if (isnan(lastVocIndex)) {
+    Serial.print("n/a");
+  } else {
+    Serial.print(lastVocIndex);
+  }
+  Serial.print("\t");
+  Serial.print("NoxIndex: ");
+  if (isnan(lastNoxIndex)) {
+    Serial.println("n/a");
+  } else {
+    Serial.println(lastNoxIndex);
+  }
+}
+
+
+
+/********************************************* getGEOJSONDataString *********************************************************/
+String getGeoJSONDataString() {
+
+
+  /* GeoJSON should look like this:
+    {
+      "type": "Feature",
+      "geometry": {
+        "type": "Point",
+        "coordinates": [100.0, 0.0]
+      },
+      "properties": {
+        "PM 1": [5.5, "myg/m3"],
+        "PM 2.5": [43.5, "myg/m3"],
+        "PM 4": [10.5, "myg/m3"],
+        "PM 10": [21.5, "myg/m3"],
+        "Humidity": [70, "%"],
+        "Temperature": [23,5, "°C"],
+        "VOC": [102, "VOC Index"],
+        "timestamp": "123456723495",
+      }
+    }
+  */
+
+  /*
+  String json =   "{\"type\":\"Feature\",\"geometry\":{\"type\": \"Point\", \"coordinates\":["+ String(gps.location.lat()) + "," + String(gps.location.lng()) + "]}, \"properties\": {\"PM 1\":[" +  String(lastPM1) + ", \"myg/m3\"], \"PM 2.5\":[" +  String(lastPM25) + ", \"myg/m3\"], \"PM 4\":[" +  String(lastPM4) + ", \"myg/m3\"], \"PM 10\":[" + String(lastPM10) + ", \"myg/m3\"], \"Humidity\":[" + 
+                  String(lastHumidity) + ", \"%\"], \"Temperature\":[" + String(lastTemperature) + ", \"°C\"], \"VOC\":[" + String(lastVocIndex) + ", \"VOC Index"], \"timestamp\":\"""\"}}";
+  */
+
+  String json = "{\"type\":\"Feature\",\"geometry\":{\"type\": \"Point\", \"coordinates\":[" + String(gps.location.lng(), 6) + "," + String(gps.location.lat(), 6) + "]}, \"properties\": {\"PM 1\":[" + String(lastPM1) + ", \"myg/m3\"], \"PM 2.5\":[" + String(lastPM25) + ", \"myg/m3\"], \"PM 4\":[" + String(lastPM4) + ", \"myg/m3\"], \"PM 10\":[" + String(lastPM10) + ", \"myg/m3\"], \"Humidity\":[" + String(lastHumidity) + ", \"%\"], \"Temperature\":[" + String(lastTemperature) + ", \"°C\"], \"VOC\":[" + String(lastVocIndex) + ", \"VOC Index\"], \"timestamp\":\"""\"}}";
+
+  //TODO: print this out!
+  //Serial.println(json);
+
+  //Serial.println("GeoJSON Datastring built");
+
+  return json;
+}
+
+/********************************************* GetGeoJSONTestString *********************************************************/
+String getGeoJSONTestString() {
+
+
+  /* GeoJSON should look like this:
+    {
+      "type": "Feature",
+      "geometry": {
+        "type": "Point",
+        "coordinates": [100.0, 0.0]
+      },
+      "properties": {
+        "Temperature": [24.5, "°C"],
+        "Noise": [100.0, "dB"],
+        "timestamp": "123456723495",
+      }
+    }
+  */
+
+  //String json = "{\"type\":\"Feature\",\"geometry\":{\"type\": \"Point\", \"coordinates\":[16.791124, 47.865672]}, \"properties\": {\"Temperature\":[35, \"°C\"], \"Noise\":[130, \"dB\"], \"timestamp\":\"\"}}";
+
+  String json = "{\"type\":\"Feature\",\"geometry\":{\"type\": \"Point\", \"coordinates\":[16.504511, 48.225247]}, \"properties\": {\"PM 1\":[" + String(lastPM1) + ", \"myg/m3\"], \"PM 2.5\":[" + String(lastPM25) + ", \"myg/m3\"], \"PM 4\":[" + String(lastPM4) + ", \"myg/m3\"], \"PM 10\":[" + String(lastPM10) + ", \"myg/m3\"], \"Humidity\":[" + String(lastHumidity) + ", \"%\"], \"Temperature\":[" + String(lastTemperature) + ", \"°C\"], \"VOC\":[" + String(lastVocIndex) + ", \"VOC Index\"], \"timestamp\":\""
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            "\"}}";
+  return json;
+}
+/********************************************* checkBattery *********************************************************/
+void checkBattery() {
+
+  //DOES NOT WORK: LOW LED on the Powerboost is active but batPin reading is 1
+
+  // reads the pin connect to the LBO output of the powerboost 500 Unit
+  int batState = digitalRead(batPin);
+
+
+  if (batState == LOW) {
+
+    //Sets the LED to red if battery is low
+    statusInfo = 5;
+    updateLED(statusInfo);
+  }
+
+  //Serial.println("Battery state: " + batState);
+}
+
+/********************************************* updateLED *********************************************************/
+void updateLED(byte status) {
+
+  //Status and LED Colours:
+  //0 = While Setup/Startup:          YELLOW (255, 225, 0)
+  //1 = Running & Everything is OK:   GREEN (0, 255, 0)
+  //2 = Measuring DATA:               GREEN (200, 255, 50)
+  //3 = NO GPS Signal/Position/Fix:   BLUE (0, 0, 255)
+  //4 = NO Cell Network/Connection:   PINK (255, 0, 255)
+  //5 = Batterry low:                 RED (255, 0, 0)
+  //6 = Sensor Error:                 VIOLETT (170, 0, 255)
+  //7 = TESTOUTPUT                    GREEN/PETROL (3, 252, 177)
+
+  statusInfo = status;
+
+  if (status == 0) {
+    ledButton.crossFade(curR, curG, curB, 255, 255, 0, 10, 500);
+    curR = 255;
+    curG = 255;
+    curB = 0;
+  } else if (status == 1) {
+    ledButton.crossFade(curR, curG, curB, 0, 255, 0, 10, 500);
+    curR = 0;
+    curG = 255;
+    curB = 0;
+    //} else if (status == 2) { ledButton.flash(200, 255, 50, 50);
+  } else if (status == 2) {
+    ledButton.crossFade(curR, curG, curB, 200, 255, 50, 10, 500);
+    //ledButton.flash(200, 255, 50, 1000);
+    curR = 200;
+    curG = 255;
+    curB = 50;
+  } else if (status == 3) {
+    ledButton.crossFade(curR, curG, curB, 0, 0, 255, 10, 500);
+    curR = 0;
+    curG = 0;
+    curB = 255;
+  } else if (status == 4) {
+    ledButton.crossFade(curR, curG, curB, 255, 0, 255, 10, 500);
+    curR = 255;
+    curG = 0;
+    curB = 255;
+  } else if (status == 5) {
+    ledButton.crossFade(curR, curG, curB, 255, 0, 0, 10, 500);
+    curR = 255;
+    curG = 0;
+    curB = 0;
+  } else if (status == 6) {
+    ledButton.crossFade(curR, curG, curB, 170, 0, 255, 10, 500);
+    curR = 170;
+    curG = 0;
+    curB = 255;
+  } else if (status == 7) {
+    ledButton.crossFade(curR, curG, curB, 3, 252, 177, 10, 500);
+    curR = 3;
+    curG = 252;
+    curB = 177;  //Testoutput
+  }
+
+  statusInfo = status;
+}