st-anything/lib/ST_Anything/EX_Servo.h

102 lines
5.4 KiB
C
Raw Permalink Normal View History

2023-03-11 14:11:03 +00:00
//******************************************************************************************
// File: EX_Servo.h
// Authors: Dan G Ogorchock
//
// Summary: EX_Servo is a class which implements the SmartThings/Hubitat "Switch Level" device capability.
// It inherits from the st::Executor class.
//
// Create an instance of this class in your sketch's global variable section
// For Example: st::EX_Servo executor1(F("servo1"), PIN_SERVO, 90, true, 1000, 0, 180, 2000, 544, 2400);
//
// st::EX_Servo() constructor requires the following arguments
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
// - byte pin_pwm - REQUIRED - the Arduino Pin to be used as a pwm output
// - int startingAngle - OPTIONAL - the value desired for the initial angle of the servo motor (0 to 180, defaults to 90)
// - bool detachAfterMove - OPTIONAL - determines if servo motor is powered down after move (defaults to false)
// - int servoDetachTime - OPTIONAL - determines how long after the servo is moved that the servo is powered down if detachAfterMove is true (defaults to 1000ms)
// - int minLevelAngle - OPTIONAL - servo angle in degrees to map to level 0 (defaults to 0 degrees)
// - int maxLevelAngle - OPTIONAL - servo angle in degrees to map to level 100 (defaults to 180 degrees)
// - int servoRate - OPTIONAL - initial servo rate in ms/degree (defaults to 2000, used to ensure a gentle move during startup, afterwards comes from SmartThings/Hubitat with each move request)
// - int minPulseWidth - OPTIONAL - minimum pulse width in milliseconds, defaults to 544 (see Arduino servo attach() function)
// - int maxPulseWidth - OPTIONAL - maximum pulse width in milliseconds, defaults to 2400 (see Arduino servo attach() function)
//
// Change History:
//
// Date Who What
// ---- --- ----
// 2018-06-23 Dan Ogorchock Original Creation
// 2018-06-24 Dan Ogorchock Since ESP32 does not support SERVO library, exclude all code to prevent compiler error
// 2018-08-19 Dan Ogorchock Added feature to optionally allow servo to be powered down after a move
// 2019-02-02 Jeff Albers Added Parameters to map servo endpoints, actively control rate of servo motion via duration input to device driver, intializes to level instead of angle
// 2019-02-09 Dan Ogorchock Adding Asynchronous Motion to eliminate blocking calls and to allow simultaneous motion across multiple servos
// 2019-03-04 Dan Ogorchock Added optional min and max pulse width parameters to allow servo specific adjustments
//
//
//******************************************************************************************
#ifndef ST_EX_SERVO
#define ST_EX_SERVO
#if not defined(ARDUINO_ARCH_ESP32)
#include "Executor.h"
#include <Servo.h>
namespace st
{
class EX_Servo: public Executor
{
private:
Servo m_Servo; //Servo object
byte m_nPinPWM; //Arduino Pin used as a PWM Output for the switch level capability
int m_nCurrentLevel; //Servo Level value from SmartThings/Hubitat (0 to 100%)
int m_nOldAngle; //starting angle for servo move
int m_nTargetAngle; //ending angle for servo move, value mapped to Servo Level (0 to 180 degrees maximum range)
int m_nCurrentAngle; //servo angle output while stepping from OldAngle to TargetAngle
long m_nCurrentRate; //Servo move Duration value from SmartThings/Hubitat (0 to 10000 milliseconds)
long m_nDetachTime; //Servo Detach Time in milliseconds
bool m_bDetachAfterMove; //Issue a servo.detach() after servo move is complete
int m_nMinLevelAngle; //Angle (0-180 degrees)to map to level 0
int m_nMaxLevelAngle; //Angle (0-180 degrees)to map to level 100
bool m_bMoveActive; //True if servo move is active (asynchronous motion)
bool m_bDetachTmrActive; //True if servo is waiting to power off
long m_nTimeStep; //Number of milliseconds per servo motor degree (i.e. rate of change for the servo)
long m_nPrevMillis; //Previous millis() value
int m_nMinPulseWidth; //Minimum Servo Pulse Width
int m_nMaxPulseWidth; //Maximum Servo Pulse Width
void writeAngleToPin(); //function to update the Arduino PWM Output Pin
public:
//constructor - called in your sketch's global variable declaration section
EX_Servo(const __FlashStringHelper *name, byte pinPWM, int startingAngle = 90, bool detachAfterMove = false, long servoDetachTime = 1000, int minLevelAngle = 0, int maxLevelAngle = 180, int servoRate = 2000, int minPulseWidth = 544, int maxPulseWidth = 2400);
//destructor
virtual ~EX_Servo();
//initialization routine
virtual void init();
//update function
void update();
//SmartThings Shield data handler (receives Level and Duration from ST/Hubitat)
virtual void beSmart(const String &str);
//called periodically to ensure state of the switch is up to date in the SmartThings Cloud / Hubitat Hub (in case an event is missed)
virtual void refresh();
//gets
virtual byte getPWMPin() const { return m_nPinPWM; }
virtual bool getAngle() const { return m_nTargetAngle; } //Angle of the Servo mapped to Level
virtual bool getLevel() const { return m_nCurrentLevel; } //Servo Level from ST/Hubitat
virtual bool getRate() const { return m_nCurrentRate; } //Duration from ST/Hubitat
//sets
virtual void setPWMPin(byte pin);
};
}
#endif
#endif