Fully functional code for LÜTR v1.

Dependencies:   PM2_Libary Adafruit_GFX BME680

Committer:
pfammjur
Date:
Tue May 25 07:50:24 2021 +0000
Revision:
18:5019da899a41
Parent:
17:80e441d2b10a
finalized Code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pfammjur 15:d14167e8c555 1 /*
pfammjur 18:5019da899a41 2 * Written by Juri Pfammatter 25/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 17:80e441d2b10a 21 #define ARRAYLENGTH 60
pfammjur 17:80e441d2b10a 22
pfammjur 15:d14167e8c555 23
pfammjur 15:d14167e8c555 24 using namespace std::chrono; //Namespce für printf usw...
pfammjur 15:d14167e8c555 25
pfammjur 15:d14167e8c555 26
pfammjur 15:d14167e8c555 27 /* BME680 */
pfammjur 16:7536b5d2365c 28 I2C i2c(I2C_SDA, I2C_SCL); //I2C Zuweisung Used inside the BME680 Mbed Lib.
pfammjur 15:d14167e8c555 29 BME680 bme680(0x77 << 1); //Object erstellen (<<1 für mbed 8bit Adresse)
pfammjur 15:d14167e8c555 30
pfammjur 15:d14167e8c555 31 /* OLED */
pfammjur 15:d14167e8c555 32 DigitalOut myled(LED1);
pfammjur 15:d14167e8c555 33 /* an I2C sub-class that provides a constructed default */
pfammjur 15:d14167e8c555 34 class I2CPreInit : public I2C
pfammjur 15:d14167e8c555 35 {
pfammjur 15:d14167e8c555 36 public:
pfammjur 15:d14167e8c555 37 I2CPreInit(PinName sda, PinName scl) : I2C(sda, scl)
pfammjur 15:d14167e8c555 38 {
pfammjur 15:d14167e8c555 39 frequency(400000);
pfammjur 15:d14167e8c555 40 //start();
pfammjur 15:d14167e8c555 41 };
pfammjur 15:d14167e8c555 42 };
pfammjur 15:d14167e8c555 43
pfammjur 15:d14167e8c555 44 I2CPreInit gI2C(I2C_SDA, I2C_SCL);
pfammjur 15:d14167e8c555 45 Adafruit_SSD1306_I2c oled(gI2C,D4,0x7A,64,128);
pfammjur 15:d14167e8c555 46
pfammjur 15:d14167e8c555 47
pfammjur 15:d14167e8c555 48 /* Futaba Servo S3001 20mm 3kg Analog */
pfammjur 15:d14167e8c555 49 // 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 50 // create servo objects
pfammjur 15:d14167e8c555 51 Servo servo_S1(PB_2);
pfammjur 15:d14167e8c555 52 int servoPeriod_mus = 20000; //Zeitperiode
pfammjur 15:d14167e8c555 53 int servoMax = 580, servoMin = 350; //2300: 180 ; 300: 0
pfammjur 18:5019da899a41 54 //float a = -2.3, b = 810; //Gas -> Rotation
pfammjur 18:5019da899a41 55 //Anpassung an defekten Sensor
pfammjur 18:5019da899a41 56 float a = -23, b = 695;
pfammjur 17:80e441d2b10a 57 float tempA = 0.8369, tempB = -0.6236; //Temperaturkompensation
pfammjur 15:d14167e8c555 58
pfammjur 15:d14167e8c555 59
pfammjur 15:d14167e8c555 60 /* Methodendeklaration */
pfammjur 15:d14167e8c555 61 void servoPos(int pos,int wait1, int wait2);
pfammjur 15:d14167e8c555 62 void checkExtreme(float temp, float hum, int press, int voc, bool reset);
pfammjur 16:7536b5d2365c 63 void setAverage(float temp, float hum, int press, int voc, int arraynr);
pfammjur 16:7536b5d2365c 64 int getAverageI(int array[]);
pfammjur 16:7536b5d2365c 65 float getAverageF(float array[]);
pfammjur 15:d14167e8c555 66
pfammjur 15:d14167e8c555 67 /* Zeitmanagement */
pfammjur 15:d14167e8c555 68 bool executeMainTask = false;
pfammjur 15:d14167e8c555 69 Timer power_button_timer,mode_button_timer, loop_timer;
pfammjur 17:80e441d2b10a 70 int Ts_ms = 500; //Durchlaufzeit -> 2Hz
pfammjur 17:80e441d2b10a 71 int mode = 1; //Anzeigemodus: Start auf aktuellen Werten
pfammjur 17:80e441d2b10a 72 int counter = 0; //Zähler für verschiedene Frequnzen
pfammjur 15:d14167e8c555 73
pfammjur 17:80e441d2b10a 74 /* Arrays für Mittelwerte*/
pfammjur 17:80e441d2b10a 75 float tempAr[ARRAYLENGTH], humAr[ARRAYLENGTH];
pfammjur 17:80e441d2b10a 76 int pressAr[ARRAYLENGTH], vocAr[ARRAYLENGTH];
pfammjur 16:7536b5d2365c 77 int arrayNr = 0;
pfammjur 17:80e441d2b10a 78 int firstRound = 0;
pfammjur 16:7536b5d2365c 79 bool firstLap = true;
pfammjur 16:7536b5d2365c 80
pfammjur 15:d14167e8c555 81 /* Sonstige Parameter */
pfammjur 17:80e441d2b10a 82 bool maxOneTime = true; //identische Position maximal ein Mal einstellen
pfammjur 15:d14167e8c555 83 bool resetExtreme = true; //reset
pfammjur 15:d14167e8c555 84 float temp, maxTemp, minTemp, hum, maxHum, minHum;
pfammjur 15:d14167e8c555 85 int press, maxPress, minPress, voc, maxVoc, minVoc;
pfammjur 15:d14167e8c555 86
pfammjur 15:d14167e8c555 87
pfammjur 15:d14167e8c555 88 /* Buttons */
pfammjur 15:d14167e8c555 89 InterruptIn power_button(D6);
pfammjur 15:d14167e8c555 90 InterruptIn mode_button(D5);
pfammjur 15:d14167e8c555 91 void power_button_fall();
pfammjur 15:d14167e8c555 92 void power_button_rise();
pfammjur 15:d14167e8c555 93 void mode_button_fall();
pfammjur 15:d14167e8c555 94 void mode_button_rise();
pfammjur 15:d14167e8c555 95
pfammjur 15:d14167e8c555 96 /* Setup */
pfammjur 15:d14167e8c555 97 void setup(){ //Setup wird 1 mal durchlaufen
pfammjur 15:d14167e8c555 98 loop_timer.start();
pfammjur 15:d14167e8c555 99 power_button.mode(PullUp); //interner PullUp
pfammjur 15:d14167e8c555 100 power_button.fall(&power_button_fall); //von 1 auf 0
pfammjur 15:d14167e8c555 101 power_button.rise(&power_button_rise); //von 0 auf 1
pfammjur 15:d14167e8c555 102 mode_button.mode(PullUp);
pfammjur 15:d14167e8c555 103 mode_button.fall(&mode_button_fall);
pfammjur 15:d14167e8c555 104 mode_button.rise(&mode_button_rise);
pfammjur 15:d14167e8c555 105 oled.clearDisplay();
pfammjur 15:d14167e8c555 106 oled.splashCustomLogo(); //Logo Anzeigen lassen
pfammjur 15:d14167e8c555 107 oled.display();
pfammjur 15:d14167e8c555 108 thread_sleep_for(1000);
pfammjur 16:7536b5d2365c 109 set_time(1620477341); //Set RTC time to Wed, 21. April 2021 19:28:30 https://www.epochconverter.com/
pfammjur 15:d14167e8c555 110 thread_sleep_for(1000);
pfammjur 15:d14167e8c555 111 oled.clearDisplay();
pfammjur 15:d14167e8c555 112 if (!bme680.begin()) { //begin() startet Sensor: Vorheizen usw...
pfammjur 15:d14167e8c555 113 oled.printf("BME680 Begin failed \r\n"); //Fehlermeldung
pfammjur 17:80e441d2b10a 114 }else{
pfammjur 17:80e441d2b10a 115 bme680.performReading(); //Nullwerte abfangen
pfammjur 15:d14167e8c555 116 }
pfammjur 15:d14167e8c555 117 servoPos(servoMax,1000,1000); //Endpositionen anfahren
pfammjur 15:d14167e8c555 118 servoPos(servoMin,1000,1000);
pfammjur 15:d14167e8c555 119
pfammjur 15:d14167e8c555 120
pfammjur 15:d14167e8c555 121 }
pfammjur 15:d14167e8c555 122
pfammjur 15:d14167e8c555 123 int main()
pfammjur 15:d14167e8c555 124 {
pfammjur 15:d14167e8c555 125 setup();
pfammjur 15:d14167e8c555 126
pfammjur 15:d14167e8c555 127 while(true)
pfammjur 15:d14167e8c555 128 {
pfammjur 15:d14167e8c555 129 loop_timer.reset(); //Timer reset
pfammjur 15:d14167e8c555 130 oled.setTextCursor(0,0); //Textposition reset
pfammjur 15:d14167e8c555 131
pfammjur 15:d14167e8c555 132 if(executeMainTask){
pfammjur 15:d14167e8c555 133
pfammjur 15:d14167e8c555 134 /* Zeit */
pfammjur 15:d14167e8c555 135 time_t seconds = time(NULL);
pfammjur 15:d14167e8c555 136 char timebuffer[32];
pfammjur 15:d14167e8c555 137 strftime(timebuffer, 32, "%b %d %Y %H:%M:%S", localtime(&seconds));//Nur Stunde, Minuten, Sekunden auslesen
pfammjur 15:d14167e8c555 138 oled.printf("%s", timebuffer);
pfammjur 15:d14167e8c555 139
pfammjur 15:d14167e8c555 140 oled.setTextCursor(0,15); //Vertikaler Abstand
pfammjur 15:d14167e8c555 141
pfammjur 15:d14167e8c555 142 /* Werte auslesen */
pfammjur 15:d14167e8c555 143 if (bme680.performReading()) {
pfammjur 18:5019da899a41 144 temp = tempA*bme680.getTemperature()+tempB; //Temperaturkompensation
pfammjur 15:d14167e8c555 145 hum = bme680.getHumidity();
pfammjur 15:d14167e8c555 146 press = static_cast<int>(bme680.getPressure()/100);
pfammjur 15:d14167e8c555 147 voc = static_cast<int>(bme680.getGasResistance()/1000.0);
pfammjur 15:d14167e8c555 148 }else{
pfammjur 15:d14167e8c555 149 oled.printf("Failed to perform reading :(\n");
pfammjur 15:d14167e8c555 150 }
pfammjur 16:7536b5d2365c 151 /* Mittelwerte */
pfammjur 17:80e441d2b10a 152 if(((counter%(24*3600/ARRAYLENGTH)==0)&& !firstLap)||((counter%(3600/ARRAYLENGTH)==0)&& firstLap)){ //erste 30min: array füllen; danach alle 30 min einen Wert eintragen
pfammjur 16:7536b5d2365c 153 setAverage(temp, hum, press, voc, arrayNr);
pfammjur 17:80e441d2b10a 154 (arrayNr==(ARRAYLENGTH-1))? arrayNr= 0: arrayNr++;
pfammjur 16:7536b5d2365c 155 }
pfammjur 15:d14167e8c555 156 /* Extremwerte */
pfammjur 15:d14167e8c555 157 checkExtreme(temp, hum, press, voc, resetExtreme);
pfammjur 15:d14167e8c555 158
pfammjur 15:d14167e8c555 159 /* Anzeige */
pfammjur 15:d14167e8c555 160 switch (mode){
pfammjur 16:7536b5d2365c 161 case 1: oled.printf("Aktuellwerte\r\n");
pfammjur 16:7536b5d2365c 162 oled.printf("Temperatur: %.2f C\r\n",temp);
pfammjur 15:d14167e8c555 163 oled.printf("Luftf.: %.2f %%\r\n",hum);
pfammjur 15:d14167e8c555 164 oled.printf("Luftdr.: %d hPa\r\n",press);
pfammjur 15:d14167e8c555 165 oled.printf("VOC: %d kOhm\r\n",voc);
pfammjur 15:d14167e8c555 166 oled.display();
pfammjur 15:d14167e8c555 167 break;
pfammjur 15:d14167e8c555 168
pfammjur 16:7536b5d2365c 169 case 2: oled.printf("Mittelwerte\r\n");
pfammjur 16:7536b5d2365c 170 oled.printf("Temperatur: %.2f C\r\n",getAverageF(tempAr));
pfammjur 16:7536b5d2365c 171 oled.printf("Luftf.: %.2f %%\r\n",getAverageF(humAr));
pfammjur 16:7536b5d2365c 172 oled.printf("Luftdr.: %d hPa\r\n",getAverageI(pressAr));
pfammjur 16:7536b5d2365c 173 oled.printf("VOC: %d kOhm\r\n",getAverageI(vocAr));
pfammjur 15:d14167e8c555 174 oled.display();
pfammjur 15:d14167e8c555 175 break;
pfammjur 15:d14167e8c555 176
pfammjur 16:7536b5d2365c 177 case 3: oled.printf("Extremwerte\r\n");
pfammjur 16:7536b5d2365c 178 oled.printf("Temp: %.1f %.1f C\r\n",minTemp, maxTemp);
pfammjur 15:d14167e8c555 179 oled.printf("Luftf.: %.1f %.1f %%\r\n",minHum, maxHum);
pfammjur 15:d14167e8c555 180 oled.printf("Luftd.: %d %d hPa\r\n",minPress, maxPress);
pfammjur 15:d14167e8c555 181 oled.printf("VOC: %d %d kOhm\r\n",minVoc, maxVoc);
pfammjur 15:d14167e8c555 182 oled.display();
pfammjur 15:d14167e8c555 183 break;
pfammjur 15:d14167e8c555 184 }
pfammjur 15:d14167e8c555 185
pfammjur 15:d14167e8c555 186 /* Servo */
pfammjur 17:80e441d2b10a 187 if(counter%10==0){ //Nur alle 5s Position ändern
pfammjur 15:d14167e8c555 188 int output = static_cast<int>(a*(bme680.getGasResistance()/1000.0)+b);
pfammjur 15:d14167e8c555 189 if(output>=servoMin && output<=servoMax){
pfammjur 15:d14167e8c555 190 servoPos(output,250,0);
pfammjur 15:d14167e8c555 191 maxOneTime = true;
pfammjur 15:d14167e8c555 192 }else if(output <= servoMin){
pfammjur 15:d14167e8c555 193 if(maxOneTime){
pfammjur 15:d14167e8c555 194 servoPos(servoMin,250,0);
pfammjur 15:d14167e8c555 195 maxOneTime = false;
pfammjur 15:d14167e8c555 196 }
pfammjur 15:d14167e8c555 197 }else{
pfammjur 15:d14167e8c555 198 if(maxOneTime){
pfammjur 15:d14167e8c555 199 servoPos(servoMax,250,0);
pfammjur 15:d14167e8c555 200 maxOneTime = false;
pfammjur 15:d14167e8c555 201 }
pfammjur 15:d14167e8c555 202 }
pfammjur 15:d14167e8c555 203 }
pfammjur 15:d14167e8c555 204
pfammjur 15:d14167e8c555 205 /* Timer */
pfammjur 15:d14167e8c555 206 int T_loop_ms = duration_cast<milliseconds>(loop_timer.elapsed_time()).count();
pfammjur 15:d14167e8c555 207 int dT_loop_ms = Ts_ms - T_loop_ms;
pfammjur 15:d14167e8c555 208 if(dT_loop_ms>=0 && dT_loop_ms<=Ts_ms)thread_sleep_for(dT_loop_ms);
pfammjur 17:80e441d2b10a 209
pfammjur 15:d14167e8c555 210 oled.clearDisplay();
pfammjur 17:80e441d2b10a 211
pfammjur 17:80e441d2b10a 212 (counter==1440000)?counter=0: counter++; //Zähler um 1 erhöhen und nach 720000s wiederholen
pfammjur 17:80e441d2b10a 213 if(counter==3600){ //Erste Runde um Array zu füllen
pfammjur 16:7536b5d2365c 214 firstLap = false;
pfammjur 16:7536b5d2365c 215 }
pfammjur 15:d14167e8c555 216
pfammjur 15:d14167e8c555 217 }else{
pfammjur 15:d14167e8c555 218 oled.clearDisplay();
pfammjur 15:d14167e8c555 219 oled.display();
pfammjur 17:80e441d2b10a 220 if(maxOneTime){
pfammjur 17:80e441d2b10a 221 servoPos(servoMax,Ts_ms,0);
pfammjur 17:80e441d2b10a 222 maxOneTime = false;
pfammjur 17:80e441d2b10a 223 }
pfammjur 15:d14167e8c555 224 }
pfammjur 15:d14167e8c555 225 }
pfammjur 15:d14167e8c555 226 }
pfammjur 15:d14167e8c555 227
pfammjur 15:d14167e8c555 228 //* Methoden *//
pfammjur 15:d14167e8c555 229 /* Servo Position */
pfammjur 15:d14167e8c555 230 void servoPos(int pos,int wait1,int wait2){
pfammjur 15:d14167e8c555 231 servo_S1.Enable(servoMin, servoPeriod_mus);
pfammjur 15:d14167e8c555 232 servo_S1.SetPosition(pos);
pfammjur 15:d14167e8c555 233 thread_sleep_for(wait1);
pfammjur 15:d14167e8c555 234 servo_S1.Disable();
pfammjur 15:d14167e8c555 235 thread_sleep_for(wait2);
pfammjur 15:d14167e8c555 236 }
pfammjur 15:d14167e8c555 237 /* Power-Buttons */
pfammjur 15:d14167e8c555 238 void power_button_fall()
pfammjur 15:d14167e8c555 239 {
pfammjur 15:d14167e8c555 240 power_button_timer.reset();
pfammjur 15:d14167e8c555 241 power_button_timer.start();
pfammjur 15:d14167e8c555 242 }
pfammjur 15:d14167e8c555 243
pfammjur 15:d14167e8c555 244 void power_button_rise()
pfammjur 15:d14167e8c555 245 {
pfammjur 15:d14167e8c555 246 int t_button = duration_cast<milliseconds>(power_button_timer.elapsed_time()).count();
pfammjur 15:d14167e8c555 247 power_button_timer.stop();
pfammjur 15:d14167e8c555 248 if(t_button > 30){
pfammjur 15:d14167e8c555 249 resetExtreme = true;
pfammjur 15:d14167e8c555 250 executeMainTask = !executeMainTask;
pfammjur 15:d14167e8c555 251 }
pfammjur 15:d14167e8c555 252 }
pfammjur 15:d14167e8c555 253 /* Mode-Buttons */
pfammjur 15:d14167e8c555 254 void mode_button_fall()
pfammjur 15:d14167e8c555 255 {
pfammjur 15:d14167e8c555 256 mode_button_timer.reset();
pfammjur 15:d14167e8c555 257 mode_button_timer.start();
pfammjur 15:d14167e8c555 258 }
pfammjur 15:d14167e8c555 259
pfammjur 15:d14167e8c555 260 void mode_button_rise()
pfammjur 15:d14167e8c555 261 {
pfammjur 15:d14167e8c555 262 int t_button = duration_cast<milliseconds>(mode_button_timer.elapsed_time()).count();
pfammjur 15:d14167e8c555 263 mode_button_timer.stop();
pfammjur 15:d14167e8c555 264 if(t_button > 30) {
pfammjur 15:d14167e8c555 265 (mode!=3) ? mode++ : mode=1;
pfammjur 15:d14167e8c555 266 }
pfammjur 15:d14167e8c555 267 }
pfammjur 16:7536b5d2365c 268
pfammjur 16:7536b5d2365c 269 /* Mittelwerte */
pfammjur 16:7536b5d2365c 270 void setAverage(float temp, float hum, int press, int voc, int arrayNr){
pfammjur 16:7536b5d2365c 271 tempAr[arrayNr] = temp;
pfammjur 16:7536b5d2365c 272 humAr[arrayNr] = hum;
pfammjur 16:7536b5d2365c 273 pressAr[arrayNr] = press;
pfammjur 16:7536b5d2365c 274 vocAr[arrayNr] = voc;
pfammjur 17:80e441d2b10a 275 if(firstRound<ARRAYLENGTH)firstRound++; //Arraylänge für Durchschnitt
pfammjur 16:7536b5d2365c 276 }
pfammjur 16:7536b5d2365c 277
pfammjur 17:80e441d2b10a 278 int getAverageI(int array[]){ //int als Rückgabewert
pfammjur 17:80e441d2b10a 279 int sum = 0;
pfammjur 17:80e441d2b10a 280 for(int j=0; j<firstRound;j++){
pfammjur 17:80e441d2b10a 281 if(array[j]!=0)sum+=array[j];
pfammjur 17:80e441d2b10a 282 }
pfammjur 17:80e441d2b10a 283 return sum/firstRound;
pfammjur 17:80e441d2b10a 284 }
pfammjur 17:80e441d2b10a 285
pfammjur 17:80e441d2b10a 286 float getAverageF(float array[]){ //float als Rückgabewert
pfammjur 16:7536b5d2365c 287 float sum = 0;
pfammjur 17:80e441d2b10a 288 for(int j=0; j<firstRound;j++){
pfammjur 17:80e441d2b10a 289 if(array[j]!=0)sum+=array[j];
pfammjur 16:7536b5d2365c 290 }
pfammjur 17:80e441d2b10a 291 return sum/firstRound;
pfammjur 16:7536b5d2365c 292 }
pfammjur 16:7536b5d2365c 293
pfammjur 15:d14167e8c555 294 /* Extemwerte */
pfammjur 15:d14167e8c555 295 void checkExtreme(float temp, float hum, int press, int voc, bool reset){
pfammjur 15:d14167e8c555 296 if(reset){ //reset
pfammjur 15:d14167e8c555 297 minTemp = temp;
pfammjur 15:d14167e8c555 298 maxTemp = temp;
pfammjur 15:d14167e8c555 299 minHum = hum;
pfammjur 15:d14167e8c555 300 maxHum = hum;
pfammjur 15:d14167e8c555 301 minPress = press;
pfammjur 15:d14167e8c555 302 maxPress = press;
pfammjur 15:d14167e8c555 303 minVoc = voc;
pfammjur 15:d14167e8c555 304 maxVoc = voc;
pfammjur 15:d14167e8c555 305 resetExtreme = false;
pfammjur 15:d14167e8c555 306 }
pfammjur 15:d14167e8c555 307 if(temp >= maxTemp)maxTemp = temp;
pfammjur 15:d14167e8c555 308 if(temp <= minTemp||minTemp <= 1.0)minTemp = temp;
pfammjur 15:d14167e8c555 309 if(hum >= maxHum) maxHum = hum;
pfammjur 15:d14167e8c555 310 if(hum <= minHum||minHum <= 1.0)minHum = hum;
pfammjur 15:d14167e8c555 311 if(press >= maxPress) maxPress = press;
pfammjur 15:d14167e8c555 312 if(press <= minPress||minPress <= 1)minPress = press;
pfammjur 15:d14167e8c555 313 if(voc >= maxVoc) maxVoc = voc;
pfammjur 15:d14167e8c555 314 if(voc <= minVoc||minVoc <= 1)minVoc = voc;
pfammjur 15:d14167e8c555 315 }