finalized code of LUTR v1
Dependencies: PM2_Libary Adafruit_GFX BME680
main.cpp@15:d14167e8c555, 2021-05-11 (annotated)
- Committer:
- pfammjur
- Date:
- Tue May 11 17:20:21 2021 +0000
- Revision:
- 15:d14167e8c555
- Child:
- 16:7536b5d2365c
added comments
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
pfammjur | 15:d14167e8c555 | 1 | /* |
pfammjur | 15:d14167e8c555 | 2 | * Written by Juri Pfammatter 1/5/2021 for use in mbedOS |
pfammjur | 15:d14167e8c555 | 3 | * |
pfammjur | 15:d14167e8c555 | 4 | * Inspired by Neal Horman - http://www.wanlink.com |
pfammjur | 15:d14167e8c555 | 5 | and Adafruit - http://www.adafruit.com |
pfammjur | 15:d14167e8c555 | 6 | */ |
pfammjur | 15:d14167e8c555 | 7 | |
pfammjur | 15:d14167e8c555 | 8 | #include "mbed.h" |
pfammjur | 15:d14167e8c555 | 9 | #include "Adafruit_SSD1306.h" |
pfammjur | 15:d14167e8c555 | 10 | #include "mbed_bme680.h" |
pfammjur | 15:d14167e8c555 | 11 | #include "platform/mbed_thread.h" |
pfammjur | 15:d14167e8c555 | 12 | #include "Servo.h" |
pfammjur | 15:d14167e8c555 | 13 | #include "FastPWM.h" |
pfammjur | 15:d14167e8c555 | 14 | |
pfammjur | 15:d14167e8c555 | 15 | /*Defines BME680*/ |
pfammjur | 15:d14167e8c555 | 16 | #define BME_SCK 13 |
pfammjur | 15:d14167e8c555 | 17 | #define BME_MISO 12 |
pfammjur | 15:d14167e8c555 | 18 | #define BME_MOSI 11 |
pfammjur | 15:d14167e8c555 | 19 | #define BME_CS 10 |
pfammjur | 15:d14167e8c555 | 20 | |
pfammjur | 15:d14167e8c555 | 21 | |
pfammjur | 15:d14167e8c555 | 22 | using namespace std::chrono; //Namespce für printf usw... |
pfammjur | 15:d14167e8c555 | 23 | |
pfammjur | 15:d14167e8c555 | 24 | |
pfammjur | 15:d14167e8c555 | 25 | /* BME680 */ |
pfammjur | 15:d14167e8c555 | 26 | I2C i2c(I2C_SDA, I2C_SCL); // I2C Zuweisung Used inside the BME680 Mbed Lib. |
pfammjur | 15:d14167e8c555 | 27 | BME680 bme680(0x77 << 1); //Object erstellen (<<1 für mbed 8bit Adresse) |
pfammjur | 15:d14167e8c555 | 28 | |
pfammjur | 15:d14167e8c555 | 29 | /* OLED */ |
pfammjur | 15:d14167e8c555 | 30 | DigitalOut myled(LED1); |
pfammjur | 15:d14167e8c555 | 31 | /* an I2C sub-class that provides a constructed default */ |
pfammjur | 15:d14167e8c555 | 32 | class I2CPreInit : public I2C |
pfammjur | 15:d14167e8c555 | 33 | { |
pfammjur | 15:d14167e8c555 | 34 | public: |
pfammjur | 15:d14167e8c555 | 35 | I2CPreInit(PinName sda, PinName scl) : I2C(sda, scl) |
pfammjur | 15:d14167e8c555 | 36 | { |
pfammjur | 15:d14167e8c555 | 37 | frequency(400000); |
pfammjur | 15:d14167e8c555 | 38 | //start(); |
pfammjur | 15:d14167e8c555 | 39 | }; |
pfammjur | 15:d14167e8c555 | 40 | }; |
pfammjur | 15:d14167e8c555 | 41 | |
pfammjur | 15:d14167e8c555 | 42 | I2CPreInit gI2C(I2C_SDA, I2C_SCL); |
pfammjur | 15:d14167e8c555 | 43 | Adafruit_SSD1306_I2c oled(gI2C,D4,0x7A,64,128); |
pfammjur | 15:d14167e8c555 | 44 | |
pfammjur | 15:d14167e8c555 | 45 | |
pfammjur | 15:d14167e8c555 | 46 | /* Futaba Servo S3001 20mm 3kg Analog */ |
pfammjur | 15:d14167e8c555 | 47 | // 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 |
pfammjur | 15:d14167e8c555 | 48 | // create servo objects |
pfammjur | 15:d14167e8c555 | 49 | Servo servo_S1(PB_2); |
pfammjur | 15:d14167e8c555 | 50 | int servoPeriod_mus = 20000; //Zeitperiode |
pfammjur | 15:d14167e8c555 | 51 | int servoMax = 580, servoMin = 350; //2300: 180 ; 300: 0 |
pfammjur | 15:d14167e8c555 | 52 | float a = -2.3, b = 810; //Gas -> Rotation |
pfammjur | 15:d14167e8c555 | 53 | |
pfammjur | 15:d14167e8c555 | 54 | |
pfammjur | 15:d14167e8c555 | 55 | /* Methodendeklaration */ |
pfammjur | 15:d14167e8c555 | 56 | void servoPos(int pos,int wait1, int wait2); |
pfammjur | 15:d14167e8c555 | 57 | void checkExtreme(float temp, float hum, int press, int voc, bool reset); |
pfammjur | 15:d14167e8c555 | 58 | |
pfammjur | 15:d14167e8c555 | 59 | /* Zeitmanagement */ |
pfammjur | 15:d14167e8c555 | 60 | bool executeMainTask = false; |
pfammjur | 15:d14167e8c555 | 61 | Timer power_button_timer,mode_button_timer, loop_timer; |
pfammjur | 15:d14167e8c555 | 62 | int Ts_ms = 500; //Durchlaufzeit |
pfammjur | 15:d14167e8c555 | 63 | int mode = 1; |
pfammjur | 15:d14167e8c555 | 64 | int counter = 0; |
pfammjur | 15:d14167e8c555 | 65 | |
pfammjur | 15:d14167e8c555 | 66 | /* Sonstige Parameter */ |
pfammjur | 15:d14167e8c555 | 67 | bool maxOneTime = true; //identische Position maximal ein mal einstellen |
pfammjur | 15:d14167e8c555 | 68 | bool resetExtreme = true; //reset |
pfammjur | 15:d14167e8c555 | 69 | float temp, maxTemp, minTemp, hum, maxHum, minHum; |
pfammjur | 15:d14167e8c555 | 70 | int press, maxPress, minPress, voc, maxVoc, minVoc; |
pfammjur | 15:d14167e8c555 | 71 | |
pfammjur | 15:d14167e8c555 | 72 | |
pfammjur | 15:d14167e8c555 | 73 | /* Buttons */ |
pfammjur | 15:d14167e8c555 | 74 | InterruptIn power_button(D6); |
pfammjur | 15:d14167e8c555 | 75 | InterruptIn mode_button(D5); |
pfammjur | 15:d14167e8c555 | 76 | void power_button_fall(); |
pfammjur | 15:d14167e8c555 | 77 | void power_button_rise(); |
pfammjur | 15:d14167e8c555 | 78 | void mode_button_fall(); |
pfammjur | 15:d14167e8c555 | 79 | void mode_button_rise(); |
pfammjur | 15:d14167e8c555 | 80 | |
pfammjur | 15:d14167e8c555 | 81 | /* Setup */ |
pfammjur | 15:d14167e8c555 | 82 | void setup(){ //Setup wird 1 mal durchlaufen |
pfammjur | 15:d14167e8c555 | 83 | loop_timer.start(); |
pfammjur | 15:d14167e8c555 | 84 | power_button.mode(PullUp); //interner PullUp |
pfammjur | 15:d14167e8c555 | 85 | power_button.fall(&power_button_fall); //von 1 auf 0 |
pfammjur | 15:d14167e8c555 | 86 | power_button.rise(&power_button_rise); //von 0 auf 1 |
pfammjur | 15:d14167e8c555 | 87 | mode_button.mode(PullUp); |
pfammjur | 15:d14167e8c555 | 88 | mode_button.fall(&mode_button_fall); |
pfammjur | 15:d14167e8c555 | 89 | mode_button.rise(&mode_button_rise); |
pfammjur | 15:d14167e8c555 | 90 | oled.clearDisplay(); |
pfammjur | 15:d14167e8c555 | 91 | oled.splashCustomLogo(); //Logo Anzeigen lassen |
pfammjur | 15:d14167e8c555 | 92 | oled.display(); |
pfammjur | 15:d14167e8c555 | 93 | thread_sleep_for(1000); |
pfammjur | 15:d14167e8c555 | 94 | set_time(1620477341); // Set RTC time to Wed, 21. April 2021 19:28:30 https://www.epochconverter.com/ |
pfammjur | 15:d14167e8c555 | 95 | thread_sleep_for(1000); |
pfammjur | 15:d14167e8c555 | 96 | oled.clearDisplay(); |
pfammjur | 15:d14167e8c555 | 97 | if (!bme680.begin()) { //begin() startet Sensor: Vorheizen usw... |
pfammjur | 15:d14167e8c555 | 98 | oled.printf("BME680 Begin failed \r\n"); //Fehlermeldung |
pfammjur | 15:d14167e8c555 | 99 | } |
pfammjur | 15:d14167e8c555 | 100 | servoPos(servoMax,1000,1000); //Endpositionen anfahren |
pfammjur | 15:d14167e8c555 | 101 | servoPos(servoMin,1000,1000); |
pfammjur | 15:d14167e8c555 | 102 | |
pfammjur | 15:d14167e8c555 | 103 | |
pfammjur | 15:d14167e8c555 | 104 | } |
pfammjur | 15:d14167e8c555 | 105 | |
pfammjur | 15:d14167e8c555 | 106 | int main() |
pfammjur | 15:d14167e8c555 | 107 | { |
pfammjur | 15:d14167e8c555 | 108 | setup(); |
pfammjur | 15:d14167e8c555 | 109 | |
pfammjur | 15:d14167e8c555 | 110 | while(true) |
pfammjur | 15:d14167e8c555 | 111 | { |
pfammjur | 15:d14167e8c555 | 112 | loop_timer.reset(); //Timer reset |
pfammjur | 15:d14167e8c555 | 113 | oled.setTextCursor(0,0); //Textposition reset |
pfammjur | 15:d14167e8c555 | 114 | |
pfammjur | 15:d14167e8c555 | 115 | if(executeMainTask){ |
pfammjur | 15:d14167e8c555 | 116 | |
pfammjur | 15:d14167e8c555 | 117 | /* Zeit */ |
pfammjur | 15:d14167e8c555 | 118 | time_t seconds = time(NULL); |
pfammjur | 15:d14167e8c555 | 119 | char timebuffer[32]; |
pfammjur | 15:d14167e8c555 | 120 | strftime(timebuffer, 32, "%b %d %Y %H:%M:%S", localtime(&seconds));//Nur Stunde, Minuten, Sekunden auslesen |
pfammjur | 15:d14167e8c555 | 121 | oled.printf("%s", timebuffer); |
pfammjur | 15:d14167e8c555 | 122 | |
pfammjur | 15:d14167e8c555 | 123 | oled.setTextCursor(0,15); //Vertikaler Abstand |
pfammjur | 15:d14167e8c555 | 124 | |
pfammjur | 15:d14167e8c555 | 125 | /* Werte auslesen */ |
pfammjur | 15:d14167e8c555 | 126 | if (bme680.performReading()) { |
pfammjur | 15:d14167e8c555 | 127 | temp = bme680.getTemperature()-4.0; |
pfammjur | 15:d14167e8c555 | 128 | hum = bme680.getHumidity(); |
pfammjur | 15:d14167e8c555 | 129 | press = static_cast<int>(bme680.getPressure()/100); |
pfammjur | 15:d14167e8c555 | 130 | voc = static_cast<int>(bme680.getGasResistance()/1000.0); |
pfammjur | 15:d14167e8c555 | 131 | }else{ |
pfammjur | 15:d14167e8c555 | 132 | oled.printf("Failed to perform reading :(\n"); |
pfammjur | 15:d14167e8c555 | 133 | } |
pfammjur | 15:d14167e8c555 | 134 | |
pfammjur | 15:d14167e8c555 | 135 | /* Extremwerte */ |
pfammjur | 15:d14167e8c555 | 136 | checkExtreme(temp, hum, press, voc, resetExtreme); |
pfammjur | 15:d14167e8c555 | 137 | |
pfammjur | 15:d14167e8c555 | 138 | /* Anzeige */ |
pfammjur | 15:d14167e8c555 | 139 | switch (mode){ |
pfammjur | 15:d14167e8c555 | 140 | case 1: oled.printf("Temperatur: %.2f C\r\n",temp); |
pfammjur | 15:d14167e8c555 | 141 | oled.printf("Luftf.: %.2f %%\r\n",hum); |
pfammjur | 15:d14167e8c555 | 142 | oled.printf("Luftdr.: %d hPa\r\n",press); |
pfammjur | 15:d14167e8c555 | 143 | oled.printf("VOC: %d kOhm\r\n",voc); |
pfammjur | 15:d14167e8c555 | 144 | oled.display(); |
pfammjur | 15:d14167e8c555 | 145 | break; |
pfammjur | 15:d14167e8c555 | 146 | |
pfammjur | 15:d14167e8c555 | 147 | case 2: oled.printf("Mittelwerte"); |
pfammjur | 15:d14167e8c555 | 148 | oled.display(); |
pfammjur | 15:d14167e8c555 | 149 | break; |
pfammjur | 15:d14167e8c555 | 150 | |
pfammjur | 15:d14167e8c555 | 151 | case 3: oled.printf("Temp: %.1f %.1f C\r\n",minTemp, maxTemp); |
pfammjur | 15:d14167e8c555 | 152 | oled.printf("Luftf.: %.1f %.1f %%\r\n",minHum, maxHum); |
pfammjur | 15:d14167e8c555 | 153 | oled.printf("Luftd.: %d %d hPa\r\n",minPress, maxPress); |
pfammjur | 15:d14167e8c555 | 154 | oled.printf("VOC: %d %d kOhm\r\n",minVoc, maxVoc); |
pfammjur | 15:d14167e8c555 | 155 | oled.display(); |
pfammjur | 15:d14167e8c555 | 156 | break; |
pfammjur | 15:d14167e8c555 | 157 | } |
pfammjur | 15:d14167e8c555 | 158 | |
pfammjur | 15:d14167e8c555 | 159 | /* Servo */ |
pfammjur | 15:d14167e8c555 | 160 | if(counter%10==0){ |
pfammjur | 15:d14167e8c555 | 161 | int output = static_cast<int>(a*(bme680.getGasResistance()/1000.0)+b); |
pfammjur | 15:d14167e8c555 | 162 | if(output>=servoMin && output<=servoMax){ |
pfammjur | 15:d14167e8c555 | 163 | servoPos(output,250,0); |
pfammjur | 15:d14167e8c555 | 164 | maxOneTime = true; |
pfammjur | 15:d14167e8c555 | 165 | }else if(output <= servoMin){ |
pfammjur | 15:d14167e8c555 | 166 | if(maxOneTime){ |
pfammjur | 15:d14167e8c555 | 167 | servoPos(servoMin,250,0); |
pfammjur | 15:d14167e8c555 | 168 | maxOneTime = false; |
pfammjur | 15:d14167e8c555 | 169 | } |
pfammjur | 15:d14167e8c555 | 170 | }else{ |
pfammjur | 15:d14167e8c555 | 171 | if(maxOneTime){ |
pfammjur | 15:d14167e8c555 | 172 | servoPos(servoMax,250,0); |
pfammjur | 15:d14167e8c555 | 173 | maxOneTime = false; |
pfammjur | 15:d14167e8c555 | 174 | } |
pfammjur | 15:d14167e8c555 | 175 | } |
pfammjur | 15:d14167e8c555 | 176 | } |
pfammjur | 15:d14167e8c555 | 177 | |
pfammjur | 15:d14167e8c555 | 178 | /* Timer */ |
pfammjur | 15:d14167e8c555 | 179 | int T_loop_ms = duration_cast<milliseconds>(loop_timer.elapsed_time()).count(); |
pfammjur | 15:d14167e8c555 | 180 | int dT_loop_ms = Ts_ms - T_loop_ms; |
pfammjur | 15:d14167e8c555 | 181 | if(dT_loop_ms>=0 && dT_loop_ms<=Ts_ms)thread_sleep_for(dT_loop_ms); |
pfammjur | 15:d14167e8c555 | 182 | oled.clearDisplay(); |
pfammjur | 15:d14167e8c555 | 183 | (counter==10000) ? counter=0 : counter++; |
pfammjur | 15:d14167e8c555 | 184 | |
pfammjur | 15:d14167e8c555 | 185 | }else{ |
pfammjur | 15:d14167e8c555 | 186 | oled.clearDisplay(); |
pfammjur | 15:d14167e8c555 | 187 | oled.display(); |
pfammjur | 15:d14167e8c555 | 188 | servoPos(servoMax,Ts_ms,0); |
pfammjur | 15:d14167e8c555 | 189 | } |
pfammjur | 15:d14167e8c555 | 190 | } |
pfammjur | 15:d14167e8c555 | 191 | } |
pfammjur | 15:d14167e8c555 | 192 | |
pfammjur | 15:d14167e8c555 | 193 | //* Methoden *// |
pfammjur | 15:d14167e8c555 | 194 | /* Servo Position */ |
pfammjur | 15:d14167e8c555 | 195 | void servoPos(int pos,int wait1,int wait2){ |
pfammjur | 15:d14167e8c555 | 196 | servo_S1.Enable(servoMin, servoPeriod_mus); |
pfammjur | 15:d14167e8c555 | 197 | servo_S1.SetPosition(pos); |
pfammjur | 15:d14167e8c555 | 198 | thread_sleep_for(wait1); |
pfammjur | 15:d14167e8c555 | 199 | servo_S1.Disable(); |
pfammjur | 15:d14167e8c555 | 200 | thread_sleep_for(wait2); |
pfammjur | 15:d14167e8c555 | 201 | } |
pfammjur | 15:d14167e8c555 | 202 | /* Power-Buttons */ |
pfammjur | 15:d14167e8c555 | 203 | void power_button_fall() |
pfammjur | 15:d14167e8c555 | 204 | { |
pfammjur | 15:d14167e8c555 | 205 | power_button_timer.reset(); |
pfammjur | 15:d14167e8c555 | 206 | power_button_timer.start(); |
pfammjur | 15:d14167e8c555 | 207 | } |
pfammjur | 15:d14167e8c555 | 208 | |
pfammjur | 15:d14167e8c555 | 209 | void power_button_rise() |
pfammjur | 15:d14167e8c555 | 210 | { |
pfammjur | 15:d14167e8c555 | 211 | int t_button = duration_cast<milliseconds>(power_button_timer.elapsed_time()).count(); |
pfammjur | 15:d14167e8c555 | 212 | power_button_timer.stop(); |
pfammjur | 15:d14167e8c555 | 213 | if(t_button > 30){ |
pfammjur | 15:d14167e8c555 | 214 | resetExtreme = true; |
pfammjur | 15:d14167e8c555 | 215 | executeMainTask = !executeMainTask; |
pfammjur | 15:d14167e8c555 | 216 | } |
pfammjur | 15:d14167e8c555 | 217 | } |
pfammjur | 15:d14167e8c555 | 218 | /* Mode-Buttons */ |
pfammjur | 15:d14167e8c555 | 219 | void mode_button_fall() |
pfammjur | 15:d14167e8c555 | 220 | { |
pfammjur | 15:d14167e8c555 | 221 | mode_button_timer.reset(); |
pfammjur | 15:d14167e8c555 | 222 | mode_button_timer.start(); |
pfammjur | 15:d14167e8c555 | 223 | } |
pfammjur | 15:d14167e8c555 | 224 | |
pfammjur | 15:d14167e8c555 | 225 | void mode_button_rise() |
pfammjur | 15:d14167e8c555 | 226 | { |
pfammjur | 15:d14167e8c555 | 227 | int t_button = duration_cast<milliseconds>(mode_button_timer.elapsed_time()).count(); |
pfammjur | 15:d14167e8c555 | 228 | mode_button_timer.stop(); |
pfammjur | 15:d14167e8c555 | 229 | if(t_button > 30) { |
pfammjur | 15:d14167e8c555 | 230 | (mode!=3) ? mode++ : mode=1; |
pfammjur | 15:d14167e8c555 | 231 | } |
pfammjur | 15:d14167e8c555 | 232 | } |
pfammjur | 15:d14167e8c555 | 233 | /* Extemwerte */ |
pfammjur | 15:d14167e8c555 | 234 | void checkExtreme(float temp, float hum, int press, int voc, bool reset){ |
pfammjur | 15:d14167e8c555 | 235 | if(reset){ //reset |
pfammjur | 15:d14167e8c555 | 236 | minTemp = temp; |
pfammjur | 15:d14167e8c555 | 237 | maxTemp = temp; |
pfammjur | 15:d14167e8c555 | 238 | minHum = hum; |
pfammjur | 15:d14167e8c555 | 239 | maxHum = hum; |
pfammjur | 15:d14167e8c555 | 240 | minPress = press; |
pfammjur | 15:d14167e8c555 | 241 | maxPress = press; |
pfammjur | 15:d14167e8c555 | 242 | minVoc = voc; |
pfammjur | 15:d14167e8c555 | 243 | maxVoc = voc; |
pfammjur | 15:d14167e8c555 | 244 | resetExtreme = false; |
pfammjur | 15:d14167e8c555 | 245 | } |
pfammjur | 15:d14167e8c555 | 246 | if(temp >= maxTemp)maxTemp = temp; |
pfammjur | 15:d14167e8c555 | 247 | if(temp <= minTemp||minTemp <= 1.0)minTemp = temp; |
pfammjur | 15:d14167e8c555 | 248 | if(hum >= maxHum) maxHum = hum; |
pfammjur | 15:d14167e8c555 | 249 | if(hum <= minHum||minHum <= 1.0)minHum = hum; |
pfammjur | 15:d14167e8c555 | 250 | if(press >= maxPress) maxPress = press; |
pfammjur | 15:d14167e8c555 | 251 | if(press <= minPress||minPress <= 1)minPress = press; |
pfammjur | 15:d14167e8c555 | 252 | if(voc >= maxVoc) maxVoc = voc; |
pfammjur | 15:d14167e8c555 | 253 | if(voc <= minVoc||minVoc <= 1)minVoc = voc; |
pfammjur | 15:d14167e8c555 | 254 | } |