Browse Source

✨ M3426 to read i2c MCP3426 ADC (#23184)

Stuart Pittaway 2 years ago
parent
commit
363a17ac46

+ 104
- 0
Marlin/src/feature/adc/adc_mcp3426.cpp View File

@@ -0,0 +1,104 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * adc_mcp3426.cpp -  library for MicroChip MCP3426 I2C A/D converter
25
+ *
26
+ * For implementation details, please take a look at the datasheet:
27
+ * https://www.microchip.com/en-us/product/MCP3426
28
+ */
29
+
30
+#include "../../inc/MarlinConfig.h"
31
+
32
+#if ENABLED(HAS_MCP3426_ADC)
33
+
34
+#include "adc_mcp3426.h"
35
+
36
+// Read the ADC value from MCP342X on a specific channel
37
+int16_t MCP3426::ReadValue(uint8_t channel, uint8_t gain) {
38
+  Error = false;
39
+
40
+  #if PINS_EXIST(I2C_SCL, I2C_SDA) && DISABLED(SOFT_I2C_EEPROM)
41
+    Wire.setSDA(pin_t(I2C_SDA_PIN));
42
+    Wire.setSCL(pin_t(I2C_SCL_PIN));
43
+  #endif
44
+
45
+  Wire.begin(); // No address joins the BUS as the master
46
+
47
+  Wire.beginTransmission(I2C_ADDRESS(MCP342X_ADC_I2C_ADDRESS));
48
+
49
+  // Continuous Conversion Mode, 16 bit, Channel 1, Gain x4
50
+  // 26 = 0b00011000
51
+  //        RXXCSSGG
52
+  //  R = Ready Bit
53
+  // XX = Channel (00=1, 01=2, 10=3 (MCP3428), 11=4 (MCP3428))
54
+  //  C = Conversion Mode Bit (1=  Continuous Conversion Mode (Default))
55
+  // SS = Sample rate, 10=15 samples per second @ 16 bits
56
+  // GG = Gain 00 =x1
57
+  uint8_t controlRegister = 0b00011000;
58
+
59
+  if (channel == 2) controlRegister |= 0b00100000; // Select channel 2
60
+
61
+  if (gain == 2)
62
+    controlRegister |= 0b00000001;
63
+  else if (gain == 4)
64
+    controlRegister |= 0b00000010;
65
+  else if (gain == 8)
66
+    controlRegister |= 0b00000011;
67
+
68
+  Wire.write(controlRegister);
69
+  if (Wire.endTransmission() != 0) {
70
+    Error = true;
71
+    return 0;
72
+  }
73
+
74
+  const uint8_t len = 3;
75
+  uint8_t buffer[len] = {};
76
+
77
+  do {
78
+    Wire.requestFrom(I2C_ADDRESS(MCP342X_ADC_I2C_ADDRESS), len);
79
+    if (Wire.available() != len) {
80
+      Error = true;
81
+      return 0;
82
+    }
83
+
84
+    for (uint8_t i = 0; i < len; ++i)
85
+      buffer[i] = Wire.read();
86
+
87
+    // Is conversion ready, if not loop around again
88
+  } while ((buffer[2] & 0x80) != 0);
89
+
90
+  union TwoBytesToInt16 {
91
+    uint8_t bytes[2];
92
+    int16_t integervalue;
93
+  };
94
+  TwoBytesToInt16 ConversionUnion;
95
+
96
+  ConversionUnion.bytes[1] = buffer[0];
97
+  ConversionUnion.bytes[0] = buffer[1];
98
+
99
+  return ConversionUnion.integervalue;
100
+}
101
+
102
+MCP3426 mcp3426;
103
+
104
+#endif // HAS_MCP3426_ADC

+ 41
- 0
Marlin/src/feature/adc/adc_mcp3426.h View File

@@ -0,0 +1,41 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+#pragma once
23
+
24
+/**
25
+ * Arduino library for MicroChip MCP3426 I2C A/D converter.
26
+ * https://www.microchip.com/en-us/product/MCP3426
27
+ */
28
+
29
+#include <stdint.h>
30
+#include <Wire.h>
31
+
32
+// Address of MCP342X chip
33
+#define MCP342X_ADC_I2C_ADDRESS 104
34
+
35
+class MCP3426 {
36
+  public:
37
+    int16_t ReadValue(uint8_t channel, uint8_t gain);
38
+    bool Error;
39
+};
40
+
41
+extern MCP3426 mcp3426;

+ 10
- 5
Marlin/src/feature/twibus.cpp View File

@@ -34,13 +34,18 @@ TWIBus i2c;
34 34
 
35 35
 TWIBus::TWIBus() {
36 36
   #if I2C_SLAVE_ADDRESS == 0
37
-    Wire.begin(                    // No address joins the BUS as the master
38
-      #if PINS_EXIST(I2C_SCL, I2C_SDA) && DISABLED(SOFT_I2C_EEPROM)
39
-        pin_t(I2C_SDA_PIN), pin_t(I2C_SCL_PIN)
40
-      #endif
41
-    );
37
+
38
+    #if PINS_EXIST(I2C_SCL, I2C_SDA) && DISABLED(SOFT_I2C_EEPROM)
39
+      Wire.setSDA(pin_t(I2C_SDA_PIN));
40
+      Wire.setSCL(pin_t(I2C_SCL_PIN));
41
+    #endif
42
+
43
+    Wire.begin();                    // No address joins the BUS as the master
44
+
42 45
   #else
46
+
43 47
     Wire.begin(I2C_SLAVE_ADDRESS); // Join the bus as a slave
48
+
44 49
   #endif
45 50
   reset();
46 51
 }

+ 63
- 0
Marlin/src/gcode/feature/adc/M3426.cpp View File

@@ -0,0 +1,63 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#include "../../../inc/MarlinConfig.h"
24
+
25
+#if ENABLED(HAS_MCP3426_ADC)
26
+
27
+#include "../../gcode.h"
28
+
29
+#include "../../../feature/adc/adc_mcp3426.h"
30
+
31
+/**
32
+ * M3426: Read 16 bit (signed) value from I2C MCP3426 ADC device
33
+ *
34
+ *  M3426 C<byte-1 value in base 10> channel 1 or 2
35
+ *  M3426 G<byte-1 value in base 10> gain 1, 2, 4 or 8
36
+ *  M3426 I<byte-2 value in base 10> 0 or 1, invert reply
37
+ */
38
+void GcodeSuite::M3426() {
39
+  uint8_t channel = parser.byteval('C', 1),       // Select the channel 1 or 2
40
+             gain = parser.byteval('G', 1);
41
+  const bool inverted = parser.byteval('I') == 1;
42
+
43
+  if (channel <= 2 && (gain == 1 || gain == 2 || gain == 4 || gain == 8)) {
44
+    int16_t result = mcp3426.ReadValue(channel, gain);
45
+
46
+    if (mcp3426.Error == false) {
47
+      if (inverted) {
48
+        // Should we invert the reading (32767 - ADC value) ?
49
+        // Caters to end devices that expect values to increase when in reality they decrease.
50
+        // e.g., A pressure sensor in a vacuum when the end device expects a positive pressure.
51
+        result = INT16_MAX - result;
52
+      }
53
+      //SERIAL_ECHOPGM(STR_OK);
54
+      SERIAL_ECHOLNPGM("V:", result, " C:", channel, " G:", gain, " I:", inverted ? 1 : 0);
55
+    }
56
+    else
57
+      SERIAL_ERROR_MSG("MCP342X i2c error");
58
+  }
59
+  else
60
+    SERIAL_ERROR_MSG("MCP342X Bad request");
61
+}
62
+
63
+#endif // HAS_MCP3426_ADC

+ 4
- 0
Marlin/src/gcode/gcode.cpp View File

@@ -1054,6 +1054,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
1054 1054
         case 7219: M7219(); break;                                // M7219: Set LEDs, columns, and rows
1055 1055
       #endif
1056 1056
 
1057
+      #if ENABLED(HAS_MCP3426_ADC)
1058
+        case 3426: M3426(); break;                                // M3426: Read MCP3426 ADC (over i2c)
1059
+      #endif
1060
+
1057 1061
       default: parser.unknown_command_warning(); break;
1058 1062
     }
