finalized code of LUTR v1

Dependencies:   PM2_Libary Adafruit_GFX BME680

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?

UserRevisionLine numberNew 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 }