Dual G2 High- Power Motor Driver 18v18 Shield + Arduino Ethernet Shield 2

Hi all,

My name is Adrian and I’m a programmer working on a project with the Pololu Dual G2 High-Power Motor Driver 18v18 Shield driving a DC motor using an Arduino Uno Rev3. Everything has been great so far, with my programming I can send commands to the Arduino using the Arduino IDE’s serial monitor. But the next step in the process involves sending the commands over an Ethernet network. For that I am using an Ethernet Shield Rev2. In my code when I call the md.init(); function (using the “dual-g2-high-power-motor-shield” library. I can no longer communicate with the Ethernet shield. When I comment out that function, the Ethernet functionality works, but of course the motor does not since it has not been initialized.

From what I can tell there aren’t any pin conflicts. The Ethernet shield requires (or can potentially require) A0, A1, D4, D10, D11, D12, and D13. I’m only using the M1 on the motor shield (not M2), so it seems like I should only need D2, D6, D7, and D9. I have tried bending back the pins required by the shield, as well as cutting the traces between D10 and D12 on the motor shield in case the M2 pin requirements were causing the conflict, all without success.

Has anyone ever encountered this issue before? I can’t seem to find this issue in any forum with this particular hardware/shield combination. Any ideas would be very welcome. The code I am using to test is below my signature. Please let me know if there’s any other info you require. The tester code I am using is below

Many thanks,
Adrian


#include <Ethernet.h>
#include <EthernetUdp.h>
#include <SPI.h>
#include <OSCBundle.h>
#include <OSCBoards.h>

#include "DualG2HighPowerMotorShield.h"

//OSC Addresses
const char *MOVE_ROBOT_ADDRESS = "/robot/locvel";

//Networking and OSC
EthernetUDP Udp;
byte mac[] = { 0xA8, 0x61, 0x0A, 0xAF, 0x04, 0xB9 };  //MAC Address of this arduino's ethernet shield
IPAddress ip(192, 168, 10, 6);                        //IP Address of this arduino (check with AngryIP after plugging in and powering)
const unsigned int OSC_RECV_PORT = 8000;              //Which port to listen to for incoming OSC data

// Uncomment the version corresponding with the version of your shield.
DualG2HighPowerMotorShield18v18 md;
float currentVel = 0;
float newVel;
float acc;
int velMin = -400;
int velMax = 400;
int newDir = 0;
int velFactor = 0;
int accFactor;

void stopIfFault() {
  if (md.getM1Fault()) {
    md.disableDrivers();
    delay(1);
    Serial.println("M1 fault");
    while (1)
      ;
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println("Dual G2 High Power Motor Shield");

  //Ethernet Init
  Ethernet.begin(mac, ip);
  Udp.begin(OSC_RECV_PORT);

  //md.init();
  md.calibrateCurrentOffsets();
  delay(10);
  md.enableDrivers();
  delay(1);

  delay(10);
}

void loop() {

  OSCBundle bundle;
  int size;

  if ((size = Udp.parsePacket()) > 0) {
    while (size--) {
      bundle.fill(Udp.read());
    }

    //bind functions here, skipping packet validation because Isadora is apparently non-compliant
    bundle.route(MOVE_ROBOT_ADDRESS, moveRobot);
    //bundle.route(MOVE_ROBOT_ADDRESS2, moveRobot2);
  }
  //md.enableDrivers();
  delay(1);  // The drivers require a maximum of 1ms to elapse when brought out of sleep mode.

  // check if data has been sent from the computer:
  while (Serial.available() > 0) {
    // look for the next valid integer in the incoming serial stream:
    velFactor = Serial.parseInt();
    newVel = map(velFactor, -10, 10, -400, 400);
    if (newVel > currentVel) {
      newDir = 1;
    } else if (newVel < currentVel) {
      newDir = -1;
    } else if (newVel == currentVel) {
      newDir = 0;
    }
    // do it again:
    accFactor = Serial.parseInt();
    acc = map(accFactor, 1, 5, 100, 10);

    // look for the newline. That's the end of your sentence:
    if (Serial.read() == '\n') {

      if (newVel >= velMin && newVel <= velMax) {
        Serial.print("Velocity: ");
        Serial.print(velFactor);
        Serial.print(" Acceleration: ");
        Serial.println(accFactor);
      }

      if (newDir == 1) {
        for (int i = currentVel; i <= newVel; i++) {
          md.setM1Speed(i);
          stopIfFault();
          delay(acc);
        }
        currentVel = newVel;
      }
      if (newDir == -1) {
        for (int i = currentVel; i >= newVel; i--) {
          md.setM1Speed(i);
          stopIfFault();
          delay(acc);
        }
        currentVel = newVel;
      }
    }
  }
}


void moveRobot(OSCMessage &msg, int offset) {

  Serial.println("Received");
}

Hello.

Even if you aren’t using M2, the library is configuring those pins when you call the init() function (including M1CS and M2CS on A0 and A1). You might try using the alternate constructor and specifying some unused pins for the ones that are conflicting. Also, I recommend putting the code for initializing the Ethernet after md.init().

I am not really familiar with the other libraries you’re using, but our library for the high-power motor divers uses timer 1 for the PWM signals, so you might check to see if your other libraries could cause a conflict with that.

Brandon

Thanks so much @BrandonM. I will give this a shot in the studio tomorrow.

I have one question about the alternate constructor. The pins I’m going to attempt move are 8, 10, 12. Pin 10 is the M2PWM pin. In the Library Reference at its github, it notes “If M1PWM and M2PWM are remapped, it will try to use analogWrite instead of timer1.” I’m not clear clear on what this means or if it will be a problem for me. Are you able to explain that?

Thanks again

I’m back in the today and testing again. I’ve tried the alternate constructor and still not succeeding. This is how I coded it:

DualG2HighPowerMotorShield(2, 7, 9, 6, A0, 4, A2, 3, A3, A1);

Yet still I can only get the shield to work when I comment out the init() function. I did move the ethernet init() after md.init() as well,

I’m not sure about timer 1 conflicts with the other libraries. Not actually sure how to research that.

Are there any obvious problems you (or anyone else) can see? Full code below.

Thanks,
Adrian

#include <Ethernet.h>
#include <EthernetUdp.h>
#include <SPI.h>
#include <OSCBundle.h>
#include <OSCBoards.h>
#include "DualG2HighPowerMotorShield.h"

//GLOBAL VARIABLES--------------------------

//OSC Addresses
const char *MOVE_ROBOT_ADDRESS = "/robot/locvel";
//const char *MOVE_ROBOT_ADDRESS2 = "/robot/locvel2";

//Networking and OSC
EthernetUDP Udp;
byte mac[] = { 0xA8, 0x61, 0x0A, 0xAF, 0x04, 0xB9 };  //MAC Address of this arduino's ethernet shield
IPAddress ip(192, 168, 10, 6);                        //IP Address of this arduino (check with AngryIP after plugging in and powering)
const unsigned int OSC_RECV_PORT = 8000;              //Which port to listen to for incoming OSC data

//Robotics
DualG2HighPowerMotorShield18v18 md;

float currentVel = 0;
float newVel;
float acc1;
int velMin = -10;
int velMax = 10;
int newDir = 0;
int velFactor1 = 0;
int accFactor;

void stopIfFault() {
  if (md.getM1Fault()) {
    md.disableDrivers();
    delay(1);
    Serial.println("M1 fault");
    while (1)
      ;
  }
}

void setup() {
  pinMode(A2, OUTPUT);
  pinMode(A3, OUTPUT);

  Serial.begin(115200);
  Serial.println("Dual G2 High Power Motor Shield");

  delay(100);

  DualG2HighPowerMotorShield(2, 7, 9, 6, A0, 4, A2, 3, A3, A1);

  md.init();
  md.calibrateCurrentOffsets();
  delay(10);
  md.enableDrivers();
  delay(1);

  delay(10);

  //Ethernet Init
  Ethernet.begin(mac, ip);
  Udp.begin(OSC_RECV_PORT);
}

void loop() {

  OSCBundle bundle;
  int size;

  if ((size = Udp.parsePacket()) > 0) {
    while (size--) {
      bundle.fill(Udp.read());
    }

    //bind functions here, skipping packet validation because Isadora is apparently non-compliant
    bundle.route(MOVE_ROBOT_ADDRESS, moveRobot);
    //bundle.route(MOVE_ROBOT_ADDRESS2, moveRobot2);
  }
}

void moveRobot(OSCMessage &msg, int offset) {

  Serial.println("Received");

  if (msg.isInt(0)) {
    velFactor1 = msg.getInt(0);
  } else if (msg.isFloat(0)) {
    velFactor1 = msg.getFloat(0);
  } else {
    return;
  }

  //newVel = map(velFactor1, -10, 10, -400, 400);

  if (newVel > currentVel) {
    newDir = 1;
  } else if (newVel < currentVel) {
    newDir = -1;
  } else if (newVel == currentVel) {
    newDir = 0;
  }

  if (msg.isInt(1)) {
    accFactor = msg.getInt(1);
  } else if (msg.isFloat(1)) {
    accFactor = msg.getFloat(1);
  } else {

    return;
  }

  acc1 = map(accFactor, 1, 5, 100, 10);

  if (newVel >= velMin && newVel <= velMax) {
    Serial.print("Velocity: ");
    Serial.print(velFactor1);
    Serial.print(" Acc1eleration: ");
    Serial.println(accFactor);
  }

  if (newDir == 1) {
    for (int i = currentVel; i <= newVel; i++) {
      md.setM1Speed(i);
      stopIfFault();
      delay(acc1);
    }
    currentVel = newVel;
  }

  if (newDir == -1) {
    for (int i = currentVel; i >= newVel; i--) {
      md.setM1Speed(i);
      stopIfFault();
      delay(acc1);
    }
    currentVel = newVel;
  }

  currentVel = newVel;

  delay(100);
}

Hello, @adriandcameron.

I looked into your code and the Ethernet library a little bit and do not see any obvious problems or explanations for why it is not working for you. It seems like your shield uses SPI to communicate with the Arduino, so there should not be any issues with the timers.

A minor note, the Ethernet Shield 2 uses I/O 4 as SS for the micro-SD card slot, which currently conflicts with the M2nSLEEP pin as your alternate constructor is currently written, but I do not expect that to be causing problems since you are not using the M2 channel anyway.

You might consider looking at and potentially try modifying the init() function in the G2 High Power Motor Driver Shield Arduino library just in case changing some of the pin configurations helps for some reason. Alternatively, there might be a memory issue at play, so you could try to look at what is going on there by following the advice in this Memories of an Arduino guide. (Specifically, the content under the SRAM header will probably be the most useful part to look at.)

- Patrick