#include <Arduino.h>
// Must specify this before the include of "ServoEasing.hpp"
#define USE_PCA9685_SERVO_EXPANDER // Activating this enables the use of the PCA9685 I2C expander chip/board.
//#define PCA9685_ACTUAL_CLOCK_FREQUENCY 26000000L // Change it, if your PCA9685 has another than the default 25 MHz internal clock.
//#define USE_SOFT_I2C_MASTER // Saves 1756 bytes program memory and 218 bytes RAM compared with Arduino Wire
//#define USE_SERVO_LIB // If USE_PCA9685_SERVO_EXPANDER is defined, Activating this enables force additional using of regular servo library.
//#define PROVIDE_ONLY_LINEAR_MOVEMENT // Activating this disables all but LINEAR movement. Saves up to 1540 bytes program memory.
//#define DISABLE_COMPLEX_FUNCTIONS // Activating this disables the SINE, CIRCULAR, BACK, ELASTIC, BOUNCE and PRECISION easings. Saves up to 1850 bytes program memory.
#define MAX_EASING_SERVOS 16
//#define DISABLE_MICROS_AS_DEGREE_PARAMETER // Activating this disables microsecond values as (target angle) parameter. Saves 128 bytes program memory.
//#define DISABLE_MIN_AND_MAX_CONSTRAINTS // Activating this disables constraints. Saves 4 bytes RAM per servo but strangely enough no program memory.
//#define DISABLE_PAUSE_RESUME // Activating this disables pause and resume functions. Saves 5 bytes RAM per servo.
//#define DEBUG // Activating this enables generate lots of lovely debug output for this library.
//#define PRINT_FOR_SERIAL_PLOTTER // Activating this enables generate the Arduino plotter output from ServoEasing.hpp.
#include "ServoEasing.hpp"
#define SERVO1_PIN 5
#define SERVO2_PIN 18
#define SERVO3_PIN 19
#define SPEED_IN_PIN A0 // 36/VP
#define MODE_ANALOG_INPUT_PIN A3 // 39
#define PCA9685_DEFAULT_ADDRESS 0x40
#define SERVO_UNDER_TEST_PIN SERVO1_PIN
#define SPEED_OR_POSITION_ANALOG_INPUT_PIN SPEED_IN_PIN
#define POSITION_ANALOG_INPUT_PIN SPEED_IN_PIN
#include "robo-data.h"
/*
* Pin mapping table for different platforms - used by all examples
*
* Platform Servo1 Servo2 Servo3 Analog Core/Pin schema
* -------------------------------------------------------------------------------
* (Mega)AVR + SAMD 9 10 11 A0
* ATtiny3217 20|PA3 0|PA4 1|PA5 2|PA6 MegaTinyCore
* ESP8266 14|D5 12|D6 13|D7 0
* ESP32 5 18 19 A0
* BluePill PB7 PB8 PB9 PA0
* APOLLO3 11 12 13 A3
* RP2040 6|GPIO18 7|GPIO19 8|GPIO20
*/
//#define LOCAL_DEBUG
#define USE_ONLY_ONE_EXPANDER // Activating this enables reuse this example for one expander at PCA9685_DEFAULT_ADDRESS
#define FIRST_PCA9685_EXPANDER_ADDRESS PCA9685_DEFAULT_ADDRESS
#define NUMBER_OF_SERVOS MAX_EASING_SERVOS
void getAndAttach16ServosToPCA9685Expander(uint8_t aPCA9685I2CAddress);
void setup() {
Serial.begin(115200);
Serial.println(F("Example for a maximum of " STR(NUMBER_OF_SERVOS) " servos"));
Serial.println();
// Initialize wire before checkI2CConnection()
Wire.begin(); // Starts with 100 kHz. Clock will be increased at first attach() except for ESP32.
checkI2CConnection(FIRST_PCA9685_EXPANDER_ADDRESS, &Serial);
getAndAttach16ServosToPCA9685Expander(FIRST_PCA9685_EXPANDER_ADDRESS);
/**************************************************
* Set servos to start position.
* This is the position where the movement starts.
*************************************************/
//writeAllServos(0);
for (uint_fast8_t i = 0; i <= ServoEasing::sServoArrayMaxIndex; ++i) {
setupLimb(i);
}
// Wait for servos to reach start position.
delay(500);
}
//https://lastminuteengineers.com/esp32-websocket-tutorial/
void loop() {
Serial.print(F("Move all to 180 degree with 20 degree per second with "));
Serial.print((180 * (1000L / 20)) / (ServoEasing::sServoArrayMaxIndex + 1));
Serial.println(F(" ms delay"));
setSpeedForAllServos(20); // This speed is taken if no further speed argument is given.
for (uint_fast8_t i = 0; i <= ServoEasing::sServoArrayMaxIndex; ++i) {
handleLimb(i, 40);
/*
* Choose delay so that the last servo starts when the first is about to end
*/
// delay((180 * (1000L / 20)) / (ServoEasing::sServoArrayMaxIndex + 1));
}
delay(1000);
// Now move back
Serial.println(F("Move all back to 0 degree with 20 degree per second"));
for (uint_fast8_t i = 0; i <= ServoEasing::sServoArrayMaxIndex; ++i) {
handleLimb(i, 10);
/*
* Choose delay so that the last servo starts when the first is about to end
*/
// delay((180 * (1000L / 20)) / (ServoEasing::sServoArrayMaxIndex + 1));
}
delay(1000);
}
/*
* Get the 16 ServoEasing objects for the PCA9685 expander
* The attach() function inserts them in the ServoEasing::ServoEasingArray[] array.
*/
void getAndAttach16ServosToPCA9685Expander(uint8_t aPCA9685I2CAddress) {
ServoEasing *tServoEasingObjectPtr;
Serial.print(F("Get ServoEasing objects and attach servos to PCA9685 expander at address=0x"));
Serial.println(aPCA9685I2CAddress, HEX);
for (uint_fast8_t i = 0; i < PCA9685_MAX_CHANNELS; ++i) {
tServoEasingObjectPtr = new ServoEasing(aPCA9685I2CAddress);
if (tServoEasingObjectPtr->attach(i) == INVALID_SERVO) {
Serial.print(F("Address=0x"));
Serial.print(aPCA9685I2CAddress, HEX);
Serial.print(F(" i="));
Serial.print(i);
Serial.println(
F(
" Error attaching servo - maybe MAX_EASING_SERVOS=" STR(MAX_EASING_SERVOS) " is to small to hold all servos"));
}
}
}