Skip to content

Commit

Permalink
Version 2.3.3 - Added compile option `ENABLE_MICROS_AS_DEGREE_PARAMET…
Browse files Browse the repository at this point in the history
…ER` to allow usage of microseconds instead of degree as function arguments for all functions using degrees as argument.
  • Loading branch information
ArminJo committed Nov 30, 2020
1 parent 9a63d04 commit c7098d4
Show file tree
Hide file tree
Showing 12 changed files with 76 additions and 35 deletions.
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ For instructions how to enable these alternatives see [Compile options / macros]
- **Reverse operation** of servo is possible eg. if it is mounted head down.
- Allow to specify an arbitrary mapping between degrees and microseconds by `attach(int aPin, int aMicrosecondsForServoLowDegree, int aMicrosecondsForServoHighDegree, int aServoLowDegree, int aServoHighDegree)`.
- **Servo speed** can be specified in **degree per second** or **milliseconds** for the complete move.
- All degree values >= 400 are taken as microsecond values for the servo pulse.

## [API](https://github.com/ArminJo/ServoEasing/blob/master/src/ServoEasing.h#L328)

Expand Down Expand Up @@ -80,9 +81,11 @@ Modify it by commenting them out or in, or change the values if applicable. Or d
| `USE_SERVO_LIB` | disabled | ServoEasing.h | Use of PCA9685 normally disables use of regular servo library. You can force using of regular servo library by defining `USE_SERVO_LIB`. See below. |
| `PROVIDE_ONLY_LINEAR_MOVEMENT` | disabled | ServoEasing.h | Saves up to 1540 bytes FLASH. |
| `DISABLE_COMPLEX_FUNCTIONS` | disabled | ServoEasing.h | Disables the SINE, CIRCULAR, BACK, ELASTIC and BOUNCE easings. Saves up to 1850 bytes FLASH. |
| `ENABLE_MICROS_AS_DEGREE_PARAMETER` | disabled | ServoEasing.h | Enables passing also microsecond values as (target angle) parameter (see OneServo example). This requires additional 128 Bytes FLASH. |
| `PRINT_FOR_SERIAL_PLOTTER` | disabled | ServoEasing.h | Generate serial output for Arduino Plotter. |
| `USE_LEIGHTWEIGHT_SERVO_LIB` | disabled | ServoEasing.h | Makes the servo pulse generating immune to other libraries blocking interrupts for a longer time like SoftwareSerial, Adafruit_NeoPixel and DmxSimple. See below. Saves up to 742 bytes FLASH and 42 bytes RAM. |


