Adafruit Motor Shield V2 library edited for Teensy 3.1 and i2c_t3

unix_guru

Member
My latest project pairs the Teensy 3.1 with Adafruit's Motor Shield V2.

To make this library work with the Teensy, and specifically the new I2C library, I replaced all references to <Wire.h> with <i2c_t3.h>
Upon compile, there were warnings about uint8_t values being passed to the new wire library. I replaced all references to uint8_t with uint16_t, recompiled, and it worked.
 

Attachments

  • Adafruit_MotorShield.h
    2.6 KB · Views: 452
  • Adafruit_MotorShield.cpp
    10.5 KB · Views: 484
  • keywords.txt
    855 bytes · Views: 388
  • Adafruit_PWMServoDriver.h
    1.5 KB · Views: 405
  • Adafruit_PWMServoDriver.cpp
    3.1 KB · Views: 454
Thank you for this! I'm not at all skilled with c++, how would I compile this -- with g++ (in the avr-gcc toolchain?) If there is a web page for compiling Teensy programs somewhere feel free to point me to it and I'll run with it.

Thanks

Happy New Year!

Bob Cochran
 
unix_guru I'm attempting to get the Motor Shield V2.3 working with my Teensy 3.1 but I'm always ending up hanging at the WIRE.endTransmission() call in Adafruit_PWMServoDriver.cpp.

I suspect I'm not wiring the Shield into the Teensy quite right. Could you let me know which pins you are connecting on the Shield. I'm currently just connecting Gnd, 5v, SCL, SDA and the 12v is there anything else I need to connect?

Thanks
 
