mirror of
https://github.com/arendst/Tasmota.git
synced 2025-04-25 07:17:16 +00:00
Merge pull request #16045 from stefanbode/patch-4
ESP32 enhancements to stepper shutter motor
This commit is contained in:
commit
bbcf9363e4
@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
@ -68,12 +67,19 @@ int32_t _analog_pin2chan(uint32_t pin) { // returns -1 if uallocated
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _analogWriteFreqRange(void) {
|
void _analogWriteFreqRange(uint8_t pin) {
|
||||||
_analogInit(); // make sure the mapping array is initialized
|
_analogInit(); // make sure the mapping array is initialized
|
||||||
for (uint32_t channel = 0; channel < MAX_PWMS; channel++) {
|
if (pin == 255) {
|
||||||
if (pwm_channel[channel] < 255) {
|
for (uint32_t channel = 0; channel < MAX_PWMS; channel++) {
|
||||||
ledcSetup(channel, pwm_frequency, pwm_bit_num);
|
if (pwm_channel[channel] < 255) {
|
||||||
}
|
ledcSetup(channel, pwm_frequency, pwm_bit_num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int32_t channel = _analog_pin2chan(pin);
|
||||||
|
if (channel >= 0) {
|
||||||
|
ledcSetup(channel, pwm_frequency, pwm_bit_num);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,12 +95,22 @@ uint32_t _analogGetResolution(uint32_t x) {
|
|||||||
|
|
||||||
void analogWriteRange(uint32_t range) {
|
void analogWriteRange(uint32_t range) {
|
||||||
pwm_bit_num = _analogGetResolution(range);
|
pwm_bit_num = _analogGetResolution(range);
|
||||||
_analogWriteFreqRange();
|
_analogWriteFreqRange(255);
|
||||||
|
}
|
||||||
|
|
||||||
|
void analogWriteRange(uint32_t range, uint8_t pin) {
|
||||||
|
pwm_bit_num = _analogGetResolution(range);
|
||||||
|
_analogWriteFreqRange(pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void analogWriteFreq(uint32_t freq) {
|
void analogWriteFreq(uint32_t freq) {
|
||||||
pwm_frequency = freq;
|
pwm_frequency = freq;
|
||||||
_analogWriteFreqRange();
|
_analogWriteFreqRange(255);
|
||||||
|
}
|
||||||
|
|
||||||
|
void analogWriteFreq(uint32_t freq, uint8_t pin) {
|
||||||
|
pwm_frequency = freq;
|
||||||
|
_analogWriteFreqRange(pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t analogAttach(uint32_t pin, bool output_invert) { // returns ledc channel used, or -1 if failed
|
int32_t analogAttach(uint32_t pin, bool output_invert) { // returns ledc channel used, or -1 if failed
|
||||||
@ -109,7 +125,7 @@ int32_t analogAttach(uint32_t pin, bool output_invert) { // returns ledc chan
|
|||||||
|
|
||||||
// ledcAttachPin(pin, channel); -- replicating here because we want the default duty
|
// ledcAttachPin(pin, channel); -- replicating here because we want the default duty
|
||||||
uint8_t group=(chan/8), channel=(chan%8), timer=((chan/2)%4);
|
uint8_t group=(chan/8), channel=(chan%8), timer=((chan/2)%4);
|
||||||
|
|
||||||
// AddLog(LOG_LEVEL_INFO, "PWM: ledc_channel pin=%i out_invert=%i", pin, output_invert);
|
// AddLog(LOG_LEVEL_INFO, "PWM: ledc_channel pin=%i out_invert=%i", pin, output_invert);
|
||||||
ledc_channel_config_t ledc_channel = {
|
ledc_channel_config_t ledc_channel = {
|
||||||
(int)pin, // gpio
|
(int)pin, // gpio
|
||||||
@ -123,7 +139,6 @@ int32_t analogAttach(uint32_t pin, bool output_invert) { // returns ledc chan
|
|||||||
};
|
};
|
||||||
ledc_channel_config(&ledc_channel);
|
ledc_channel_config(&ledc_channel);
|
||||||
|
|
||||||
|
|
||||||
ledcSetup(channel, pwm_frequency, pwm_bit_num);
|
ledcSetup(channel, pwm_frequency, pwm_bit_num);
|
||||||
// Serial.printf("PWM: New attach pin %d to channel %d\n", pin, channel);
|
// Serial.printf("PWM: New attach pin %d to channel %d\n", pin, channel);
|
||||||
return channel;
|
return channel;
|
||||||
@ -143,19 +158,18 @@ extern "C" void __wrap__Z11analogWritehi(uint8_t pin, int val) {
|
|||||||
/*
|
/*
|
||||||
The primary goal of this function is to add phase control to PWM ledc
|
The primary goal of this function is to add phase control to PWM ledc
|
||||||
functions.
|
functions.
|
||||||
|
|
||||||
Phase control allows to stress less the power supply of LED lights.
|
Phase control allows to stress less the power supply of LED lights.
|
||||||
By default all phases are starting at the same moment. This means
|
By default all phases are starting at the same moment. This means
|
||||||
the the power supply always takes a power hit at the start of each
|
the the power supply always takes a power hit at the start of each
|
||||||
new cycle, even if the average power is low.
|
new cycle, even if the average power is low.
|
||||||
|
Phase control is also of major importance for H-bridge where
|
||||||
Phase control is also of major importance for H-bridge where
|
|
||||||
both PWM lines should NEVER be active at the same time.
|
both PWM lines should NEVER be active at the same time.
|
||||||
|
|
||||||
Unfortunately Arduino Core does not allow any customization nor
|
Unfortunately Arduino Core does not allow any customization nor
|
||||||
extendibility for the ledc/analogWrite functions. We have therefore
|
extendibility for the ledc/analogWrite functions. We have therefore
|
||||||
no other choice than duplicating part of Arduino code.
|
no other choice than duplicating part of Arduino code.
|
||||||
|
|
||||||
WARNING: this means it can easily break if ever Arduino internal
|
WARNING: this means it can easily break if ever Arduino internal
|
||||||
implementation changes.
|
implementation changes.
|
||||||
*/
|
*/
|
||||||
|
@ -26,7 +26,9 @@
|
|||||||
|
|
||||||
// input range is in full range, ledc needs bits
|
// input range is in full range, ledc needs bits
|
||||||
void analogWriteRange(uint32_t range);
|
void analogWriteRange(uint32_t range);
|
||||||
|
void analogWriteRange(uint32_t range, uint8_t pin);
|
||||||
void analogWriteFreq(uint32_t freq);
|
void analogWriteFreq(uint32_t freq);
|
||||||
|
void analogWriteFreq(uint32_t freq, uint8_t pin);
|
||||||
int32_t analogAttach(uint32_t pin, bool output_invert = false); // returns the ledc channel, or -1 if failed. This is implicitly called by analogWrite if the channel was not already allocated
|
int32_t analogAttach(uint32_t pin, bool output_invert = false); // returns the ledc channel, or -1 if failed. This is implicitly called by analogWrite if the channel was not already allocated
|
||||||
void analogWrite(uint8_t pin, int val);
|
void analogWrite(uint8_t pin, int val);
|
||||||
|
|
||||||
|
@ -182,8 +182,9 @@ void ShutterRtc50mS(void)
|
|||||||
startWaveformClockCycles(Pin(GPIO_PWM1, i), cc/2, cc/2, 0, -1, 0, false);
|
startWaveformClockCycles(Pin(GPIO_PWM1, i), cc/2, cc/2, 0, -1, 0, false);
|
||||||
#endif // ESP8266
|
#endif // ESP8266
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
analogWriteFreq(Shutter[i].pwm_velocity);
|
analogWriteFreq(Shutter[i].pwm_velocity,Pin(GPIO_PWM1, i));
|
||||||
analogWrite(Pin(GPIO_PWM1, i), 50);
|
TasmotaGlobal.pwm_value[i] = 512;
|
||||||
|
PwmApplyGPIO(false);
|
||||||
#endif // ESP32
|
#endif // ESP32
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -467,7 +468,6 @@ void ShutterDecellerateForStop(uint8_t i)
|
|||||||
delay(50);
|
delay(50);
|
||||||
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Velocity %ld, Delta %d"), Shutter[i].pwm_velocity, Shutter[i].accelerator );
|
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Velocity %ld, Delta %d"), Shutter[i].pwm_velocity, Shutter[i].accelerator );
|
||||||
// Control will be done in RTC Ticker.
|
// Control will be done in RTC Ticker.
|
||||||
|
|
||||||
}
|
}
|
||||||
if (ShutterGlobal.position_mode == SHT_COUNTER){
|
if (ShutterGlobal.position_mode == SHT_COUNTER){
|
||||||
missing_steps = ((Shutter[i].target_position-Shutter[i].start_position)*Shutter[i].direction*ShutterGlobal.open_velocity_max/RESOLUTION/STEPS_PER_SECOND) - RtcSettings.pulse_counter[i];
|
missing_steps = ((Shutter[i].target_position-Shutter[i].start_position)*Shutter[i].direction*ShutterGlobal.open_velocity_max/RESOLUTION/STEPS_PER_SECOND) - RtcSettings.pulse_counter[i];
|
||||||
@ -477,7 +477,13 @@ void ShutterDecellerateForStop(uint8_t i)
|
|||||||
//AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Remain %d count %d -> target %d, dir %d"), missing_steps, RtcSettings.pulse_counter[i], (uint32_t)(Shutter[i].target_position-Shutter[i].start_position)*Shutter[i].direction*ShutterGlobal.open_velocity_max/RESOLUTION/STEPS_PER_SECOND, Shutter[i].direction);
|
//AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Remain %d count %d -> target %d, dir %d"), missing_steps, RtcSettings.pulse_counter[i], (uint32_t)(Shutter[i].target_position-Shutter[i].start_position)*Shutter[i].direction*ShutterGlobal.open_velocity_max/RESOLUTION/STEPS_PER_SECOND, Shutter[i].direction);
|
||||||
while (RtcSettings.pulse_counter[i] < (uint32_t)(Shutter[i].target_position-Shutter[i].start_position)*Shutter[i].direction*ShutterGlobal.open_velocity_max/RESOLUTION/STEPS_PER_SECOND && missing_steps > 0) {
|
while (RtcSettings.pulse_counter[i] < (uint32_t)(Shutter[i].target_position-Shutter[i].start_position)*Shutter[i].direction*ShutterGlobal.open_velocity_max/RESOLUTION/STEPS_PER_SECOND && missing_steps > 0) {
|
||||||
}
|
}
|
||||||
|
#ifdef ESP8266
|
||||||
analogWrite(Pin(GPIO_PWM1, i), 0); // removed with 8.3 because of reset caused by watchog
|
analogWrite(Pin(GPIO_PWM1, i), 0); // removed with 8.3 because of reset caused by watchog
|
||||||
|
#endif
|
||||||
|
#ifdef ESP32
|
||||||
|
TasmotaGlobal.pwm_value[i] = 0;
|
||||||
|
PwmApplyGPIO(false);
|
||||||
|
#endif // ESP32
|
||||||
Shutter[i].real_position = ShutterCalculatePosition(i);
|
Shutter[i].real_position = ShutterCalculatePosition(i);
|
||||||
//AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Remain steps %d"), missing_steps);
|
//AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Remain steps %d"), missing_steps);
|
||||||
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Real %d, Pulsecount %d, tobe %d, Start %d"), Shutter[i].real_position,RtcSettings.pulse_counter[i], (uint32_t)(Shutter[i].target_position-Shutter[i].start_position)*Shutter[i].direction*ShutterGlobal.open_velocity_max/RESOLUTION/STEPS_PER_SECOND, Shutter[i].start_position);
|
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Real %d, Pulsecount %d, tobe %d, Start %d"), Shutter[i].real_position,RtcSettings.pulse_counter[i], (uint32_t)(Shutter[i].target_position-Shutter[i].start_position)*Shutter[i].direction*ShutterGlobal.open_velocity_max/RESOLUTION/STEPS_PER_SECOND, Shutter[i].start_position);
|
||||||
@ -635,8 +641,15 @@ void ShutterStartInit(uint32_t i, int32_t direction, int32_t target_pos)
|
|||||||
switch (ShutterGlobal.position_mode) {
|
switch (ShutterGlobal.position_mode) {
|
||||||
#ifdef SHUTTER_STEPPER
|
#ifdef SHUTTER_STEPPER
|
||||||
case SHT_COUNTER:
|
case SHT_COUNTER:
|
||||||
|
#ifdef ESP8266
|
||||||
analogWriteFreq(Shutter[i].pwm_velocity);
|
analogWriteFreq(Shutter[i].pwm_velocity);
|
||||||
analogWrite(Pin(GPIO_PWM1, i), 0);
|
analogWrite(Pin(GPIO_PWM1, i), 0);
|
||||||
|
#endif
|
||||||
|
#ifdef ESP32
|
||||||
|
analogWriteFreq(PWM_MIN,Pin(GPIO_PWM1, i));
|
||||||
|
TasmotaGlobal.pwm_value[i] = 0;
|
||||||
|
PwmApplyGPIO(false);
|
||||||
|
#endif
|
||||||
RtcSettings.pulse_counter[i] = 0;
|
RtcSettings.pulse_counter[i] = 0;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user