소스 검색

work on firmware, state machine

Thomas Buck 2 년 전
부모
커밋
c2645f9ba4
12개의 변경된 파일310개의 추가작업 그리고 59개의 파일을 삭제
  1. 11
    0
      include/config.h
  2. 12
    2
      include/config_pins.h
  3. 4
    4
      include/lcd.h
  4. 69
    2
      include/statemachine.h
  5. 12
    0
      include/states.h
  6. 1
    1
      include/steppers.h
  7. 1
    0
      platformio.ini
  8. 41
    1
      src/lcd.cpp
  9. 10
    10
      src/main.cpp
  10. 61
    38
      src/statemachine.cpp
  11. 87
    0
      src/states.cpp
  12. 1
    1
      src/steppers.cpp

+ 11
- 0
include/config.h 파일 보기

@@ -1,6 +1,10 @@
1 1
 #ifndef _CONFIG_H_
2 2
 #define _CONFIG_H_
3 3
 
4
+/***************************************
5
+ ********** Firmware Settings **********
6
+ ***************************************/
7
+
4 8
 #define FIRMWARE_VERSION "0.1"
5 9
 
6 10
 #define LED_BLINK_INTERVAL 500
@@ -9,6 +13,13 @@
9 13
 #define ENCODER_CLICK_BEEP_FREQ 2000
10 14
 #define ENCODER_CLICK_BEEP_TIME 50
11 15
 
16
+/***************************************
17
+ ********** Hardware Settings **********
18
+ ***************************************/
19
+
20
+#define USE_20X4_TEXT_LCD
21
+//#define USE_FULL_GRAPHIC_LCD
22
+
12 23
 #define XY_BELT_PITCH 2.0
13 24
 #define XY_PULLEY_TEETH 40.0
14 25
 #define XY_MICRO_STEPS 16.0

+ 12
- 2
include/config_pins.h 파일 보기

@@ -47,6 +47,8 @@
47 47
 #define TEMP_0_PIN		13   // ANALOG NUMBERING
48 48
 #define TEMP_1_PIN		14   // ANALOG NUMBERING
49 49
 
50
+#ifdef USE_20X4_TEXT_LCD
51
+
50 52
 // from https://reprap.org/wiki/RepRapDiscount_Smart_Controller
51 53
 
52 54
 //STOP / KILL button
@@ -71,12 +73,20 @@
71 73
 //SD card detect pin
72 74
 #define SDCARDDETECT 49 //[RAMPS14-SMART-ADAPTER]
73 75
 
76
+#endif // USE_20X4_TEXT_LCD
77
+
78
+#ifdef USE_FULL_GRAPHIC_LCD
79
+
80
+// TODO
81
+
82
+#endif // USE_FULL_GRAPHIC_LCD
83
+
74 84
 #endif // _CONFIG_PINS_H_
75 85
 
76 86
 #if ((X_MIN_PIN != -1) && (X_MAX_PIN != -1)) || ((X_MIN_PIN == -1) && (X_MAX_PIN == -1))
77
-#error define one of X_MIN_PIN and X_MAX_PIN
87
+#error define one of X_MIN_PIN or X_MAX_PIN
78 88
 #endif
79 89
 
80 90
 #if ((Y_MIN_PIN != -1) && (Y_MAX_PIN != -1)) || ((Y_MIN_PIN == -1) && (Y_MAX_PIN == -1))
81
-#error define one of Y_MIN_PIN and Y_MAX_PIN
91
+#error define one of Y_MIN_PIN or Y_MAX_PIN
82 92
 #endif

+ 4
- 4
include/lcd.h 파일 보기

@@ -1,10 +1,10 @@
1 1
 #ifndef _LCD_H_
2 2
 #define _LCD_H_
3 3
 
4
-#include <LiquidCrystal.h>
5
-
6
-extern LiquidCrystal lcd;
7
-
8 4
 void lcd_init(void);
9 5
 
6
+void lcd_clear(void);
7
+void lcd_set_heading(const char *heading);
8
+void lcd_set_text(const char *text);
9
+
10 10
 #endif // _LCD_H_

+ 69
- 2
include/statemachine.h 파일 보기

@@ -1,7 +1,74 @@
1 1
 #ifndef _STATE_MACHINE_H_
2 2
 #define _STATE_MACHINE_H_
3 3
 
