Browse Source

add aux relais channels and fertilizer stirring menu.

Thomas Buck 2 years ago
parent
commit
85d1e25412
7 changed files with 268 additions and 34 deletions
  1. 9
    1
      include/Plants.h
  2. 10
    1
      include/Statemachine.h
  3. 2
    0
      include/config.h
  4. 8
    0
      include/config_pins.h
  5. 3
    1
      src/Functionality.cpp
  6. 41
    2
      src/Plants.cpp
  7. 195
    29
      src/Statemachine.cpp

+ 9
- 1
include/Plants.h View File

@@ -34,11 +34,12 @@ public:
34 34
     // valves: no of plants + 1 for water inlet
35 35
     // pumps: no of fertilizers
36 36
     // switches: 2, low and high level
37
-    Plants(int valve_count, int pump_count, int switch_count);
37
+    Plants(int valve_count, int pump_count, int switch_count, int aux_count);
38 38
     
39 39
     void setValvePins(int pins[]);
40 40
     void setPumpPins(int pins[]);
41 41
     void setSwitchPins(int pins[], bool pullup);
42
+    void setAuxPins(int pins[]);
42 43
     
43 44
     void abort(void);
44 45
     
@@ -55,15 +56,22 @@ public:
55 56
     void startPlant(int id);
56 57
     void stopPlant(int id);
57 58
     void stopAllPlants(void);
59
+
60
+    int countAux(void);
61
+    void startAux(int id);
62
+    void stopAux(int id);
63
+    void stopAllAux(void);
58 64
     
59 65
     GPIOBank *getValves(void);
60 66
     GPIOBank *getPumps(void);
61 67
     GPIOBank *getSwitches(void);
68
+    GPIOBank *getAux(void);
62 69
     
63 70
 private:
64 71
     GPIOBank valves;
65 72
     GPIOBank pumps;
66 73
     GPIOBank switches;
74
+    GPIOBank aux;
67 75
 };
68 76
 
69 77
 extern Plants plants;

+ 10
- 1
include/Statemachine.h View File

@@ -31,12 +31,15 @@ public:
31 31
         init = 0,
32 32
         menu_a, // manual, auto
33 33
         menu_b, // pumps, valves
34
+        menu_c, // aux
34 35
         
35 36
         auto_mode_a, // select mode 1
36 37
         auto_mode_b, // select mode 2
37
-        auto_fert, // select fertilizer
38
+        auto_fert_a, // select fertilizer 1
39
+        auto_fert_b, // select fertilizer 2
38 40
         auto_fert_run,
39 41
         auto_tank_run,
42
+        auto_stirr_run,
40 43
         auto_plant, // select plant
41 44
         auto_plant_run,
42 45
         auto_done,
@@ -59,6 +62,12 @@ public:
59 62
         menu_valves_run,
60 63
         menu_valves_done,
61 64
         
65
+        menu_aux, // select aux channel
66
+        menu_aux_time, // set runtime
67
+        menu_aux_go, // running
68
+        menu_aux_run,
69
+        menu_aux_done,
70
+
62 71
         error
63 72
     };
64 73
     

+ 2
- 0
include/config.h View File

@@ -32,9 +32,11 @@
32 32
 // in seconds
33 33
 #define MAX_TANK_FILL_TIME (67 + 3)
34 34
 #define AUTO_PUMP_RUNTIME 5
35
+#define AUTO_STIRR_RUNTIME 60
35 36
 #define MAX_AUTO_PLANT_RUNTIME (35 * 60)
36 37
 #define MAX_PUMP_RUNTIME 30
37 38
 #define MAX_VALVE_RUNTIME (45 * 60)
39
+#define MAX_AUX_RUNTIME (5 * 60)
38 40
 
39 41
 // Sketch version
40 42
 #define FIRMWARE_VERSION "0.2"

+ 8
- 0
include/config_pins.h View File

@@ -56,6 +56,10 @@
56 56
 #define SWITCH_COUNT 2
57 57
 #define SWITCH_PINS 19, 20
