Kaynağa Gözat

fix fullauto mode.

Thomas Buck 2 yıl önce
ebeveyn
işleme
1d21b0d2d6
2 değiştirilmiş dosya ile 241 ekleme ve 33 silme
  1. 14
    1
      src/GPIOBank.cpp
  2. 227
    32
      src/Statemachine.cpp

+ 14
- 1
src/GPIOBank.cpp Dosyayı Görüntüle

@@ -19,6 +19,7 @@
19 19
 
20 20
 #include <Arduino.h>
21 21
 
22
+#include "DebugLog.h"
22 23
 #include "GPIOBank.h"
23 24
 #include "config.h"
24 25
 #include "config_pins.h"
@@ -34,6 +35,9 @@
34 35
 
35 36
 //#define GPIO_HIGH_AS_INPUT
36 37
 
38
+//#define DEBUG_PRINT_OUTPUTS
39
+//#define DEBUG_DISABLE_OUTPUTS
40
+
37 41
 // ----------------------------------------------------------------------------
38 42
 
39 43
 #if defined(TWI_GPIO) && (I2C_GPIO_EXPANDER_COUNT > 0)
@@ -74,6 +78,7 @@ static void gpio_pinMode(int pin, int value) {
74 78
 }
75 79
 
76 80
 static void gpio_digitalWrite(int pin, int value) {
81
+#ifndef DEBUG_DISABLE_OUTPUTS
77 82
     if (pin < 100) {
78 83
         digitalWrite(pin, value);
79 84
     } else if (pin < 0) {
@@ -88,6 +93,7 @@ static void gpio_digitalWrite(int pin, int value) {
88 93
         }
89 94
 #endif
90 95
     }
96
+#endif
91 97
 }
92 98
 