4
-void statemachine_run(int click, int encoder, int kill);
5
-void statemachine_motors_done(void);
4
+#include <Array.h>
5
+
6
+struct StateMachineInput {
7
+    StateMachineInput(int c, int e, int k, int m)
8
+            : click(c), encoder(e), kill(k), motors_done(m) { };
9
+
10
+    int click;
11
+    int encoder;
12
+    int kill;
13
+    int motors_done;
14
+};
15
+
16
+class State {
17
+public:
18
+    State(State *_parent = NULL);
19
+    State *getParent(void) { return parent; }
20
+
21
+    virtual void setChild(State *_child) { child = _child; }
22
+    State *getChild(void) { return child; }
23
+
24
+    void setTitle(const char *_title) { title = _title; }
25
+    const char *getTitle(void) { return title; }
26
+
27
+    virtual void enterState(void) = 0;
28
+    virtual void inState(StateMachineInput smi) = 0;
29
+
30
+private:
31
+    State *parent;
32
+    State *child;
33
+    const char *title;
34
+};
35
+
36
+class StateText : public State {
37
+public:
38
+    StateText(State *_parent = NULL);
39
+
40
+    void setHeading(const char *_heading);
41
+    void setText(const char *_text);
42
+
43
+    typedef void(*EnterFuncPtr)(void);
44
+    typedef void(*InFuncPtr)(StateMachineInput smi);
45
+
46
+    void onEnter(EnterFuncPtr func);
47
+    void whenIn(InFuncPtr func);
48
+
49
+    virtual void enterState(void);
50
+    virtual void inState(StateMachineInput smi);
51
+
52
+private:
53
+    const char *heading;
54
+    const char *text;
55
+    EnterFuncPtr onEnterFunc;
56
+    InFuncPtr whenInFunc;
57
+};
58
+
59
+class StateMenu : public State {
60
+public:
61
+    StateMenu(State *_parent = NULL);
62
+    virtual void setChild(State *_child);
63
+
64
+    void addChild(State *_child, int pos = -1);
65
+
66
+    virtual void enterState(void);
67
+    virtual void inState(StateMachineInput smi);
68
+
69
+private:
70
+    int menuPos;
71
+    Array<State *, 42> children;
72
+};
6 73
 
7 74
 #endif // _STATE_MACHINE_H_

+ 12
- 0
include/states.h 파일 보기

@@ -0,0 +1,12 @@
1
+#ifndef _STATES_H_
2
+#define _STATES_H_
3
+
4
+#include "statemachine.h"
5
+
6
+void states_init(void);
7
+void states_run(struct StateMachineInput smi);
8
+
9
+State *states_get(void);
10
+void states_go_to(State *state);
11
+
12
+#endif // _STATES_H_

+ 1
- 1
include/steppers.h 파일 보기

@@ -5,7 +5,7 @@ void steppers_init(void);
5 5
 bool steppers_run(void);
6 6
 
7 7
 bool steppers_homed(void);
8
-int steppers_start_homing(void);
8
+void steppers_start_homing(void);
9 9
 
10 10
 int steppers_move_x(long pos);
11 11
 int steppers_move_y(long pos);

+ 1
- 0
platformio.ini 파일 보기

@@ -22,3 +22,4 @@ lib_deps =
22 22
     arduino-libraries/LiquidCrystal
23 23
     https://github.com/waspinator/AccelStepper
24 24
     https://github.com/mathertel/RotaryEncoder
25
+    https://github.com/janelia-arduino/Array

+ 41
- 1
src/lcd.cpp 파일 보기

@@ -4,14 +4,54 @@
4 4
 #include "config_pins.h"
5 5
 #include "lcd.h"
6 6
 
7
+#if (defined(USE_20X4_TEXT_LCD) && defined(USE_FULL_GRAPHIC_LCD)) || (!defined(USE_20X4_TEXT_LCD) && !defined(USE_FULL_GRAPHIC_LCD))
8
+#error define one of USE_20X4_TEXT_LCD or USE_FULL_GRAPHIC_LCD
9
+#endif
10
+
11
+#ifdef USE_20X4_TEXT_LCD
12
+#include <LiquidCrystal.h>
7 13
 LiquidCrystal lcd(LCD_PINS_RS, LCD_PINS_ENABLE, LCD_PINS_D4, LCD_PINS_D5, LCD_PINS_D6, LCD_PINS_D7);
14
+#endif // USE_20X4_TEXT_LCD
15
+
16
+#ifdef USE_FULL_GRAPHIC_LCD
17
+// TODO
18
+#endif // USE_FULL_GRAPHIC_LCD
8 19
 
