From 0bb017f561d64c4af6aeb4cf5bb351db4cc8b989 Mon Sep 17 00:00:00 2001 From: TD-er Date: Fri, 20 Oct 2023 18:25:46 +0200 Subject: [PATCH] [Lib Update] Update Adafruit Motor Shield V2 library to v1.1.1 --- .../.github/workflows/githubci.yml | 32 ++ .../Adafruit_MotorShield.cpp | 444 +++++++++++------- .../Adafruit_MotorShield.h | 75 +-- lib/Adafruit_Motor_Shield_V2/README.md | 51 +- .../Accel_ConstantSpeed.ino | 30 +- .../Accel_MultiStepper/Accel_MultiStepper.ino | 24 +- .../examples/DCMotorTest/DCMotorTest.ino | 32 +- .../examples/MotorParty/.esp32.test.skip | 0 .../examples/MotorParty/.metro_m4.test.skip | 0 .../examples/MotorParty/.nrf52840.test.skip | 0 .../examples/MotorParty/MotorParty.ino | 42 +- .../examples/StackingTest/StackingTest.ino | 26 +- .../examples/StepperTest/StepperTest.ino | 42 +- .../encoderMotorRPM/encoderMotorRPM.ino | 121 +++++ .../library.properties | 3 +- .../utility/Adafruit_MS_PWMServoDriver.cpp | 105 ++--- .../utility/Adafruit_MS_PWMServoDriver.h | 23 +- 17 files changed, 642 insertions(+), 408 deletions(-) create mode 100644 lib/Adafruit_Motor_Shield_V2/.github/workflows/githubci.yml create mode 100644 lib/Adafruit_Motor_Shield_V2/examples/MotorParty/.esp32.test.skip create mode 100644 lib/Adafruit_Motor_Shield_V2/examples/MotorParty/.metro_m4.test.skip create mode 100644 lib/Adafruit_Motor_Shield_V2/examples/MotorParty/.nrf52840.test.skip create mode 100644 lib/Adafruit_Motor_Shield_V2/examples/encoderMotorRPM/encoderMotorRPM.ino diff --git a/lib/Adafruit_Motor_Shield_V2/.github/workflows/githubci.yml b/lib/Adafruit_Motor_Shield_V2/.github/workflows/githubci.yml new file mode 100644 index 000000000..9257f0fa5 --- /dev/null +++ b/lib/Adafruit_Motor_Shield_V2/.github/workflows/githubci.yml @@ -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 diff --git a/lib/Adafruit_Motor_Shield_V2/Adafruit_MotorShield.cpp b/lib/Adafruit_Motor_Shield_V2/Adafruit_MotorShield.cpp index e98855711..4c88de33a 100644 --- a/lib/Adafruit_Motor_Shield_V2/Adafruit_MotorShield.cpp +++ b/lib/Adafruit_Motor_Shield_V2/Adafruit_MotorShield.cpp @@ -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 #include "Adafruit_MotorShield.h" +#include "Arduino.h" #include -#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); } diff --git a/lib/Adafruit_Motor_Shield_V2/Adafruit_MotorShield.h b/lib/Adafruit_Motor_Shield_V2/Adafruit_MotorShield.h index 48d03328d..5fd149975 100644 --- a/lib/Adafruit_Motor_Shield_V2/Adafruit_MotorShield.h +++ b/lib/Adafruit_Motor_Shield_V2/Adafruit_MotorShield.h @@ -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 -#include #include "utility/Adafruit_MS_PWMServoDriver.h" +#include //#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 diff --git a/lib/Adafruit_Motor_Shield_V2/README.md b/lib/Adafruit_Motor_Shield_V2/README.md index 20b99aaab..a0ce1479a 100644 --- a/lib/Adafruit_Motor_Shield_V2/README.md +++ b/lib/Adafruit_Motor_Shield_V2/README.md @@ -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! + -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! - +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 - - - - 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. diff --git a/lib/Adafruit_Motor_Shield_V2/examples/Accel_ConstantSpeed/Accel_ConstantSpeed.ino b/lib/Adafruit_Motor_Shield_V2/examples/Accel_ConstantSpeed/Accel_ConstantSpeed.ino index 7b2aa940b..fcc40ed74 100644 --- a/lib/Adafruit_Motor_Shield_V2/examples/Accel_ConstantSpeed/Accel_ConstantSpeed.ino +++ b/lib/Adafruit_Motor_Shield_V2/examples/Accel_ConstantSpeed/Accel_ConstantSpeed.ino @@ -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 -#include #include -#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(); } diff --git a/lib/Adafruit_Motor_Shield_V2/examples/Accel_MultiStepper/Accel_MultiStepper.ino b/lib/Adafruit_Motor_Shield_V2/examples/Accel_MultiStepper/Accel_MultiStepper.ino index 62052bf64..6d7379b37 100644 --- a/lib/Adafruit_Motor_Shield_V2/examples/Accel_MultiStepper/Accel_MultiStepper.ino +++ b/lib/Adafruit_Motor_Shield_V2/examples/Accel_MultiStepper/Accel_MultiStepper.ino @@ -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 -#include #include -#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); diff --git a/lib/Adafruit_Motor_Shield_V2/examples/DCMotorTest/DCMotorTest.ino b/lib/Adafruit_Motor_Shield_V2/examples/DCMotorTest/DCMotorTest.ino index e1f055701..8f31a0a83 100644 --- a/lib/Adafruit_Motor_Shield_V2/examples/DCMotorTest/DCMotorTest.ino +++ b/lib/Adafruit_Motor_Shield_V2/examples/DCMotorTest/DCMotorTest.ino @@ -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 #include -#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); } diff --git a/lib/Adafruit_Motor_Shield_V2/examples/MotorParty/.esp32.test.skip b/lib/Adafruit_Motor_Shield_V2/examples/MotorParty/.esp32.test.skip new file mode 100644 index 000000000..e69de29bb diff --git a/lib/Adafruit_Motor_Shield_V2/examples/MotorParty/.metro_m4.test.skip b/lib/Adafruit_Motor_Shield_V2/examples/MotorParty/.metro_m4.test.skip new file mode 100644 index 000000000..e69de29bb diff --git a/lib/Adafruit_Motor_Shield_V2/examples/MotorParty/.nrf52840.test.skip b/lib/Adafruit_Motor_Shield_V2/examples/MotorParty/.nrf52840.test.skip new file mode 100644 index 000000000..e69de29bb diff --git a/lib/Adafruit_Motor_Shield_V2/examples/MotorParty/MotorParty.ino b/lib/Adafruit_Motor_Shield_V2/examples/MotorParty/MotorParty.ino index 6583cd71d..321098aea 100644 --- a/lib/Adafruit_Motor_Shield_V2/examples/MotorParty/MotorParty.ino +++ b/lib/Adafruit_Motor_Shield_V2/examples/MotorParty/MotorParty.ino @@ -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 +#include #include -#include "utility/Adafruit_MS_PWMServoDriver.h" -#include // 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); } diff --git a/lib/Adafruit_Motor_Shield_V2/examples/StackingTest/StackingTest.ino b/lib/Adafruit_Motor_Shield_V2/examples/StackingTest/StackingTest.ino index ace5af48c..cddf770f4 100644 --- a/lib/Adafruit_Motor_Shield_V2/examples/StackingTest/StackingTest.ino +++ b/lib/Adafruit_Motor_Shield_V2/examples/StackingTest/StackingTest.ino @@ -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 #include -#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); diff --git a/lib/Adafruit_Motor_Shield_V2/examples/StepperTest/StepperTest.ino b/lib/Adafruit_Motor_Shield_V2/examples/StepperTest/StepperTest.ino index da76ba872..4cea7cbfe 100644 --- a/lib/Adafruit_Motor_Shield_V2/examples/StepperTest/StepperTest.ino +++ b/lib/Adafruit_Motor_Shield_V2/examples/StepperTest/StepperTest.ino @@ -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 #include -#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); } \ No newline at end of file diff --git a/lib/Adafruit_Motor_Shield_V2/examples/encoderMotorRPM/encoderMotorRPM.ino b/lib/Adafruit_Motor_Shield_V2/examples/encoderMotorRPM/encoderMotorRPM.ino new file mode 100644 index 000000000..ccad893c5 --- /dev/null +++ b/lib/Adafruit_Motor_Shield_V2/examples/encoderMotorRPM/encoderMotorRPM.ino @@ -0,0 +1,121 @@ +#include +#include +#include + +// 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(); + } +} diff --git a/lib/Adafruit_Motor_Shield_V2/library.properties b/lib/Adafruit_Motor_Shield_V2/library.properties index ca5970f74..5e1171a73 100644 --- a/lib/Adafruit_Motor_Shield_V2/library.properties +++ b/lib/Adafruit_Motor_Shield_V2/library.properties @@ -1,5 +1,5 @@ name=Adafruit Motor Shield V2 Library -version=1.0.4 +version=1.1.1 author=Adafruit maintainer=Adafruit 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 diff --git a/lib/Adafruit_Motor_Shield_V2/utility/Adafruit_MS_PWMServoDriver.cpp b/lib/Adafruit_Motor_Shield_V2/utility/Adafruit_MS_PWMServoDriver.cpp index 4f94f48fb..9f7b44a31 100644 --- a/lib/Adafruit_Motor_Shield_V2/utility/Adafruit_MS_PWMServoDriver.cpp +++ b/lib/Adafruit_Motor_Shield_V2/utility/Adafruit_MS_PWMServoDriver.cpp @@ -16,98 +16,71 @@ ****************************************************/ #include -#include -#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); } diff --git a/lib/Adafruit_Motor_Shield_V2/utility/Adafruit_MS_PWMServoDriver.h b/lib/Adafruit_Motor_Shield_V2/utility/Adafruit_MS_PWMServoDriver.h index 359e8e1f0..3345f305f 100644 --- a/lib/Adafruit_Motor_Shield_V2/utility/Adafruit_MS_PWMServoDriver.h +++ b/lib/Adafruit_Motor_Shield_V2/utility/Adafruit_MS_PWMServoDriver.h @@ -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 #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);