58 58
 
59
+// stirrer
60
+#define AUX_COUNT 1
61
+#define AUX_PINS 21
62
+
59 63
 #endif // FUNCTION_CONTROL
60 64
 
61 65
 #endif // PLATFORM_AVR
@@ -87,6 +91,10 @@
87 91
 #define PUMP_COUNT 3
88 92
 #define PUMP_PINS 2, 0, 4
89 93
 
94
+// stirrer
95
+#define AUX_COUNT 1
96
+#define AUX_PINS 19
97
+
90 98
 // bottom, top
91 99
 #define SWITCH_COUNT 2
92 100
 #define SWITCH_PINS 26, 25

+ 3
- 1
src/Functionality.cpp View File

@@ -64,10 +64,11 @@ bool doing_multi_input = false;
64 64
 #include "Statemachine.h"
65 65
 #include "WifiStuff.h"
66 66
 
67
-Plants plants(VALVE_COUNT, PUMP_COUNT, SWITCH_COUNT);
67
+Plants plants(VALVE_COUNT, PUMP_COUNT, SWITCH_COUNT, AUX_COUNT);
68 68
 int valve_pins[VALVE_COUNT] = { VALVE_PINS };
69 69
 int pump_pins[PUMP_COUNT] = { PUMP_PINS };
70 70
 int switch_pins[SWITCH_COUNT] = { SWITCH_PINS };
71
+int aux_pins[AUX_COUNT] = { AUX_PINS };
71 72
 
72 73
 Statemachine sm(write_to_all, backspace);
73 74
 
