Browse Source

add support for PCF8574 gpio expansion

Thomas Buck 2 years ago
parent
commit
6de07b6cc9
5 changed files with 130 additions and 28 deletions
  1. 2
    0
      include/GPIOBank.h
  2. 34
    2
      include/config_pins.h
  3. 1
    0
      platformio.ini
  4. 16
    16
      src/Functionality.cpp
  5. 77
    10
      src/GPIOBank.cpp

+ 2
- 0
include/GPIOBank.h View File

20
 #ifndef _GPIO_BANK_H_
20
 #ifndef _GPIO_BANK_H_
21
 #define _GPIO_BANK_H_
21
 #define _GPIO_BANK_H_
22
 
22
 
23
+void gpio_i2c_init(void);
24
+
23
 class GPIOBank {
25
 class GPIOBank {
24
 public:
26
 public:
25
     GPIOBank(int _size);
27
     GPIOBank(int _size);

+ 34
- 2
include/config_pins.h View File

31
 
31
 
32
 #ifdef FUNCTION_UI
32
 #ifdef FUNCTION_UI
33
 
33
 
34
+/*
35
+ * AVR UI
36
+ */
37
+
34
 #define SERIAL_LCD_TX_PIN 10
38
 #define SERIAL_LCD_TX_PIN 10
35
 
39
 
36
 #define KEYMATRIX_ROWS 4
40
 #define KEYMATRIX_ROWS 4
44
 
48
 
45
 #ifdef FUNCTION_CONTROL
49
 #ifdef FUNCTION_CONTROL
46
 
50
 
51
+/*
52
+ * AVR Controller
53
+ */
54
+
47
 // out 1, out 2, out 3, out 4, in
55
 // out 1, out 2, out 3, out 4, in
48
 #define VALVE_COUNT 5
56
 #define VALVE_COUNT 5
49
 #define VALVE_PINS 10, 11, 12, 14, 15
57
 #define VALVE_PINS 10, 11, 12, 14, 15
75
 
83
 
76
 #ifdef FUNCTION_UI
84
 #ifdef FUNCTION_UI
77
 
85
 
86
+/*
87
+ * ESP UI
88
+ */
89
+
78
 #error configuration not supported
90
 #error configuration not supported
79
 
91
 
80
 #endif // FUNCTION_UI
92
 #endif // FUNCTION_UI
83
 
95
 
84
 #ifdef FUNCTION_CONTROL
96
 #ifdef FUNCTION_CONTROL
85
 
97
 
86
-#define PLANT_COUNT 4
87
-#define PLANT_PINS 27, 14, 5, 18
98
+/*
99
+ * ESP Controller
100
+ */
101
+
102
+/*
103
+ * I2C Port Expander PCF8574(A)
104
+ *
105
+ * Address ranges:
106
+ * PCF8574: 0x20 - 0x27
107
+ * PCF8574A: 0x38 - 0x3F
108
+ */
109
+#define I2C_GPIO_EXPANDER_COUNT 1
110
+#define I2C_GPIO_EXPANDER_ADDR 0x20
111
+
112
+/*
113
+ * GPIO Numbering Scheme
114
+ * 000 - 099: normal ESP32 GPIOs
115
+ * 100 - 228: consecutive I2C Expander GPIOs
116
+ */
117
+
118
+#define PLANT_COUNT 8
119
+#define PLANT_PINS 27, 14, 5, 18, 100, 101, 102, 103
88
 
120
 
89
 #define INLET_PIN 15
121
 #define INLET_PIN 15
90
 
122
 

+ 1
- 0
platformio.ini View File

34
     https://github.com/Links2004/arduinoWebSockets
34
     https://github.com/Links2004/arduinoWebSockets
35
     https://github.com/rlogiacco/CircularBuffer
35
     https://github.com/rlogiacco/CircularBuffer
36
     https://github.com/tobiasschuerg/InfluxDB-Client-for-Arduino.git
36
     https://github.com/tobiasschuerg/InfluxDB-Client-for-Arduino.git
37
+    https://github.com/RobTillaart/PCF8574
37
 
38
 
38
 [env:arduino_ui]
39
 [env:arduino_ui]
39
 platform = atmelavr
40
 platform = atmelavr

+ 16
- 16
src/Functionality.cpp View File

56
 
56
 
57
 #ifdef FUNCTION_CONTROL
57
 #ifdef FUNCTION_CONTROL
58
 
58
 
59
-#ifndef FUNCTION_UI
60
 #include <Wire.h>
59
 #include <Wire.h>
61
-#endif // ! FUNCTION_UI
62
 
60
 
63
 #include "Plants.h"
61
 #include "Plants.h"
64
 #include "Statemachine.h"
62
 #include "Statemachine.h"
457
 }
455
 }
458
 
456
 