1059 1063
     break;

+ 5
- 0
Marlin/src/gcode/gcode.h View File

@@ -297,6 +297,7 @@
297 297
  * M917 - L6470 tuning: Find minimum current thresholds. (Requires at least one _DRIVER_TYPE L6470)
298 298
  * M918 - L6470 tuning: Increase speed until max or error. (Requires at least one _DRIVER_TYPE L6470)
299 299
  * M951 - Set Magnetic Parking Extruder parameters. (Requires MAGNETIC_PARKING_EXTRUDER)
300
+ * M3426 - Read MCP3426 ADC over I2C. (Requires HAS_MCP3426_ADC)
300 301
  * M7219 - Control Max7219 Matrix LEDs. (Requires MAX7219_GCODE)
301 302
  *
302 303
  *** SCARA ***
@@ -1204,6 +1205,10 @@ private:
1204 1205
     static void M1004();
1205 1206
   #endif
1206 1207
 
1208
+  #if ENABLED(HAS_MCP3426_ADC)
1209
+    static void M3426();
1210
+  #endif
1211
+
1207 1212
   #if ENABLED(MAX7219_GCODE)
1208 1213
     static void M7219();
1209 1214
   #endif

+ 5
- 0
Marlin/src/pins/stm32f4/pins_INDEX_REV03.h View File

