finalized code of LUTR v1

Dependencies:   PM2_Libary Adafruit_GFX BME680

Revision:
15:d14167e8c555
Child:
16:7536b5d2365c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue May 11 17:20:21 2021 +0000
@@ -0,0 +1,254 @@
+/*
+ *  Written by Juri Pfammatter 1/5/2021 for use in mbedOS
+ *
+ *  Inspired by Neal Horman - http://www.wanlink.com
+            and Adafruit - http://www.adafruit.com
+ */
+ 
+#include "mbed.h"
+#include "Adafruit_SSD1306.h"
+#include "mbed_bme680.h"
+#include "platform/mbed_thread.h"
+#include "Servo.h"
+#include "FastPWM.h"
+
+/*Defines BME680*/
+#define BME_SCK 13
+#define BME_MISO 12
+#define BME_MOSI 11
+#define BME_CS 10
+
+  
+using namespace std::chrono;                                                    //Namespce für printf usw...
+  
+  
+/* BME680 */
+I2C i2c(I2C_SDA, I2C_SCL);                                                      // I2C Zuweisung Used inside the BME680 Mbed Lib.
+BME680 bme680(0x77 << 1);                                                       //Object erstellen (<<1 für mbed 8bit Adresse)
+
+/* OLED */
+DigitalOut myled(LED1);
+/* an I2C sub-class that provides a constructed default */
+class I2CPreInit : public I2C
+{
+public:
+    I2CPreInit(PinName sda, PinName scl) : I2C(sda, scl)
+    {
+        frequency(400000);
+        //start();
+    };
+};
+
+I2CPreInit gI2C(I2C_SDA, I2C_SCL);
+Adafruit_SSD1306_I2c oled(gI2C,D4,0x7A,64,128);
+
+
+/* Futaba Servo S3001 20mm 3kg Analog */
+// https://www.modellmarkt24.ch/pi/RC-Elektronik/Servos/Standard-Servo-20mm/futaba-servo-s3001-20mm-3kg-analog.html?gclid=CjwKCAjw3pWDBhB3EiwAV1c5rK_-x_Bt19_wIY-IcS2C-RULXKBtYfY0byxejkZLjASro-EMPBUhrxoCgaQQAvD_BwE
+// create servo objects
+Servo servo_S1(PB_2);
+int servoPeriod_mus = 20000;                                                    //Zeitperiode
+int servoMax = 580, servoMin = 350;                                             //2300: 180 ; 300: 0
+float a = -2.3, b = 810;                                                        //Gas -> Rotation
+
+
+/* Methodendeklaration */
+void servoPos(int pos,int wait1, int wait2);
+void checkExtreme(float temp, float hum, int press, int voc, bool reset);
+
+/* Zeitmanagement */
+bool           executeMainTask = false;
+Timer          power_button_timer,mode_button_timer, loop_timer;
+int            Ts_ms = 500;                                                     //Durchlaufzeit
+int            mode = 1;
+int            counter = 0;
+
+/* Sonstige Parameter */
+bool maxOneTime = true;                                                         //identische Position maximal ein mal einstellen
+bool resetExtreme = true;                                                       //reset
+float temp, maxTemp, minTemp, hum, maxHum, minHum;
+int press, maxPress, minPress, voc, maxVoc, minVoc;
+
+
+/* Buttons */
+InterruptIn    power_button(D6);
+InterruptIn    mode_button(D5);
+void           power_button_fall();          
+void           power_button_rise();
+void           mode_button_fall();
+void           mode_button_rise();
+
+/* Setup */
+void setup(){                                                                   //Setup wird 1 mal durchlaufen
+    loop_timer.start();
+    power_button.mode(PullUp);                                                  //interner PullUp
+    power_button.fall(&power_button_fall);                                      //von 1 auf 0
+    power_button.rise(&power_button_rise);                                      //von 0 auf 1
+    mode_button.mode(PullUp);
+    mode_button.fall(&mode_button_fall);
+    mode_button.rise(&mode_button_rise);
+    oled.clearDisplay();
+    oled.splashCustomLogo();                                                    //Logo Anzeigen lassen
+    oled.display();
+    thread_sleep_for(1000);                                                     
+    set_time(1620477341);                                                       // Set RTC time to Wed, 21. April 2021 19:28:30 https://www.epochconverter.com/
+    thread_sleep_for(1000);
+    oled.clearDisplay();
+    if (!bme680.begin()) {                                                      //begin() startet Sensor: Vorheizen usw...
+        oled.printf("BME680 Begin failed \r\n");                                //Fehlermeldung
+    }
+    servoPos(servoMax,1000,1000);                                               //Endpositionen anfahren
+    servoPos(servoMin,1000,1000);
+    
+    
+}
+
+int main()
+{   
+    setup();
+    
+    while(true)
+    {
+        loop_timer.reset();                                                     //Timer reset
+        oled.setTextCursor(0,0);                                                //Textposition reset
+        
+        if(executeMainTask){
+            
+            /* Zeit */
+            time_t seconds = time(NULL);
+            char timebuffer[32];
+            strftime(timebuffer, 32, "%b %d %Y  %H:%M:%S", localtime(&seconds));//Nur Stunde, Minuten, Sekunden auslesen
+            oled.printf("%s", timebuffer);
+            
+            oled.setTextCursor(0,15);                                           //Vertikaler Abstand
+            
+            /* Werte auslesen */
+            if (bme680.performReading()) {                          
+                temp = bme680.getTemperature()-4.0;
+                hum = bme680.getHumidity();
+                press = static_cast<int>(bme680.getPressure()/100);
+                voc = static_cast<int>(bme680.getGasResistance()/1000.0);
+            }else{
+                oled.printf("Failed to perform reading :(\n");
+            }
+            
+            /* Extremwerte */
+            checkExtreme(temp, hum, press, voc, resetExtreme);
+            
+            /* Anzeige */
+            switch (mode){
+                case 1: oled.printf("Temperatur:  %.2f C\r\n",temp);
+                        oled.printf("Luftf.:      %.2f %%\r\n",hum);
+                        oled.printf("Luftdr.:     %d hPa\r\n",press);
+                        oled.printf("VOC:         %d kOhm\r\n",voc);
+                        oled.display();
+                        break;
+                    
+                case 2: oled.printf("Mittelwerte");
+                        oled.display();
+                        break;
+                    
+                case 3: oled.printf("Temp:   %.1f %.1f C\r\n",minTemp, maxTemp);
+                        oled.printf("Luftf.: %.1f %.1f %%\r\n",minHum, maxHum);
+                        oled.printf("Luftd.: %d  %d hPa\r\n",minPress, maxPress);
+                        oled.printf("VOC:    %d  %d kOhm\r\n",minVoc, maxVoc);
+                        oled.display();
+                        break;
+            }
+            
+            /* Servo */
+            if(counter%10==0){
+                int output = static_cast<int>(a*(bme680.getGasResistance()/1000.0)+b);
+                if(output>=servoMin && output<=servoMax){
+                    servoPos(output,250,0);
+                    maxOneTime = true;
+                }else if(output <= servoMin){
+                    if(maxOneTime){
+                        servoPos(servoMin,250,0);  
+                        maxOneTime = false;
+                    }
+                }else{    
+                    if(maxOneTime){
+                        servoPos(servoMax,250,0);  
+                        maxOneTime = false;
+                    } 
+                }
+            }
+            
+            /* Timer */
+            int T_loop_ms = duration_cast<milliseconds>(loop_timer.elapsed_time()).count();
+            int dT_loop_ms = Ts_ms - T_loop_ms;
+            if(dT_loop_ms>=0 && dT_loop_ms<=Ts_ms)thread_sleep_for(dT_loop_ms);
+            oled.clearDisplay();
+            (counter==10000) ? counter=0 : counter++;
+            
+        }else{
+            oled.clearDisplay();
+            oled.display();
+            servoPos(servoMax,Ts_ms,0);
+        }
+    }
+}
+
+//* Methoden *//
+/* Servo Position */
+void servoPos(int pos,int wait1,int wait2){
+    servo_S1.Enable(servoMin, servoPeriod_mus);
+    servo_S1.SetPosition(pos);
+    thread_sleep_for(wait1);
+    servo_S1.Disable();
+    thread_sleep_for(wait2);
+}
+/* Power-Buttons */
+void power_button_fall()
+{
+    power_button_timer.reset();
+    power_button_timer.start();
+}
+ 
+void power_button_rise()
+{
+    int t_button = duration_cast<milliseconds>(power_button_timer.elapsed_time()).count();
+    power_button_timer.stop();
+    if(t_button > 30){
+        resetExtreme = true;
+        executeMainTask = !executeMainTask;
+    }
+}
+/* Mode-Buttons */
+void mode_button_fall()
+{
+    mode_button_timer.reset();
+    mode_button_timer.start();
+}
+ 
+void mode_button_rise()
+{
+    int t_button = duration_cast<milliseconds>(mode_button_timer.elapsed_time()).count();
+    mode_button_timer.stop();
+    if(t_button > 30) {
+        (mode!=3) ? mode++ : mode=1;   
+    }
+}
+/* Extemwerte */
+void checkExtreme(float temp, float hum, int press, int voc, bool reset){
+        if(reset){                                                              //reset
+            minTemp = temp;
+            maxTemp = temp;
+            minHum = hum;
+            maxHum = hum;
+            minPress = press;
+            maxPress = press;
+            minVoc = voc;
+            maxVoc = voc;
+            resetExtreme = false;
+        }
+        if(temp >= maxTemp)maxTemp = temp;
+        if(temp <= minTemp||minTemp <= 1.0)minTemp = temp;
+        if(hum >= maxHum) maxHum = hum;
+        if(hum <= minHum||minHum <= 1.0)minHum = hum;
+        if(press >= maxPress) maxPress = press;
+        if(press <= minPress||minPress <= 1)minPress = press;
+        if(voc >= maxVoc) maxVoc = voc;
+        if(voc <= minVoc||minVoc <= 1)minVoc = voc;
+    }