459
 void control_setup(void) {
457
 void control_setup(void) {
460
-    plants.setValvePins(valve_pins);
461
-    plants.setPumpPins(pump_pins);
462
-    plants.setSwitchPins(switch_pins, true);
463
-    plants.setAuxPins(aux_pins);
464
-    
465
-#ifndef FUNCTION_UI
466
-    
467
     debug.println("Initializing I2C Master");
458
     debug.println("Initializing I2C Master");
468
     Wire.setClock(I2C_BUS_SPEED);
459
     Wire.setClock(I2C_BUS_SPEED);
469
     
460
     
473
     Wire.begin();
464
     Wire.begin();
474
 #endif // defined(I2C_SDA_PIN) && defined(I2C_SCL_PIN)
465
 #endif // defined(I2C_SDA_PIN) && defined(I2C_SCL_PIN)
475
     
466
     
467
+    gpio_i2c_init();
468
+
476
 #ifdef DEBUG_WAIT_FOR_SERIAL_CONN
469
 #ifdef DEBUG_WAIT_FOR_SERIAL_CONN
477
     debug.println("Wait for Serial");
470
     debug.println("Wait for Serial");
478
     while (!Serial);
471
     while (!Serial);
479
 #endif // DEBUG_WAIT_FOR_SERIAL_CONN
472
 #endif // DEBUG_WAIT_FOR_SERIAL_CONN
480
-    
481
-#endif // ! FUNCTION_UI
473
+
474
+    debug.println("Initializing GPIOs");
475
+    plants.setValvePins(valve_pins);
476
+    plants.setPumpPins(pump_pins);
477
+    plants.setSwitchPins(switch_pins, true);
478
+    plants.setAuxPins(aux_pins);
482
 }
479
 }
483
 
480
 