@@ -42,6 +42,9 @@
42 42
 #define SRAM_EEPROM_EMULATION
43 43
 #define MARLIN_EEPROM_SIZE                0x2000  // 8KB
44 44
 
45
+// I2C MCP3426 (16-Bit, 240SPS, dual-channel ADC)
46
+#define HAS_MCP3426_ADC
47
+
45 48
 //
46 49
 // Servos
47 50
 //
@@ -116,6 +119,8 @@
116 119
 #define FAN2_PIN                            PE4
117 120
 #define FAN3_PIN                            PE5
118 121
 
122
+#define FAN_SOFT_PWM
123
+
119 124
 // Neopixel Rings
120 125
 #define NEOPIXEL_PIN                        PC7
121 126
 #define NEOPIXEL2_PIN                       PC8

+ 1
- 0
ini/features.ini View File

@@ -94,6 +94,7 @@ NEXTION_TFT                            = src_filter=+<src/lcd/extui/nextion>
94 94
 USE_UHS2_USB                           = src_filter=+<src/sd/usb_flashdrive/lib-uhs2>
95 95
 USE_UHS3_USB                           = src_filter=+<src/sd/usb_flashdrive/lib-uhs3>
96 96
 USB_FLASH_DRIVE_SUPPORT                = src_filter=+<src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp>
97
+HAS_MCP3426_ADC                        = src_filter=+<src/feature/adc> +<src/gcode/feature/adc>
97 98
 AUTO_BED_LEVELING_BILINEAR             = src_filter=+<src/feature/bedlevel/abl>
98 99
 AUTO_BED_LEVELING_(3POINT|(BI)?LINEAR) = src_filter=+<src/gcode/bedlevel/abl>
99 100
 MESH_BED_LEVELING                      = src_filter=+<src/feature/bedlevel/mbl> +<src/gcode/bedlevel/mbl>

+ 1
- 0
platformio.ini View File

@@ -92,6 +92,7 @@ default_src_filter = +<src/*> -<src/config> -<src/HAL> +<src/HAL/shared>
92 92
   -<src/HAL/shared/cpu_exception>
93 93
   -<src/HAL/shared/eeprom_if_i2c.cpp>
94 94
   -<src/HAL/shared/eeprom_if_spi.cpp>
95
+  -<src/feature/adc> -<src/gcode/feature/adc>
95 96
   -<src/feature/babystep.cpp>
96 97
   -<src/feature/backlash.cpp>
97 98
   -<src/feature/baricuda.cpp> -<src/gcode/feature/baricuda>

Loading…
Cancel
Save