From 3b9e57415e71424670904f3d9492c0dfb1cc5bab Mon Sep 17 00:00:00 2001 From: Roastlawyer <88754980+Roastlawyer@users.noreply.github.com> Date: Tue, 11 Apr 2023 23:59:32 -0600 Subject: [PATCH 1/6] Allow Driving FFB Servo's through PCA9685 Allow Driving FFB Servo's through PCA9685 Allows connecting and driving your FFB servo's through a PCA9685 I2C board instead of needing them directly connected to the ESP/Arduino, allowing you to control all your servo's using only two pins. I setup the PCA code to follow the input format of the ESP32Servo and Servo.h libraries, allowing the servo commands to be passed to the PCA without changes. Edit when squashing commits Cleanup of changes AdvancedConfig.h, & Lucidgloves-firmware.ino Remove unneeded include of "advancedConfig.h" in _main.ino Moved PCA9685 related defines in AdvancedConfig.h to only actually be defined if they where going to be accessed. Did the same for I2C in lucidgloves-firmware.ino as it is currently only used for this. Moves the PCA9685 initialization out of _main.ino and into the preexisting "setupServoHaptics" function in haptics.ino. This eliminated the need for any changes to _main.ino to implement PCA9685 support --- .../lucidgloves-firmware/AdvancedConfig.h | 10 ++++ .../lucidgloves-firmware/PCA9685Servo.hpp | 59 +++++++++++++++++++ firmware/lucidgloves-firmware/haptics.ino | 19 +++++- .../lucidgloves-firmware.ino | 13 +++- 4 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 firmware/lucidgloves-firmware/PCA9685Servo.hpp diff --git a/firmware/lucidgloves-firmware/AdvancedConfig.h b/firmware/lucidgloves-firmware/AdvancedConfig.h index 030e78b..935e73b 100644 --- a/firmware/lucidgloves-firmware/AdvancedConfig.h +++ b/firmware/lucidgloves-firmware/AdvancedConfig.h @@ -66,3 +66,13 @@ #if defined(ESP32) && ESP32_DUAL_CORE #define ESP32_DUAL_CORE_SET true #endif + + + +//Advanced options relating to I2C and the PCA9685 +#if ENABLE_PCA_9865_SERVO + #define PWM_Board_0_I2C_ADDRESS 0x40 //The I2C address of the PCA9685 Board. Default is 0x40 + #define PWM_Board_0_PWM_FREQUENCY 50 //set the PWM frequency the board uses. Default is 50hz (20ms Cycles) which is what most analogue servos use + #define ServoMin_uS 500 // Min microsecond pulse length, moves servo to 0* or fully retracted position. Value for sg90 and mg90s by default (ESP32Servo default is 500) + #define ServoMax_uS 2500 // Max microsecond pulse length, moves servo to 180* or whatever it's max rotation position is. Value for sg90 and mg90s by default (ESP32Servo default is 2500) +#endif diff --git a/firmware/lucidgloves-firmware/PCA9685Servo.hpp b/firmware/lucidgloves-firmware/PCA9685Servo.hpp new file mode 100644 index 0000000..c16acc0 --- /dev/null +++ b/firmware/lucidgloves-firmware/PCA9685Servo.hpp @@ -0,0 +1,59 @@ +#pragma once + +#include + +Adafruit_PWMServoDriver pwm_board_0 = Adafruit_PWMServoDriver(PWM_Board_0_I2C_ADDRESS, Wire); + + +int Initialize_PCA9685_Board() +{ + pwm_board_0.begin(); + pwm_board_0.setOscillatorFrequency(25000000); + pwm_board_0.setPWMFreq(PWM_Board_0_PWM_FREQUENCY); // Analog servos usually run at ~50 Hz updates + Serial.println("PCA9685 Board Initialized "); +} + + +#define MIN_PULSE_WIDTH ServoMin_uS //Sets the MIN_PULSE_WIDTH setting used by smooth stepping to your configured ServoMin (Default in esp32servo is 500) +#define MAX_PULSE_WIDTH ServoMax_uS //Sets the Max_PULSE_WIDTH setting used by smooth stepping to your configured ServoMax (Default in esp32servo is 2500) + +class Servo +{ +public: + Servo(); + int attach(int pin); // input to match servo.h & esp32servo.h format + void write(int value); // Write as an angle (converted into microsecond pulse below) + void writeMicroseconds(int value); // Write to servo directly as an "X" microsecond pulse + +private: + int minMicroSeconds = ServoMin_uS; // microsecond value to move servo to 0* or fully retracted position + int maxMicroSeconds = ServoMax_uS; // microsecond value to move servo to 180* or whatever it's max rotation position is + int driverChannel = 0; // driverboard channel connected to the servo +}; + + +Servo::Servo() //things break if this is gone +{} + +int Servo::attach(int pin) +{ + this->driverChannel = pin; +} + +void Servo::write(int value) +{ + { + if (value < 0) + value = 0; + else if (value > 180) + value = 180; + + value = map(value, 0, 180, this->minMicroSeconds, this->maxMicroSeconds); + } + this->writeMicroseconds(value); +} + +void Servo::writeMicroseconds(int value){ + pwm_board_0.writeMicroseconds(this->driverChannel, value); + //Serial.println("Servo called!"); +} diff --git a/firmware/lucidgloves-firmware/haptics.ino b/firmware/lucidgloves-firmware/haptics.ino index 5162272..27da066 100644 --- a/firmware/lucidgloves-firmware/haptics.ino +++ b/firmware/lucidgloves-firmware/haptics.ino @@ -1,9 +1,11 @@ #if USING_FORCE_FEEDBACK -#if defined(ESP32) - #include "ESP32Servo.h" +#if ENABLE_PCA_9865_SERVO + #include "PCA9685Servo.hpp" +#elif defined(ESP32) + #include #else - #include "Servo.h" + #include #endif Servo pinkyServo; @@ -12,7 +14,18 @@ Servo middleServo; Servo indexServo; Servo thumbServo; +struct { + void setup() { + Wire.begin(PIN_I2C_SDA, PIN_I2C_SCL); + Serial.println("I2C Initialized"); + } +} i2c; + void setupServoHaptics(){ + #if (ENABLE_PCA_9865_SERVO) + i2c.setup(); + Initialize_PCA9685_Board(); + #endif pinkyServo.attach(PIN_PINKY_MOTOR); ringServo.attach(PIN_RING_MOTOR); middleServo.attach(PIN_MIDDLE_MOTOR); diff --git a/firmware/lucidgloves-firmware/lucidgloves-firmware.ino b/firmware/lucidgloves-firmware/lucidgloves-firmware.ino index 8a1fa69..23cd503 100644 --- a/firmware/lucidgloves-firmware/lucidgloves-firmware.ino +++ b/firmware/lucidgloves-firmware/lucidgloves-firmware.ino @@ -77,7 +77,7 @@ #define PIN_PNCH_BTN 23 //unused if gesture set #define PIN_CALIB 32 //button for recalibration (You can set this to GPIO0 to use the BOOT button, but only when using Bluetooth.) #define DEBUG_LED 2 - #define PIN_PINKY_MOTOR 19 //used for force feedback + #define PIN_PINKY_MOTOR 19 //used for force feedback **alternatively this is which board channel you are plugged into on the PCA9685 servodriver board (accepted values 0-15 in that case)** #define PIN_RING_MOTOR 18 //^ #define PIN_MIDDLE_MOTOR 5 //^ #define PIN_INDEX_MOTOR 17 //^ @@ -160,3 +160,14 @@ #define PIN_INDEX_SECOND MUX(7) #define PIN_THUMB_SECOND MUX(9) #endif + + +//Drive FFB Servo's from a PCA9685 Board +// To use you must install the Adafruit PCA9685 PWM Servo Driver Library +// https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library + +#define ENABLE_PCA_9865_SERVO false +#if ENABLE_PCA_9865_SERVO + #define PIN_I2C_SDA 0 //Pin to use for the I2C SDA line connected to the PCA9685 + #define PIN_I2C_SCL 0 //Pin to use for the I2C SCL line connected to the PCA9685 +#endif From cfe87da39fd74b3075abf931876eff2bf591ff53 Mon Sep 17 00:00:00 2001 From: Roastlawyer <88754980+Roastlawyer@users.noreply.github.com> Date: Mon, 5 Jun 2023 05:44:36 -0600 Subject: [PATCH 2/6] Seperate I2C function from haptics.ino The function itself was moved into its own file for I2C to make it easier if someone else needs I2C support for other hardware in the future. Currently it's still called in the haptics.ino with the PCA9685 setup code as that is the only thing to use it. --- firmware/lucidgloves-firmware/I2C.h | 9 +++++++++ firmware/lucidgloves-firmware/haptics.ino | 11 +++-------- 2 files changed, 12 insertions(+), 8 deletions(-) create mode 100644 firmware/lucidgloves-firmware/I2C.h diff --git a/firmware/lucidgloves-firmware/I2C.h b/firmware/lucidgloves-firmware/I2C.h new file mode 100644 index 0000000..c112ef3 --- /dev/null +++ b/firmware/lucidgloves-firmware/I2C.h @@ -0,0 +1,9 @@ + #pragma once + #include "AdvancedConfig.h" + #include + + +void Setup_I2C() { + Wire.begin(PIN_I2C_SDA, PIN_I2C_SCL); + Serial.println("I2C Initialized"); +} diff --git a/firmware/lucidgloves-firmware/haptics.ino b/firmware/lucidgloves-firmware/haptics.ino index 27da066..4247744 100644 --- a/firmware/lucidgloves-firmware/haptics.ino +++ b/firmware/lucidgloves-firmware/haptics.ino @@ -1,6 +1,8 @@ #if USING_FORCE_FEEDBACK #if ENABLE_PCA_9865_SERVO + #pragma once + #include "I2C.h" #include "PCA9685Servo.hpp" #elif defined(ESP32) #include @@ -14,16 +16,9 @@ Servo middleServo; Servo indexServo; Servo thumbServo; -struct { - void setup() { - Wire.begin(PIN_I2C_SDA, PIN_I2C_SCL); - Serial.println("I2C Initialized"); - } -} i2c; - void setupServoHaptics(){ #if (ENABLE_PCA_9865_SERVO) - i2c.setup(); + Setup_I2C(); Initialize_PCA9685_Board(); #endif pinkyServo.attach(PIN_PINKY_MOTOR); From 42558220b3dc2b6083cdc7a03149fb4ddbaa9fb7 Mon Sep 17 00:00:00 2001 From: Roastlawyer <88754980+Roastlawyer@users.noreply.github.com> Date: Tue, 6 Jun 2023 22:03:10 -0600 Subject: [PATCH 3/6] Abstract servo code into classes Changes servo code to derive from a new abstract IServo class that can be easily expanded on to make addition of future servo library support easier. + minor cleanup of extra spaces and lines in I2C.h & PCA9685Servo.ino --- .../lucidgloves-firmware/AdvancedConfig.h | 2 +- firmware/lucidgloves-firmware/ConfigUtils.h | 4 +++ firmware/lucidgloves-firmware/I2C.h | 6 ++--- firmware/lucidgloves-firmware/IServo.ino | 9 +++++++ .../lucidgloves-firmware/PCA9685Servo.hpp | 1 - .../lucidgloves-firmware/ServoDirectGPIO.ino | 27 +++++++++++++++++++ .../lucidgloves-firmware/ServoPCA9685.ino | 27 +++++++++++++++++++ firmware/lucidgloves-firmware/haptics.ino | 25 ++++++++--------- .../lucidgloves-firmware.ino | 24 ++++++++--------- 9 files changed, 94 insertions(+), 31 deletions(-) create mode 100644 firmware/lucidgloves-firmware/IServo.ino create mode 100644 firmware/lucidgloves-firmware/ServoDirectGPIO.ino create mode 100644 firmware/lucidgloves-firmware/ServoPCA9685.ino diff --git a/firmware/lucidgloves-firmware/AdvancedConfig.h b/firmware/lucidgloves-firmware/AdvancedConfig.h index 935e73b..9c3b3c1 100644 --- a/firmware/lucidgloves-firmware/AdvancedConfig.h +++ b/firmware/lucidgloves-firmware/AdvancedConfig.h @@ -70,7 +70,7 @@ //Advanced options relating to I2C and the PCA9685 -#if ENABLE_PCA_9865_SERVO +#if SERVO_INTERFACE == SERVO_PCA9685 #define PWM_Board_0_I2C_ADDRESS 0x40 //The I2C address of the PCA9685 Board. Default is 0x40 #define PWM_Board_0_PWM_FREQUENCY 50 //set the PWM frequency the board uses. Default is 50hz (20ms Cycles) which is what most analogue servos use #define ServoMin_uS 500 // Min microsecond pulse length, moves servo to 0* or fully retracted position. Value for sg90 and mg90s by default (ESP32Servo default is 500) diff --git a/firmware/lucidgloves-firmware/ConfigUtils.h b/firmware/lucidgloves-firmware/ConfigUtils.h index c1305e6..cf9eafe 100644 --- a/firmware/lucidgloves-firmware/ConfigUtils.h +++ b/firmware/lucidgloves-firmware/ConfigUtils.h @@ -45,6 +45,10 @@ class ordered_lock { #define COMM_SERIAL 0 #define COMM_BTSERIAL 1 +//ServoInterface +#define SERVO_DIRECT 0 +#define SERVO_PCA9685 1 + //Encode #define ENCODE_LEGACY 0 #define ENCODE_ALPHA 1 diff --git a/firmware/lucidgloves-firmware/I2C.h b/firmware/lucidgloves-firmware/I2C.h index c112ef3..24ede82 100644 --- a/firmware/lucidgloves-firmware/I2C.h +++ b/firmware/lucidgloves-firmware/I2C.h @@ -1,6 +1,6 @@ - #pragma once - #include "AdvancedConfig.h" - #include +#pragma once +#include "AdvancedConfig.h" +#include void Setup_I2C() { diff --git a/firmware/lucidgloves-firmware/IServo.ino b/firmware/lucidgloves-firmware/IServo.ino new file mode 100644 index 0000000..8a7001c --- /dev/null +++ b/firmware/lucidgloves-firmware/IServo.ino @@ -0,0 +1,9 @@ +//Interface for Servo Connections + +class IServo { + + public: + virtual bool isReady() = 0; + + virtual void InitServoInterface() = 0; +}; diff --git a/firmware/lucidgloves-firmware/PCA9685Servo.hpp b/firmware/lucidgloves-firmware/PCA9685Servo.hpp index c16acc0..89b2eab 100644 --- a/firmware/lucidgloves-firmware/PCA9685Servo.hpp +++ b/firmware/lucidgloves-firmware/PCA9685Servo.hpp @@ -1,5 +1,4 @@ #pragma once - #include Adafruit_PWMServoDriver pwm_board_0 = Adafruit_PWMServoDriver(PWM_Board_0_I2C_ADDRESS, Wire); diff --git a/firmware/lucidgloves-firmware/ServoDirectGPIO.ino b/firmware/lucidgloves-firmware/ServoDirectGPIO.ino new file mode 100644 index 0000000..5c36d7b --- /dev/null +++ b/firmware/lucidgloves-firmware/ServoDirectGPIO.ino @@ -0,0 +1,27 @@ +//only compiles if needed +#if USING_FORCE_FEEDBACK && SERVO_INTERFACE == SERVO_DIRECT + #pragma once + #if defined(ESP32) + #include + #else + #include + #endif + +class DirectServoConnection : public IServo { + private: + bool m_isReady; + + public: + DirectServoConnection() { + m_isReady = false; + } + + bool isReady(){ + return m_isReady; + } + + void InitServoInterface(){ + m_isReady = true; + } +}; +#endif diff --git a/firmware/lucidgloves-firmware/ServoPCA9685.ino b/firmware/lucidgloves-firmware/ServoPCA9685.ino new file mode 100644 index 0000000..60cf4de --- /dev/null +++ b/firmware/lucidgloves-firmware/ServoPCA9685.ino @@ -0,0 +1,27 @@ +//only compiles if needed +#if USING_FORCE_FEEDBACK && SERVO_INTERFACE == SERVO_PCA9685 +#pragma once +#include "I2C.h" +#include "PCA9685Servo.hpp" + +class PCA9685ServoConnection : public IServo +{ + private: + bool m_isReady; + + public: + PCA9685ServoConnection() { + m_isReady = false; + } + + bool isReady(){ + return m_isReady; + } + + void InitServoInterface(){ + Setup_I2C(); + Initialize_PCA9685_Board(); + m_isReady = true; + } +}; +#endif diff --git a/firmware/lucidgloves-firmware/haptics.ino b/firmware/lucidgloves-firmware/haptics.ino index 4247744..c6be714 100644 --- a/firmware/lucidgloves-firmware/haptics.ino +++ b/firmware/lucidgloves-firmware/haptics.ino @@ -1,26 +1,23 @@ #if USING_FORCE_FEEDBACK -#if ENABLE_PCA_9865_SERVO - #pragma once - #include "I2C.h" - #include "PCA9685Servo.hpp" -#elif defined(ESP32) - #include -#else - #include -#endif - Servo pinkyServo; Servo ringServo; Servo middleServo; Servo indexServo; Servo thumbServo; +IServo* servoint; + void setupServoHaptics(){ - #if (ENABLE_PCA_9865_SERVO) - Setup_I2C(); - Initialize_PCA9685_Board(); - #endif + + #if SERVO_INTERFACE == SERVO_DIRECT + servoint = new DirectServoConnection(); + #elif SERVO_INTERFACE == SERVO_PCA9685 + servoint = new PCA9685ServoConnection(); + #endif + + servoint->InitServoInterface(); //Calls the InitServoInterface() function. What that function does is determined by the defined servo interface + pinkyServo.attach(PIN_PINKY_MOTOR); ringServo.attach(PIN_RING_MOTOR); middleServo.attach(PIN_MIDDLE_MOTOR); diff --git a/firmware/lucidgloves-firmware/lucidgloves-firmware.ino b/firmware/lucidgloves-firmware/lucidgloves-firmware.ino index 23cd503..789b6a4 100644 --- a/firmware/lucidgloves-firmware/lucidgloves-firmware.ino +++ b/firmware/lucidgloves-firmware/lucidgloves-firmware.ino @@ -55,7 +55,18 @@ #define USING_CALIB_PIN true //When PIN_CALIB is shorted (or it's button pushed) it will reset calibration if this is on. +//servo Configuration #define USING_FORCE_FEEDBACK false //Force feedback haptics allow you to feel the solid objects you hold +#define SERVO_INTERFACE SERVO_DIRECT //How your servos are connected. Options are: SERVO_DIRECT (mcu gpio pins), SERVO_PCA9685 (through I2C PCA9685 board) + //servos through gpio Pins + + //servos through PCA9685 + // To use you must install the Adafruit PCA9685 PWM Servo Driver Library + // https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library + #if SERVO_INTERFACE == SERVO_PCA9685 + #define PIN_I2C_SDA -1 //Pin to use for the I2C SDA line connected to the PCA9685 + #define PIN_I2C_SCL -1 //Pin to use for the I2C SCL line connected to the PCA9685 + #endif #define FLIP_FORCE_FEEDBACK true #define SERVO_SCALING false //dynamic scaling of servo motors @@ -128,7 +139,7 @@ #define PIN_PNCH_BTN 12 //unused if gesture set #define PIN_CALIB 13 //button for recalibration #define DEBUG_LED LED_BUILTIN - #define PIN_PINKY_MOTOR 2 //used for force feedback + #define PIN_PINKY_MOTOR 2 //used for force feedback **alternatively this is which board channel you are plugged into on the PCA9685 servodriver board (accepted values 0-15 in that case)** #define PIN_RING_MOTOR 3 //^ #define PIN_MIDDLE_MOTOR 4 //^ #define PIN_INDEX_MOTOR 5 //^ @@ -160,14 +171,3 @@ #define PIN_INDEX_SECOND MUX(7) #define PIN_THUMB_SECOND MUX(9) #endif - - -//Drive FFB Servo's from a PCA9685 Board -// To use you must install the Adafruit PCA9685 PWM Servo Driver Library -// https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library - -#define ENABLE_PCA_9865_SERVO false -#if ENABLE_PCA_9865_SERVO - #define PIN_I2C_SDA 0 //Pin to use for the I2C SDA line connected to the PCA9685 - #define PIN_I2C_SCL 0 //Pin to use for the I2C SCL line connected to the PCA9685 -#endif From 774c82f95bfc7fe8bc5dc2ea960b758ebed9f0f3 Mon Sep 17 00:00:00 2001 From: Roastlawyer <88754980+Roastlawyer@users.noreply.github.com> Date: Wed, 7 Jun 2023 02:17:44 -0600 Subject: [PATCH 4/6] Separate PCA9685.hpp into a header & .cpp file Moves the function & method declarations out of PCA9685.hpp and into their own .cpp file. Code mostly by danwillm. Co-Authored-By: danwillm <39023874+danwillm@users.noreply.github.com> --- .../lucidgloves-firmware/PCA9685Servo.cpp | 32 +++++++++++++++ .../lucidgloves-firmware/PCA9685Servo.hpp | 41 +------------------ .../lucidgloves-firmware/ServoPCA9685.ino | 1 - 3 files changed, 34 insertions(+), 40 deletions(-) create mode 100644 firmware/lucidgloves-firmware/PCA9685Servo.cpp diff --git a/firmware/lucidgloves-firmware/PCA9685Servo.cpp b/firmware/lucidgloves-firmware/PCA9685Servo.cpp new file mode 100644 index 0000000..0cbf9f2 --- /dev/null +++ b/firmware/lucidgloves-firmware/PCA9685Servo.cpp @@ -0,0 +1,32 @@ +#pragma once +#include "PCA9685Servo.hpp" + +Servo::Servo() +{ + pwm_board_0.begin(); + pwm_board_0.setOscillatorFrequency(25000000); + pwm_board_0.setPWMFreq(PWM_Board_0_PWM_FREQUENCY); // Analog servos usually run at ~50 Hz updates + Serial.println("PCA9685 Board Initialized "); +} + +int Servo::attach(int pin) +{ + this->driverChannel = pin; +} + +void Servo::write(int value) +{ + { + if (value < 0) + value = 0; + else if (value > 180) + value = 180; + + value = map(value, 0, 180, this->minMicroSeconds, this->maxMicroSeconds); + } + this->writeMicroseconds(value); +} + +void Servo::writeMicroseconds(int value){ + pwm_board_0.writeMicroseconds(this->driverChannel, value); +} diff --git a/firmware/lucidgloves-firmware/PCA9685Servo.hpp b/firmware/lucidgloves-firmware/PCA9685Servo.hpp index 89b2eab..f200c91 100644 --- a/firmware/lucidgloves-firmware/PCA9685Servo.hpp +++ b/firmware/lucidgloves-firmware/PCA9685Servo.hpp @@ -1,17 +1,6 @@ #pragma once #include - -Adafruit_PWMServoDriver pwm_board_0 = Adafruit_PWMServoDriver(PWM_Board_0_I2C_ADDRESS, Wire); - - -int Initialize_PCA9685_Board() -{ - pwm_board_0.begin(); - pwm_board_0.setOscillatorFrequency(25000000); - pwm_board_0.setPWMFreq(PWM_Board_0_PWM_FREQUENCY); // Analog servos usually run at ~50 Hz updates - Serial.println("PCA9685 Board Initialized "); -} - +#include "AdvancedConfig.h" #define MIN_PULSE_WIDTH ServoMin_uS //Sets the MIN_PULSE_WIDTH setting used by smooth stepping to your configured ServoMin (Default in esp32servo is 500) #define MAX_PULSE_WIDTH ServoMax_uS //Sets the Max_PULSE_WIDTH setting used by smooth stepping to your configured ServoMax (Default in esp32servo is 2500) @@ -28,31 +17,5 @@ class Servo int minMicroSeconds = ServoMin_uS; // microsecond value to move servo to 0* or fully retracted position int maxMicroSeconds = ServoMax_uS; // microsecond value to move servo to 180* or whatever it's max rotation position is int driverChannel = 0; // driverboard channel connected to the servo + Adafruit_PWMServoDriver pwm_board_0; }; - - -Servo::Servo() //things break if this is gone -{} - -int Servo::attach(int pin) -{ - this->driverChannel = pin; -} - -void Servo::write(int value) -{ - { - if (value < 0) - value = 0; - else if (value > 180) - value = 180; - - value = map(value, 0, 180, this->minMicroSeconds, this->maxMicroSeconds); - } - this->writeMicroseconds(value); -} - -void Servo::writeMicroseconds(int value){ - pwm_board_0.writeMicroseconds(this->driverChannel, value); - //Serial.println("Servo called!"); -} diff --git a/firmware/lucidgloves-firmware/ServoPCA9685.ino b/firmware/lucidgloves-firmware/ServoPCA9685.ino index 60cf4de..eb34cab 100644 --- a/firmware/lucidgloves-firmware/ServoPCA9685.ino +++ b/firmware/lucidgloves-firmware/ServoPCA9685.ino @@ -20,7 +20,6 @@ class PCA9685ServoConnection : public IServo void InitServoInterface(){ Setup_I2C(); - Initialize_PCA9685_Board(); m_isReady = true; } }; From 082316e804d8d48c2e7b361d8938656783c73a58 Mon Sep 17 00:00:00 2001 From: Roastlawyer <88754980+Roastlawyer@users.noreply.github.com> Date: Fri, 9 Jun 2023 05:27:09 -0600 Subject: [PATCH 5/6] Seperate PCA initialization from constructor definition Servo::Servo() class The previous version of the PCA initialization code was being called before I2C was initialized, was being reran for each of the 5 servo objects, & wasn't acknowledging the configured I2C pins. This commit redoes it to be run as part of a subfunction within InitServoInterface() just as I2C initialization is. --- firmware/lucidgloves-firmware/PCA9685Servo.cpp | 8 +++++++- firmware/lucidgloves-firmware/PCA9685Servo.hpp | 3 ++- firmware/lucidgloves-firmware/ServoPCA9685.ino | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/firmware/lucidgloves-firmware/PCA9685Servo.cpp b/firmware/lucidgloves-firmware/PCA9685Servo.cpp index 0cbf9f2..5555d8d 100644 --- a/firmware/lucidgloves-firmware/PCA9685Servo.cpp +++ b/firmware/lucidgloves-firmware/PCA9685Servo.cpp @@ -1,7 +1,9 @@ #pragma once #include "PCA9685Servo.hpp" -Servo::Servo() +Adafruit_PWMServoDriver pwm_board_0 = Adafruit_PWMServoDriver(PWM_Board_0_I2C_ADDRESS, Wire); + +int Initialize_PCA9685_Board() { pwm_board_0.begin(); pwm_board_0.setOscillatorFrequency(25000000); @@ -9,6 +11,9 @@ Servo::Servo() Serial.println("PCA9685 Board Initialized "); } +Servo::Servo() +{} + int Servo::attach(int pin) { this->driverChannel = pin; @@ -29,4 +34,5 @@ void Servo::write(int value) void Servo::writeMicroseconds(int value){ pwm_board_0.writeMicroseconds(this->driverChannel, value); + //Serial.println("Servo called!"); } diff --git a/firmware/lucidgloves-firmware/PCA9685Servo.hpp b/firmware/lucidgloves-firmware/PCA9685Servo.hpp index f200c91..f05543c 100644 --- a/firmware/lucidgloves-firmware/PCA9685Servo.hpp +++ b/firmware/lucidgloves-firmware/PCA9685Servo.hpp @@ -2,6 +2,8 @@ #include #include "AdvancedConfig.h" +int Initialize_PCA9685_Board(); + #define MIN_PULSE_WIDTH ServoMin_uS //Sets the MIN_PULSE_WIDTH setting used by smooth stepping to your configured ServoMin (Default in esp32servo is 500) #define MAX_PULSE_WIDTH ServoMax_uS //Sets the Max_PULSE_WIDTH setting used by smooth stepping to your configured ServoMax (Default in esp32servo is 2500) @@ -17,5 +19,4 @@ class Servo int minMicroSeconds = ServoMin_uS; // microsecond value to move servo to 0* or fully retracted position int maxMicroSeconds = ServoMax_uS; // microsecond value to move servo to 180* or whatever it's max rotation position is int driverChannel = 0; // driverboard channel connected to the servo - Adafruit_PWMServoDriver pwm_board_0; }; diff --git a/firmware/lucidgloves-firmware/ServoPCA9685.ino b/firmware/lucidgloves-firmware/ServoPCA9685.ino index eb34cab..60cf4de 100644 --- a/firmware/lucidgloves-firmware/ServoPCA9685.ino +++ b/firmware/lucidgloves-firmware/ServoPCA9685.ino @@ -20,6 +20,7 @@ class PCA9685ServoConnection : public IServo void InitServoInterface(){ Setup_I2C(); + Initialize_PCA9685_Board(); m_isReady = true; } }; From f236671dac1252245489a7ed8f8a10674dd424b0 Mon Sep 17 00:00:00 2001 From: Roastlawyer <88754980+Roastlawyer@users.noreply.github.com> Date: Fri, 9 Jun 2023 19:03:29 -0600 Subject: [PATCH 6/6] Recombine PCA9685Servo.cpp & PCA9685Servo.hpp into a single .ino file Recombines PCA9685Servo.cpp & PCA9685Servo.hpp into a single .ino file so that #if statements can be used to prevent PCA code from being compiled & included when not actually using a PCA board. --- .../lucidgloves-firmware/PCA9685Servo.cpp | 38 ---------------- .../lucidgloves-firmware/ServoPCA9685.ino | 2 - .../{PCA9685Servo.hpp => _PCA9685Servo.ino} | 43 +++++++++++++++++-- 3 files changed, 39 insertions(+), 44 deletions(-) delete mode 100644 firmware/lucidgloves-firmware/PCA9685Servo.cpp rename firmware/lucidgloves-firmware/{PCA9685Servo.hpp => _PCA9685Servo.ino} (53%) diff --git a/firmware/lucidgloves-firmware/PCA9685Servo.cpp b/firmware/lucidgloves-firmware/PCA9685Servo.cpp deleted file mode 100644 index 5555d8d..0000000 --- a/firmware/lucidgloves-firmware/PCA9685Servo.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once -#include "PCA9685Servo.hpp" - -Adafruit_PWMServoDriver pwm_board_0 = Adafruit_PWMServoDriver(PWM_Board_0_I2C_ADDRESS, Wire); - -int Initialize_PCA9685_Board() -{ - pwm_board_0.begin(); - pwm_board_0.setOscillatorFrequency(25000000); - pwm_board_0.setPWMFreq(PWM_Board_0_PWM_FREQUENCY); // Analog servos usually run at ~50 Hz updates - Serial.println("PCA9685 Board Initialized "); -} - -Servo::Servo() -{} - -int Servo::attach(int pin) -{ - this->driverChannel = pin; -} - -void Servo::write(int value) -{ - { - if (value < 0) - value = 0; - else if (value > 180) - value = 180; - - value = map(value, 0, 180, this->minMicroSeconds, this->maxMicroSeconds); - } - this->writeMicroseconds(value); -} - -void Servo::writeMicroseconds(int value){ - pwm_board_0.writeMicroseconds(this->driverChannel, value); - //Serial.println("Servo called!"); -} diff --git a/firmware/lucidgloves-firmware/ServoPCA9685.ino b/firmware/lucidgloves-firmware/ServoPCA9685.ino index 60cf4de..1ed6fd5 100644 --- a/firmware/lucidgloves-firmware/ServoPCA9685.ino +++ b/firmware/lucidgloves-firmware/ServoPCA9685.ino @@ -1,8 +1,6 @@ //only compiles if needed #if USING_FORCE_FEEDBACK && SERVO_INTERFACE == SERVO_PCA9685 -#pragma once #include "I2C.h" -#include "PCA9685Servo.hpp" class PCA9685ServoConnection : public IServo { diff --git a/firmware/lucidgloves-firmware/PCA9685Servo.hpp b/firmware/lucidgloves-firmware/_PCA9685Servo.ino similarity index 53% rename from firmware/lucidgloves-firmware/PCA9685Servo.hpp rename to firmware/lucidgloves-firmware/_PCA9685Servo.ino index f05543c..69795ac 100644 --- a/firmware/lucidgloves-firmware/PCA9685Servo.hpp +++ b/firmware/lucidgloves-firmware/_PCA9685Servo.ino @@ -1,12 +1,20 @@ -#pragma once +//only compiles if needed +#if USING_FORCE_FEEDBACK && SERVO_INTERFACE == SERVO_PCA9685 #include -#include "AdvancedConfig.h" - -int Initialize_PCA9685_Board(); #define MIN_PULSE_WIDTH ServoMin_uS //Sets the MIN_PULSE_WIDTH setting used by smooth stepping to your configured ServoMin (Default in esp32servo is 500) #define MAX_PULSE_WIDTH ServoMax_uS //Sets the Max_PULSE_WIDTH setting used by smooth stepping to your configured ServoMax (Default in esp32servo is 2500) +Adafruit_PWMServoDriver pwm_board_0 = Adafruit_PWMServoDriver(PWM_Board_0_I2C_ADDRESS, Wire); + +int Initialize_PCA9685_Board() +{ + pwm_board_0.begin(); + pwm_board_0.setOscillatorFrequency(25000000); + pwm_board_0.setPWMFreq(PWM_Board_0_PWM_FREQUENCY); // Analog servos usually run at ~50 Hz updates + Serial.println("PCA9685 Board Initialized "); +} + class Servo { public: @@ -20,3 +28,30 @@ class Servo int maxMicroSeconds = ServoMax_uS; // microsecond value to move servo to 180* or whatever it's max rotation position is int driverChannel = 0; // driverboard channel connected to the servo }; + +Servo::Servo() +{} + +int Servo::attach(int pin) +{ + this->driverChannel = pin; +} + +void Servo::write(int value) +{ + { + if (value < 0) + value = 0; + else if (value > 180) + value = 180; + + value = map(value, 0, 180, this->minMicroSeconds, this->maxMicroSeconds); + } + this->writeMicroseconds(value); +} + +void Servo::writeMicroseconds(int value){ + pwm_board_0.writeMicroseconds(this->driverChannel, value); + //Serial.println("Servo called!"); +} +#endif