Browse Source

add support for kickstarting gravity-fed valves with a pump.

Thomas Buck 2 years ago
parent
commit
4dab9e16f5
10 changed files with 240 additions and 58 deletions
  1. 1
    0
      include/GPIOBank.h
  2. 4
    1
      include/Plants.h
  3. 2
    0
      include/Statemachine.h
  4. 4
    2
      include/config.h
  5. 6
    2
      include/config_pins.h
  6. 2
    0
      src/Functionality.cpp
  7. 17
    0
      src/GPIOBank.cpp
  8. 24
    5
      src/Plants.cpp
  9. 137
    19
      src/Statemachine.cpp
  10. 43
    29
      src/WifiStuff.cpp

+ 1
- 0
include/GPIOBank.h View File

28
     ~GPIOBank(void);
28
     ~GPIOBank(void);
29
     
29
     
30
     void setPinNumbers(int _pins[]);
30
     void setPinNumbers(int _pins[]);
31
+    int getPinNumber(int pin);
31
     void setOutput(void);
32
     void setOutput(void);
32
     void setInput(bool pullup);
33
     void setInput(bool pullup);
33
     
34
     

+ 4
- 1
include/Plants.h View File

40
     void setPumpPins(int pins[]);
40
     void setPumpPins(int pins[]);
41
     void setSwitchPins(int pins[], bool pullup);
41
     void setSwitchPins(int pins[], bool pullup);
42
     void setAuxPins(int pins[]);
42
     void setAuxPins(int pins[]);
43
+    void setKickstartPins(int pins[]);
43
     
44
     
44
     void abort(void);
45
     void abort(void);
45
     
46
     
53
     void stopAllFertilizers(void);
54
     void stopAllFertilizers(void);
54
     
55
     
55
     int countPlants(void);
56
     int countPlants(void);
56
-    void startPlant(int id);
57
+    void startPlant(int id, bool do_kickstart);
57
     void stopPlant(int id);
58
     void stopPlant(int id);
58
     void stopAllPlants(void);
59
     void stopAllPlants(void);
59
 
60
 
66
     GPIOBank *getPumps(void);
67
     GPIOBank *getPumps(void);
67
     GPIOBank *getSwitches(void);
68
     GPIOBank *getSwitches(void);
68
     GPIOBank *getAux(void);
69
     GPIOBank *getAux(void);
70
+    GPIOBank *getKickstart(void);
69
     
71
     
70
 private:
72
 private:
71
     GPIOBank valves;
73
     GPIOBank valves;
72
     GPIOBank pumps;
74
     GPIOBank pumps;
73
     GPIOBank switches;
75
     GPIOBank switches;
74
     GPIOBank aux;
76
     GPIOBank aux;
77
+    GPIOBank kickstart;
75
 };
78
 };
76
 
79
 
77
 extern Plants plants;
80
 extern Plants plants;

+ 2
- 0
include/Statemachine.h View File

42
         auto_tank_run,
42
         auto_tank_run,
43
         auto_stirr_run,
43
         auto_stirr_run,
44
         auto_plant, // select plant
44
         auto_plant, // select plant
45
+        auto_plant_kickstart_run,
45
         auto_plant_run,
46
         auto_plant_run,
46
         auto_done,
47
         auto_done,
47
 
48
 
48
         fillnwater_plant, // select plants
49
         fillnwater_plant, // select plants
49
         fillnwater_tank_run,
50
         fillnwater_tank_run,
51
+        fillnwater_kickstart_run,
50
         fillnwater_plant_run,
52
         fillnwater_plant_run,
51
 
53
 
52
         automation_mode,
54
         automation_mode,

+ 4
- 2
include/config.h View File

37
 #define MAX_PUMP_RUNTIME 30
37
 #define MAX_PUMP_RUNTIME 30
38
 #define MAX_VALVE_RUNTIME (45 * 60)
38
 #define MAX_VALVE_RUNTIME (45 * 60)
39
 #define MAX_AUX_RUNTIME (5 * 60)
39
 #define MAX_AUX_RUNTIME (5 * 60)
40
+#define KICKSTART_RUNTIME 10
40
 
41
 
41
 // Sketch version
42
 // Sketch version
42
-#define FIRMWARE_VERSION "0.4"
43
+#define FIRMWARE_VERSION "0.5"
43
 
44
 
44
 // all given in milliseconds
45
 // all given in milliseconds
45
 #define SERVER_HANDLE_INTERVAL 10
46
 #define SERVER_HANDLE_INTERVAL 10
70
 #define INFLUXDB_DATABASE "giessomat"
71
 #define INFLUXDB_DATABASE "giessomat"
71
 
72
 
72
 #define DOOR_LOCK_PIN 4223
73
 #define DOOR_LOCK_PIN 4223
73
-#define DOOR_LOCK_ON_TIME 100 /* in ms */
74
 #define DOOR_LOCK_PIN_MAX_DIGITS 6
