-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrobot_arm_esp32.ino
212 lines (183 loc) · 7 KB
/
robot_arm_esp32.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#include <Adafruit_PWMServoDriver.h>
#include <ArduinoJson.h>
#include <Wire.h>
#include "armDriver.h"
#define UPDATE_ARM_DELAY 1.0
#define SERIAL_READ_DELAY 10
#define SERIAL_WRITE_DELAY 250
const uint8_t NUM_OF_SERVOS = 5;
const uint8_t servoMinAngles[] = {0, 0, 0, 0, 0};
const uint8_t servoMaxAngles[] = {180, 120, 160, 180, 70};
// Enum to define the arm actions
enum class ArmAction {
NO_ACTION,
TURN_BASE_LEFT,
TURN_BASE_RIGHT,
MOVE_ARM_UP,
MOVE_ARM_DOWN,
SHIFT_ARM_RIGHT,
SHIFT_ARM_LEFT,
ROTATE_FINGER_RIGHT,
ROTATE_FINGER_LEFT
};
ArmAction armAction = ArmAction::NO_ACTION;
float currentAngles[NUM_OF_SERVOS];
uint8_t targetAngles[NUM_OF_SERVOS];
// Define task handles
TaskHandle_t armControlTask;
TaskHandle_t serialCommunicationTask;
TaskHandle_t serialWriterTask;
// This callback gets called any time a new gamepad is connected.
// Up to 4 gamepads can be connected at the same time.
// Function declarations
void armControlTaskFunction(void *parameter);
void serialCommunicationTaskFunction(void *parameter);
void serialWriterTaskFunction(void *parameter);
void setup() {
// Start serial communication
Serial.begin(115200);
// Create the arm control task
for (uint8_t i = 0; i < NUM_OF_SERVOS; i++) {
currentAngles[i] = (float) servoMinAngles[i];
switch (i) {
case 0:
targetAngles[0] = 90;
break;
case 1:
targetAngles[1] = 0;
break;
case 2:
targetAngles[2] = 160;
break;
case 3:
targetAngles[3] = 50;
break;
case 4:
targetAngles[4] = 10;
break;
default:
break;
}
}
// Create the arm control task
Serial.println("xTaskCreatePinnedToCore armControlTaskFunction ");
delay(100);
xTaskCreatePinnedToCore(
armControlTaskFunction, // Task function
"Arm Control Task", // Task name
2048, // Stack size (in bytes)
NULL, // Task parameters
1, // Task priority
&armControlTask, // Task handle
0 // Core ID (0 or 1)
);
// Create the serial communication task
Serial.println("xTaskCreatePinnedToCore serialCommunicationTaskFunction ");
delay(100);
xTaskCreatePinnedToCore(
serialCommunicationTaskFunction, // Task function
"Serial Communication Task", // Task name
2048, // Stack size (in bytes)
NULL, // Task parameters
3, // Task priority
&serialCommunicationTask, // Task handle
1 // Core ID (0 or 1)
);
// Create the serial communication task
Serial.println("xTaskCreatePinnedToCore serialWriterTaskFunction ");
delay(100);
xTaskCreatePinnedToCore(
serialWriterTaskFunction, // Task function
"Serial Writer Task", // Task name
2048, // Stack size (in bytes)
NULL, // Task parameters
2, // Task priority
&serialWriterTask, // Task handle
0 // Core ID (0 or 1)
);
delay(100);
}
void loop() {
// Empty. Tasks are running in the background.
}
// Task function for arm control
void armControlTaskFunction(void *parameter) {
// Create an instance of ArmManager
// uint8_t currentAngles[ArmManager::NUM_SERVOS];
ArmManager armManager(NUM_OF_SERVOS, servoMinAngles, servoMaxAngles);
Serial.println("armControlTaskFunction start");
for (;;) {
// Control the robot arm using ArmManager
for (uint8_t i = 0; i < NUM_OF_SERVOS; i++) {
armManager.setServoTargetAngle(i, targetAngles[i]);
}
armManager.moveArm();
// armManager.printStatus();
armManager.getCurrentAngles(currentAngles);
armAction = ArmAction::NO_ACTION;
// Wait for some time before the next iteration
vTaskDelay(UPDATE_ARM_DELAY / portTICK_PERIOD_MS);
}
}
// Task function for serial reader
void serialCommunicationTaskFunction(void *parameter) {
Serial.println("serialCommunicationTaskFunction start ");
String jsonString = "";
for (;;) {
if (Serial.available()) {
// Read the incoming serial data
jsonString = Serial.readStringUntil('\n');
// String jsonString = Serial.readString();
Serial.println("receive:");
Serial.println(jsonString);
// Parse the JSON string
StaticJsonDocument<256> doc;
DeserializationError error = deserializeJson(doc, jsonString);
// Check if the JSON parsing was successful
if (error) {
Serial.print("JSON parsing error: ");
Serial.println(error.c_str());
} else {
// Check if the parsed JSON document contains the "servo_target_angles" array
if (doc.containsKey("servo_target_angles")) {
// Get the "servo_target_angles" array from the JSON document
JsonArray servoAngles = doc["servo_target_angles"].as<JsonArray>();
// Check if the array size matches the number of servos
if (servoAngles.size() == NUM_OF_SERVOS) {
// Update the target angles in the ArmManager
for (uint8_t i = 0; i < NUM_OF_SERVOS; i++) {
targetAngles[i] = servoAngles[i];
}
} else {
Serial.println("Invalid number of servo target angles.");
}
} else {
Serial.println("Missing servo_target_angles in JSON");
}
}
}
// Wait for some time before the next iteration
vTaskDelay(SERIAL_READ_DELAY / portTICK_PERIOD_MS);
}
}
// Task function for serial writer
void serialWriterTaskFunction(void *parameter) {
Serial.println("serialWriterTaskFunction start");
for (;;) {
StaticJsonDocument<512> doc;
// Populate the JSON document with the current angles
JsonArray servoAngles = doc.createNestedArray("servo_current_angles");
// armManager.getCurrentAngles(currentAngles);
for (uint8_t i = 0; i < NUM_OF_SERVOS; i++) {
servoAngles.add(currentAngles[i]);
}
// Serialize the JSON document to a string
String jsonString;
serializeJson(doc, jsonString);
// Print the JSON string
Serial.println(jsonString);
// Read incoming serial data
// Wait for some time before the next iteration
vTaskDelay(SERIAL_WRITE_DELAY / portTICK_PERIOD_MS);
}
}