484
 void control_begin(void) {
481
 void control_begin(void) {
540
     
537
     
541
     //debug.println("write_to_all i2c");
538
     //debug.println("write_to_all i2c");
542
     
539
     
540
+    // rarely some lines don't update
541
+    delay(100);
542
+
543
     for (int i = 0; i < 4; i++) {
543
     for (int i = 0; i < 4; i++) {
544
         Wire.beginTransmission(OWN_I2C_ADDRESS);
544
         Wire.beginTransmission(OWN_I2C_ADDRESS);
545
         Wire.write(0x03); // display command
545
         Wire.write(0x03); // display command
546
-    
546
+
547
         Wire.write(i);
547
         Wire.write(i);
548
-        
548
+
549
         int l = strlen(lines[i]);
549
         int l = strlen(lines[i]);
550
         Wire.write(l);
550
         Wire.write(l);
551
-        
551
+
552
         for (int n = 0; n < l; n++) {
552
         for (int n = 0; n < l; n++) {
553
             Wire.write(lines[i][n]);
553
             Wire.write(lines[i][n]);
554
         }
554
         }
555
-    
555
+
556
         Wire.endTransmission();
556
         Wire.endTransmission();
557
     }
557
     }
558
     
558
     
559
     Wire.beginTransmission(OWN_I2C_ADDRESS);
559
     Wire.beginTransmission(OWN_I2C_ADDRESS);
560
-    Wire.write(0x04); // display command
560
+    Wire.write(0x04); // button command
561
     Wire.write((int8_t)num_input);
561
     Wire.write((int8_t)num_input);
562
     Wire.endTransmission();
562
     Wire.endTransmission();
563
     
563
     

+ 77
- 10
src/GPIOBank.cpp View File

20
 #include <Arduino.h>
20
 #include <Arduino.h>
21
 
21
 
22
 #include "GPIOBank.h"
22
 #include "GPIOBank.h"
23
+#include "config.h"
24
+#include "config_pins.h"
23
 
25
 
24
 #ifdef PLATFORM_ESP
26
 #ifdef PLATFORM_ESP
27
+#include <PCF8574.h>
28
+#include <Wire.h>
25
 #include "WifiStuff.h"
29
 #include "WifiStuff.h"
26
 #endif // PLATFORM_ESP
30
 #endif // PLATFORM_ESP
27
 
31
 
28
 //#define GPIO_HIGH_AS_INPUT
32
 //#define GPIO_HIGH_AS_INPUT
29
 
33
 
34
+// ----------------------------------------------------------------------------
35
+
36
+#if (I2C_GPIO_EXPANDER_COUNT > 0)
37
+static PCF8574 expand[I2C_GPIO_EXPANDER_COUNT];
38
+#endif
39
+
40
+void gpio_i2c_init(void) {
41
+#if (I2C_GPIO_EXPANDER_COUNT > 0)
42
+    for (int i = 0; i < I2C_GPIO_EXPANDER_COUNT; i++) {
43
+        expand[i].begin(0xFF);
44
+    }
45
+#endif
46
+}
47
+
48
+static void gpio_pinMode(int pin, int value) {
49
+    if (pin < 100) {
50
+        pinMode(pin, value);
51
+    } else {
52
+        pin -= 100;
53
+        int ex = pin / 8;
54
+        pin = pin % 8;
55
+        if (ex < I2C_GPIO_EXPANDER_COUNT) {
56
+            uint8_t mask = expand[ex].getButtonMask();
57
+            if (value == OUTPUT) {
58
+                mask &= ~(1 << pin);
59
+            } else {
60
+                mask |= (1 << pin);
61
+            }
62
+            expand[ex].setButtonMask(mask);
63
+        }
64
+    }
65
+}
66
+
67
+static void gpio_digitalWrite(int pin, int value) {
68
+    if (pin < 100) {
69
+        digitalWrite(pin, value);
70
+    } else {
71
+        pin -= 100;
72
+        int ex = pin / 8;
73
+        pin = pin % 8;
74
+        if (ex < I2C_GPIO_EXPANDER_COUNT) {
75
+            expand[ex].write(pin, value);
76
+        }
77
+    }
78
+}
79
+
80
+static int gpio_digitalRead(int pin) {
81
+    if (pin < 100) {
82
+        return digitalRead(pin);
83
+    } else {
84
+        pin -= 100;
85
+        int ex = pin / 8;
86
+        pin = pin % 8;
87
+        if (ex < I2C_GPIO_EXPANDER_COUNT) {
88
+            return expand[ex].readButton(pin);
89
+        } else {
90
+            return 0;
91
+        }
92
+    }
93
+}
94
+
95
+// ----------------------------------------------------------------------------
96
+
30
 GPIOBank::GPIOBank(int _size) {
97
 GPIOBank::GPIOBank(int _size) {
31
     size = _size;
98
     size = _size;
32
     pins = new int[size];
99
     pins = new int[size];
48
 void GPIOBank::setOutput(void) {
115
 void GPIOBank::setOutput(void) {
49
     for (int i = 0; i < size; i++) {
116
     for (int i = 0; i < size; i++) {
50
 #ifdef GPIO_HIGH_AS_INPUT
117
 #ifdef GPIO_HIGH_AS_INPUT
51
-        pinMode(pins[i], INPUT);
118
+        gpio_pinMode(pins[i], INPUT);
52
 #else
119
 #else
53
-        pinMode(pins[i], OUTPUT);
54
-        digitalWrite(pins[i], HIGH);
120
+        gpio_pinMode(pins[i], OUTPUT);
121
+        gpio_digitalWrite(pins[i], HIGH);
55
 #endif
122
 #endif
56
         out_state[i] = true;
123
         out_state[i] = true;
57
     }
124
     }
61
 void GPIOBank::setInput(bool pullup) {
128
 void GPIOBank::setInput(bool pullup) {
62
     for (int i = 0; i < size; i++) {
129
     for (int i = 0; i < size; i++) {
63
         if (pullup) {
130
         if (pullup) {
64
-            pinMode(pins[i], INPUT_PULLUP);
131
+            gpio_pinMode(pins[i], INPUT_PULLUP);
65
         } else {
132
         } else {
66
-            pinMode(pins[i], INPUT);
133
+            gpio_pinMode(pins[i], INPUT);
67
         }
134
         }
68
     }
135
     }
69
     is_output = false;
136
     is_output = false;
81
     if ((n >= 0) && (n < size)) {
148
     if ((n >= 0) && (n < size)) {
82
 #ifdef GPIO_HIGH_AS_INPUT
149
 #ifdef GPIO_HIGH_AS_INPUT
83
         if (state) {
150
         if (state) {
84
-            pinMode(pins[n], OUTPUT);
85
-            digitalWrite(pins[n], LOW);
151
+            gpio_pinMode(pins[n], OUTPUT);
152
+            gpio_digitalWrite(pins[n], LOW);
86
         } else {
153
         } else {
87
-            pinMode(pins[n], INPUT);
154
+            gpio_pinMode(pins[n], INPUT);
88
         }
155
         }
89
 #else
156
 #else
90
-        digitalWrite(pins[n], (!state) ? HIGH : LOW);
157
+        gpio_digitalWrite(pins[n], (!state) ? HIGH : LOW);
91
 #endif
158
 #endif
92
 
159
 
93
         out_state[n] = !state;
160
         out_state[n] = !state;
109
         if (is_output) {
176
         if (is_output) {
110
             return !out_state[n];
177
             return !out_state[n];
111
         } else {
178
         } else {
112
-            return (!digitalRead(pins[n]));
179
+            return (!gpio_digitalRead(pins[n]));
113
         }
180
         }
114
     } else {
181
     } else {
115
         return false;
182
         return false;

Loading…
Cancel
Save