Hi all,
I am trying to control 3 ODrives with a Teensy 3.2.
In the Arduino library we create ODrive object like so:
#define odrive_serial Serial1
ODriveArduino odrive(Serial1);
Now i want to be able to create 3 of those and be able to reference them like an array, e.g.
odrive_serial[0]
odrive[0]
So i can send commands like so…
odrive_serial[1] << "w axis0 bla bla bla;
Serial.println(odrive[1].readFloat());
Here is what I have tried:
HardwareSerial odrive_serial[] = {Serial1, Serial2, Serial3};
ODriveArduino odrive[];
for (int i = 0; i < 3; i++) {
odrive[i](odrive_serial[i]);
}
this did not compile successfully. I have tried other options and played around with the code to no avail.
However, this code compiles but does not read the correct ODrive…
HardwareSerial odrive_serial[] = {Serial1, Serial2, Serial3};
ODriveArduino odrive[3] = {ODriveArduino(odrive_serial[0]),
ODriveArduino(odrive_serial[1]),
ODriveArduino(odrive_serial[2])};
I don’t think you should have to declare the array of hardware serial objects…
ODriveArduino odrive[3] = {ODriveArduino(Serial1), ODriveArduino(Serial2), ODriveArduino(Serial3)};
Seems like it should work? I only have one controller here so no super way for me to test.
This is an minimized teensy code that sends a command to 1st odrive and reads the position back. this WORKS…
#include <ODriveArduino.h>
#include <sstream>
// Printing with stream operator
template<class T> inline Print& operator <<(Print &obj, T arg) {
obj.print(arg);
return obj;
}
template<> inline Print& operator <<(Print &obj, float arg) {
obj.print(arg, 4);
return obj;
}
HardwareSerial odrive_serial[] = {odrive_serial[0] = Serial1,
odrive_serial[1] = Serial2,
odrive_serial[2] = Serial3};
ODriveArduino odrive[] = {ODriveArduino(odrive_serial[0]),
ODriveArduino(odrive_serial[1]),
ODriveArduino(odrive_serial[2])};
void setup() {
Serial.begin(115200);
for (int i = 0; i < 3; i++) {
odrive_serial[i].begin(115200);
}
}
void loop() {
String str = "";
if (Serial.available()) {
while (Serial.available()) {
char c = Serial.read();
if (c == '\n') {
break;
}
str += c;
}
//Serial.println(str);
// position
// read position format: p<space>axis, example: read axis1 position -> p 1
// go to position format: p<space>axis<space>value, example: axis0 go to 1234 -> p 0 1234
if (str[0] == 'p') {
if (str.length() == 3) { // read
odrive_serial[0] << "p 1\n";
Serial.println(odrive[0].readString());
} else { // write
odrive_serial[0] << str + '\n';
}
}
}
delay(5);
}
HOWEVER.
if i wanted to do the same to the 2nd odrive by [1] instead of [0] it STILL communicate to the 1st odrive
if (str.length() == 3) { // read
odrive_serial[1] << "p 1\n";
Serial.println(odrive[1].readString());
Ok this thanks to @aburka, using pointers fixes the issue to all who are stuck figuring this out.
HardwareSerial* odrive_serial[] = {&Serial1,
&Serial2,
&Serial3};
ODriveArduino odrive[] = {ODriveArduino(*odrive_serial[0]),
ODriveArduino(*odrive_serial[1]),
ODriveArduino(*odrive_serial[2])};
This way you use pointers to point to the serial objects.
So for example, to read 1st odrive axis 0 position:
*odrive_serial[0] << "w axis0.encoder.pos_estimate\n";
Serial.println(odrive[0].readString());
1 Like