9 20
 void lcd_init(void) {
21
+#ifdef USE_20X4_TEXT_LCD
10 22
     lcd.begin(20, 4);
23
+    lcd.clear();
11 24
 
12 25
     lcd.print(F("    Fuellfix  v2    "));
13
-    lcd.print(F("    Initializing    "));
26
+    lcd.print(F("  Initializing....  "));
14 27
     lcd.print(F("Software Version "));
15 28
     lcd.print(F(FIRMWARE_VERSION));
16 29
     lcd.print(F("made by: xythobuz.de"));
30
+#endif // USE_20X4_TEXT_LCD
31
+}
32
+
33
+void lcd_clear(void) {
34
+    Serial.println();
35
+
36
+#ifdef USE_20X4_TEXT_LCD
37
+    lcd.clear();
38
+#endif // USE_20X4_TEXT_LCD
39
+}
40
+
41
+void lcd_set_heading(const char *heading) {
42
+    Serial.println(heading);
43
+
44
+#ifdef USE_20X4_TEXT_LCD
45
+    lcd.setCursor(0, 0);
46
+    lcd.print(heading);
47
+#endif // USE_20X4_TEXT_LCD
48
+}
49
+
50
+void lcd_set_text(const char *text) {
51
+    Serial.println(text);
52
+
53
+#ifdef USE_20X4_TEXT_LCD
54
+    lcd.setCursor(0, 1);
55
+    lcd.print(text);
56
+#endif // USE_20X4_TEXT_LCD
17 57
 }

+ 10
- 10
src/main.cpp 파일 보기

@@ -6,7 +6,7 @@
6 6
 #include "encoder.h"
7 7
 #include "lcd.h"
8 8
 #include "steppers.h"
9
-#include "statemachine.h"
9
+#include "states.h"
10 10
 
