Skip to content

Commit 062ff7b

Browse files
committed
feat: use signed value based on group input
1 parent 63a5c02 commit 062ff7b

4 files changed

Lines changed: 89 additions & 39 deletions

File tree

‎.dir-locals.el‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
((nil . ((eval . (add-to-list 'eglot-server-programs
2+
'(arduino-mode .
3+
("arduino-language-server"
4+
"-clangd" "clangd"
5+
"-cli" "arduino-cli"
6+
"-cli-config" "./arduino-cli.yaml"
7+
"-fqbn" "controllino_rp2:rp2040:controllino_micro")))))

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
.pre-commit-config.yaml
22
result*
3+
arduino-cli.yaml

‎erratic_TS25_ctrl_firmware.ino‎

Lines changed: 78 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
#include <Arduino.h>
22
#include <ODriveMCPCAN.hpp>
33

4-
#define DEBUG 1
4+
//#define DEBUG 1
55
#define DEBUG_GInputs 0
66

77
const uint32_t SPEED_SEND_INTERVAL = 10;
88

9-
const float_t EXTRUSION_SPD_RPS_MIN = 0.0;
9+
const float_t EXTRUSION_SPD_RPS_MIN = -30.0;
1010
const float_t EXTRUSION_SPD_RPS_MAX = 30.0;
1111

12-
const pin_size_t DI_ROBOT_BWD_PIN = CONTROLLINO_MICRO_AI1;
1312
const pin_size_t DI_ROBOT_SPD0_PIN = CONTROLLINO_MICRO_AI2;
1413
const pin_size_t DI_ROBOT_SPD1_PIN = CONTROLLINO_MICRO_AI3;
1514
const pin_size_t DI_ROBOT_SPD2_PIN = CONTROLLINO_MICRO_AI4;
@@ -19,6 +18,27 @@ const pin_size_t DI_ROBOT_SPD5_PIN = CONTROLLINO_MICRO_DI1;
1918
const pin_size_t DI_ROBOT_SPD6_PIN = CONTROLLINO_MICRO_DI2;
2019
const pin_size_t DI_ROBOT_SPD7_PIN = CONTROLLINO_MICRO_DI3;
2120

21+
const uint8_t NUM_SPD_BITS = 8;
22+
23+
pin_size_t ROBOT_SPD_PINS[] = {
24+
DI_ROBOT_SPD0_PIN,
25+
DI_ROBOT_SPD1_PIN,
26+
DI_ROBOT_SPD2_PIN,
27+
DI_ROBOT_SPD3_PIN,
28+
DI_ROBOT_SPD4_PIN,
29+
DI_ROBOT_SPD5_PIN,
30+
DI_ROBOT_SPD6_PIN,
31+
DI_ROBOT_SPD7_PIN,
32+
};
33+
34+
35+
// this is default on the controllino but I'm setting it just to be sure
36+
const uint8_t AI_RESOLUTION = 23;
37+
38+
// Calculate threshold value for 7V in a 0-24V range with 23-bit resolution
39+
// 7V comes from spec from ABB, I think
40+
const uint32_t AI_DIGITAL_THRESHOLD = (7.0 / 24.0) * ((1UL << AI_RESOLUTION) - 1);
41+
2242
// CAN bus baudrate. Make sure this matches for every device on the bus
2343
const uint32_t CAN_BAUDRATE = 125000;
2444

@@ -28,10 +48,11 @@ const uint32_t ODRV0_NODE_ID = 0;
2848
// vendored/modified from controllino_rp2\hardware\rp2040
2949
MCP2515Class& g_can_intf = CAN;
3050

31-
3251
void printAndHalt(const char* message) {
52+
#ifdef DEBUG
3353
Serial.println(message);
34-
while (true); // Infinite loop
54+
#endif
55+
while (true);
3556
}
3657

3758
// Instantiate ODrive objects
@@ -92,52 +113,60 @@ bool setupCan() {
92113
}
93114

94115
void setup() {
116+
#ifdef DEBUG
95117
Serial.begin(115200);
96-
// wait since Controllino Micro uses software USB not hardware USB-to-serial
118+
119+
// wait since Controllino Micro uses software USB not hardware USB-to-serial */
97120
while (!Serial);
98121
Serial.println("Starting...");
122+
#endif
99123

100-
// setup robot input pins
101-
pinMode(DI_ROBOT_BWD_PIN, INPUT);
102-
pinMode(DI_ROBOT_SPD0_PIN, INPUT);
103-
pinMode(DI_ROBOT_SPD1_PIN, INPUT);
104-
pinMode(DI_ROBOT_SPD2_PIN, INPUT);
105-
pinMode(DI_ROBOT_SPD3_PIN, INPUT);
106-
pinMode(DI_ROBOT_SPD4_PIN, INPUT);
107-
pinMode(DI_ROBOT_SPD5_PIN, INPUT);
108-
pinMode(DI_ROBOT_SPD6_PIN, INPUT);
109-
pinMode(DI_ROBOT_SPD7_PIN, INPUT);
124+
delay(200);
125+
126+
analogReadResolution(AI_RESOLUTION);
127+
128+
// setup robot spd input pins
129+
for (pin_size_t pin : ROBOT_SPD_PINS) {
130+
setDigitalThreshold(pin, AI_DIGITAL_THRESHOLD); // noop for digital inputs
131+
pinMode(pin, INPUT);
132+
}
110133

111134
// Register callbacks for the heartbeat and encoder feedback messages
112135
g_odrv0.onFeedback(onFeedback, &g_odrv0_user_data);
113136
g_odrv0.onStatus(onHeartbeat, &g_odrv0_user_data);
114137

115-
if (!setupCan()) {
116-
printAndHalt("CAN failed to initialize: reset required");
117-
}
138+
if (!setupCan()) printAndHalt("CAN failed to initialize: reset required");
118139

140+
#ifdef DEBUG
119141
Serial.println("Waiting for ODrive...");
142+
#endif
120143
while (!g_odrv0_user_data.received_heartbeat) {
121144
pumpEvents(g_can_intf);
122145
delay(100);
123146
}
124147

148+
#ifdef DEBUG
125149
Serial.println("found ODrive");
126150

127151
// request bus voltage and current (1sec timeout)
128152
Serial.println("attempting to read bus voltage and current");
153+
#endif
154+
129155
Get_Bus_Voltage_Current_msg_t vbus;
130156

131-
if (!g_odrv0.request(vbus, 1)) {
157+
if (!g_odrv0.getBusVI(vbus, 1000)) {
132158
printAndHalt("vbus request failed!");
133159
}
134160

161+
#ifdef DEBUG
135162
Serial.print("DC voltage [V]: ");
136163
Serial.println(vbus.Bus_Voltage);
137164
Serial.print("DC current [A]: ");
138165
Serial.println(vbus.Bus_Current);
139166

140167
Serial.println("Enabling closed loop control...");
168+
#endif
169+
141170
while (g_odrv0_user_data.last_heartbeat.Axis_State != ODriveAxisState::AXIS_STATE_CLOSED_LOOP_CONTROL) {
142171
g_odrv0.clearErrors();
143172
delay(1);
@@ -155,7 +184,9 @@ void setup() {
155184
pumpEvents(g_can_intf);
156185
}
157186
}
187+
#ifdef DEBUG
158188
Serial.println("ODrive running!");
189+
#endif
159190
}
160191

161192
#if DEBUG_GInputs == 1
@@ -174,9 +205,20 @@ uint8_t readSpdInputs() {
174205
}
175206
#else
176207
uint8_t readSpdInputs() {
177-
return (digitalRead(DI_ROBOT_SPD0_PIN) << 0) | (digitalRead(DI_ROBOT_SPD1_PIN) << 1) | (digitalRead(DI_ROBOT_SPD2_PIN) << 2) | (digitalRead(DI_ROBOT_SPD3_PIN) << 3) | (digitalRead(DI_ROBOT_SPD4_PIN) << 4) | (digitalRead(DI_ROBOT_SPD5_PIN) << 5) | (digitalRead(DI_ROBOT_SPD6_PIN) << 6) | (digitalRead(DI_ROBOT_SPD7_PIN) << 7);
208+
uint8_t rawValue = 0;
209+
210+
for (int i = 0; i < NUM_SPD_BITS; i++) {
211+
rawValue |= (digitalRead(ROBOT_SPD_PINS[i]) << i);
212+
}
213+
return rawValue;
214+
}
215+
#endif
216+
217+
int8_t readSignedSpdInputs() {
218+
// Convert to signed int8_t
219+
// Values 128-255 will become -128 to -1
220+
return (int8_t)readSpdInputs();
178221
}
179-
#endif // DEBUG_GInputs
180222

181223
uint32_t g_prev_millis = 0;
182224
uint32_t g_cur_millis = 0;
@@ -190,28 +232,27 @@ void loop() {
190232
if (g_cur_millis - g_prev_millis >= SPEED_SEND_INTERVAL) {
191233
g_prev_millis = g_cur_millis;
192234

193-
g_spd_reading = readSpdInputs();
235+
g_spd_reading = readSignedSpdInputs();
194236

195-
#if DEBUG == 1
196-
Serial.print("g_spdReading:");
197-
Serial.print(g_spd_reading);
198-
#endif // DEBUG
199237

200-
if (g_spd_reading < 1) {
201-
g_odrv0.setVelocity(0);
202-
} else {
203-
g_odrv0.setVelocity(map(g_spd_reading, 1, 255, EXTRUSION_SPD_RPS_MIN, EXTRUSION_SPD_RPS_MAX));
204-
}
238+
g_odrv0.setVelocity(map(g_spd_reading,
239+
-127,
240+
127,
241+
EXTRUSION_SPD_RPS_MIN, EXTRUSION_SPD_RPS_MAX));
205242

206-
#if DEBUG == 1
207-
// print position and velocity for Serial Plotter
243+
#ifdef DEBUG
244+
Serial.print("g_spdReading:");
245+
Serial.print(g_spd_reading);
246+
Serial.print(",");
247+
Serial.print("g_odrv0-vel:");
208248
if (g_odrv0_user_data.received_feedback) {
209249
Get_Encoder_Estimates_msg_t feedback = g_odrv0_user_data.last_feedback;
210250
g_odrv0_user_data.received_feedback = false;
211-
Serial.print(",");
212-
Serial.print("g_odrv0-vel:");
251+
213252
Serial.println(feedback.Vel_Estimate);
253+
} else {
254+
Serial.println("ERROR");
214255
}
215-
#endif // DEBUG
256+
#endif
216257
}
217258
}

‎flake.nix‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,10 @@
8787
};
8888
devShells.default = pkgs.mkShell {
8989
inputsFrom = [ config.treefmt.build.devShell ];
90-
packages = [
90+
packages = with pkgs; [
9191
self'.packages.arduino-cli
92-
pkgs.picotool
92+
arduino-language-server
93+
picotool
9394
];
9495
};
9596
treefmt.programs = {

0 commit comments

Comments
 (0)