Control 2 Pololu Dual MC33926 Motor Driver Carrier

Hi,

I want to control four Pololu Concentric Linear Actuator. To do this I use two of Pololu Dual MC33926 Motor Driver Carrier and Arduino MEGA shield.

I want to modifie the librairy of dual MC33926 motor driver for arduino posted by ryantm (who i thanks) on the following links
github.com/pololu/dual-mc33926- … otorShield
this librairy use timer 1 to control PWM but in arduino mega there is just 3 pwm with timer 1. So i want to use timer 3 (or timer 2) for the second motor driver shield.

Can you help me to release a new version of the library.

Hello.

Could you tell me which product you are referring to (the shield or just the carrier)? The library code is designed specifically to work with the shield. You might be able to modify the library code to work with the carrier, or you can just use the analogWrite() function to generate the PWM. However, we can not do this for you, though we would be happy to answer specific questions if you run into trouble.

-Robert

HI

I refer to carrier product which use the same H-bridge than the shield. I has modified the library. Unfortunately I can’t verify if it works, because I haven’t receive materiel yet (Alphacrucis have problems to deliver on time). I joined the program, it will work according to you.

I use timer 3 because it’s 16bits like timer 1

Thanks
Test1.ino (2.25 KB)
DualMC33926MotorShield.cpp (3.71 KB)

Hello.

The MC33926 shield has extra logic on the inputs, so the library for the shield is not directly compatible with the carrier (it requires more significant modifications than you made). Since you are using the carrier, I suggest you start by creating a simple program from scratch that just outputs the appropriate control signals for the drivers (e.g. digitalWrite() high for IN1, digitalWrite() low for IN2, and analogWrite() for PWM).

-Robert

Hi

Sorry, I took the connection schema of shield instead of schema of carrier.
According to the MC33926 datasheet truth table:

EN : VDD (Default- overriding jumper)
INV: VDD (Default- overriding jumper)
SLEW: VDD (Default- overriding jumper)
D1:LOW (GND) (Default- overriding jumper)

IN1: Digital output from ARDUINO
IN2: Digital output from ARDUINO
PWM / nD2: PWM output from ARDUINO

nSF: Digital input (ARDUINO)
FB: Analog input (ARDUINO)

I mad this modifications in the library:

#include "DualMC33926MotorShield.h"

// Constructor ////////////////////////////////////////////////////////////////

DualMC33926MotorShield::DualMC33926MotorShield(unsigned char M1IN1, unsigned char M1IN2, unsigned char M1PWM, unsigned char M1FB, unsigned char M2IN1, unsigned char M2IN2, unsigned char M2PWM, unsigned char M2FB, unsigned char nSF)
{
  //Pin map
  _M1IN1 = M1IN1;
  _M1IN2 = M1IN2;
  _M1PWM = M1PWM;
  _M1FB = M1FB; 

  _M2IN1 = M2IN1;
  _M2IN2 = M2IN2;
  _M2PWM =M2PWM;
  _M2FB = M2FB;
  
  _nSF = nSF;

}

// Public Methods //////////////////////////////////////////////////////////////
void DualMC33926MotorShield::init()
{
// Define pinMode for the pins and set the frequency for timer1 and 3.

  pinMode(_M1IN1,OUTPUT);
  pinMode(_M1IN2,OUTPUT);
  pinMode(_M1PWM,OUTPUT);
  pinMode(_M1FB,INPUT);
  pinMode(_M2IN1,OUTPUT);
  pinMode(_M2IN2,OUTPUT);
  pinMode(_M2PWM,OUTPUT);
  pinMode(_M2FB,INPUT);
  pinMode(_nSF,INPUT);

  #if defined(__AVR_ATmega2560__)|| defined(__AVR_ATmega1820__)
  // Timer 1 configuration
  // prescaler: clockI/O / 1
  // outputs enabled
  // phase-correct PWM
  // top of 400
  //
  // PWM frequency calculation
  // 16MHz / 1 (prescaler) / 2 (phase-correct) / 400 (top) = 20kHz
  TCCR1A = 0b10100000;
  TCCR1B = 0b00010001;
  ICR1 = 400;

  // Timer 3 configuration
  // prescaler: clockI/O / 1
  // outputs enabled
  // phase-correct PWM
  // top of 400
  //
  TCCR3A = 0b10100000;
  TCCR3B = 0b00010001;
  ICR3 = 400;
  #endif
}


// Set speed for motor 1, speed is a number betwenn -400 and 400
void DualMC33926MotorShield::setM1Speed(int speed)
{
  unsigned char reverse = 0;
  
  if (speed < 0)
  {
    speed = -speed;  // Make speed a positive quantity
    reverse = 1;  // Preserve the direction
  }
  if (speed > 400)  // Max PWM dutycycle
    speed = 400;
  		#if defined(__AVR_ATmega2560__)|| defined(__AVR_ATmega1820__)
  		OCR1A = speed;
		OCR3A = speed;

  		#else
  		analogWrite(_M1PWM,speed * 51 / 80); // default to using analogWrite, mapping 400 to 255
  		#endif
  if (reverse)
    {
	digitalWrite(_M1IN1,HIGH);
	digitalWrite(_M1IN2,LOW);
    }

  else
    {
	digitalWrite(_M1IN1,LOW);
	digitalWrite(_M1IN2,HIGH);
    }

}

// Set speed for motor 2, speed is a number betwenn -400 and 400
void DualMC33926MotorShield::setM2Speed(int speed)
{
  unsigned char reverse = 0;
  
  if (speed < 0)
  {
    speed = -speed;  // Make speed a positive quantity
    reverse = 1;  // Preserve the direction
  }
  if (speed > 400)  // Max PWM dutycycle
    speed = 400;
  		#if defined(__AVR_ATmega2560__)|| defined(__AVR_ATmega1820__)
  		OCR1B = speed;
		OCR3B = speed;

  		#else
  		analogWrite(_M2PWM,speed * 51 / 80); // default to using analogWrite, mapping 400 to 255
 		#endif
 if (reverse)
    {
	digitalWrite(_M2IN1,HIGH);
	digitalWrite(_M2IN2,LOW);
    }
  else
    {
	digitalWrite(_M2IN1,LOW);
	digitalWrite(_M2IN2,HIGH);
    }
}