finalized code of LUTR v1

Dependencies:   PM2_Libary Adafruit_GFX BME680

Committer:
pfammjur
Date:
Sun May 23 11:53:32 2021 +0000
Revision:
17:80e441d2b10a
Parent:
16:7536b5d2365c
Child:
18:5019da899a41
added temperature compensation

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