Once you put in the external pull-up resistors that unix_guru mentions (these are adding 2 separate resistors between A4/A5 and 3.3v power) another common issue is not dealing with voltage issues. The Teensy 3.0/3.1/LC are 3.3v processors. The Adafruit shield defaults to 5v, since the majority of Arduinos are 5v. The Adafruit documentation says that the board supports both 3.3v and 5v logic systems, but you need to change a jumper to use 3.3v, and hook up the 3.3v power instead of 5v. Quoting from the fine manual on page 7 (note, I don't own the motor shield, but lacking 4.7K pull-up resistors that unix_guru say and not properly dealing with 3.3/5v issues are two common solutions to i2c problems):

For use with the Due or other 3.3v processors, you must configure the board for 3.3v logic levels. Find the set of 3 pads labeled "Logic". Cut the small trace between the center pad and 5v and add a jumper from 3.3v to the center.

Alternatively, you could use a voltage level converter on A4/A5 (in addition to using the pull-up resistors) to convert the signals to 5v and keep the Vin pin as power (assuming you are powering your Teensy via USB).

Note, I would try it with the standard Wire library first before moving to the t3_i2c library (just to eliminate variables).

If you want make the motor run faster you will need to switch to the t3_i2c library, and set the parameter to use 400Khz i2c speed instead of 100Khz that is standard. In moving to t3_i2c, you will need to change all <Wire.h> to <t3_i2c.h> in all libraries and in the sketch.
 
Last edited:
Thank you both for your suggestions. I had already tried pullups and both voltage combinations - it turns out that my problem was actually a memory corruption in my setup code. I was keeping a reference to a stack allocated object and obviously that was getting corrupted by the time I hit loop() leading to an incorrect address being passed into Wire. etc...

It actually turns out that there is no need (at least in my setup) to use pullups or 3.3v though as I said I have actually tried all combinations and they all work now I have identified the real culprit.

Thanks again
 
Hi Folks,

I have similar questions to Hutchiko (and probably many others) about the physical connection of wires between the Teensy 3.1 and various motor shields. Specifically I am trying to connect to the Adafruit motor shield v2.3. I tried looking at the accelstepper motor guide at the PJRC site but, remarkably, there's just a picture of a breadboard connection to some Pololu driver boards with no explanation of what other components are connected and no actual schematic.

If I just try and connect directly between the Adafruit shield board and the Teensy, am I just connecting SDA/SCL/GND and 5v (which is not 5v anymore but 3v because I have cut the trace and jumpered the other pads as instructed by Adafruit)? Do I want 4.7k resistors between my A4/A5 and 3.3v on the Teensy board connections as well as adjusting the voltage levels on the Ada board?

The Adafruit shield is starting to seem like overkill for what I need right now and I might consider using the StepStick a4988 driver boards (a replacement for the Pololu stuff), but I am not clear what exactly the components are that in the picture that connect the drivers board to the teensy?
https://www.pjrc.com/teensy/td_libs_AccelStepper.html

Thanks,
Cere
 
...and Thank you unix_guru for saving me lots of details and guesswork on modifying the Adafruit motor code to use i2c_t3!
 
But while I'm here, I guess I should be more open to the servo idea, actually. Is there a recommended servo motor (small is ok) that would work well with the Teensy in terms of current draw? Mostly I care about having a high resolution of motion increments < 1 deg, if possible. I think an AC motor is ok just to be controlled by PWM but I need to be able to reverse directions.

I know this isn't the best forum for advise on motors but honestly, it's hard to find a single site that works through all the various parameters around choosing a motor type.
 
The DRV883X H-Bridge solution allows forward and reverse directions using Teensy TTL/PWM signals as direction/speed control. I don't know how well PWM will do for resolution since you would be limited to 1/256 speed increments, whatever that means for a servo. Maybe short-duration pulses would work? The motor current is supplied directly from the battery (which would provide VIN to the Teensy also) and would be limited by the H-Bridge to less than 1.8 A each.
 
Servos or Steppers? - Teensy 3.1

Actually, I guess the servo library sort of dictates the resolution of the servo in a way. i.e: "On standard servos a parameter value of 1000 is fully counter-clockwise, 2000 is fully clockwise, and 1500 is in the middle." https://www.arduino.cc/en/Reference/ServoWriteMicroseconds

So if you are talking steppers then you absolutely need the H-Bridge. Either the one mentioned above, or any (ANY) H-bridge with enough current to drive your stepper.
In my discussion above, I chose to use the Adafruit Motor shield, because it used I2C and didn't "waste" valuable GPIO pins for driving the phases of the H-bridge.
most of it's documented here -> http://arduino-pi.blogspot.ca/2014/12/teensy-31-repstrap-printer-with-dc.html

But SERVO motors do not draw power from the Teensy. You run a common ground, and a separate power supply for the servo motor, then have a "signal" wire that you PWM control from the Teensy. it's really negligible current draw. You can likely have as many servos as you have PWMable (or soft PWMable) GPIO pins available.
 
I just wanted to write in and say that I finally got the courage to try to get this Adafruit motor sheild to work with Teensy and, as others have reported, it works GREAT! I chose to use the 3v supply on the adafruit board thinking that I would get a better signal range from the PWM of the Teensy, so I cut the trace between the 5v pin an soldered across to the 3v as instructed. Works great!

Only thing is that I do get some compile warnings about uninitialized/unused variables but they don't seem to stop the show. So yay!
 
Hi,

I just stumbled upon this thread.
I'm trying for a couple of days now to get the combination Teensy-LC with the smaller V2 Motorshield from adafruit to work together but had no success.

Now I saw this thread and tried the files provided in post #1 but no success.

Could you show what IDE you are using and under which OS etc?

I would like the combination Teensy-LC, Adafruit motorshield V2 (mini) and an Adafruit BLE Uart to work together to build a small robot.

Regards, Otto.
 
It looks like nearly the same thing except more compact. Probably the board I should have gotten for my purpose. They imply that the exact same code will work but aren't explicit about it. So ymmv.

One caviot about these board (which probably doesn't matter to anyone other than me): The I2c/PWM converter driver chip they use to talk to the TB6612 motor drivers only goes up to ~1.5kHz, which sucks because the TB6612 motor drivers can take in PWM signal up to 100kHz. I find the noise humm from PWM control in the audible range annoying and can't understand why manufactures continue to use them.
 
Hello, I am interested in using i2c_t3 on a teensy 3.2 along with adafruit motor shield v2 as to get the 400kHz bus speed. I've gone though all the code provided above by @unix_guru but for the life of me I am not sure how to create the motor shield object and get it initialized. I slimmed down the code to help make it quicker to go through. As you can see in the commented code I have tried several different ways. Thanks in advance :)

Code:
//i2c_3t test with Adafruit Motor Shield v2

#include <SPI.h>
//#include <Wire.h>
#include <i2c_t3.h>  //Add in future to increase bus speed
#include <Adafruit_MotorShield.h>
#include <PID_v2.h>
#include <stdint.h>
#include "TeensyTimerTool.h"

using namespace TeensyTimerTool;

//TwoWire *_i2c;
  i2c_t3 *_i2c;

//Inputs

PeriodicTimer t1(TCK);
PeriodicTimer t2(TCK);

// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();

// And connect a DC motor to port M1
Adafruit_DCMotor *needleMotor = AFMS.getMotor(1);
Adafruit_DCMotor *wireMotor = AFMS.getMotor(2);
Adafruit_DCMotor *catheterMotor = AFMS.getMotor(3);
        
//end calibration values
//////////////////////////////////////////////


//*****************************************************
void setup() 
//*****************************************************
{
 
  //_i2c = &Wire;
  
  //_i2c->begin();

  Wire.begin();
  Wire.setClock(400000);
  

//Setup for Master mode, pins 18/19, external pullups, 400kHz, 200ms default timeout
  //Wire.begin(I2C_MASTER, 0x00, I2C_PINS_18_19, I2C_PULLUP_EXT, 400000);
  //Wire.setDefaultTimeout(200000); // 200ms
  
  Serial.begin(115200);           // set up Serial library at 9600 bps

  Serial.print("System Initializing");
  Serial.print("\r\n");

  AFMS.begin();  // create with the default frequency 1.6KHz
  //AFMS.begin(1000);  // OR with a different frequency, say 1KHz
  
  //t1.begin(encoderLoop, 2_kHz);
  //t2.begin(dataLoop, 1_kHz);
  
}

//*****************************************************
void loop() 
//*****************************************************
{ 
  needleMotor->run(FORWARD);
  needleMotor->setSpeed(100);
  delay(100);
}//end loop
 
Back
Top