Juri Pfammatter / Mbed OS LÜTR

Dependencies:   PM2_Libary Adafruit_GFX BME680

BME680OLED.cpp

Committer:
pfammjur
Date:
2021-05-10
Revision:
13:c9035c1e77a1
Parent:
12:b217d70735ec
Child:
14:ebd47e8c6360

File content as of revision 13:c9035c1e77a1:

/*
 *  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 OLED
#define SCREEN_ADRESS 0x3D
//Defines BME680
#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10
  
#define SEALEVELPRESSURE_HPA (1013.25)
  
using namespace std::chrono;                                                    //Namespce für printf
  
  
//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);
static BufferedSerial pc(USBTX, USBRX);                                         //pc Seriel für baud
// 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 servoOutput_mus_S1 = 0;
int servo_counter = 0;
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;
int            mode = 1;
int            counter = 0;

//Sonstige Parameter
bool maxOneTime = true;                                                     //identische Position maximal ein mal einstellen
bool resetExtreme = false;
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();

void setup(){                                                                   //Setup wird 1 mal durchlaufen
    loop_timer.start();
    power_button.mode(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);
    thread_sleep_for(1000);                                                     //Logo Anzeigen lassen
    pc.set_baud(9600);                                                          //baudrate
    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);
    servoPos(servoMin,1000,1000);
    
    
}

int main()
{   
    setup();
    resetExtreme = true;
    
    while(true)
    {
        loop_timer.reset();
        oled.setTextCursor(0,0);
        
        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);
            
            //Werte auslesen
            temp = bme680.getTemperature()-4.0;
            hum = bme680.getHumidity();
            press = static_cast<int>(bme680.getPressure()/100);
            voc = static_cast<int>(bme680.getGasResistance()/1000.0);
            
            //Extermwerte
            checkExtreme(temp, hum, press, voc, resetExtreme);
            
            //Anzeige
            
            switch (mode){
                case 1:
                    if (bme680.performReading()) {                                                                          //Sensor auslesen
                        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();
                    }else{
                        printf("Failed to perform reading :(\n");
                    }
                    break;
                    
                case 2:
                    if (bme680.performReading()) {
                        oled.printf("Mittelwerte");
                        oled.display();
                    }else{
                        printf("Failed to perform reading :(\n");
                    }
                    break;
                    
                case 3:
                    if (bme680.performReading()) {
                        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();
                    }else{
                        printf("Failed to perform reading :(\n");
                    }
                    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;
                    } 
                }
            }
            //LED
            //myled = !myled;
            
            //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);
        }
    }
}

//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);
}
//User-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){                                                         //Initialwerte setzen
            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;
    }