93 99
 static int gpio_digitalRead(int pin) {
@@ -186,7 +192,14 @@ void GPIOBank::setPin(int n, bool state) {
186 192
 #endif
187 193
 
188 194
         out_state[n] = !state;
189
-        
195
+
196
+#ifdef DEBUG_PRINT_OUTPUTS
197
+        debug.print("Set GPIO ");
198
+        debug.print(pins[n]);
199
+        debug.print(" to ");
200
+        debug.println(out_state[n]);
201
+#endif
202
+
190 203
 #ifdef PLATFORM_ESP
191 204
         wifi_schedule_websocket();
192 205
 #endif // PLATFORM_ESP

+ 227
- 32
src/Statemachine.cpp Dosyayı Görüntüle

@@ -348,18 +348,190 @@ void Statemachine::input(int n) {
348 348
         } else if (n == -2) {
349 349
             switch_to((state == auto_fert_a) ? auto_fert_b : auto_fert_a);
350 350
         }
351
+    } else if (state == fullauto_stirr_run) {
352
+        // allow user to stop stirring and continue with fertilizers
353
+        plants.abort();
354
+        stop_time = millis();
355
+        if (selected_ferts.countSet() > 0) {
356
+            selected_time = auto_pump_runtime[0];
357
+            for (int i = 0; i < plants.countFertilizers(); i++) {
358
+                if (auto_pump_runtime[i] > selected_time) {
359
+                    selected_time = auto_pump_runtime[i];
360
+                }
361
+
362
+                if (selected_ferts.isSet(i)) {
363
+                    plants.startFertilizer(i);
364
+                }
365
+            }
366
+
367
+            start_time = millis();
368
+            switch_to(fullauto_fert_run);
369
+        } else {
370
+            auto wl = plants.getWaterlevel();
371
+            if ((wl != Plants::full) && (wl != Plants::invalid)) {
372
+                // if the waterlevel is currently empty, we
373
+                // set a flag to record the time to fill
374
+                filling_started_empty = (wl == Plants::empty);
375
+
376
+                plants.openWaterInlet();
377
+                selected_id = plants.countPlants() + 1;
378
+                selected_time = MAX_TANK_FILL_TIME;
379
+                start_time = millis();
380
+                switch_to(fullauto_tank_run);
381
+            } else if (wl == Plants::full) {
382
+                // check if kickstart is required for this
383
+                bool need_kickstart = false;
384
+                for (int i = 0; i < plants.countPlants(); i++) {
385
+                    if (selected_plants.isSet(i)) {
386
+                        if (plants.getKickstart()->getPinNumber(i) >= 0) {
387
+                            need_kickstart = true;
388
+                        }
389
+                    }
390
+                }
391
+
392
+                // start kickstart/valve as needed
393
+                for (int i = 0; i < plants.countPlants(); i++) {
394
+                    if (selected_plants.isSet(i)) {
395
+                        plants.startPlant(i, need_kickstart);
396
+                    }
397
+                }
398
+
399
+                watering_started_full = (wl == Plants::full);
400
+
401
+                selected_time = MAX_AUTO_PLANT_RUNTIME;
402
+                start_time = millis();
403
+                if (need_kickstart) {
404
+                    switch_to(fullauto_kickstart_run);
405
+                } else {
406
+                    switch_to(fullauto_plant_run);
407
+                }
408
+            } else if (wl == Plants::invalid) {
409
+                plants.abort();
410
+                error_condition = F("Invalid sensor state");
411
+                state = fullauto_fert;
412
+                switch_to(error);
413
+            }
414
+        }
415
+    } else if (state == fullauto_fert_run) {
416
+        // allow user to stop fertizilers and continue with tank filling
417
+        auto wl = plants.getWaterlevel();
418
+        if ((wl != Plants::full) && (wl != Plants::invalid)) {
419
+            // if the waterlevel is currently empty, we
420
+            // set a flag to record the time to fill
421
+            filling_started_empty = (wl == Plants::empty);
422
+
423
+            plants.openWaterInlet();
424
+            selected_id = plants.countPlants() + 1;
425
+            selected_time = MAX_TANK_FILL_TIME;
426
+            start_time = millis();
427
+            switch_to(fullauto_tank_run);
428
+        } else if (wl == Plants::full) {
429
+            // check if kickstart is required for this
430
+            bool need_kickstart = false;
431
+            for (int i = 0; i < plants.countPlants(); i++) {
432
+                if (selected_plants.isSet(i)) {
433
+                    if (plants.getKickstart()->getPinNumber(i) >= 0) {
434
+                        need_kickstart = true;
435
+                    }
436
+                }
437
+            }
438
+
439
+            // start kickstart/valve as needed
440
+            for (int i = 0; i < plants.countPlants(); i++) {
441
+                if (selected_plants.isSet(i)) {
442
+                    plants.startPlant(i, need_kickstart);
443
+                }
444
+            }
445
+
446
+            watering_started_full = (wl == Plants::full);
447
+
448
+            selected_time = MAX_AUTO_PLANT_RUNTIME;
449
+            start_time = millis();
450
+            if (need_kickstart) {
451
+                switch_to(fullauto_kickstart_run);
452
+            } else {
453
+                switch_to(fullauto_plant_run);
454
+            }
455
+        } else if (wl == Plants::invalid) {
456
+            plants.abort();
457
+            error_condition = F("Invalid sensor state");
458
+            state = fullauto_fert;
459
+            switch_to(error);
460
+        }
461
+    } else if ((state == fullauto_tank_run)
462
+            || (state == fullauto_tank_purge_run)) {
463
+        // allow user to stop tank and continue with kickstart
464
+        plants.abort();
465
+        stop_time = millis();
466
+        auto wl = plants.getWaterlevel();
467
+        if ((wl != Plants::empty) && (wl != Plants::invalid)) {
468
+            // check if kickstart is required for this
469
+            bool need_kickstart = false;
470
+            for (int i = 0; i < plants.countPlants(); i++) {
471
+                if (selected_plants.isSet(i)) {
472
+                    if (plants.getKickstart()->getPinNumber(i) >= 0) {
473
+                        need_kickstart = true;
474
+                    }
475
+                }
476
+            }
477
+
478
+            // start kickstart/valve as needed
479
+            for (int i = 0; i < plants.countPlants(); i++) {
480
+                if (selected_plants.isSet(i)) {
481
+                    plants.startPlant(i, need_kickstart);
482
+                }
483
+            }
484
+
485
+            watering_started_full = (wl == Plants::full);
486
+
487
+            selected_time = MAX_AUTO_PLANT_RUNTIME;
488
+            start_time = millis();
489
+            if (need_kickstart) {
490
+                if (state == fullauto_tank_run) {
491
+                    switch_to(fullauto_kickstart_run);
492
+                } else {
493
+                    switch_to(fullauto_kickstart_purge_run);
494
+                }
495
+            } else {
496
+                if (state == fullauto_tank_run) {
497
+                    switch_to(fullauto_plant_run);
498
+                } else {
499
+                    switch_to(fullauto_plant_purge_run);
500
+                }
501
+            }
502
+        } else if (wl == Plants::empty) {
503
+            stop_time = millis();
504
+            switch_to(auto_done);
505
+        } else if (wl == Plants::invalid) {
506
+            error_condition = F("Invalid sensor state");
507
+            state = auto_mode_a;
508
+            switch_to(error);
509
+        }
510
+    } else if ((state == fullauto_kickstart_run)
511
+            || (state == fullauto_kickstart_purge_run)) {
512
+        // allow user to stop kickstarting and continue with plants
513
+        plants.abort();
514
+        selected_time = MAX_AUTO_PLANT_RUNTIME;
515
+        start_time = millis();
516
+
517
+        // start required valves
518
+        for (int i = 0; i < plants.countPlants(); i++) {
519
+            if (selected_plants.isSet(i)) {
520
+                plants.startPlant(i, false);
521
+            }
522
+        }
523
+
524
+        if (state == fullauto_kickstart_run) {
525
+            switch_to(fullauto_plant_run);
526
+        } else {
527
+            switch_to(fullauto_plant_purge_run);
528
+        }
351 529
     } else if ((state == auto_fert_run) || (state == auto_tank_run)
352 530
             || (state == auto_stirr_run) || (state == auto_plant_run)
353 531
             || (state == auto_plant_kickstart_run)
354 532
             || (state == fillnwater_kickstart_run)
355
-            || (state == fullauto_stirr_run)
356
-            || (state == fullauto_fert_run)
357
-            || (state == fullauto_tank_run)
358
-            || (state == fullauto_kickstart_run)
359 533
             || (state == fullauto_plant_run)
360 534
             || (state == fullauto_plant_overrun)
361
-            || (state == fullauto_tank_purge_run)
362
-            || (state == fullauto_kickstart_purge_run)
363 535
             || (state == fullauto_plant_purge_run)
364 536
             || (state == fullauto_plant_purge_overrun)) {
365 537
         plants.abort();
@@ -1119,6 +1291,7 @@ void Statemachine::act(void) {
1119 1291
         if ((runtime / 1000UL) >= KICKSTART_RUNTIME) {
1120 1292
             // kickstart is done, switch over to valves
1121 1293
             plants.abort();
1294
+            selected_time = MAX_AUTO_PLANT_RUNTIME;
1122 1295
             start_time = millis();
1123 1296
 
1124 1297
             // start required valves
@@ -1155,6 +1328,12 @@ void Statemachine::act(void) {
1155 1328
             }
1156 1329
         }
1157 1330
 
1331
+        if ((millis() - last_animation_time) >= 500) {
1332
+            // update animation if needed
1333
+            last_animation_time = millis();
1334
+            switch_to(state);
1335
+        }
1336
+
1158 1337
         if (selected_ferts.countSet() <= 0) {
1159 1338
             plants.abort();
1160 1339
 
@@ -1438,37 +1617,53 @@ void Statemachine::act(void) {
1438 1617
         // check water level state
1439 1618
         auto wl = plants.getWaterlevel();
1440 1619
         if (wl == Plants::empty) {
1441
-            plants.abort();
1442
-            stop_time = millis();
1620
+            if ((state == auto_plant_run) || (state == fillnwater_plant_run)) {
1621
+                plants.abort();
1622
+                stop_time = millis();
1623
+            }
1443 1624
 
1444
-            // if we started watering with a full tank
1445
-            // and then finished watering when it was empty
1446
-            // and we were only watering a single plant
1447
-            // look at this as a "calibration run" and record
1448
-            // the time it took to empty the tank
1449
-            if ((state == fillnwater_plant_run) && watering_started_full && (selected_plants.countSet() == 1)) {
1450
-                unsigned long time_to_water = stop_time - start_time;
1451
-                debug.print("Watering plant ");
1452
-                debug.print(selected_plants.getFirstSet() + 1);
1453
-                debug.print(" with the complete tank took ");
1454
-                debug.print(String(time_to_water));
1455
-                debug.println("ms");
1625
+            if ((state == auto_plant_run) || (state == fillnwater_plant_run)
1626
+            || (state == fullauto_plant_run)) {
1627
+                // if we started watering with a full tank
1628
+                // and then finished watering when it was empty
1629
+                // and we were only watering a single plant
1630
+                // look at this as a "calibration run" and record
1631
+                // the time it took to empty the tank
1632
+                if (watering_started_full && (selected_plants.countSet() == 1)) {
1633
+                    unsigned long time_to_water = stop_time - start_time;
1634
+                    debug.print("Watering plant ");
1635
+                    debug.print(selected_plants.getFirstSet() + 1);
1636
+                    debug.print(" with the complete tank took ");
1637
+                    debug.print(String(time_to_water));
1638
+                    debug.println("ms");
1456 1639
 
1457
-#if defined(PLATFORM_ESP)
1458
-                bool success = wifi_write_database(time_to_water, "calibrated_watering", selected_plants.getFirstSet() + 1);
1459
-                if (!success) {
1460
-                    debug.print("Error writing to InfluxDB ");
1461
-                    debug.print(INFLUXDB_HOST);
1462
-                    debug.print(":");
1463
-                    debug.print(INFLUXDB_PORT);
1464
-                    debug.print("/");
1465
-                    debug.print(INFLUXDB_DATABASE);
1466
-                    debug.println("/calibrated_watering");
1640
+    #if defined(PLATFORM_ESP)
1641
+                    bool success = wifi_write_database(time_to_water, "calibrated_watering", selected_plants.getFirstSet() + 1);
1642
+                    if (!success) {
1643
+                        debug.print("Error writing to InfluxDB ");
1644
+                        debug.print(INFLUXDB_HOST);
1645
+                        debug.print(":");
1646
+                        debug.print(INFLUXDB_PORT);
1647
+                        debug.print("/");
1648
+                        debug.print(INFLUXDB_DATABASE);
1649
+                        debug.println("/calibrated_watering");
1650
+                    }
1651
+    #endif // PLATFORM_ESP
1467 1652
                 }
1468
-#endif // PLATFORM_ESP
1469 1653
             }
1470 1654
 
1471
-            switch_to(auto_done);
1655
+            if ((state == auto_plant_run) || (state == fillnwater_plant_run)) {
1656
+                switch_to(auto_done);
1657
+            } else if (state == fullauto_plant_run) {
1658
+                start_time = millis();
1659
+                selected_time = OVERRUN_RUNTIME;
1660
+                switch_to(fullauto_plant_overrun);
1661
+            } else if (state == fullauto_plant_purge_run) {
1662
+                start_time = millis();
1663
+                selected_time = OVERRUN_RUNTIME;
1664
+                switch_to(fullauto_plant_purge_overrun);
1665
+
1666
+            }
1472 1667
         } else if (wl == Plants::invalid) {
1473 1668
             plants.abort();
1474 1669
             error_condition = F("Invalid sensor state");

Loading…
İptal
Kaydet