11 11
 void setup() {
12 12
     pinMode(LED_PIN, OUTPUT);
@@ -115,27 +115,27 @@ void setup() {
115 115
 
116 116
     // wait some time to show splash screen
117 117
     delay(2000);
118
+
119
+    Serial.println(F("Init state machine"));
120
+    states_init();
121
+
118 122
     blocking_beep(100, 2000);
119 123
     Serial.println(F("starting main loop"));
120 124
 }
121 125
 
122 126
 void loop() {
123 127
     unsigned long t = millis();
124
-
125 128
     common_run(t);
129
+    bool still_running = steppers_run();
126 130
     encoder_run();
127 131
 
128 132
     int click = encoder_click();
133
+    int kill = kill_switch();
134
+
129 135
     if (click) {
130 136
         async_beep(ENCODER_CLICK_BEEP_TIME, ENCODER_CLICK_BEEP_FREQ);
131 137
     }
132 138
 
133
-    int kill = kill_switch();
134
-
135
-    statemachine_run(click, encoder_change(), kill);
136
-
137
-    bool still_running = steppers_run();
138
-    if (!still_running) {
139
-        statemachine_motors_done();
140
-    }
139
+    struct StateMachineInput smi(click, encoder_change(), kill, !still_running);
140
+    states_run(smi);
141 141
 }

+ 61
- 38
src/statemachine.cpp 파일 보기

@@ -2,56 +2,79 @@
2 2
 
3 3
 #include "config.h"
4 4
 #include "config_pins.h"
5
-#include "common.h"
6 5
 #include "lcd.h"
7
-#include "steppers.h"
8
-#include "statemachine.h"
6
+#include "states.h"
9 7
 
10
-enum states {
11
-    sm_init,
12
-    sm_ask_homing,
13
-    sm_do_homing,
14
-    sm_menu
15
-};
8
+State::State(State *_parent) : parent(_parent), child(NULL), title("no title") {
9
+    if (_parent != NULL) {
10
+        _parent->setChild(this);
11
+    }
12
+}
16 13
 
17
-static states state = sm_init;
14
+// --------------------------------------
18 15
 
19
-static void switch_state(states s) {
20
-    state = s;
16
+StateText::StateText(State *_parent) : State(_parent) {
17
+    heading = "";
18
+    text = "";
19
+    onEnterFunc = []() { };
20
+    whenInFunc = [](StateMachineInput smi) {
21
+        State *s = states_get();
22
+        if (smi.click && (s != NULL) && (s->getChild() != NULL)) {
23
+            states_go_to(s->getChild());
24
+        }
25
+    };
26
+}
21 27
 
22
-    if (state == sm_ask_homing) {
23
-        lcd.clear();
24
-        lcd.print(F("  Homing Required!"));
25
-        lcd.setCursor(0, 2);
26
-        lcd.print(F(" Click to home XYZE"));
27
-    } else if (state == sm_do_homing) {
28
+void StateText::setHeading(const char *_heading) {
29
+    heading = _heading;
30
+}
28 31
 
29
-    } else if (state == sm_menu) {
32
+void StateText::setText(const char *_text) {
33
+    text = _text;
34
+}
30 35
 
31
-    }
36
+void StateText::onEnter(EnterFuncPtr func) {
37
+    onEnterFunc = func;
32 38
 }
33 39
 
34
-void statemachine_run(int click, int encoder, int kill) {
35
-    if (state == sm_init) {
36
-        if (click) {
37
-            switch_state(sm_ask_homing);
38
-        }
39
-    } else if (state == sm_ask_homing) {
40
-        if (click) {
41
-            switch_state(sm_do_homing);
42
-        }
43
-    } else if (state == sm_do_homing) {
40
+void StateText::whenIn(InFuncPtr func) {
41
+    whenInFunc = func;
42
+}
44 43
 
45
-    } else if (state == sm_menu) {
44
+void StateText::enterState(void) {
45
+    lcd_clear();
46
+    lcd_set_heading(heading);
47
+    lcd_set_text(text);
46 48
 
47
-    }
49
+    onEnterFunc();
48 50
 }
49 51
 
50
-void statemachine_motors_done(void) {
51
-    if (state == sm_do_homing) {
52
-        if (steppers_homed()) {
53
-            async_beep(100, 2000);
54
-            switch_state(sm_menu);
55
-        }
52
+void StateText::inState(struct StateMachineInput smi) {
53
+    whenInFunc(smi);
54
+}
55
+
56
+// --------------------------------------
57
+
58
+StateMenu::StateMenu(State *_parent) : State(_parent) {
59
+    menuPos = 0;
60
+}
61
+
62
+void StateMenu::setChild(State *_child) {
63
+    children.push_back(_child);
64
+}
65
+
66
+void StateMenu::addChild(State *_child, int pos) {
67
+    if (pos < 0) {
68
+        setChild(_child);
69
+    } else {
70
+        // TODO insert child at pos in children
56 71
     }
57 72
 }
73
+
74
+void StateMenu::enterState(void) {
75
+    menuPos = 0;
76
+}
77
+
78
+void StateMenu::inState(struct StateMachineInput smi) {
79
+
80
+}

+ 87
- 0
src/states.cpp 파일 보기

@@ -0,0 +1,87 @@
1
+#include <Arduino.h>
2
+
3
+#include "config.h"
4
+#include "config_pins.h"
5
+#include "common.h"
6
+#include "lcd.h"
7
+#include "steppers.h"
8
+#include "statemachine.h"
9
+#include "states.h"
10
+
11
+// --------------------------------------
12
+
13
+StateText sm_ask_homing = StateText();
14
+StateText sm_do_homing = StateText(&sm_ask_homing);
15
+StateMenu sm_menu = StateMenu(&sm_do_homing);
16
+
17
+StateMenu sm_auto = StateMenu(&sm_menu);
18
+
19
+StateMenu sm_config = StateMenu(&sm_menu);
20
+
21
+// --------------------------------------
22
+
23
+State *current_state = NULL;
24
+
25
+void states_init(void) {
26
+    // ----------------------------------
27
+
28
+    sm_ask_homing.setHeading("Homing Required!");
29
+    sm_ask_homing.setText("Click to home all four axes.");
30
+
31
+    // ----------------------------------
32
+
33
+    sm_do_homing.setTitle("Home all axes");
34
+    sm_do_homing.setHeading("Homing");
35
+
36
+    sm_do_homing.onEnter([]() {
37
+        steppers_start_homing();
38
+    });
39
+
40
+    sm_do_homing.whenIn([](StateMachineInput smi) {
41
+        if (smi.motors_done) {
42
+            if (steppers_homed()) {
43
+                async_beep(100, 2000);
44
+                states_go_to(&sm_menu);
45
+            }
46
+        }
47
+
48
+        // TODO update text with current axis
49
+    });
50
+
51
+    // ----------------------------------
52
+
53
+    sm_menu.setTitle("Main Menu");
54
+    sm_menu.addChild(&sm_do_homing, 1);
55
+
56
+    // ----------------------------------
57
+
58
+    sm_auto.setTitle("Filling Menu");
59
+    sm_auto.setChild(&sm_menu);
60
+
61
+    // ----------------------------------
62
+
63
+    sm_config.setTitle("Configuration");
64
+    sm_auto.setChild(&sm_menu);
65
+
66
+    // ----------------------------------
67
+
68
+    states_go_to(&sm_ask_homing);
69
+}
70
+
71
+void states_run(StateMachineInput smi) {
72
+    if (current_state != NULL) {
73
+        current_state->inState(smi);
74
+    }
75
+}
76
+
77
+State *states_get(void) {
78
+    return current_state;
79
+}
80
+
81
+void states_go_to(State *state) {
82
+    current_state = state;
83
+
84
+    if (current_state != NULL) {
85
+        current_state->enterState();
86
+    }
87
+}

+ 1
- 1
src/steppers.cpp 파일 보기

@@ -75,7 +75,7 @@ bool steppers_homed(void) {
75 75
     return (state == step_homed);
76 76
 }
77 77
 
78
-int steppers_start_homing(void) {
78
+void steppers_start_homing(void) {
79 79
     state = step_homing_x_fast;
80 80
 
81 81
 }

Loading…
취소
저장