Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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;
}