diff --git a/Marlin/src/HAL/HAL_ESP32/HAL.h b/Marlin/src/HAL/HAL_ESP32/HAL.h index 4c831edf4f..9e4ab78a9a 100644 --- a/Marlin/src/HAL/HAL_ESP32/HAL.h +++ b/Marlin/src/HAL/HAL_ESP32/HAL.h @@ -75,6 +75,8 @@ extern portMUX_TYPE spinlock; typedef int16_t pin_t; +#define HAL_SERVO_LIB Servo + // -------------------------------------------------------------------------- // Public Variables // -------------------------------------------------------------------------- diff --git a/Marlin/src/HAL/HAL_ESP32/HAL_Servo_ESP32.cpp b/Marlin/src/HAL/HAL_ESP32/HAL_Servo_ESP32.cpp new file mode 100644 index 0000000000..bf3d228a6a --- /dev/null +++ b/Marlin/src/HAL/HAL_ESP32/HAL_Servo_ESP32.cpp @@ -0,0 +1,69 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#ifdef ARDUINO_ARCH_ESP32 + +#include "../../inc/MarlinConfig.h" + +#if HAS_SERVOS + +#include "HAL_Servo_ESP32.h" + +int Servo::channel_next_free = 0; + +Servo::Servo() { + this->channel = channel_next_free++; +} + +int8_t Servo::attach(const int pin) { + if (this->channel >= CHANNEL_MAX_NUM) return -1; + if (pin > 0) this->pin = pin; + + ledcSetup(this->channel, 50, 16); // channel X, 50 Hz, 16-bit depth + ledcAttachPin(this->pin, this->channel); + return true; +} + +void Servo::detach() { ledcDetachPin(this->pin) } + +int Servo::read() { return this->degrees; } + +void Servo::write(int degrees) { + this->degrees = constrain(degrees, MIN_ANGLE, MAX_ANGLE); + int us = map(this->degrees, MIN_ANGLE, MAX_ANGLE, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH); + int duty = map(us, 0, TAU_USEC, 0, MAX_COMPARE); + ledcWrite(channel, duty); +} + +void Servo::move(const int value) { + constexpr uint16_t servo_delay[] = SERVO_DELAY; + static_assert(COUNT(servo_delay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long."); + if (this->attach(0) >= 0) { + this->write(value); + safe_delay(servo_delay[this->channel]); + #if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE) + this->detach(); + #endif + } +} +#endif // HAS_SERVOS + +#endif // ARDUINO_ARCH_ESP32 diff --git a/Marlin/src/HAL/HAL_ESP32/HAL_Servo_ESP32.h b/Marlin/src/HAL/HAL_ESP32/HAL_Servo_ESP32.h new file mode 100644 index 0000000000..b6c250038e --- /dev/null +++ b/Marlin/src/HAL/HAL_ESP32/HAL_Servo_ESP32.h @@ -0,0 +1,49 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include + +class Servo { + static const int MIN_ANGLE = 0, + MAX_ANGLE = 180, + MIN_PULSE_WIDTH = 544, // Shortest pulse sent to a servo + MAX_PULSE_WIDTH = 2400, // Longest pulse sent to a servo + TAU_MSEC = 20, + TAU_USEC = (TAU_MSEC * 1000), + MAX_COMPARE = ((1 << 16) - 1), // 65535 + CHANNEL_MAX_NUM = 16; + +public: + Servo(); + int8_t attach(const int pin); // attach the given pin to the next free channel, set pinMode, return channel number (-1 on fail) + void detach(); + void write(int degrees); // set angle + void move(const int degrees); // attach the servo, then move to value + int read(); // returns current pulse width as an angle between 0 and 180 degrees + +private: + static int channel_next_free; + int channel; + int pin; + int degrees; +}; diff --git a/Marlin/src/HAL/shared/servo.cpp b/Marlin/src/HAL/shared/servo.cpp index ec25569f9d..684fc320a8 100644 --- a/Marlin/src/HAL/shared/servo.cpp +++ b/Marlin/src/HAL/shared/servo.cpp @@ -53,7 +53,7 @@ #include "../../inc/MarlinConfig.h" -#if HAS_SERVOS && !(IS_32BIT_TEENSY || defined(TARGET_LPC1768) || defined(STM32F1) || defined(STM32F1xx) || defined(STM32F4) || defined(STM32F4xx) || defined(STM32F7xx)) +#if HAS_SERVOS && !(IS_32BIT_TEENSY || defined(TARGET_LPC1768) || defined(STM32F1) || defined(STM32F1xx) || defined(STM32F4) || defined(STM32F4xx) || defined(STM32F7xx) || defined(ARDUINO_ARCH_ESP32)) #include "servo.h" #include "servo_private.h" diff --git a/Marlin/src/HAL/shared/servo.h b/Marlin/src/HAL/shared/servo.h index 1bcc200a54..dea3e20d51 100644 --- a/Marlin/src/HAL/shared/servo.h +++ b/Marlin/src/HAL/shared/servo.h @@ -80,6 +80,8 @@ #include "../HAL_STM32F4/HAL_Servo_STM32F4.h" #elif defined(ARDUINO_ARCH_STM32) #include "../HAL_STM32/HAL_Servo_STM32.h" +#elif defined(ARDUINO_ARCH_ESP32) + #include "../HAL_ESP32/HAL_Servo_ESP32.h" #else #include