Skip to content

Commit

Permalink
fix shutterfrequency change on mutiple channels (#19737)
Browse files Browse the repository at this point in the history
* fix shutterfrequency change on mutiple channels

* LEDC channel management for stepper shutter

LEDC channels dynamically assigned to ensure up to 16 shutters can be defined. Number of simultaneous moving shutters is limited by number of LEDC channels.

* bugfix  >=
  • Loading branch information
stefanbode authored Oct 15, 2023
1 parent 56314e5 commit 124fbf8
Showing 1 changed file with 27 additions and 38 deletions.
65 changes: 27 additions & 38 deletions tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* Shutter or Blind support using two consecutive relays
* Shutters for ESP32 with max eight shutters using more RAM and Settings from filesystem
\*********************************************************************************************/
#include "soc/soc_caps.h"

#define XDRV_27 27
#ifndef SHUTTER_STEPPER
Expand Down Expand Up @@ -178,6 +179,7 @@ struct SHUTTER {
uint16_t last_reported_time = 0; // get information on skipped 50ms loop() slots
uint32_t last_stop_time = 0; // record the last time the relay was switched off
uint8_t button_simu_pressed = 0; // record if both button where pressed simultanously
uint8_t ledc_channel = 0; // current used channel for PWM
} Shutter[MAX_SHUTTERS_ESP32];

struct SHUTTERGLOBAL {
Expand Down Expand Up @@ -469,9 +471,6 @@ int32_t ShutterCalculatePosition(uint32_t i)

void ShutterDecellerateForStop(uint8_t i)
{
#ifdef ESP32
bool pwm_apply = false; // ESP32 only, do we need to apply PWM changes
#endif
switch (ShutterGlobal.position_mode) {
case SHT_PWM_VALUE:
case SHT_COUNTER:
Expand All @@ -491,13 +490,10 @@ 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);
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
#endif
#ifdef ESP32
TasmotaGlobal.pwm_value[i] = 0;
pwm_apply = true;
#endif // ESP32
ledcWrite(Shutter[i].ledc_channel, 0);
ledcAttachPin(Pin(GPIO_PWM1, i), SOC_LEDC_CHANNEL_NUM);
Shutter[i].ledc_channel = 0;
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: 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);
Expand All @@ -506,9 +502,6 @@ void ShutterDecellerateForStop(uint8_t i)
Shutter[i].pwm_velocity = 0;
break;
}
#ifdef ESP32
if (pwm_apply) { PwmApplyGPIO(false); }
#endif
}

uint16_t ShutterGetCycleTime(uint8_t i, uint8_t max_runtime) {
Expand Down Expand Up @@ -539,6 +532,20 @@ uint16_t ShutterGetCycleTime(uint8_t i, uint8_t max_runtime) {
return cycle_time;
}

uint8_t ShutterGetFreeChannel() {
uint8_t nextFreeChannel = 0;
for (uint8_t i = 0; i < MAX_SHUTTERS_ESP32; i++) {
//SOC_LEDC_CHANNEL_NUM
nextFreeChannel = tmax(nextFreeChannel, Shutter[i].ledc_channel);
}
if (nextFreeChannel >= SOC_LEDC_CHANNEL_NUM) {
AddLog(LOG_LEVEL_ERROR, PSTR("SHT: All PWM channel busy. Open issue-ticket."));
} else {
AddLog(LOG_LEVEL_DEBUG, PSTR("SHT: Use channel %d"), nextFreeChannel+1);
}
return nextFreeChannel++;
}

uint8_t ShutterGetOptions(uint8_t index) {
return ShutterSettings.shutter_options[index];
}
Expand Down Expand Up @@ -964,9 +971,6 @@ void ShutterReportPosition(bool always, uint32_t index)

void ShutterRtc50mS(void)
{
#ifdef ESP32
bool pwm_apply = false; // ESP32 only, do we need to apply PWM changes
#endif
// No Logging allowed. RTC Timer
for (uint8_t i = 0; i < TasmotaGlobal.shutters_present; i++) {
if (Shutter[i].direction) {
Expand All @@ -987,25 +991,15 @@ void ShutterRtc50mS(void)
//AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Accelerator i=%d -> %d"),i, Shutter[i].accelerator);
ShutterUpdateVelocity(i);
digitalWrite(Pin(GPIO_PWM1, i), LOW);
#ifdef ESP8266
// Convert frequency into clock cycles
uint32_t cc = microsecondsToClockCycles(1000000UL) / Shutter[i].pwm_velocity;
startWaveformClockCycles(Pin(GPIO_PWM1, i), cc/2, cc/2, 0, -1, 0, false);
#endif // ESP8266
#ifdef ESP32
ledcWriteTone(i, Shutter[i].pwm_velocity); //
ledcWrite(i, 512); // Setzt den PWM-Wert auf 0

ledcWriteTone(Shutter[i].ledc_channel, Shutter[i].pwm_velocity); //
//ledcWrite(i, 512); // Setzt den PWM-Wert auf 0
TasmotaGlobal.pwm_value[i] = 512;
pwm_apply = true;
#endif // ESP32
}
break;
}
} // if (Shutter[i].direction)
}
#ifdef ESP32
if (pwm_apply) { PwmApplyGPIO(false); }
#endif
}

void ShutterSetPosition(uint32_t device, uint32_t position)
Expand Down Expand Up @@ -1172,16 +1166,11 @@ void ShutterStartInit(uint32_t i, int32_t direction, int32_t target_pos)
switch (ShutterGlobal.position_mode) {
#ifdef SHUTTER_STEPPER
case SHT_COUNTER:
#ifdef ESP8266
analogWriteFreq(Shutter[i].pwm_velocity);
analogWrite(Pin(GPIO_PWM1, i), 0);
#endif
#ifdef ESP32
ledcSetup(i, Shutter[i].pwm_velocity, 8);
ledcAttachPin(Pin(GPIO_PWM1, i), i); // Nehmen Sie an, dass GPIO_PWM1 der gewünschte GPIO-Pin ist.
ledcWriteTone(i, Shutter[i].pwm_velocity); //
ledcWrite(i, 0); // Setzt den PWM-Wert auf 0
#endif
Shutter[i].ledc_channel = ShutterGetFreeChannel();
ledcSetup(Shutter[i].ledc_channel, Shutter[i].pwm_velocity, 8);
ledcAttachPin(Pin(GPIO_PWM1, i), Shutter[i].ledc_channel);
ledcWriteTone(Shutter[i].ledc_channel, Shutter[i].pwm_velocity);
ledcWrite(Shutter[i].ledc_channel, 0); // Setzt den PWM-Wert auf 0
RtcSettings.pulse_counter[i] = 0;
break;
#endif
Expand Down

0 comments on commit 124fbf8

Please sign in to comment.