@@ -459,6 +460,7 @@ void control_setup(void) {
459 460
     plants.setValvePins(valve_pins);
460 461
     plants.setPumpPins(pump_pins);
461 462
     plants.setSwitchPins(switch_pins, true);
463
+    plants.setAuxPins(aux_pins);
462 464
     
463 465
 #ifndef FUNCTION_UI
464 466
     

+ 41
- 2
src/Plants.cpp View File

@@ -27,8 +27,8 @@
27 27
 // valves: no of plants + 1 for water inlet
28 28
 // pumps: no of fertilizers
29 29
 // switches: 2, low and high level
30
-Plants::Plants(int valve_count, int pump_count, int switch_count) :
31
-        valves(valve_count), pumps(pump_count), switches(switch_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) {
32 32
 }
33 33
 
34 34
     
@@ -44,6 +44,10 @@ GPIOBank *Plants::getSwitches(void) {
44 44
     return &switches;
45 45
 }
46 46
 
47
+GPIOBank *Plants::getAux(void) {
48
+    return &aux;
49
+}
50
+
47 51
 void Plants::setValvePins(int pins[]) {
48 52
     valves.setPinNumbers(pins);
49 53
     valves.setOutput();
@@ -61,10 +65,17 @@ void Plants::setSwitchPins(int pins[], bool pullup) {
61 65
     switches.setInput(pullup);
62 66
 }
63 67
 
68
+void Plants::setAuxPins(int pins[]) {
69
+    aux.setPinNumbers(pins);
70
+    aux.setOutput();
71
+    aux.setAll(false);
72
+}
73
+
64 74
 void Plants::abort(void) {
65 75
     closeWaterInlet();
66 76
     stopAllFertilizers();
67 77
     stopAllPlants();
78
+    stopAllAux();
68 79
 }
69 80
 
70 81
 Plants::Waterlevel Plants::getWaterlevel(void) {
@@ -155,3 +166,31 @@ void Plants::stopAllPlants(void) {
155 166
         stopPlant(i);
156 167
     }
157 168
 }
169
+
170
+int Plants::countAux(void) {
171
+    return aux.getSize();
172
+}
173
+
174
+void Plants::startAux(int id) {
175
+    debug.print("Plants::startAux ");
176
+    debug.println(id);
177
+
178
+    if ((id >= 0) && (id < countAux())) {
179
+        aux.setPin(id, true);
180
+    }
181
+}
182
+
183
+void Plants::stopAux(int id) {
184
+    debug.print("Plants::stopAux ");
185
+    debug.println(id);
186
+
187
+    if ((id >= 0) && (id < countAux())) {
188
+        aux.setPin(id, false);
189
+    }
190
+}
191
+
192
+void Plants::stopAllAux(void) {
193
+    for (int i = 0; i < countAux(); i++) {
194
+        stopAux(i);
195
+    }
196
+}

+ 195
- 29
src/Statemachine.cpp View File

@@ -76,11 +76,14 @@ static const char *state_names[] = {
76 76
     stringify(init),
77 77
     stringify(menu_a),
78 78
     stringify(menu_b),
79
+    stringify(menu_c),
79 80
     stringify(auto_mode_a),
80 81
     stringify(auto_mode_b),
81
-    stringify(auto_fert),
82
+    stringify(auto_fert_a),
83
+    stringify(auto_fert_b),
82 84
     stringify(auto_fert_run),
83 85
     stringify(auto_tank_run),
86
+    stringify(auto_stirr_run),
84 87
     stringify(auto_plant),
85 88
     stringify(auto_plant_run),
86 89
     stringify(auto_done),
@@ -98,6 +101,11 @@ static const char *state_names[] = {
98 101
     stringify(menu_valves_go),
99 102
     stringify(menu_valves_run),
100 103
     stringify(menu_valves_done),
104
+    stringify(menu_aux),
105
+    stringify(menu_aux_time),
106
+    stringify(menu_aux_go),
107
+    stringify(menu_aux_run),
108
+    stringify(menu_aux_done),
101 109
     stringify(error)
102 110
 };
103 111
 
@@ -134,7 +142,7 @@ void Statemachine::begin(void) {
134 142
 void Statemachine::input(int n) {
135 143
     if (state == init) {
136 144
         switch_to(menu_a);
137
-    } else if ((state == menu_a) || (state == menu_b)) {
145
+    } else if ((state == menu_a) || (state == menu_b) || (state == menu_c)) {
138 146
         if (n == 1) {
139 147
             switch_to(auto_mode_a);
140 148
         } else if (n == 2) {
@@ -143,17 +151,19 @@ void Statemachine::input(int n) {
143 151
             switch_to(menu_pumps);
144 152
         } else if (n == 4) {
145 153
             switch_to(menu_valves);
154
+        } else if (n == 5) {
155
+            switch_to(menu_aux);
146 156
         } else if (n == -1) {
147 157
             switch_to(init);
148 158
         } else if (n == -2) {
149
-            switch_to((state == menu_a) ? menu_b : menu_a);
159
+            switch_to((state == menu_a) ? menu_b : ((state == menu_b) ? menu_c : menu_a));
150 160
         }
151 161
     } else if (state == automation_mode) {
152 162
         // TODO
153 163
         switch_to(menu_a);
154 164
     } else if ((state == auto_mode_a) || (state == auto_mode_b)) {
155 165
         if (n == 1) {
156
-            switch_to(auto_fert);
166
+            switch_to(auto_fert_a);
157 167
         } else if (n == 2) {
158 168
             selected_plants.clear();
159 169
             switch_to(fillnwater_plant);
@@ -181,7 +191,7 @@ void Statemachine::input(int n) {
181 191
         } else if (n == -2) {
182 192
             switch_to((state == auto_mode_a) ? auto_mode_b : auto_mode_a);
183 193
         }
184
-    } else if (state == auto_fert) {
194
+    } else if ((state == auto_fert_a) || (state == auto_fert_b)) {
185 195
         if ((n >= 1) && (n <= 3)) {
186 196
             auto wl = plants.getWaterlevel();
187 197
             if ((wl != Plants::full) && (wl != Plants::invalid)) {
@@ -198,17 +208,22 @@ void Statemachine::input(int n) {
198 208
                 state = auto_mode_a;
199 209
                 switch_to(error);
200 210
             }
201
-        } else if ((n == -1) || (n == -2)) {
211
+        } else if (n == 4) {
212
+            plants.startAux(0);
213
+            selected_id = 1;
214
+            selected_time = AUTO_STIRR_RUNTIME;
215
+            start_time = millis();
216
+            switch_to(auto_stirr_run);
217
+        } else if (n == -1) {
202 218
             switch_to(auto_mode_a);
219
+        } else if (n == -2) {
220
+            switch_to((state == auto_fert_a) ? auto_fert_b : auto_fert_a);
203 221
         }
204
-    } else if (state == auto_fert_run) {
205
-            plants.abort();
206
-            stop_time = millis();
207
-            switch_to(auto_done);
208
-    } else if (state == auto_tank_run) {
209
-            plants.abort();
210
-            stop_time = millis();
211
-            switch_to(auto_done);
222
+    } else if ((state == auto_fert_run) || (state == auto_tank_run)
223
+            || (state == auto_stirr_run)) {
224
+        plants.abort();
225
+        stop_time = millis();
226
+        switch_to(auto_done);
212 227
     } else if (state == auto_plant) {
213 228
         if (n == -1) {
214 229
             if (db.hasDigits()) {
@@ -528,11 +543,82 @@ void Statemachine::input(int n) {
528 543
             switch_to(menu_valves_time);
529 544
         }
530 545
     } else if (state == menu_valves_run) {
531
-            plants.abort();
532
-            stop_time = millis();
533
-            switch_to(menu_valves_done);
546
+        plants.abort();
547
+        stop_time = millis();
548
+        switch_to(menu_valves_done);
534 549
     } else if (state == menu_valves_done) {
535 550
         switch_to(menu_b);
551
+    } else if (state == menu_aux) {
552
+        if (n == -1) {
553
+            if (db.hasDigits()) {
554
+                backspace();
555
+                db.removeDigit();
556
+            } else {
557
+                switch_to(menu_c);
558
+            }
559
+        } else if (n == -2) {
560
+            if (!db.hasDigits()) {
561
+                return;
562
+            }
563
+
564
+            selected_id = number_input();
565
+
566
+            if ((selected_id <= 0) || (selected_id > plants.countAux())) {
567
+                error_condition = "Invalid valve ID!";
568
+                switch_to(error);
569
+            } else {
570
+                switch_to(menu_aux_time);
571
+            }
572
+        } else {
573
+            if (db.spaceLeft()) {
574
+                db.addDigit(n);
575
+            } else {
576
+                backspace();
577
+            }
578
+        }
579
+    } else if (state == menu_aux_time) {
580
+        if (n == -1) {
581
+            if (db.hasDigits()) {
582
+                backspace();
583
+                db.removeDigit();
584
+            } else {
585
+                switch_to(menu_aux);
586
+            }
587
+        } else if (n == -2) {
588
+            if (!db.hasDigits()) {
589
+                return;
590
+            }
591
+
592
+            selected_time = number_input();
593
+
594
+            if ((selected_time <= 0) || (selected_time > MAX_AUX_RUNTIME)) {
595
+                error_condition = "Invalid time range!";
596
+                switch_to(error);
597
+            } else {
598
+                switch_to(menu_aux_go);
599
+            }
600
+        } else {
601
+            if (db.spaceLeft()) {
602
+                db.addDigit(n);
603
+            } else {
604
+                backspace();
605
+            }
606
+        }
607
+    } else if (state == menu_aux_go) {
608
+        if (n == -2) {
609
+            start_time = millis();
610
+            last_animation_time = start_time;
611
+            plants.startAux(selected_id - 1);
612
+            switch_to(menu_aux_run);
613
+        } else {
614
+            switch_to(menu_aux_time);
615
+        }
616
+    } else if (state == menu_aux_run) {
617
+        plants.abort();
618
+        stop_time = millis();
619
+        switch_to(menu_aux_done);
620
+    } else if (state == menu_aux_done) {
621
+        switch_to(menu_c);
536 622
     } else if (state == error) {
537 623
         if (old_state != error) {
538 624
             switch_to(old_state);
@@ -557,13 +643,15 @@ uint32_t Statemachine::number_input(void) {
557 643
 }
558 644
 
559 645
 void Statemachine::act(void) {
560
-    if ((state == menu_pumps_run) || (state == menu_valves_run)) {
646
+    if ((state == menu_pumps_run) || (state == menu_valves_run)
647
+            || (state == menu_aux_run)
648
+            || (state == auto_stirr_run)) {
561 649
         unsigned long runtime = millis() - start_time;
562 650
         if ((runtime / 1000UL) >= selected_time) {
563 651
             // stop if timeout has been reached
564 652
             plants.abort();
565 653
             stop_time = millis();
566
-            switch_to((state == menu_pumps_run) ? menu_pumps_done : menu_valves_done);
654
+            switch_to((state == menu_pumps_run) ? menu_pumps_done : ((state == menu_valves_run) ? menu_valves_done : ((state == menu_aux_run) ? menu_aux_done : auto_done)));
567 655
         } else if ((millis() - last_animation_time) >= 500) {
568 656
             // update animation if needed
569 657
             last_animation_time = millis();
@@ -757,14 +845,17 @@ void Statemachine::act(void) {
757 845
         }
758 846
     }
759 847
 
760
-    if ((state == menu_a) || (state == menu_b) || (state == automation_mode)
848
+    if ((state == menu_a) || (state == menu_b) || (state == menu_c)
849
+            || (state == automation_mode) || (state == auto_done)
761 850
             || (state == auto_mode_a) || (state == auto_mode_b)
762
-            || (state == auto_fert) || (state == auto_done)
851
+            || (state == auto_fert_a) || (state == auto_fert_b)
763 852
             || (state == auto_plant) || (state == fillnwater_plant)
764 853
             || (state == menu_pumps) || (state == menu_pumps_time)
765 854
             || (state == menu_pumps_go) || (state == menu_pumps_done)
766 855
             || (state == menu_valves) || (state == menu_valves_time)
767
-            || (state == menu_valves_go) || (state == menu_valves_done)) {
856
+            || (state == menu_valves_go) || (state == menu_valves_done)
857
+            || (state == menu_aux) || (state == menu_aux_time)
858
+            || (state == menu_aux_go) || (state == menu_aux_done)) {
768 859
         unsigned long runtime = millis() - into_state_time;
769 860
         if (runtime >= BACK_TO_IDLE_TIMEOUT) {
770 861
             debug.print("Idle timeout reached in state ");
@@ -796,16 +887,22 @@ void Statemachine::switch_to(States s) {
796 887
               "# Execute input num.",
797 888
               -1);
798 889
     } else if (s == menu_a) {
799
-        print("----- Menu 1/2 -----",
890
+        print("----- Menu 1/3 -----",
800 891
               "1: Manual Operation",
801 892
               "2: Automation",
802
-              "#: Go to page 2/2...",
893
+              "#: Go to page 2/3...",
803 894
               -1);
804 895
     } else if (s == menu_b) {
805
-        print("----- Menu 2/2 -----",
896
+        print("----- Menu 2/3 -----",
806 897
               "3: Fertilizer pumps",
807 898
               "4: Outlet valves",
808
-              "#: Go to page 1/2...",
899
+              "#: Go to page 3/3...",
900
+              -1);
901
+    } else if (s == menu_c) {
902
+        print("----- Menu 3/3 -----",
903
+              "5: Aux. Outputs",
904
+              "",
905
+              "#: Go to page 1/3...",
809 906
               -1);
810 907
     } else if (state == automation_mode) {
811 908
         // TODO
@@ -826,11 +923,17 @@ void Statemachine::switch_to(States s) {
826 923
               "4: Water a plant",
827 924
               "#: Go to page 1/2...",
828 925
               -1);
829
-    } else if (s == auto_fert) {
830
-        print("---- Fertilizer ----",
926
+    } else if (s == auto_fert_a) {
927
+        print("-- Fertilizer 1/2 --",
831 928
               "1: Vegetation Phase",
832 929
               "2: Bloom Phase",
833
-              "3: Special",
930
+              "#: Go to page 2/2...",
931
+              -1);
932
+    } else if (s == auto_fert_b) {
933
+        print("-- Fertilizer 2/2 --",
934
+              "3: Special Fert.",
935
+              "4: Run Stirrer",
936
+              "#: Go to page 1/2...",
834 937
               -1);
835 938
     } else if (s == auto_fert_run) {
836 939
         unsigned long runtime = millis() - start_time;
@@ -847,6 +950,21 @@ void Statemachine::switch_to(States s) {
847 950
               b.c_str(),
848 951
               "Hit any key to stop!",
849 952
               -1);
953
+    } else if (s == auto_stirr_run) {
954
+        unsigned long runtime = millis() - start_time;
955
+        String a = String("Time: ") + String(runtime / 1000UL) + String("s / ") + String(selected_time) + String('s');
956
+
957
+        unsigned long anim = runtime * 20UL / (selected_time * 1000UL);
958
+        String b;
959
+        for (unsigned long i = 0; i < anim; i++) {
960
+            b += '#';
961
+        }
962
+
963
+        print("----- Stirring -----",
964
+              a.c_str(),
965
+              b.c_str(),
966
+              "Hit any key to stop!",
967
+              -1);
850 968
     } else if ((s == auto_tank_run) || (s == fillnwater_tank_run)) {
851 969
         unsigned long runtime = millis() - start_time;
852 970
         String a = String("Time: ") + String(runtime / 1000UL) + String("s / ") + String(selected_time) + String('s');
@@ -1050,6 +1168,54 @@ void Statemachine::switch_to(States s) {
1050 1168
             }
1051 1169
         }
1052 1170
 #endif // PLATFORM_ESP
1171
+    } else if (s == menu_aux) {
1172
+        String a = String("(Input 1 to ") + String(plants.countAux()) + String(")");
1173
+
1174
+        print("------- Aux. -------",
1175
+              "Please select aux.",
1176
+              a.c_str(),
1177
+              "Aux.: ",
1178
+              3);
1179
+    } else if (s == menu_aux_time) {
1180
+        String header = String("------ Aux  ") + String(selected_id) + String(" ------");
1181
+
1182
+        print(header.c_str(),
1183
+              "Please set runtime",
1184
+              "(Input in seconds)",
1185
+              "Runtime: ",
1186
+              3);
1187
+    } else if (s == menu_aux_go) {
1188
+        String a = String("Aux No. ") + String(selected_id);
1189
+        String b = String("Runtime ") + String(selected_time) + String('s');
1190
+
1191
+        print("----- Confirm? -----",
1192
+              a.c_str(),
1193
+              b.c_str(),
1194
+              "           # Confirm",
1195
+              -1);
1196
+    } else if (s == menu_aux_run) {
1197
+        unsigned long runtime = millis() - start_time;
1198
+        String a = String("Time: ") + String(runtime / 1000UL) + String("s / ") + String(selected_time) + String('s');
1199
+
1200
+        unsigned long anim = runtime * 20UL / (selected_time * 1000UL);
1201
+        String b;
1202
+        for (unsigned long i = 0; i <= anim; i++) {
1203
+            b += '#';
1204
+        }
1205
+
1206
+        print("----- Stirring -----",
1207
+              a.c_str(),
1208
+              b.c_str(),
1209
+              "Hit any key to stop!",
1210
+              -1);
1211
+    } else if (s == menu_aux_done) {
1212
+        String a = String("after ") + String((stop_time - start_time) / 1000UL) + String("s.");
1213
+
1214
+        print("------- Done -------",
1215
+              "Stirring finished",
1216
+              a.c_str(),
1217
+              "Hit any key for menu",
1218
+              -1);
1053 1219
     } else if (s == error) {
1054 1220
         print("------ Error! ------",
1055 1221
               "There is a problem:",

Loading…
Cancel
Save