# Modifying compile options
### Modifying compile options with Arduino IDE
First use *Sketch/Show Sketch Folder (Ctrl+K)*.<br/>
Expand Down Expand Up @@ -154,8 +157,8 @@ Control 8 servos to move a Quadruped robot.<br/>
The full example with IR remote control, NeoPixel and US distance sensor support is available [here](https://github.com/ArminJo/QuadrupedControl).
Only for AVR, because it uses EEPROM.

### YouTube Video
[![mePed V2 in actions](https://i.ytimg.com/vi/MsIjTRRUyGU/hqdefault.jpg)](https://youtu.be/MsIjTRRUyGU )
### YouTube Videos
[![mePed V2 in actions](https://i.ytimg.com/vi/MsIjTRRUyGU/hqdefault.jpg)](https://youtu.be/MsIjTRRUyGU)
[![Another implementation](https://i.ytimg.com/vi/CSodffeebyg/hqdefault.jpg)](https://youtu.be/CSodffeebyg)

## RobotArmControl example
Expand All @@ -177,6 +180,8 @@ You must comment out the line `#define USE_PCA9685_SERVO_EXPANDER` in *ServoEasi
### YouTube Video
[![Servos 16-19 and 28-31 in action](https://i.ytimg.com/vi/XMVh3IT5BgU/hqdefault.jpg)](https://youtu.be/XMVh3IT5BgU)

### mePed V2 with PCA9685 expander
![mePed V2 with PCA9685 expander](pictures/mePedWithPCA9685.jpg)

# Servo utilities

Expand Down Expand Up @@ -233,7 +238,7 @@ This will print internal information visible in the Arduino *Serial Monitor* whi

# Revision History
### Version 2.3.3 - work in progress
- DegreeToMicrosecondsOrUnits() does not convert values >= 400 in order to support Microseconds instead of degrees as function arguments.
- Added compile option `ENABLE_MICROS_AS_DEGREE_PARAMETER` to allow usage of microseconds instead of degree as function arguments for all functions using degrees as argument.
- Improved LightweightServo API.

### Version 2.3.2
Expand Down
1 change: 1 addition & 0 deletions examples/EndPositionsTest/ADCUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ uint16_t readADCChannelWithReferenceMultiSamples(uint8_t aChannelNumber, uint8_t

/*
* use ADC_PRESCALE16 which gives 13 us conversion time and good linearity
* @return the maximum of aNumberOfSamples measurements.
*/
uint16_t readADCChannelWithReferenceMax(uint8_t aChannelNumber, uint8_t aReference, uint16_t aNumberOfSamples) {
uint16_t tADCValue = 0;
Expand Down
8 changes: 7 additions & 1 deletion examples/OneServo/OneServo.ino
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,12 @@ void loop() {
#ifdef INFO
Serial.println(F("Move from 180 to 0 degree with 360 degree per second using interrupts"));
#endif
/*
* If you comment out the line
* #define ENABLE_MICROS_AS_DEGREE_PARAMETER
* in ServoEasing.h, you can specify the target angle directly as microseconds here
*/
// Servo1.startEaseTo(DEFAULT_MICROSECONDS_FOR_0_DEGREE, 360, true);
Servo1.startEaseTo(0, 360, true);
// Wait for 250 ms. The servo should have moved 90 degree.
delay(250);
Expand All @@ -162,7 +168,7 @@ void loop() {
*/
Servo1.stop();
#ifdef INFO
Serial.println(F("Stop for 1 second at 90 degree"));
Serial.println(F("Interrupt movement with stop() for 1 second at 90 degree"));
#endif
delay(1000);
// continue movement using interrupts
Expand Down
1 change: 1 addition & 0 deletions examples/QuadrupedControl/ADCUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ uint16_t readADCChannelWithReferenceMultiSamples(uint8_t aChannelNumber, uint8_t

/*
* use ADC_PRESCALE16 which gives 13 us conversion time and good linearity
* @return the maximum of aNumberOfSamples measurements.
*/
uint16_t readADCChannelWithReferenceMax(uint8_t aChannelNumber, uint8_t aReference, uint16_t aNumberOfSamples) {
uint16_t tADCValue = 0;
Expand Down
1 change: 1 addition & 0 deletions examples/RobotArmControl/ADCUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ uint16_t readADCChannelWithReferenceMultiSamples(uint8_t aChannelNumber, uint8_t

/*
* use ADC_PRESCALE16 which gives 13 us conversion time and good linearity
* @return the maximum of aNumberOfSamples measurements.
*/
uint16_t readADCChannelWithReferenceMax(uint8_t aChannelNumber, uint8_t aReference, uint16_t aNumberOfSamples) {
uint16_t tADCValue = 0;
Expand Down
50 changes: 26 additions & 24 deletions examples/RobotArmControl/EasyButtonAtInt01.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,29 +37,7 @@
#define VERSION_EASY_BUTTON "3.1.0"
#define VERSION_EASY_BUTTON_MAJOR 3
#define VERSION_EASY_BUTTON_MINOR 1

/*
* Version 3.1.0 - 6/2020
* - 2 sets of constructors, one for only one button used and one for the second button if two buttons used.
* - Map pin numbers for Digispark pro boards, for use with with digispark library.
*
* Version 3.0.0 - 5/2020
* - Added button release handler and adapted examples.
* - Revoke change for "only one true result per press for checkForLongPressBlocking()". It is superseded by button release handler.
* - Support buttons which are active high by defining BUTTON_IS_ACTIVE_HIGH.
* - Improved detection of maximum bouncing period used in DebounceTest.
*
* Version 2.1.0 - 5/2020
* - Avoid 1 ms delay for checkForLongPressBlocking() if button is not pressed.
* - Only one true result per press for checkForLongPressBlocking().
*
* Version 2.0.0 - 1/2020
* - Ported to ATtinyX5 and ATiny167.
* - Support also PinChangeInterrupt for button 1 on Pin PA0 to PA7 for ATtiniy87/167.
* - Long press detection support.
* - Double press detection support.
* - Renamed to EasyButtonAtInt01.cpp.h
*/
// The change log is at the bottom of the file

#if defined(__AVR__)
#include <Arduino.h>
Expand Down Expand Up @@ -318,7 +296,7 @@ class EasyButton {
void handleINT01Interrupts(); // internal use only

bool LastBounceWasChangeToInactive; // Internal state, reflects actual reading with spikes and bouncing. Negative logic: true / active means button pin is LOW
volatile bool ButtonStateIsActive; // Negative logic: true / active means button pin is LOW. If last press duration < BUTTON_DEBOUNCING_MILLIS it holds wrong value (true instead of false) :-(
volatile bool ButtonStateIsActive; // Negative logic: true / active means button pin is LOW. If last press duration < BUTTON_DEBOUNCING_MILLIS it holds wrong value (true instead of false) :-(
volatile bool ButtonToggleState; // Toggle is on press, not on release - initial value is false

/*
Expand Down Expand Up @@ -380,6 +358,30 @@ void __attribute__ ((weak)) handleINT1Interrupt();
#endif

#endif // defined(__AVR__)

/*
* Version 3.1.0 - 6/2020
* - 2 sets of constructors, one for only one button used and one for the second button if two buttons used.
* - Map pin numbers for Digispark pro boards, for use with with digispark library.
*
* Version 3.0.0 - 5/2020
* - Added button release handler and adapted examples.
* - Revoke change for "only one true result per press for checkForLongPressBlocking()". It is superseded by button release handler.
* - Support buttons which are active high by defining BUTTON_IS_ACTIVE_HIGH.
* - Improved detection of maximum bouncing period used in DebounceTest.
*
* Version 2.1.0 - 5/2020
* - Avoid 1 ms delay for checkForLongPressBlocking() if button is not pressed.
* - Only one true result per press for checkForLongPressBlocking().
*
* Version 2.0.0 - 1/2020
* - Ported to ATtinyX5 and ATiny167.
* - Support also PinChangeInterrupt for button 1 on Pin PA0 to PA7 for ATtiniy87/167.
* - Long press detection support.
* - Double press detection support.
* - Renamed to EasyButtonAtInt01.cpp.h
*/

#endif /* EASY_BUTTON_AT_INT01_H_ */

#pragma once
1 change: 1 addition & 0 deletions examples/SpeedTest/ADCUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ uint16_t readADCChannelWithReferenceMultiSamples(uint8_t aChannelNumber, uint8_t

/*
* use ADC_PRESCALE16 which gives 13 us conversion time and good linearity
* @return the maximum of aNumberOfSamples measurements.
*/
uint16_t readADCChannelWithReferenceMax(uint8_t aChannelNumber, uint8_t aReference, uint16_t aNumberOfSamples) {
uint16_t tADCValue = 0;
Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"type": "git",
"url": "https://github.com/ArminJo/ServoEasing"
},
"version": "2.3.2",
"version": "2.3.3",
"exclude": "pictures",
"authors": {
"name": "Armin Joachimsmeyer",
Expand Down
4 changes: 2 additions & 2 deletions library.properties
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name=ServoEasing
version=2.3.2
version=2.3.3
author=Armin Joachimsmeyer
maintainer=Armin Joachimsmeyer <[email protected]>
sentence=Enables smooth servo movement. <br/>Linear as well as other (Cubic, Circular, Bounce, etc.) ease movements for servos are provided. The Arduino Servo library or PCA9685 servo expanders are supported.<br/>
paragraph=Just use <b>myServo.easeTo()</b> instead of <b>myServo.write()</b> and you have smooth servo movement.<br/><b>Non blocking</b> movement for all servos attached to the Arduino Servo library is implemented by reusing the interrupts of the Arduino servo timer.<br/><b>All servos can move synchronized.</b><br/><br/>Includes the following <b>easing functions</b>:<ul><li><b>Linear</b>, <b>Quadratic</b>, <b>Cubic</b> and <b>Quartic</b></li><li><b>Sine</b>, <b>Circular</b>, <b>Back</b>, <b>Elastic</b> and <b>Bounce</b></li><li><b>User defined</b></li></ul>Each function supports the <b>easing types</b> <b>In</b>, <b>Out</b>, <b>InOut</b> and <b>BouncingOutIn</b><br/>Trim and reverse operations are supported as well as continuous rotating servos.<br/><br/><b>New: </b>.<br/>
paragraph=Just use <b>myServo.easeTo()</b> instead of <b>myServo.write()</b> and you have smooth servo movement.<br/><b>Non blocking</b> movement for all servos attached to the Arduino Servo library is implemented by reusing the interrupts of the Arduino servo timer.<br/><b>All servos can move synchronized.</b><br/><br/>Includes the following <b>easing functions</b>:<ul><li><b>Linear</b>, <b>Quadratic</b>, <b>Cubic</b> and <b>Quartic</b></li><li><b>Sine</b>, <b>Circular</b>, <b>Back</b>, <b>Elastic</b> and <b>Bounce</b></li><li><b>User defined</b></li></ul>Each function supports the <b>easing types</b> <b>In</b>, <b>Out</b>, <b>InOut</b> and <b>BouncingOutIn</b><br/>Trim and reverse operations are supported as well as continuous rotating servos.<br/><br/><b>New: Improved LightweightServo API, added compile option ENABLE_MICROS_AS_DEGREE_PARAMETER.</b>.<br/>
category=Device Control
url=https://github.com/ArminJo/ServoEasing
architectures=avr,megaavr,sam,samd,esp8266,esp32,stm32,STM32F1,apollo3
Binary file added pictures/mePedWithPCA9685.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 21 additions & 3 deletions src/ServoEasing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -478,8 +478,10 @@ void ServoEasing::write(int aValue) {
#endif
return;
}
if (aValue < 400) { // treat values less than 400 as angles in degrees (valid values in microseconds are handled as microseconds)
sServoNextPositionArray[mServoIndex] = aValue;
sServoNextPositionArray[mServoIndex] = aValue;

if (aValue < THRESHOLD_VALUE_FOR_INTERPRETING_VALUE_AS_MICROSECONDS) {
// treat values less than 400 as angles in degrees, others are handled as microseconds
aValue = DegreeToMicrosecondsOrUnits(aValue);
}
writeMicrosecondsOrUnits(aValue);
Expand Down Expand Up @@ -592,14 +594,20 @@ int ServoEasing::MicrosecondsOrUnitsToDegree(int aMicrosecondsOrUnits) {

/**
* We have around 10 µs per degree
* We do not convert values >= 400.
* This allows it to use Microseconds instead of degrees as function arguments for all functions using degree as argument.
*/
int ServoEasing::DegreeToMicrosecondsOrUnits(int aDegree) {
// For microseconds and PCA9685 units:
#if defined ENABLE_MICROS_AS_DEGREE_PARAMETER
if (aDegree < 400) {
return map(aDegree, 0, 180, mServo0DegreeMicrosecondsOrUnits, mServo180DegreeMicrosecondsOrUnits);
#endif
return map(aDegree, 0, 180, mServo0DegreeMicrosecondsOrUnits, mServo180DegreeMicrosecondsOrUnits);
#if defined ENABLE_MICROS_AS_DEGREE_PARAMETER
} else {
return aDegree;
}
#endif
}

/**
Expand Down Expand Up @@ -681,7 +689,17 @@ bool ServoEasing::startEaseTo(int aDegree, uint_fast16_t aDegreesPerSecond, bool
#endif
aDegreesPerSecond = 1;
}

#if defined ENABLE_MICROS_AS_DEGREE_PARAMETER
uint_fast16_t tMillisForCompleteMove;
int tDegree = aDegree;
if (aDegree >= THRESHOLD_VALUE_FOR_INTERPRETING_VALUE_AS_MICROSECONDS) {
tDegree = MicrosecondsOrUnitsToDegree(tDegree);
}
tMillisForCompleteMove = abs(tDegree - tCurrentAngle) * 1000L / aDegreesPerSecond;
#else
uint_fast16_t tMillisForCompleteMove = abs(aDegree - tCurrentAngle) * 1000L / aDegreesPerSecond;
#endif

#ifndef PROVIDE_ONLY_LINEAR_MOVEMENT
if ((mEasingType & CALL_STYLE_MASK) == CALL_STYLE_BOUNCING_OUT_IN) {
Expand Down
8 changes: 7 additions & 1 deletion src/ServoEasing.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,12 @@
#define TIMING_OUTPUT_PIN 12
#endif

/*
* If you require passing microsecond values as parameter instead of degree values. This requires additional 128 Bytes FLASH.
*/
//#define ENABLE_MICROS_AS_DEGREE_PARAMETER
#define THRESHOLD_VALUE_FOR_INTERPRETING_VALUE_AS_MICROSECONDS 400 // treat values less than 400 as angles in degrees, others are handled as microseconds

// Enable this to generate output for Arduino Serial Plotter (Ctrl-Shift-L)
//#define PRINT_FOR_SERIAL_PLOTTER

Expand Down Expand Up @@ -516,7 +522,7 @@ extern float (*sEaseFunctionArray[])(float aPercentageOfCompletion);

/*
* Version 2.3.3 - 11/2020
* - DegreeToMicrosecondsOrUnits() does not convert values >= 400 in order to support Microseconds instead of degrees as function arguments.
* - Added compile option `ENABLE_MICROS_AS_DEGREE_PARAMETER` to allow usage of microseconds instead of degree as function arguments for all functions using degrees as argument.
* - Improved LightweightServo API.
*
* Version 2.3.2 - 9/2020
Expand Down

0 comments on commit c7098d4

Please sign in to comment.