[Lib Update] Update Adafruit Motor Shield V2 library to v1.1.1

This commit is contained in:
TD-er
2023-10-20 18:25:46 +02:00
parent c8accd2020
commit 0bb017f561
17 changed files with 642 additions and 408 deletions
@@ -0,0 +1,32 @@
name: Arduino Library CI
on: [pull_request, push, repository_dispatch]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-python@v4
with:
python-version: '3.x'
- uses: actions/checkout@v3
- uses: actions/checkout@v3
with:
repository: adafruit/ci-arduino
path: ci
- name: pre-install
run: bash ci/actions_install.sh
- name: test platforms
run: python3 ci/build_platform.py main_platforms
- name: clang
run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r .
- name: doxygen
env:
GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }}
PRETTYNAME : "Adafruit Motor Shield V2 Arduino Library"
run: bash ci/doxy_gen_and_deploy.sh
@@ -1,63 +1,102 @@
/******************************************************************
This is the library for the Adafruit Motor Shield V2 for Arduino.
It supports DC motors & Stepper motors with microstepping as well
as stacking-support. It is *not* compatible with the V1 library!
/*!
* @file Adafruit_MotorShield.cpp
*
* @mainpage Adafruit FXOS8700 accel/mag sensor driver
*
* @section intro_sec Introduction
*
* This is the library for the Adafruit Motor Shield V2 for Arduino.
* It supports DC motors & Stepper motors with microstepping as well
* as stacking-support. It is *not* compatible with the V1 library!
* For use with the Motor Shield https://www.adafruit.com/products/1483
* and Motor FeatherWing https://www.adafruit.com/product/2927
*
* This shield/wing uses I2C to communicate, 2 pins (SCL+SDA) are required
* to interface.
*
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
* @section author Author
*
* Written by Limor Fried/Ladyada for Adafruit Industries.
*
* @section license License
*
* BSD license, all text here must be included in any redistribution.
*
*/
It will only work with https://www.adafruit.com/products/1483
Adafruit invests time and resources providing this open
source code, please support Adafruit and open-source hardware
by purchasing products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information.
All text above must be included in any redistribution.
******************************************************************/
#if (ARDUINO >= 100)
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include <Wire.h>
#include "Adafruit_MotorShield.h"
#include "Arduino.h"
#include <Adafruit_MS_PWMServoDriver.h>
#if defined(ARDUINO_SAM_DUE)
#define WIRE Wire1
#else
#define WIRE Wire
#endif
#if (MICROSTEPS == 8)
uint8_t microstepcurve[] = {0, 50, 98, 142, 180, 212, 236, 250, 255};
///! A sinusoial microstepping curve for the PWM output (8-bit range) with 9
/// points - last one is start of next step.
static uint8_t microstepcurve[] = {0, 50, 98, 142, 180, 212, 236, 250, 255};
#elif (MICROSTEPS == 16)
uint8_t microstepcurve[] = {0, 25, 50, 74, 98, 120, 141, 162, 180, 197, 212, 225, 236, 244, 250, 253, 255};
///! A sinusoial microstepping curve for the PWM output (8-bit range) with 17
/// points - last one is start of next step.
static uint8_t microstepcurve[] = {0, 25, 50, 74, 98, 120, 141, 162, 180,
197, 212, 225, 236, 244, 250, 253, 255};
#endif
Adafruit_MotorShield::Adafruit_MotorShield(uint8_t addr) {
_addr = addr;
_pwm = Adafruit_MS_PWMServoDriver(_addr);
}
/**************************************************************************/
/*!
@brief Create the Motor Shield object at an I2C address, default is 0x60
@param addr Optional I2C address if you've changed it
*/
/**************************************************************************/
Adafruit_MotorShield::Adafruit_MotorShield(uint8_t addr) { _addr = addr; }
void Adafruit_MotorShield::begin(uint16_t freq) {
/**************************************************************************/
/*!
@brief Initialize the I2C hardware and PWM driver, then turn off all pins.
@param freq
The PWM frequency for the driver, used for speed control and microstepping.
By default we use 1600 Hz which is a little audible but efficient.
@param theWire
A pointer to an optional I2C interface. If not provided, we use Wire or
Wire1 (on Due)
@returns true if successful, false otherwise
*/
/**************************************************************************/
bool Adafruit_MotorShield::begin(uint16_t freq, TwoWire *theWire) {
// init PWM w/_freq
//Wire.begin(); called in ESPEasy framework
_pwm.begin();
_pwm = Adafruit_MS_PWMServoDriver(_addr);
if (!_pwm.begin(theWire))
return false;
_freq = freq;
_pwm.setPWMFreq(_freq); // This is the maximum PWM frequency
for (uint8_t i=0; i<16; i++)
_pwm.setPWMFreq(_freq); // This is the maximum PWM frequency
for (uint8_t i = 0; i < 16; i++)
_pwm.setPWM(i, 0, 0);
return true;
}
/**************************************************************************/
/*!
@brief Helper that sets the PWM output on a pin and manages 'all on or off'
@param pin The PWM output on the driver that we want to control (0-15)
@param value The 12-bit PWM value we want to set (0-4095) - 4096 is a
special 'all on' value
*/
/**************************************************************************/
void Adafruit_MotorShield::setPWM(uint8_t pin, uint16_t value) {
if (value > 4095) {
_pwm.setPWM(pin, 4096, 0);
} else
_pwm.setPWM(pin, 0, value);
}
/**************************************************************************/
/*!
@brief Helper that sets the PWM output on a pin as if it were a GPIO
@param pin The PWM output on the driver that we want to control (0-15)
@param value HIGH or LOW depending on the value you want!
*/
/**************************************************************************/
void Adafruit_MotorShield::setPin(uint8_t pin, boolean value) {
if (value == LOW)
_pwm.setPWM(pin, 0, 0);
@@ -65,8 +104,17 @@ void Adafruit_MotorShield::setPin(uint8_t pin, boolean value) {
_pwm.setPWM(pin, 4096, 0);
}
/**************************************************************************/
/*!
@brief Mini factory that will return a pointer to an already-allocated
Adafruit_DCMotor object. Initializes the DC motor and turns off all pins
@param num The DC motor port we want to use: 1 thru 4 are valid
@returns NULL if something went wrong, or a pointer to a Adafruit_DCMotor
*/
/**************************************************************************/
Adafruit_DCMotor *Adafruit_MotorShield::getMotor(uint8_t num) {
if (num > 4) return NULL;
if (num > 4)
return NULL;
num--;
@@ -74,15 +122,28 @@ Adafruit_DCMotor *Adafruit_MotorShield::getMotor(uint8_t num) {
// not init'd yet!
dcmotors[num].motornum = num;
dcmotors[num].MC = this;
uint8_t pwm=0, in1=0, in2=0;
if (num == 0) {
pwm = 8; in2 = 9; in1 = 10;
} else if (num == 1) {
pwm = 13; in2 = 12; in1 = 11;
} else if (num == 2) {
pwm = 2; in2 = 3; in1 = 4;
} else if (num == 3) {
pwm = 7; in2 = 6; in1 = 5;
uint8_t pwm, in1, in2;
switch (num) {
case 0:
pwm = 8;
in2 = 9;
in1 = 10;
break;
case 1:
pwm = 13;
in2 = 12;
in1 = 11;
break;
case 2:
pwm = 2;
in2 = 3;
in1 = 4;
break;
default:
pwm = 7;
in2 = 6;
in1 = 5;
break;
}
dcmotors[num].PWMpin = pwm;
dcmotors[num].IN1pin = in1;
@@ -91,9 +152,21 @@ Adafruit_DCMotor *Adafruit_MotorShield::getMotor(uint8_t num) {
return &dcmotors[num];
}
Adafruit_StepperMotor *Adafruit_MotorShield::getStepper(uint16_t steps, uint8_t num) {
if (num > 2) return NULL;
/**************************************************************************/
/*!
@brief Mini factory that will return a pointer to an already-allocated
Adafruit_StepperMotor object with a given 'steps per rotation.
Then initializes the stepper motor and turns off all pins.
@param steps How many steps per revolution (used for RPM calculation)
@param num The stepper motor port we want to use: only 1 or 2 are valid
@returns NULL if something went wrong, or a pointer to a
Adafruit_StepperMotor
*/
/**************************************************************************/
Adafruit_StepperMotor *Adafruit_MotorShield::getStepper(uint16_t steps,
uint8_t num) {
if (num > 2)
return NULL;
num--;
@@ -102,13 +175,21 @@ Adafruit_StepperMotor *Adafruit_MotorShield::getStepper(uint16_t steps, uint8_t
steppers[num].steppernum = num;
steppers[num].revsteps = steps;
steppers[num].MC = this;
uint8_t pwma=0, pwmb=0, ain1=0, ain2=0, bin1=0, bin2=0;
uint8_t pwma, pwmb, ain1, ain2, bin1, bin2;
if (num == 0) {
pwma = 8; ain2 = 9; ain1 = 10;
pwmb = 13; bin2 = 12; bin1 = 11;
} else if (num == 1) {
pwma = 2; ain2 = 3; ain1 = 4;
pwmb = 7; bin2 = 6; bin1 = 5;
pwma = 8;
ain2 = 9;
ain1 = 10;
pwmb = 13;
bin2 = 12;
bin1 = 11;
} else {
pwma = 2;
ain2 = 3;
ain1 = 4;
pwmb = 7;
bin2 = 6;
bin1 = 5;
}
steppers[num].PWMApin = pwma;
steppers[num].PWMBpin = pwmb;
@@ -120,25 +201,37 @@ Adafruit_StepperMotor *Adafruit_MotorShield::getStepper(uint16_t steps, uint8_t
return &steppers[num];
}
/******************************************
MOTORS
******************************************/
/**************************************************************************/
/*!
@brief Create a DCMotor object, un-initialized!
You should never call this, instead have the {@link Adafruit_MotorShield}
give you a DCMotor object with {@link Adafruit_MotorShield.getMotor}
*/
/**************************************************************************/
Adafruit_DCMotor::Adafruit_DCMotor(void) {
MC = NULL;
motornum = 0;
PWMpin = IN1pin = IN2pin = 0;
}
/**************************************************************************/
/*!
@brief Control the DC Motor direction and action
@param cmd The action to perform, can be FORWARD, BACKWARD or RELEASE
*/
/**************************************************************************/
void Adafruit_DCMotor::run(uint8_t cmd) {
switch (cmd) {
case FORWARD:
MC->setPin(IN2pin, LOW); // take low first to avoid 'break'
MC->setPin(IN2pin, LOW); // take low first to avoid 'break'
MC->setPin(IN1pin, HIGH);
break;
case BACKWARD:
MC->setPin(IN1pin, LOW); // take low first to avoid 'break'
MC->setPin(IN1pin, LOW); // take low first to avoid 'break'
MC->setPin(IN2pin, HIGH);
break;
case RELEASE:
@@ -148,64 +241,73 @@ void Adafruit_DCMotor::run(uint8_t cmd) {
}
}
/**************************************************************************/
/*!
@brief Control the DC Motor speed/throttle
@param speed The 8-bit PWM value, 0 is off, 255 is on
*/
/**************************************************************************/
void Adafruit_DCMotor::setSpeed(uint8_t speed) {
MC->setPWM(PWMpin, speed*16);
MC->setPWM(PWMpin, speed * 16);
}
/**************************************************************************/
/*!
@brief Control the DC Motor speed/throttle with 12 bit resolution.
@param speed The 12-bit PWM value, 0 (full off) to 4095 (full on)
*/
/**************************************************************************/
void Adafruit_DCMotor::setSpeedFine(uint16_t speed) {
MC->setPWM(PWMpin, speed > 4095 ? 4095 : speed);
}
/**************************************************************************/
/*!
@brief Set DC motor to full on.
*/
/**************************************************************************/
void Adafruit_DCMotor::fullOn() { MC->_pwm.setPWM(PWMpin, 4096, 0); }
/**************************************************************************/
/*!
@brief Set DC motor to full off.
*/
/**************************************************************************/
void Adafruit_DCMotor::fullOff() { MC->_pwm.setPWM(PWMpin, 0, 4096); }
/******************************************
STEPPERS
******************************************/
/**************************************************************************/
/*!
@brief Create a StepperMotor object, un-initialized!
You should never call this, instead have the {@link Adafruit_MotorShield}
give you a StepperMotor object with {@link Adafruit_MotorShield.getStepper}
*/
/**************************************************************************/
Adafruit_StepperMotor::Adafruit_StepperMotor(void) {
revsteps = steppernum = currentstep = 0;
}
/*
uint16_t steps, Adafruit_MotorShield controller) {
revsteps = steps;
steppernum = 1;
currentstep = 0;
if (steppernum == 1) {
latch_state &= ~_BV(MOTOR1_A) & ~_BV(MOTOR1_B) &
~_BV(MOTOR2_A) & ~_BV(MOTOR2_B); // all motor pins to 0
// enable both H bridges
pinMode(11, OUTPUT);
pinMode(3, OUTPUT);
digitalWrite(11, HIGH);
digitalWrite(3, HIGH);
// use PWM for microstepping support
MC->setPWM(1, 255);
MC->setPWM(2, 255);
} else if (steppernum == 2) {
latch_state &= ~_BV(MOTOR3_A) & ~_BV(MOTOR3_B) &
~_BV(MOTOR4_A) & ~_BV(MOTOR4_B); // all motor pins to 0
// enable both H bridges
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
// use PWM for microstepping support
// use PWM for microstepping support
MC->setPWM(3, 255);
MC->setPWM(4, 255);
}
}
/**************************************************************************/
/*!
@brief Set the delay for the Stepper Motor speed in RPM
@param rpm The desired RPM, we will do our best to reach it!
*/
/**************************************************************************/
void Adafruit_StepperMotor::setSpeed(uint16_t rpm) {
//Serial.println("steps per rev: "); Serial.println(revsteps);
//Serial.println("RPM: "); Serial.println(rpm);
// Serial.println("steps per rev: "); Serial.println(revsteps);
// Serial.println("RPM: "); Serial.println(rpm);
usperstep = 60000000 / ((uint32_t)revsteps * (uint32_t)rpm);
}
/**************************************************************************/
/*!
@brief Release all pins of the stepper motor so it free-spins
*/
/**************************************************************************/
void Adafruit_StepperMotor::release(void) {
MC->setPin(AIN1pin, LOW);
MC->setPin(AIN2pin, LOW);
@@ -215,72 +317,91 @@ void Adafruit_StepperMotor::release(void) {
MC->setPWM(PWMBpin, 0);
}
void Adafruit_StepperMotor::step(uint16_t steps, uint8_t dir, uint8_t style) {
/**************************************************************************/
/*!
@brief Move the stepper motor with the given RPM speed, don't forget to
call
{@link Adafruit_StepperMotor.setSpeed} to set the speed!
@param steps The number of steps we want to move
@param dir The direction to go, can be FORWARD or BACKWARD
@param style How to perform each step, can be SINGLE, DOUBLE, INTERLEAVE or
MICROSTEP
*/
/**************************************************************************/
void Adafruit_StepperMotor::step(uint16_t steps, uint8_t dir, uint8_t style) {
uint32_t uspers = usperstep;
//uint8_t ret = 0;
if (style == INTERLEAVE) {
uspers /= 2;
}
else if (style == MICROSTEP) {
} else if (style == MICROSTEP) {
uspers /= MICROSTEPS;
steps *= MICROSTEPS;
#ifdef MOTORDEBUG
Serial.print("steps = "); Serial.println(steps, DEC);
Serial.print("steps = ");
Serial.println(steps, DEC);
#endif
}
while (steps--) {
//Serial.println("step!"); Serial.println(uspers);
// Serial.println("step!"); Serial.println(uspers);
onestep(dir, style);
delayMicroseconds(uspers);
#ifdef ESP8266
yield(); // required for ESP8266
#endif
}
}
/**************************************************************************/
/*!
@brief Move the stepper motor one step only, with no delays
@param dir The direction to go, can be FORWARD or BACKWARD
@param style How to perform each step, can be SINGLE, DOUBLE, INTERLEAVE or
MICROSTEP
@returns The current step/microstep index, useful for
Adafruit_StepperMotor.step to keep track of the current location, especially
when microstepping
*/
/**************************************************************************/
uint8_t Adafruit_StepperMotor::onestep(uint8_t dir, uint8_t style) {
//uint8_t a, b, c, d;
uint8_t ocrb, ocra;
ocra = ocrb = 255;
// next determine what sort of stepping procedure we're up to
if (style == SINGLE) {
if ((currentstep/(MICROSTEPS/2)) % 2) { // we're at an odd step, weird
if ((currentstep / (MICROSTEPS / 2)) % 2) { // we're at an odd step, weird
if (dir == FORWARD) {
currentstep += MICROSTEPS/2;
currentstep += MICROSTEPS / 2;
} else {
currentstep -= MICROSTEPS / 2;
}
else {
currentstep -= MICROSTEPS/2;
}
} else { // go to the next even step
} else { // go to the next even step
if (dir == FORWARD) {
currentstep += MICROSTEPS;
}
else {
currentstep -= MICROSTEPS;
currentstep += MICROSTEPS;
} else {
currentstep -= MICROSTEPS;
}
}
} else if (style == DOUBLE) {
if (! (currentstep/(MICROSTEPS/2) % 2)) { // we're at an even step, weird
if (!(currentstep / (MICROSTEPS / 2) % 2)) { // we're at an even step, weird
if (dir == FORWARD) {
currentstep += MICROSTEPS/2;
currentstep += MICROSTEPS / 2;
} else {
currentstep -= MICROSTEPS/2;
currentstep -= MICROSTEPS / 2;
}
} else { // go to the next odd step
} else { // go to the next odd step
if (dir == FORWARD) {
currentstep += MICROSTEPS;
currentstep += MICROSTEPS;
} else {
currentstep -= MICROSTEPS;
currentstep -= MICROSTEPS;
}
}
} else if (style == INTERLEAVE) {
if (dir == FORWARD) {
currentstep += MICROSTEPS/2;
currentstep += MICROSTEPS / 2;
} else {
currentstep -= MICROSTEPS/2;
currentstep -= MICROSTEPS / 2;
}
}
@@ -292,52 +413,56 @@ uint8_t Adafruit_StepperMotor::onestep(uint8_t dir, uint8_t style) {
currentstep--;
}
currentstep += MICROSTEPS*4;
currentstep %= MICROSTEPS*4;
currentstep += MICROSTEPS * 4;
currentstep %= MICROSTEPS * 4;
ocra = ocrb = 0;
if ( (currentstep >= 0) && (currentstep < MICROSTEPS)) {
if (currentstep < MICROSTEPS) {
ocra = microstepcurve[MICROSTEPS - currentstep];
ocrb = microstepcurve[currentstep];
} else if ( (currentstep >= MICROSTEPS) && (currentstep < MICROSTEPS*2)) {
} else if ((currentstep >= MICROSTEPS) && (currentstep < MICROSTEPS * 2)) {
ocra = microstepcurve[currentstep - MICROSTEPS];
ocrb = microstepcurve[MICROSTEPS*2 - currentstep];
} else if ( (currentstep >= MICROSTEPS*2) && (currentstep < MICROSTEPS*3)) {
ocra = microstepcurve[MICROSTEPS*3 - currentstep];
ocrb = microstepcurve[currentstep - MICROSTEPS*2];
} else if ( (currentstep >= MICROSTEPS*3) && (currentstep < MICROSTEPS*4)) {
ocra = microstepcurve[currentstep - MICROSTEPS*3];
ocrb = microstepcurve[MICROSTEPS*4 - currentstep];
ocrb = microstepcurve[MICROSTEPS * 2 - currentstep];
} else if ((currentstep >= MICROSTEPS * 2) &&
(currentstep < MICROSTEPS * 3)) {
ocra = microstepcurve[MICROSTEPS * 3 - currentstep];
ocrb = microstepcurve[currentstep - MICROSTEPS * 2];
} else if ((currentstep >= MICROSTEPS * 3) &&
(currentstep < MICROSTEPS * 4)) {
ocra = microstepcurve[currentstep - MICROSTEPS * 3];
ocrb = microstepcurve[MICROSTEPS * 4 - currentstep];
}
}
currentstep += MICROSTEPS*4;
currentstep %= MICROSTEPS*4;
currentstep += MICROSTEPS * 4;
currentstep %= MICROSTEPS * 4;
#ifdef MOTORDEBUG
Serial.print("current step: "); Serial.println(currentstep, DEC);
Serial.print(" pwmA = "); Serial.print(ocra, DEC);
Serial.print(" pwmB = "); Serial.println(ocrb, DEC);
Serial.print("current step: ");
Serial.println(currentstep, DEC);
Serial.print(" pwmA = ");
Serial.print(ocra, DEC);
Serial.print(" pwmB = ");
Serial.println(ocrb, DEC);
#endif
MC->setPWM(PWMApin, ocra*16);
MC->setPWM(PWMBpin, ocrb*16);
MC->setPWM(PWMApin, ocra * 16);
MC->setPWM(PWMBpin, ocrb * 16);
// release all
uint8_t latch_state = 0; // all motor pins to 0
//Serial.println(step, DEC);
// Serial.println(step, DEC);
if (style == MICROSTEP) {
if ((currentstep >= 0) && (currentstep < MICROSTEPS))
if (currentstep < MICROSTEPS)
latch_state |= 0x03;
if ((currentstep >= MICROSTEPS) && (currentstep < MICROSTEPS*2))
if ((currentstep >= MICROSTEPS) && (currentstep < MICROSTEPS * 2))
latch_state |= 0x06;
if ((currentstep >= MICROSTEPS*2) && (currentstep < MICROSTEPS*3))
if ((currentstep >= MICROSTEPS * 2) && (currentstep < MICROSTEPS * 3))
latch_state |= 0x0C;
if ((currentstep >= MICROSTEPS*3) && (currentstep < MICROSTEPS*4))
if ((currentstep >= MICROSTEPS * 3) && (currentstep < MICROSTEPS * 4))
latch_state |= 0x09;
} else {
switch (currentstep/(MICROSTEPS/2)) {
switch (currentstep / (MICROSTEPS / 2)) {
case 0:
latch_state |= 0x1; // energize coil 1 only
break;
@@ -365,30 +490,31 @@ uint8_t Adafruit_StepperMotor::onestep(uint8_t dir, uint8_t style) {
}
}
#ifdef MOTORDEBUG
Serial.print("Latch: 0x"); Serial.println(latch_state, HEX);
Serial.print("Latch: 0x");
Serial.println(latch_state, HEX);
#endif
if (latch_state & 0x1) {
// Serial.println(AIN2pin);
// Serial.println(AIN2pin);
MC->setPin(AIN2pin, HIGH);
} else {
MC->setPin(AIN2pin, LOW);
}
if (latch_state & 0x2) {
MC->setPin(BIN1pin, HIGH);
// Serial.println(BIN1pin);
// Serial.println(BIN1pin);
} else {
MC->setPin(BIN1pin, LOW);
}
if (latch_state & 0x4) {
MC->setPin(AIN1pin, HIGH);
// Serial.println(AIN1pin);
// Serial.println(AIN1pin);
} else {
MC->setPin(AIN1pin, LOW);
}
if (latch_state & 0x8) {
MC->setPin(BIN2pin, HIGH);
// Serial.println(BIN2pin);
// Serial.println(BIN2pin);
} else {
MC->setPin(BIN2pin, LOW);
}
@@ -1,14 +1,14 @@
/******************************************************************
This is the library for the Adafruit Motor Shield V2 for Arduino.
This is the library for the Adafruit Motor Shield V2 for Arduino.
It supports DC motors & Stepper motors with microstepping as well
as stacking-support. It is *not* compatible with the V1 library!
It will only work with https://www.adafruit.com/products/1483
Adafruit invests time and resources providing this open
source code, please support Adafruit and open-source hardware
by purchasing products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information.
All text above must be included in any redistribution.
@@ -17,13 +17,12 @@
#ifndef _Adafruit_MotorShield_h_
#define _Adafruit_MotorShield_h_
#include <inttypes.h>
#include <Wire.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
#include <inttypes.h>
//#define MOTORDEBUG
#define MICROSTEPS 16 // 8 or 16
#define MICROSTEPS 16 // 8 or 16
#define MOTOR1_A 2
#define MOTOR1_B 3
@@ -46,32 +45,38 @@
class Adafruit_MotorShield;
class Adafruit_DCMotor
{
public:
/** Object that controls and keeps state for a single DC motor */
class Adafruit_DCMotor {
public:
Adafruit_DCMotor(void);
friend class Adafruit_MotorShield;
friend class Adafruit_MotorShield; ///< Let MotorShield create DCMotors
void run(uint8_t);
void setSpeed(uint8_t);
private:
void setSpeedFine(uint16_t speed);
void fullOn();
void fullOff();
private:
uint8_t PWMpin, IN1pin, IN2pin;
Adafruit_MotorShield *MC;
uint8_t motornum;
};
/** Object that controls and keeps state for a single stepper motor */
class Adafruit_StepperMotor {
public:
public:
Adafruit_StepperMotor(void);
friend class Adafruit_MotorShield;
void step(uint16_t steps, uint8_t dir, uint8_t style = SINGLE);
void setSpeed(uint16_t);
void step(uint16_t steps, uint8_t dir, uint8_t style = SINGLE);
uint8_t onestep(uint8_t dir, uint8_t style);
void release(void);
friend class Adafruit_MotorShield; ///< Let MotorShield create StepperMotors
private:
uint32_t usperstep;
private:
uint8_t PWMApin, AIN1pin, AIN2pin;
uint8_t PWMBpin, BIN1pin, BIN2pin;
uint16_t revsteps; // # steps per revolution
@@ -80,23 +85,27 @@ class Adafruit_StepperMotor {
uint8_t steppernum;
};
class Adafruit_MotorShield
{
public:
Adafruit_MotorShield(uint8_t addr = 0x60);
friend class Adafruit_DCMotor;
void begin(uint16_t freq = 1600);
/** Object that controls and keeps state for the whole motor shield.
Use it to create DC and Stepper motor objects! */
class Adafruit_MotorShield {
public:
Adafruit_MotorShield(uint8_t addr = 0x60);
void setPWM(uint8_t pin, uint16_t val);
void setPin(uint8_t pin, boolean val);
Adafruit_DCMotor *getMotor(uint8_t n);
Adafruit_StepperMotor *getStepper(uint16_t steps, uint8_t n);
private:
uint8_t _addr;
uint16_t _freq;
Adafruit_DCMotor dcmotors[4];
Adafruit_StepperMotor steppers[2];
Adafruit_MS_PWMServoDriver _pwm;
bool begin(uint16_t freq = 1600, TwoWire *theWire = &Wire);
Adafruit_DCMotor *getMotor(uint8_t n);
Adafruit_StepperMotor *getStepper(uint16_t steps, uint8_t n);
friend class Adafruit_DCMotor; ///< Let DCMotors control the Shield
void setPWM(uint8_t pin, uint16_t val);
void setPin(uint8_t pin, boolean val);
private:
uint8_t _addr;
uint16_t _freq;
Adafruit_DCMotor dcmotors[4];
Adafruit_StepperMotor steppers[2];
Adafruit_MS_PWMServoDriver _pwm;
};
#endif
+9 -42
View File
@@ -1,47 +1,14 @@
# Adafruit Motor Shield v2 Library
# Adafruit Motor Shield V2 Library [![Build Status](https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library/actions)[![Documentation](https://github.com/adafruit/ci-arduino/blob/master/assets/doxygen_badge.svg)](http://adafruit.github.io/Adafruit_Motor_Shield_V2_Library/html/index.html)
This is the library for the Adafruit Motor Shield V2 for Arduino.
It supports DC motors & Stepper motors with microstepping as well
as stacking-support. It is *not* compatible with the V1 library!
<img src="https://cdn-shop.adafruit.com/1200x900/1438-00.jpg" height="300"/>
It will only work with https://www.adafruit.com/products/1438
This is the library for the Adafruit Motor Shield V2 for Arduino. It supports DC motors & Stepper motors with microstepping as well as stacking-support. It is *not* compatible with the V1 library!
<!-- START COMPATIBILITY TABLE -->
For use with the Motor Shield https://www.adafruit.com/products/1438
and Motor FeatherWing https://www.adafruit.com/product/2927
## Compatibility
MCU | Tested Works | Doesn't Work | Not Tested | Notes
------------------ | :----------: | :----------: | :---------: | -----
Atmega328 @ 16MHz | X | | |
Atmega328 @ 12MHz | X | | |
Atmega32u4 @ 16MHz | X | | |
Atmega32u4 @ 8MHz | X | | |
ESP8266 | | | X |
Atmega2560 @ 16MHz | X | | |
ATSAM3X8E | | X | |
ATSAM21D | | X | |
ATtiny85 @ 16MHz | | | X |
ATtiny85 @ 8MHz | | | X |
Intel Curie @ 32MHz | | | X |
STM32F2 | | | X |
* ATmega328 @ 16MHz : Arduino UNO, Adafruit Pro Trinket 5V, Adafruit Metro 328, Adafruit Metro Mini
* ATmega328 @ 12MHz : Adafruit Pro Trinket 3V
* ATmega32u4 @ 16MHz : Arduino Leonardo, Arduino Micro, Arduino Yun, Teensy 2.0
* ATmega32u4 @ 8MHz : Adafruit Flora, Bluefruit Micro
* ESP8266 : Adafruit Huzzah
* ATmega2560 @ 16MHz : Arduino Mega
* ATSAM3X8E : Arduino Due
* ATSAM21D : Arduino Zero, M0 Pro
* ATtiny85 @ 16MHz : Adafruit Trinket 5V
* ATtiny85 @ 8MHz : Adafruit Gemma, Arduino Gemma, Adafruit Trinket 3V
<!-- END COMPATIBILITY TABLE -->
Adafruit invests time and resources providing this open
source code, please support Adafruit and open-source hardware
by purchasing products from Adafruit!
Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information.
All text above must be included in any redistribution.
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information.
All text above must be included in any redistribution.
@@ -3,50 +3,52 @@
//
// Shows how to run AccelStepper in the simplest,
// fixed speed mode with no accelerations
// Requires the Adafruit_Motorshield v2 library
// Requires the Adafruit_Motorshield v2 library
// https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library
// And AccelStepper with AFMotor support
// And AccelStepper with AFMotor support
// https://github.com/adafruit/AccelStepper
// This tutorial is for Adafruit Motorshield v2 only!
// Will not work with v1 shields
#include <AccelStepper.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// Or, create it with a different I2C address (say for stacking)
// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61);
// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61);
// Connect a stepper motor with 200 steps per revolution (1.8 degree)
// to motor port #2 (M3 and M4)
Adafruit_StepperMotor *myStepper1 = AFMS.getStepper(200, 2);
// you can change these to DOUBLE or INTERLEAVE or MICROSTEP!
void forwardstep1() {
void forwardstep1() {
myStepper1->onestep(FORWARD, SINGLE);
}
void backwardstep1() {
void backwardstep1() {
myStepper1->onestep(BACKWARD, SINGLE);
}
AccelStepper Astepper1(forwardstep1, backwardstep1); // use functions to step
void setup()
{
{
Serial.begin(9600); // set up Serial library at 9600 bps
Serial.println("Stepper test!");
AFMS.begin(); // create with the default frequency 1.6KHz
//AFMS.begin(1000); // OR with a different frequency, say 1KHz
Astepper1.setSpeed(50);
if (!AFMS.begin()) { // create with the default frequency 1.6KHz
// if (!AFMS.begin(1000)) { // OR with a different frequency, say 1KHz
Serial.println("Could not find Motor Shield. Check wiring.");
while (1);
}
Serial.println("Motor Shield found.");
Astepper1.setSpeed(50);
}
void loop()
{
{
Astepper1.runSpeed();
}
@@ -1,17 +1,15 @@
// Shows how to run three Steppers at once with varying speeds
//
// Requires the Adafruit_Motorshield v2 library
// Requires the Adafruit_Motorshield v2 library
// https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library
// And AccelStepper with AFMotor support
// And AccelStepper with AFMotor support
// https://github.com/adafruit/AccelStepper
// This tutorial is for Adafruit Motorshield v2 only!
// Will not work with v1 shields
#include <AccelStepper.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
Adafruit_MotorShield AFMSbot(0x61); // Rightmost jumper closed
Adafruit_MotorShield AFMStop(0x60); // Default address, no jumpers
@@ -27,24 +25,24 @@ Adafruit_StepperMotor *myStepper3 = AFMSbot.getStepper(200, 2);
// you can change these to DOUBLE or INTERLEAVE or MICROSTEP!
// wrappers for the first motor!
void forwardstep1() {
void forwardstep1() {
myStepper1->onestep(FORWARD, SINGLE);
}
void backwardstep1() {
void backwardstep1() {
myStepper1->onestep(BACKWARD, SINGLE);
}
// wrappers for the second motor!
void forwardstep2() {
void forwardstep2() {
myStepper2->onestep(FORWARD, DOUBLE);
}
void backwardstep2() {
void backwardstep2() {
myStepper2->onestep(BACKWARD, DOUBLE);
}
// wrappers for the third motor!
void forwardstep3() {
void forwardstep3() {
myStepper3->onestep(FORWARD, INTERLEAVE);
}
void backwardstep3() {
void backwardstep3() {
myStepper3->onestep(BACKWARD, INTERLEAVE);
}
@@ -54,14 +52,14 @@ AccelStepper stepper2(forwardstep2, backwardstep2);
AccelStepper stepper3(forwardstep3, backwardstep3);
void setup()
{
{
AFMSbot.begin(); // Start the bottom shield
AFMStop.begin(); // Start the top shield
stepper1.setMaxSpeed(100.0);
stepper1.setAcceleration(100.0);
stepper1.moveTo(24);
stepper2.setMaxSpeed(200.0);
stepper2.setAcceleration(100.0);
stepper2.moveTo(50000);
@@ -1,20 +1,18 @@
/*
/*
This is a test sketch for the Adafruit assembled Motor Shield for Arduino v2
It won't work with v1.x motor shields! Only for the v2's with built in PWM
control
For use with the Adafruit Motor Shield v2
For use with the Adafruit Motor Shield v2
----> http://www.adafruit.com/products/1438
*/
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// Or, create it with a different I2C address (say for stacking)
// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61);
// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61);
// Select which 'port' M1, M2, M3 or M4. In this case, M1
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);
@@ -25,9 +23,13 @@ void setup() {
Serial.begin(9600); // set up Serial library at 9600 bps
Serial.println("Adafruit Motorshield v2 - DC Motor test!");
AFMS.begin(); // create with the default frequency 1.6KHz
//AFMS.begin(1000); // OR with a different frequency, say 1KHz
if (!AFMS.begin()) { // create with the default frequency 1.6KHz
// if (!AFMS.begin(1000)) { // OR with a different frequency, say 1KHz
Serial.println("Could not find Motor Shield. Check wiring.");
while (1);
}
Serial.println("Motor Shield found.");
// Set the speed to start, from 0 (off) to 255 (max speed)
myMotor->setSpeed(150);
myMotor->run(FORWARD);
@@ -37,28 +39,28 @@ void setup() {
void loop() {
uint8_t i;
Serial.print("tick");
myMotor->run(FORWARD);
for (i=0; i<255; i++) {
myMotor->setSpeed(i);
myMotor->setSpeed(i);
delay(10);
}
for (i=255; i!=0; i--) {
myMotor->setSpeed(i);
myMotor->setSpeed(i);
delay(10);
}
Serial.print("tock");
myMotor->run(BACKWARD);
for (i=0; i<255; i++) {
myMotor->setSpeed(i);
myMotor->setSpeed(i);
delay(10);
}
for (i=255; i!=0; i--) {
myMotor->setSpeed(i);
myMotor->setSpeed(i);
delay(10);
}
@@ -1,9 +1,9 @@
/*
/*
This is a test sketch for the Adafruit assembled Motor Shield for Arduino v2
It won't work with v1.x motor shields! Only for the v2's with built in PWM
control
For use with the Adafruit Motor Shield v2
For use with the Adafruit Motor Shield v2
----> http://www.adafruit.com/products/1438
This sketch creates a fun motor party on your desk *whiirrr*
@@ -12,15 +12,13 @@ Connect a DC motor to M1
Connect a hobby servo to SERVO1
*/
#include <Wire.h>
#include <Servo.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
#include <Servo.h>
// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// Or, create it with a different I2C address (say for stacking)
// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61);
// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61);
// Connect a stepper motor with 200 steps per revolution (1.8 degree)
// to motor port #2 (M3 and M4)
@@ -36,18 +34,22 @@ void setup() {
Serial.begin(9600); // set up Serial library at 9600 bps
Serial.println("MMMMotor party!");
AFMS.begin(); // create with the default frequency 1.6KHz
//AFMS.begin(1000); // OR with a different frequency, say 1KHz
if (!AFMS.begin()) { // create with the default frequency 1.6KHz
// if (!AFMS.begin(1000)) { // OR with a different frequency, say 1KHz
Serial.println("Could not find Motor Shield. Check wiring.");
while (1);
}
Serial.println("Motor Shield found.");
// Attach a servo to pin #10
servo1.attach(10);
// turn on motor M1
myMotor->setSpeed(200);
myMotor->run(RELEASE);
// setup the stepper
myStepper->setSpeed(10); // 10 rpm
myStepper->setSpeed(10); // 10 rpm
}
int i;
@@ -55,29 +57,29 @@ void loop() {
myMotor->run(FORWARD);
for (i=0; i<255; i++) {
servo1.write(map(i, 0, 255, 0, 180));
myMotor->setSpeed(i);
myMotor->setSpeed(i);
myStepper->step(1, FORWARD, INTERLEAVE);
delay(3);
}
for (i=255; i!=0; i--) {
servo1.write(map(i, 0, 255, 0, 180));
myMotor->setSpeed(i);
myMotor->setSpeed(i);
myStepper->step(1, BACKWARD, INTERLEAVE);
delay(3);
}
myMotor->run(BACKWARD);
for (i=0; i<255; i++) {
servo1.write(map(i, 0, 255, 0, 180));
myMotor->setSpeed(i);
myMotor->setSpeed(i);
myStepper->step(1, FORWARD, DOUBLE);
delay(3);
}
for (i=255; i!=0; i--) {
servo1.write(map(i, 0, 255, 0, 180));
myMotor->setSpeed(i);
myMotor->setSpeed(i);
myStepper->step(1, BACKWARD, DOUBLE);
delay(3);
}
@@ -1,15 +1,13 @@
/*
/*
This is a test sketch for the Adafruit assembled Motor Shield for Arduino v2
It won't work with v1.x motor shields! Only for the v2's with built in PWM
control
For use with the Adafruit Motor Shield v2
For use with the Adafruit Motor Shield v2
----> http://www.adafruit.com/products/1438
*/
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
Adafruit_MotorShield AFMSbot(0x61); // Rightmost jumper closed
Adafruit_MotorShield AFMStop(0x60); // Default address, no jumpers
@@ -30,7 +28,7 @@ void setup() {
AFMSbot.begin(); // Start the bottom shield
AFMStop.begin(); // Start the top shield
// turn on the DC motor
myMotor1->setSpeed(200);
myMotor1->run(RELEASE);
@@ -39,35 +37,35 @@ void setup() {
int i;
void loop() {
myMotor1->run(FORWARD);
for (i=0; i<255; i++) {
myMotor1->setSpeed(i);
myMotor1->setSpeed(i);
myStepper1->onestep(FORWARD, INTERLEAVE);
myStepper2->onestep(BACKWARD, DOUBLE);
myStepper3->onestep(FORWARD, MICROSTEP);
delay(3);
}
for (i=255; i!=0; i--) {
myMotor1->setSpeed(i);
myMotor1->setSpeed(i);
myStepper1->onestep(BACKWARD, INTERLEAVE);
myStepper2->onestep(FORWARD, DOUBLE);
myStepper3->onestep(BACKWARD, MICROSTEP);
delay(3);
}
myMotor1->run(BACKWARD);
for (i=0; i<255; i++) {
myMotor1->setSpeed(i);
myMotor1->setSpeed(i);
myStepper1->onestep(FORWARD, DOUBLE);
myStepper2->onestep(BACKWARD, INTERLEAVE);
myStepper3->onestep(FORWARD, MICROSTEP);
delay(3);
}
for (i=255; i!=0; i--) {
myMotor1->setSpeed(i);
myMotor1->setSpeed(i);
myStepper1->onestep(BACKWARD, DOUBLE);
myStepper2->onestep(FORWARD, INTERLEAVE);
myStepper3->onestep(BACKWARD, MICROSTEP);
@@ -1,21 +1,18 @@
/*
/*
This is a test sketch for the Adafruit assembled Motor Shield for Arduino v2
It won't work with v1.x motor shields! Only for the v2's with built in PWM
control
For use with the Adafruit Motor Shield v2
----> http://www.adafruit.com/products/1438
For use with the Adafruit Motor Shield v2
----> http://www.adafruit.com/products/1438
*/
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// Or, create it with a different I2C address (say for stacking)
// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61);
// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61);
// Connect a stepper motor with 200 steps per revolution (1.8 degree)
// to motor port #2 (M3 and M4)
@@ -24,28 +21,33 @@ Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);
void setup() {
Serial.begin(9600); // set up Serial library at 9600 bps
while (!Serial);
Serial.println("Stepper test!");
AFMS.begin(); // create with the default frequency 1.6KHz
//AFMS.begin(1000); // OR with a different frequency, say 1KHz
myMotor->setSpeed(10); // 10 rpm
if (!AFMS.begin()) { // create with the default frequency 1.6KHz
// if (!AFMS.begin(1000)) { // OR with a different frequency, say 1KHz
Serial.println("Could not find Motor Shield. Check wiring.");
while (1);
}
Serial.println("Motor Shield found.");
myMotor->setSpeed(10); // 10 rpm
}
void loop() {
Serial.println("Single coil steps");
myMotor->step(100, FORWARD, SINGLE);
myMotor->step(100, BACKWARD, SINGLE);
myMotor->step(100, FORWARD, SINGLE);
myMotor->step(100, BACKWARD, SINGLE);
Serial.println("Double coil steps");
myMotor->step(100, FORWARD, DOUBLE);
myMotor->step(100, FORWARD, DOUBLE);
myMotor->step(100, BACKWARD, DOUBLE);
Serial.println("Interleave coil steps");
myMotor->step(100, FORWARD, INTERLEAVE);
myMotor->step(100, BACKWARD, INTERLEAVE);
myMotor->step(100, FORWARD, INTERLEAVE);
myMotor->step(100, BACKWARD, INTERLEAVE);
Serial.println("Microstep steps");
myMotor->step(50, FORWARD, MICROSTEP);
myMotor->step(50, FORWARD, MICROSTEP);
myMotor->step(50, BACKWARD, MICROSTEP);
}
@@ -0,0 +1,121 @@
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include <Adafruit_SSD1306.h>
// Connect to the two encoder outputs!
#define ENCODER_A 12
#define ENCODER_B 11
// These let us convert ticks-to-RPM
#define GEARING 20
#define ENCODERMULT 12
// 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 *myMotor = AFMS.getMotor(1);
// We'll display the speed/direction on the OLED
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &Wire);
volatile float RPM = 0;
volatile uint32_t lastA = 0;
volatile bool motordir = FORWARD;
void interruptA() {
motordir = digitalRead(ENCODER_B);
digitalWrite(LED_BUILTIN, HIGH);
uint32_t currA = micros();
if (lastA < currA) {
// did not wrap around
float rev = currA - lastA; // us
rev = 1.0 / rev; // rev per us
rev *= 1000000; // rev per sec
rev *= 60; // rev per min
rev /= GEARING; // account for gear ratio
rev /= ENCODERMULT; // account for multiple ticks per rotation
RPM = rev;
}
lastA = currA;
digitalWrite(LED_BUILTIN, LOW);
}
void setup() {
Serial.begin(9600); // set up Serial library at 9600 bps
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
pinMode(ENCODER_B, INPUT_PULLUP);
pinMode(ENCODER_A, INPUT_PULLUP);
attachInterrupt(ENCODER_A, interruptA, RISING);
delay(100);
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
display.display();
display.setTextSize(2);
display.setTextColor(WHITE);
//while (!Serial) delay(1);
Serial.println("MMMMotor party!");
if (!AFMS.begin()) { // create with the default frequency 1.6KHz
// if (!AFMS.begin(1000)) { // OR with a different frequency, say 1KHz
Serial.println("Could not find Motor Shield. Check wiring.");
while (1);
}
Serial.println("Motor Shield found."); Serial.println("Begun");
// turn on motor M1
myMotor->setSpeed(0);
}
void printRPM() {
display.clearDisplay();
display.setCursor(0,0);
Serial.print("Direction: ");
if (motordir) {
display.println("Forward");
Serial.println("forward @ ");
} else {
display.println("Backward");
Serial.println("backward @ ");
}
display.print((int)RPM); display.println(" RPM");
Serial.print((int)RPM); Serial.println(" RPM");
display.display();
}
int i;
void loop() {
delay(50);
myMotor->run(FORWARD);
for (i=0; i<255; i++) {
myMotor->setSpeed(i);
delay(20);
printRPM();
}
for (i=255; i!=0; i--) {
myMotor->setSpeed(i);
delay(20);
printRPM();
}
myMotor->run(BACKWARD);
for (i=0; i<255; i++) {
myMotor->setSpeed(i);
delay(20);
printRPM();
}
for (i=255; i!=0; i--) {
myMotor->setSpeed(i);
delay(20);
printRPM();
}
}
@@ -1,5 +1,5 @@
name=Adafruit Motor Shield V2 Library
version=1.0.4
version=1.1.1
author=Adafruit
maintainer=Adafruit <info@adafruit.com>
sentence=Library for the Adafruit Motor Shield V2 for Arduino. It supports DC motors & stepper motors with microstepping as well as stacking-support.
@@ -7,3 +7,4 @@ paragraph=Library for the Adafruit Motor Shield V2 for Arduino. It supports DC m
category=Device Control
url=https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library
architectures=*
depends=Adafruit ILI9341, Adafruit GFX Library, Adafruit SSD1306, AccelStepper, Servo
@@ -16,98 +16,71 @@
****************************************************/
#include <Adafruit_MS_PWMServoDriver.h>
#include <Wire.h>
#if defined(ARDUINO_SAM_DUE)
#define WIRE Wire1
#else
#define WIRE Wire
#endif
Adafruit_MS_PWMServoDriver::Adafruit_MS_PWMServoDriver(uint8_t addr) {
_i2caddr = addr;
}
void Adafruit_MS_PWMServoDriver::begin(void) {
//Wire.begin(); called in ESPEasy framework
reset();
bool Adafruit_MS_PWMServoDriver::begin(TwoWire *theWire) {
if (i2c_dev)
delete i2c_dev;
i2c_dev = new Adafruit_I2CDevice(_i2caddr, theWire);
if (!i2c_dev->begin())
return false;
reset();
return true;
}
void Adafruit_MS_PWMServoDriver::reset(void) {
write8(PCA9685_MODE1, 0x0);
}
void Adafruit_MS_PWMServoDriver::reset(void) { write8(PCA9685_MODE1, 0x0); }
void Adafruit_MS_PWMServoDriver::setPWMFreq(float freq) {
//Serial.print("Attempting to set freq ");
//Serial.println(freq);
// Serial.print("Attempting to set freq ");
// Serial.println(freq);
freq *= 0.9f; // Correct for overshoot in the frequency setting (see issue #11).
freq *=
0.9; // Correct for overshoot in the frequency setting (see issue #11).
float prescaleval = 25000000;
prescaleval /= 4096;
prescaleval /= freq;
prescaleval -= 1;
//Serial.print("Estimated pre-scale: "); Serial.println(prescaleval);
uint8_t prescale = floor(prescaleval + 0.5f);
//Serial.print("Final pre-scale: "); Serial.println(prescale);
// Serial.print("Estimated pre-scale: "); Serial.println(prescaleval);
uint8_t prescale = floor(prescaleval + 0.5);
// Serial.print("Final pre-scale: "); Serial.println(prescale);
uint8_t oldmode = read8(PCA9685_MODE1);
uint8_t newmode = (oldmode&0x7F) | 0x10; // sleep
write8(PCA9685_MODE1, newmode); // go to sleep
write8(PCA9685_PRESCALE, prescale); // set the prescaler
uint8_t newmode = (oldmode & 0x7F) | 0x10; // sleep
write8(PCA9685_MODE1, newmode); // go to sleep
write8(PCA9685_PRESCALE, prescale); // set the prescaler
write8(PCA9685_MODE1, oldmode);
delay(5);
write8(PCA9685_MODE1, oldmode | 0xa1); // This sets the MODE1 register to turn on auto increment.
// This is why the beginTransmission below was not working.
write8(PCA9685_MODE1,
oldmode |
0xa1); // This sets the MODE1 register to turn on auto increment.
// This is why the beginTransmission below was not working.
// Serial.print("Mode now 0x"); Serial.println(read8(PCA9685_MODE1), HEX);
}
void Adafruit_MS_PWMServoDriver::setPWM(uint8_t num, uint16_t on, uint16_t off) {
//Serial.print("Setting PWM "); Serial.print(num); Serial.print(": "); Serial.print(on); Serial.print("->"); Serial.println(off);
WIRE.beginTransmission(_i2caddr);
#if ARDUINO >= 100
WIRE.write(LED0_ON_L+4*num);
WIRE.write(on);
WIRE.write(on>>8);
WIRE.write(off);
WIRE.write(off>>8);
#else
WIRE.send(LED0_ON_L+4*num);
WIRE.send((uint8_t)on);
WIRE.send((uint8_t)(on>>8));
WIRE.send((uint8_t)off);
WIRE.send((uint8_t)(off>>8));
#endif
WIRE.endTransmission();
void Adafruit_MS_PWMServoDriver::setPWM(uint8_t num, uint16_t on,
uint16_t off) {
// Serial.print("Setting PWM "); Serial.print(num); Serial.print(": ");
// Serial.print(on); Serial.print("->"); Serial.println(off);
uint8_t buffer[5];
buffer[0] = LED0_ON_L + 4 * num;
buffer[1] = on;
buffer[2] = on >> 8;
buffer[3] = off;
buffer[4] = off >> 8;
i2c_dev->write(buffer, 5);
}
uint8_t Adafruit_MS_PWMServoDriver::read8(uint8_t addr) {
WIRE.beginTransmission(_i2caddr);
#if ARDUINO >= 100
WIRE.write(addr);
#else
WIRE.send(addr);
#endif
WIRE.endTransmission();
WIRE.requestFrom((uint8_t)_i2caddr, (uint8_t)1);
#if ARDUINO >= 100
return WIRE.read();
#else
return WIRE.receive();
#endif
uint8_t buffer[1] = {addr};
i2c_dev->write_then_read(buffer, 1, buffer, 1);
return buffer[0];
}
void Adafruit_MS_PWMServoDriver::write8(uint8_t addr, uint8_t d) {
WIRE.beginTransmission(_i2caddr);
#if ARDUINO >= 100
WIRE.write(addr);
WIRE.write(d);
#else
WIRE.send(addr);
WIRE.send(d);
#endif
WIRE.endTransmission();
uint8_t buffer[2] = {addr, d};
i2c_dev->write(buffer, 2);
}
@@ -1,17 +1,17 @@
/***************************************************
/***************************************************
This is a library for our Adafruit 16-channel PWM & Servo driver
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/products/815
These displays use I2C to communicate, 2 pins are required to
These displays use I2C to communicate, 2 pins are required to
interface. For Arduino UNOs, thats SCL -> Analog 5, SDA -> Analog 4
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
@@ -19,11 +19,12 @@
#define _Adafruit_MS_PWMServoDriver_H
#if ARDUINO >= 100
#include "Arduino.h"
#include "Arduino.h"
#else
#include "WProgram.h"
#include "WProgram.h"
#endif
#include <Adafruit_I2CDevice.h>
#define PCA9685_SUBADR1 0x2
#define PCA9685_SUBADR2 0x3
@@ -42,17 +43,17 @@
#define ALLLED_OFF_L 0xFC
#define ALLLED_OFF_H 0xFD
class Adafruit_MS_PWMServoDriver {
public:
public:
Adafruit_MS_PWMServoDriver(uint8_t addr = 0x40);
void begin(void);
bool begin(TwoWire *theWire = &Wire);
void reset(void);
void setPWMFreq(float freq);
void setPWM(uint8_t num, uint16_t on, uint16_t off);
private:
private:
uint8_t _i2caddr;
Adafruit_I2CDevice *i2c_dev = NULL; ///< Pointer to I2C bus interface
uint8_t read8(uint8_t addr);
void write8(uint8_t addr, uint8_t d);