74
 #define DOOR_LOCK_PIN_MAX_DIGITS 6
75
+#define DOOR_LOCK_ON_TIME 200 /* in ms */
76
+#define DOOR_LOCK_NEXT_DELAY 100 /* in ms */
75
 
77
 
76
 #endif // _CONFIG_H_
78
 #endif // _CONFIG_H_

+ 6
- 2
include/config_pins.h View File

106
  * PCF8574: 0x20 - 0x27
106
  * PCF8574: 0x20 - 0x27
107
  * PCF8574A: 0x38 - 0x3F
107
  * PCF8574A: 0x38 - 0x3F
108
  */
108
  */
109
-#define I2C_GPIO_EXPANDER_COUNT 1
110
-#define I2C_GPIO_EXPANDER_ADDR 0x20
109
+#define I2C_GPIO_EXPANDER_COUNT 2
110
+#define I2C_GPIO_EXPANDER_ADDR 0x20, 0x21
111
 
111
 
112
 /*
112
 /*
113
  * GPIO Numbering Scheme
113
  * GPIO Numbering Scheme
124
 #define VALVE_COUNT (PLANT_COUNT + 1)
124
 #define VALVE_COUNT (PLANT_COUNT + 1)
125
 #define VALVE_PINS PLANT_PINS, INLET_PIN
125
 #define VALVE_PINS PLANT_PINS, INLET_PIN
126
 
126
 
127
+// kickstarting pumps, same count as plants!
128
+// set pin to -1 to disable kickstart for this plant.
129
+#define KICKSTART_PINS -1, -1, -1, -1, 108, 109, 110, 111
130
+
127
 // a, b, c
131
 // a, b, c
128
 #define PUMP_COUNT 3
132
 #define PUMP_COUNT 3
129
 #define PUMP_PINS 2, 0, 4
133
 #define PUMP_PINS 2, 0, 4

+ 2
- 0
src/Functionality.cpp View File

67
 int pump_pins[PUMP_COUNT] = { PUMP_PINS };
67
 int pump_pins[PUMP_COUNT] = { PUMP_PINS };
68
 int switch_pins[SWITCH_COUNT] = { SWITCH_PINS };
68
 int switch_pins[SWITCH_COUNT] = { SWITCH_PINS };
69
 int aux_pins[AUX_COUNT] = { AUX_PINS };
69
 int aux_pins[AUX_COUNT] = { AUX_PINS };
70
+int kickstart_pins[VALVE_COUNT - 1] = { KICKSTART_PINS };
70
 
71
 
71
 Statemachine sm(write_to_all, backspace);
72
 Statemachine sm(write_to_all, backspace);
72
 
73
 
476
     plants.setPumpPins(pump_pins);
477
     plants.setPumpPins(pump_pins);
477
     plants.setSwitchPins(switch_pins, true);
478
     plants.setSwitchPins(switch_pins, true);
478
     plants.setAuxPins(aux_pins);
479
     plants.setAuxPins(aux_pins);
480
+    plants.setKickstartPins(kickstart_pins);
479
 }
481
 }
480
 
482
 
481
 void control_begin(void) {
483
 void control_begin(void) {

+ 17
- 0
src/GPIOBank.cpp View File

34
 // ----------------------------------------------------------------------------
34
 // ----------------------------------------------------------------------------
35
 
35
 
36
 #if (I2C_GPIO_EXPANDER_COUNT > 0)
36
 #if (I2C_GPIO_EXPANDER_COUNT > 0)
37
+static uint8_t expand_addr[I2C_GPIO_EXPANDER_COUNT] = { I2C_GPIO_EXPANDER_ADDR };
37
 static PCF8574 expand[I2C_GPIO_EXPANDER_COUNT];
38
 static PCF8574 expand[I2C_GPIO_EXPANDER_COUNT];
38
 #endif
39
 #endif
39
 
40
 
40
 void gpio_i2c_init(void) {
41
 void gpio_i2c_init(void) {
41
 #if (I2C_GPIO_EXPANDER_COUNT > 0)
42
 #if (I2C_GPIO_EXPANDER_COUNT > 0)
42
     for (int i = 0; i < I2C_GPIO_EXPANDER_COUNT; i++) {
43
     for (int i = 0; i < I2C_GPIO_EXPANDER_COUNT; i++) {
44
+        expand[i].setAddress(expand_addr[i]);
43
         expand[i].begin(0xFF);
45
         expand[i].begin(0xFF);
44
     }
46
     }
45
 #endif
47
 #endif
48
 static void gpio_pinMode(int pin, int value) {
50
 static void gpio_pinMode(int pin, int value) {
49
     if (pin < 100) {
51
     if (pin < 100) {
50
         pinMode(pin, value);
52
         pinMode(pin, value);
53
+    } else if (pin < 0) {
54
+        // ignore negative pin numbers
51
     } else {
55
     } else {
52
         pin -= 100;
56
         pin -= 100;
53
         int ex = pin / 8;
57
         int ex = pin / 8;
67
 static void gpio_digitalWrite(int pin, int value) {
71
 static void gpio_digitalWrite(int pin, int value) {
68
     if (pin < 100) {
72
     if (pin < 100) {
69
         digitalWrite(pin, value);
73
         digitalWrite(pin, value);
74
+    } else if (pin < 0) {
75
+        // ignore negative pin numbers
70
     } else {
76
     } else {
71
         pin -= 100;
77
         pin -= 100;
72
         int ex = pin / 8;
78
         int ex = pin / 8;
80
 static int gpio_digitalRead(int pin) {
86
 static int gpio_digitalRead(int pin) {
81
     if (pin < 100) {
87
     if (pin < 100) {
82
         return digitalRead(pin);
88
         return digitalRead(pin);
89
+    } else if (pin < 0) {
90
+        // ignore negative pin numbers
91
+        return 0;
83
     } else {
92
     } else {
84
         pin -= 100;
93
         pin -= 100;
85
         int ex = pin / 8;
94
         int ex = pin / 8;
112
     }
121
     }
113
 }
122
 }
114
 
123
 
124
+int GPIOBank::getPinNumber(int pin) {
125
+    if ((pin >= 0) && (pin < size)) {
126
+        return pins[pin];
127
+    } else {
128
+        return -1;
129
+    }
130
+}
131
+
115
 void GPIOBank::setOutput(void) {
132
 void GPIOBank::setOutput(void) {
116
     for (int i = 0; i < size; i++) {
133
     for (int i = 0; i < size; i++) {
117
 #ifdef GPIO_HIGH_AS_INPUT
134
 #ifdef GPIO_HIGH_AS_INPUT

+ 24
- 5
src/Plants.cpp View File

28
 // pumps: no of fertilizers
28
 // pumps: no of fertilizers
29
 // switches: 2, low and high level
29
 // switches: 2, low and high level
30
 Plants::Plants(int valve_count, int pump_count, int switch_count, int aux_count) :
30
 Plants::Plants(int valve_count, int pump_count, int switch_count, int aux_count) :
31
-        valves(valve_count), pumps(pump_count), switches(switch_count), aux(aux_count) {
31
+        valves(valve_count), pumps(pump_count), switches(switch_count), aux(aux_count),
32
+        kickstart(valve_count - 1) {
32
 }
33
 }
33
-
34
     
34
     
35
 GPIOBank *Plants::getValves(void) {
35
 GPIOBank *Plants::getValves(void) {
36
     return &valves;
36
     return &valves;
48
     return &aux;
48
     return &aux;
49
 }
49
 }
50
 
50
 
51
+GPIOBank *Plants::getKickstart(void) {
52
+    return &kickstart;
53
+}
54
+
51
 void Plants::setValvePins(int pins[]) {
55
 void Plants::setValvePins(int pins[]) {
52
     valves.setPinNumbers(pins);
56
     valves.setPinNumbers(pins);
53
     valves.setOutput();
57
     valves.setOutput();
71
     aux.setAll(false);
75
     aux.setAll(false);
72
 }
76
 }
73
 
77
 
78
+void Plants::setKickstartPins(int pins[]) {
79
+    kickstart.setPinNumbers(pins);
80
+    kickstart.setOutput();
81
+    kickstart.setAll(false);
82
+}
83
+
74
 void Plants::abort(void) {
84
 void Plants::abort(void) {
75
     closeWaterInlet();
85
     closeWaterInlet();
76
     stopAllFertilizers();
86
     stopAllFertilizers();
143
     return valves.getSize() - 1;
153
     return valves.getSize() - 1;
144
 }
154
 }
145
 
155
 
146
-void Plants::startPlant(int id) {
156
+void Plants::startPlant(int id, bool do_kickstart) {
147
     debug.print("Plants::startPlant ");
157
     debug.print("Plants::startPlant ");
148
-    debug.println(id);
158
+    debug.print(id);
159
+    debug.print(", ");
160
+    debug.println(do_kickstart);
149
     
161
     
150
     if ((id >= 0) && (id < countPlants())) {
162
     if ((id >= 0) && (id < countPlants())) {
151
-        valves.setPin(id, true);
163
+        if (do_kickstart) {
164
+            valves.setPin(id, false);
165
+            kickstart.setPin(id, true);
166
+        } else {
167
+            kickstart.setPin(id, false);
168
+            valves.setPin(id, true);
169
+        }
152
     }
170
     }
153
 }
171
 }
154
 
172
 
158
     
176
     
159
     if ((id >= 0) && (id < countPlants())) {
177
     if ((id >= 0) && (id < countPlants())) {
160
         valves.setPin(id, false);
178
         valves.setPin(id, false);
179
+        kickstart.setPin(id, false);
161
     }
180
     }
162
 }
181
 }
163
 
182
 

+ 137
- 19
src/Statemachine.cpp View File

87
     stringify(auto_tank_run),
87
     stringify(auto_tank_run),
88
     stringify(auto_stirr_run),
88
     stringify(auto_stirr_run),
89
     stringify(auto_plant),
89
     stringify(auto_plant),
90
+    stringify(auto_plant_kickstart_run),
90
     stringify(auto_plant_run),
91
     stringify(auto_plant_run),
91
     stringify(auto_done),
92
     stringify(auto_done),
92
     stringify(fillnwater_plant),
93
     stringify(fillnwater_plant),
93
     stringify(fillnwater_tank_run),
94
     stringify(fillnwater_tank_run),
95
+    stringify(fillnwater_kickstart_run),
94
     stringify(fillnwater_plant_run),
96
     stringify(fillnwater_plant_run),
95
     stringify(automation_mode),
97
     stringify(automation_mode),
96
     stringify(menu_pumps),
98
     stringify(menu_pumps),
203
                         plants.startAux(STIRRER_COUNT + i);
205
                         plants.startAux(STIRRER_COUNT + i);
204
                         delay(DOOR_LOCK_ON_TIME);
206
                         delay(DOOR_LOCK_ON_TIME);
205
                         plants.stopAux(STIRRER_COUNT + i);
207
                         plants.stopAux(STIRRER_COUNT + i);
208
+                        delay(DOOR_LOCK_NEXT_DELAY);
206
                     }
209
                     }
207
                 }
210
                 }
208
                 plants.stopAllAux();
211
                 plants.stopAllAux();
315
             switch_to((state == auto_fert_a) ? auto_fert_b : auto_fert_a);
318
             switch_to((state == auto_fert_a) ? auto_fert_b : auto_fert_a);
316
         }
319
         }
317
     } else if ((state == auto_fert_run) || (state == auto_tank_run)
320
     } else if ((state == auto_fert_run) || (state == auto_tank_run)
318
-            || (state == auto_stirr_run)) {
321
+            || (state == auto_stirr_run) || (state == auto_plant_run)
322
+            || (state == auto_plant_kickstart_run)
323
+            || (state == fillnwater_kickstart_run)) {
319
         plants.abort();
324
         plants.abort();
320
         stop_time = millis();
325
         stop_time = millis();
321
         switch_to(auto_done);
326
         switch_to(auto_done);
335
             if (!db.hasDigits()) {
340
             if (!db.hasDigits()) {
336
                 auto wl = plants.getWaterlevel();
341
                 auto wl = plants.getWaterlevel();
337
                 if ((wl != Plants::empty) && (wl != Plants::invalid)) {
342
                 if ((wl != Plants::empty) && (wl != Plants::invalid)) {
343
+                    // check if kickstart is required for this
344
+                    bool need_kickstart = false;
345
+                    for (int i = 0; i < plants.countPlants(); i++) {
346
+                        if (selected_plants.isSet(i)) {
347
+                            if (plants.getKickstart()->getPinNumber(i) >= 0) {
348
+                                need_kickstart = true;
349
+                            }
350
+                        }
351
+                    }
352
+
353
+                    // start kickstart/valve as needed
338
                     for (int i = 0; i < plants.countPlants(); i++) {
354
                     for (int i = 0; i < plants.countPlants(); i++) {
339
                         if (selected_plants.isSet(i)) {
355
                         if (selected_plants.isSet(i)) {
340
-                            plants.startPlant(i);
356
+                            plants.startPlant(i, need_kickstart);
341
                         }
357
                         }
342
                     }
358
                     }
343
                     
359
                     
344
                     selected_time = MAX_AUTO_PLANT_RUNTIME;
360
                     selected_time = MAX_AUTO_PLANT_RUNTIME;
345
                     start_time = millis();
361
                     start_time = millis();
346
-                    switch_to(auto_plant_run);
362
+                    if (need_kickstart) {
363
+                        switch_to(auto_plant_kickstart_run);
364
+                    } else {
365
+                        switch_to(auto_plant_run);
366
+                    }
347
                 } else if (wl == Plants::empty) {
367
                 } else if (wl == Plants::empty) {
348
                     stop_time = millis();
368
                     stop_time = millis();
349
                     switch_to(auto_mode_b);
369
                     switch_to(auto_mode_b);
372
                 backspace();
392
                 backspace();
373
             }
393
             }
374
         }
394
         }
375
-    } else if (state == auto_plant_run) {
376
-        plants.abort();
377
-        stop_time = millis();
378
-        switch_to(auto_done);
379
     } else if (state == auto_done) {
395
     } else if (state == auto_done) {
380
         switch_to(auto_mode_a);
396
         switch_to(auto_mode_a);
381
     } else if (state == menu_pumps) {
397
     } else if (state == menu_pumps) {
449
                         stop_time = millis();
465
                         stop_time = millis();
450
                         auto wl = plants.getWaterlevel();
466
                         auto wl = plants.getWaterlevel();
451
                         if ((wl != Plants::empty) && (wl != Plants::invalid)) {
467
                         if ((wl != Plants::empty) && (wl != Plants::invalid)) {
468
+                            // check if kickstart is required for this
469
+                            bool need_kickstart = false;
452
                             for (int i = 0; i < plants.countPlants(); i++) {
470
                             for (int i = 0; i < plants.countPlants(); i++) {
453
                                 if (selected_plants.isSet(i)) {
471
                                 if (selected_plants.isSet(i)) {
454
-                                    plants.startPlant(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);
455
                                 }
482
                                 }
456
                             }
483
                             }
457
 
484
 
460
 
487
 
461
                             selected_time = MAX_AUTO_PLANT_RUNTIME;
488
                             selected_time = MAX_AUTO_PLANT_RUNTIME;
462
                             start_time = millis();
489
                             start_time = millis();
463
-                            switch_to(fillnwater_plant_run);
490
+                            if (need_kickstart) {
491
+                                switch_to(fillnwater_kickstart_run);
492
+                            } else {
493
+                                switch_to(fillnwater_plant_run);
494
+                            }
464
                         } else if (wl == Plants::empty) {
495
                         } else if (wl == Plants::empty) {
465
                             stop_time = millis();
496
                             stop_time = millis();
466
                             switch_to(auto_mode_a);
497
                             switch_to(auto_mode_a);
500
         stop_time = millis();
531
         stop_time = millis();
501
         auto wl = plants.getWaterlevel();
532
         auto wl = plants.getWaterlevel();
502
         if ((wl != Plants::empty) && (wl != Plants::invalid)) {
533
         if ((wl != Plants::empty) && (wl != Plants::invalid)) {
534
+            // check if kickstart is required for this
535
+            bool need_kickstart = false;
503
             for (int i = 0; i < plants.countPlants(); i++) {
536
             for (int i = 0; i < plants.countPlants(); i++) {
504
                 if (selected_plants.isSet(i)) {
537
                 if (selected_plants.isSet(i)) {
505
-                    plants.startPlant(i);
538
+                    if (plants.getKickstart()->getPinNumber(i) >= 0) {
539
+                        need_kickstart = true;
540
+                    }
541
+                }
542
+            }
543
+
544
+            // start kickstart/valve as needed
545
+            for (int i = 0; i < plants.countPlants(); i++) {
546
+                if (selected_plants.isSet(i)) {
547
+                    plants.startPlant(i, need_kickstart);
506
                 }
548
                 }
507
             }
549
             }
508
 
550
 
510
 
552
 
511
             selected_time = MAX_AUTO_PLANT_RUNTIME;
553
             selected_time = MAX_AUTO_PLANT_RUNTIME;
512
             start_time = millis();
554
             start_time = millis();
513
-            switch_to(fillnwater_plant_run);
555
+            if (need_kickstart) {
556
+                switch_to(fillnwater_kickstart_run);
557
+            } else {
558
+                switch_to(fillnwater_plant_run);
559
+            }
514
         } else if (wl == Plants::empty) {
560
         } else if (wl == Plants::empty) {
515
             switch_to(auto_mode_a);
561
             switch_to(auto_mode_a);
516
         } else if (wl == Plants::invalid) {
562
         } else if (wl == Plants::invalid) {
660
                 if (selected_id >= (plants.countPlants() + 1)) {
706
                 if (selected_id >= (plants.countPlants() + 1)) {
661
                     plants.openWaterInlet();
707
                     plants.openWaterInlet();
662
                 } else {
708
                 } else {
663
-                    plants.startPlant(selected_id - 1);
709
+                    // TODO support testing kickstart
710
+                    plants.startPlant(selected_id - 1, false);
664
                 }
711
                 }
665
                 
712
                 
666
                 switch_to(menu_valves_run);
713
                 switch_to(menu_valves_run);
803
             switch_to(state);
850
             switch_to(state);
804
         }
851
         }
805
     }
852
     }
806
-    
853
+
807
 #ifdef CHECK_SENSORS_VALVE_PUMP_MENU_FULL
854
 #ifdef CHECK_SENSORS_VALVE_PUMP_MENU_FULL
808
     if ((state == menu_pumps_run) || ((state == menu_valves_run) && (selected_id == (plants.countPlants() + 1)))) {
855
     if ((state == menu_pumps_run) || ((state == menu_valves_run) && (selected_id == (plants.countPlants() + 1)))) {
809
         // check water level state
856
         // check water level state
820
         }
867
         }
821
     }
868
     }
822
 #endif // CHECK_SENSORS_VALVE_PUMP_MENU_FULL
869
 #endif // CHECK_SENSORS_VALVE_PUMP_MENU_FULL
823
-    
870
+
824
 #ifdef CHECK_SENSORS_VALVE_PUMP_MENU_EMPTY
871
 #ifdef CHECK_SENSORS_VALVE_PUMP_MENU_EMPTY
825
     if ((state == menu_valves_run) && (selected_id <= plants.countPlants())) {
872
     if ((state == menu_valves_run) && (selected_id <= plants.countPlants())) {
826
         // check water level state
873
         // check water level state
837
         }
884
         }
838
     }
885
     }
839
 #endif // CHECK_SENSORS_VALVE_PUMP_MENU_EMPTY
886
 #endif // CHECK_SENSORS_VALVE_PUMP_MENU_EMPTY
840
-    
887
+
888
+    if ((state == auto_plant_kickstart_run) || (state == fillnwater_kickstart_run)) {
889
+        unsigned long runtime = millis() - start_time;
890
+        if ((runtime / 1000UL) >= KICKSTART_RUNTIME) {
891
+            // kickstart is done, switch over to valves
892
+            plants.abort();
893
+            start_time = millis();
894
+
895
+            // start required valves
896
+            for (int i = 0; i < plants.countPlants(); i++) {
897
+                if (selected_plants.isSet(i)) {
898
+                    plants.startPlant(i, false);
899
+                }
900
+            }
901
+
902
+            if (state == auto_plant_kickstart_run) {
903
+                switch_to(auto_plant_run);
904
+            } else {
905
+                switch_to(fillnwater_plant_run);
906
+            }
907
+        } else if ((millis() - last_animation_time) >= 500) {
908
+            // update animation if needed
909
+            last_animation_time = millis();
910
+            switch_to(state);
911
+        }
912
+    }
913
+
841
     if ((state == auto_fert_run) || (state == auto_tank_run) || (state == fillnwater_tank_run)) {
914
     if ((state == auto_fert_run) || (state == auto_tank_run) || (state == fillnwater_tank_run)) {
842
         unsigned long runtime = millis() - start_time;
915
         unsigned long runtime = millis() - start_time;
843
         if ((runtime / 1000UL) >= selected_time) {
916
         if ((runtime / 1000UL) >= selected_time) {
847
             if (state == fillnwater_tank_run) {
920
             if (state == fillnwater_tank_run) {
848
                 auto wl = plants.getWaterlevel();
921
                 auto wl = plants.getWaterlevel();
849
                 if ((wl != Plants::empty) && (wl != Plants::invalid)) {
922
                 if ((wl != Plants::empty) && (wl != Plants::invalid)) {
923
+                    // check if kickstart is required for this
924
+                    bool need_kickstart = false;
850
                     for (int i = 0; i < plants.countPlants(); i++) {
925
                     for (int i = 0; i < plants.countPlants(); i++) {
851
                         if (selected_plants.isSet(i)) {
926
                         if (selected_plants.isSet(i)) {
852
-                            plants.startPlant(i);
927
+                            if (plants.getKickstart()->getPinNumber(i) >= 0) {
928
+                                need_kickstart = true;
929
+                            }
930
+                        }
931
+                    }
932
+
933
+                    // start kickstart/valve as needed
934
+                    for (int i = 0; i < plants.countPlants(); i++) {
935
+                        if (selected_plants.isSet(i)) {
936
+                            plants.startPlant(i, need_kickstart);
853
                         }
937
                         }
854
                     }
938
                     }
855
 
939
 
857
 
941
 
858
                     selected_time = MAX_AUTO_PLANT_RUNTIME;
942
                     selected_time = MAX_AUTO_PLANT_RUNTIME;
859
                     start_time = millis();
943
                     start_time = millis();
860
-                    switch_to(fillnwater_plant_run);
944
+                    if (need_kickstart) {
945
+                        switch_to(fillnwater_kickstart_run);
946
+                    } else {
947
+                        switch_to(fillnwater_plant_run);
948
+                    }
861
                 } else if (wl == Plants::empty) {
949
                 } else if (wl == Plants::empty) {
862
                     stop_time = millis();
950
                     stop_time = millis();
863
                     switch_to(auto_done);
951
                     switch_to(auto_done);
905
 
993
 
906
                 auto wl = plants.getWaterlevel();
994
                 auto wl = plants.getWaterlevel();
907
                 if ((wl != Plants::empty) && (wl != Plants::invalid)) {
995
                 if ((wl != Plants::empty) && (wl != Plants::invalid)) {
996
+                    // check if kickstart is required for this
997
+                    bool need_kickstart = false;
908
                     for (int i = 0; i < plants.countPlants(); i++) {
998
                     for (int i = 0; i < plants.countPlants(); i++) {
909
                         if (selected_plants.isSet(i)) {
999
                         if (selected_plants.isSet(i)) {
910
-                            plants.startPlant(i);
1000
+                            if (plants.getKickstart()->getPinNumber(i) >= 0) {
1001
+                                need_kickstart = true;
1002
+                            }
1003
+                        }
1004
+                    }
1005
+
1006
+                    // start kickstart/valve as needed
1007
+                    for (int i = 0; i < plants.countPlants(); i++) {
1008
+                        if (selected_plants.isSet(i)) {
1009
+                            plants.startPlant(i, need_kickstart);
911
                         }
1010
                         }
912
                     }
1011
                     }
913
 
1012
 
915
 
1014
 
916
                     selected_time = MAX_AUTO_PLANT_RUNTIME;
1015
                     selected_time = MAX_AUTO_PLANT_RUNTIME;
917
                     start_time = millis();
1016
                     start_time = millis();
918
-                    switch_to(fillnwater_plant_run);
1017
+                    if (need_kickstart) {
1018
+                        switch_to(fillnwater_kickstart_run);
1019
+                    } else {
1020
+                        switch_to(fillnwater_plant_run);
1021
+                    }
919
                 } else if (wl == Plants::empty) {
1022
                 } else if (wl == Plants::empty) {
920
                     stop_time = millis();
1023
                     stop_time = millis();
921
                     switch_to(auto_mode_a);
1024
                     switch_to(auto_mode_a);
1158
               a.c_str(),
1261
               a.c_str(),
1159
               b.c_str(),
1262
               b.c_str(),
1160
               3);
1263
               3);
1264
+    } else if ((s == auto_plant_kickstart_run) || (s == fillnwater_kickstart_run)) {
1265
+        unsigned long runtime = millis() - start_time;
1266
+        String a = String("Time: ") + String(runtime / 1000UL) + String("s / ") + String(KICKSTART_RUNTIME) + String('s');
1267
+
1268
+        unsigned long anim = runtime * 20UL / (KICKSTART_RUNTIME * 1000UL);
1269
+        String b;
1270
+        for (unsigned long i = 0; i < anim; i++) {
1271
+            b += '#';
1272
+        }
1273
+
1274
+        print("---- Kick-Start ----",
1275
+              a.c_str(),
1276
+              b.c_str(),
1277
+              "Hit any key to stop!",
1278
+              -1);
1161
     } else if ((s == auto_plant_run) || (s == fillnwater_plant_run)) {
1279
     } else if ((s == auto_plant_run) || (s == fillnwater_plant_run)) {
1162
         unsigned long runtime = millis() - start_time;
1280
         unsigned long runtime = millis() - start_time;
1163
         String a = String("Time: ") + String(runtime / 1000UL) + String("s / ") + String(selected_time) + String('s');
1281
         String a = String("Time: ") + String(runtime / 1000UL) + String("s / ") + String(selected_time) + String('s');

+ 43
- 29
src/WifiStuff.cpp View File

217
         }
217
         }
218
     }
218
     }
219
     ws += " ],\n";
219
     ws += " ],\n";
220
+
221
+    ws += F("\"kickstart\": [ ");
222
+    for (int i = 0; i < VALVE_COUNT - 1; i++) {
223
+        ws += "\"";
224
+        ws += get_plants()->getKickstart()->getPin(i) ? "1" : "0";
225
+        ws += "\"";
226
+
227
+        if (i < (VALVE_COUNT - 2)) {
228
+            ws += ", ";
229
+        }
230
+    }
231
+    ws += " ],\n";
220
     
232
     
221
     ws += "\"switchstate\": \"";
233
     ws += "\"switchstate\": \"";
222
     Plants::Waterlevel wl = get_plants()->getWaterlevel();
234
     Plants::Waterlevel wl = get_plants()->getWaterlevel();
268
     message += F("font-family: monospace;\n");
280
     message += F("font-family: monospace;\n");
269
     message += F("}\n");
281
     message += F("}\n");
270
     
282
     
271
-    message += F(".switch {\n");
272
-    message += F("width: max-content;\n");
273
-    message += F("border: 1px solid black;\n");
274
-    message += F("border-radius: 50%;\n");
275
-    message += F("padding: 2em;\n");
276
-    message += F("margin: 1em;\n");
277
-    message += F("}\n");
278
-    
279
-    message += F(".valve {\n");
280
-    message += F("width: max-content;\n");
281
-    message += F("border: 1px solid black;\n");
282
-    message += F("border-radius: 50%;\n");
283
-    message += F("padding: 2em;\n");
284
-    message += F("margin: 1em;\n");
285
-    message += F("}\n");
286
-    
287
-    message += F(".pump {\n");
288
-    message += F("width: max-content;\n");
289
-    message += F("border: 1px solid black;\n");
290
-    message += F("border-radius: 50%;\n");
291
-    message += F("padding: 2em;\n");
292
-    message += F("margin: 1em;\n");
293
-    message += F("}\n");
294
-
295
-    message += F(".aux {\n");
283
+    message += F(".ioelem {\n");
296
     message += F("width: max-content;\n");
284
     message += F("width: max-content;\n");
297
     message += F("border: 1px solid black;\n");
285
     message += F("border: 1px solid black;\n");
298
     message += F("border-radius: 50%;\n");
286
     message += F("border-radius: 50%;\n");
419
     
407
     
420
     message += F("<div class='container'>\n");
408
     message += F("<div class='container'>\n");
421
     for (int i = 0; i < SWITCH_COUNT; i++) {
409
     for (int i = 0; i < SWITCH_COUNT; i++) {
422
-        message += F("<div class='switch' style='background-color: ");
410
+        message += F("<div class='ioelem switch' style='background-color: ");
423
         bool v = get_plants()->getSwitches()->getPin(i);
411
         bool v = get_plants()->getSwitches()->getPin(i);
424
         
412
         
425
 #ifdef INVERT_SENSOR_BOTTOM
413
 #ifdef INVERT_SENSOR_BOTTOM
448
     message += F("Valves:\n");
436
     message += F("Valves:\n");
449
     message += F("<div class='container'>\n");
437
     message += F("<div class='container'>\n");
450
     for (int i = 0; i < VALVE_COUNT; i++) {
438
     for (int i = 0; i < VALVE_COUNT; i++) {
451
-        message += F("<div class='valve' style='background-color: ");
439
+        message += F("<div class='ioelem valve' style='background-color: ");
452
         if (get_plants()->getValves()->getPin(i)) {
440
         if (get_plants()->getValves()->getPin(i)) {
453
             message += F("red");
441
             message += F("red");
454
         } else {
442
         } else {
463
     message += F("Pumps:\n");
451
     message += F("Pumps:\n");
464
     message += F("<div class='container'>\n");
452
     message += F("<div class='container'>\n");
465
     for (int i = 0; i < PUMP_COUNT; i++) {
453
     for (int i = 0; i < PUMP_COUNT; i++) {
466
-        message += F("<div class='pump' style='background-color: ");
454
+        message += F("<div class='ioelem pump' style='background-color: ");
467
         if (get_plants()->getPumps()->getPin(i)) {
455
         if (get_plants()->getPumps()->getPin(i)) {
468
             message += F("red");
456
             message += F("red");
469
         } else {
457
         } else {
478
     message += F("Aux:\n");
466
     message += F("Aux:\n");
479
     message += F("<div class='container'>\n");
467
     message += F("<div class='container'>\n");
480
     for (int i = 0; i < AUX_COUNT; i++) {
468
     for (int i = 0; i < AUX_COUNT; i++) {
481
-        message += F("<div class='aux' style='background-color: ");
469
+        message += F("<div class='ioelem aux' style='background-color: ");
482
         if (get_plants()->getAux()->getPin(i)) {
470
         if (get_plants()->getAux()->getPin(i)) {
483
             message += F("red");
471
             message += F("red");
484
         } else {
472
         } else {
490
     }
478
     }
491
     message += F("</div><hr>\n");
479
     message += F("</div><hr>\n");
492
 
480
 
481
+    message += F("Kickstart:\n");
482
+    message += F("<div class='container'>\n");
483
+    for (int i = 0; i < VALVE_COUNT - 1; i++) {
484
+        message += F("<div class='ioelem kickstart' style='background-color: ");
485
+        if (get_plants()->getKickstart()->getPin(i)) {
486
+            message += F("red");
487
+        } else {
488
+            message += F("green");
489
+        }
490
+        message += F(";'>A");
491
+        message += String(i + 1);
492
+        message += F("</div>");
493
+    }
494
+    message += F("</div><hr>\n");
495
+
493
     message += F("Green means valve is closed / pump is off / switch is not submersed.\n");
496
     message += F("Green means valve is closed / pump is off / switch is not submersed.\n");
494
     message += F("<br>\n");
497
     message += F("<br>\n");
495
     message += F("Red means valve is open / pump is running / switch is submersed.</div>\n");
498
     message += F("Red means valve is open / pump is running / switch is submersed.</div>\n");
643
     message += F(           "aux[i].style = 'background-color: red;';\n");
646
     message += F(           "aux[i].style = 'background-color: red;';\n");
644
     message += F(       "}\n");
647
     message += F(       "}\n");
645
     message += F(    "}\n");
648
     message += F(    "}\n");
649
+
650
+    message += F(    "for (let i = 0; i < ");
651
+    message += String(VALVE_COUNT - 1);
652
+    message += F("; i++) {\n");
653
+    message += F(       "var kickstart = document.getElementsByClassName('kickstart');\n");
654
+    message += F(       "if (msg.kickstart[i] == '0') {\n");
655
+    message += F(           "kickstart[i].style = 'background-color: green;';\n");
656
+    message += F(       "} else {\n");
657
+    message += F(           "kickstart[i].style = 'background-color: red;';\n");
658
+    message += F(       "}\n");
659
+    message += F(    "}\n");
646
     
660
     
647
     message += F(    "var switchstate = document.getElementById('switchstate');\n");
661
     message += F(    "var switchstate = document.getElementById('switchstate');\n");
648
     message += F(    "switchstate.innerHTML = msg.switchstate;\n");
662
     message += F(    "switchstate.innerHTML = msg.switchstate;\n");

Loading…
Cancel
Save