Code help, Arduino ODrive object array

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