finalized code of LUTR v1
Dependencies: PM2_Libary Adafruit_GFX BME680
Diff: main.cpp
- 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; + }