Merge pull request #16045 from stefanbode/patch-4

ESP32 enhancements to stepper shutter motor
This commit is contained in:
Theo Arends 2022-07-22 15:01:51 +02:00 committed by GitHub
commit bbcf9363e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 18 deletions

View File

@ -11,7 +11,6 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef ESP32
@ -68,12 +67,19 @@ int32_t _analog_pin2chan(uint32_t pin) { // returns -1 if uallocated
return -1;
}
void _analogWriteFreqRange(void) {
void _analogWriteFreqRange(uint8_t pin) {
_analogInit(); // make sure the mapping array is initialized
for (uint32_t channel = 0; channel < MAX_PWMS; channel++) {
if (pwm_channel[channel] < 255) {
ledcSetup(channel, pwm_frequency, pwm_bit_num);
}
if (pin == 255) {
for (uint32_t channel = 0; channel < MAX_PWMS; channel++) {
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) {
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) {
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
@ -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
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);
ledc_channel_config_t ledc_channel = {
(int)pin, // gpio
@ -123,7 +139,6 @@ int32_t analogAttach(uint32_t pin, bool output_invert) { // returns ledc chan
};
ledc_channel_config(&ledc_channel);
ledcSetup(channel, pwm_frequency, pwm_bit_num);
// Serial.printf("PWM: New attach pin %d to channel %d\n", pin, 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
functions.
Phase control allows to stress less the power supply of LED lights.
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
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.
Unfortunately Arduino Core does not allow any customization nor
extendibility for the ledc/analogWrite functions. We have therefore
no other choice than duplicating part of Arduino code.
WARNING: this means it can easily break if ever Arduino internal
implementation changes.
*/

View File

@ -26,7 +26,9 @@
// input range is in full range, ledc needs bits
void analogWriteRange(uint32_t range);
void analogWriteRange(uint32_t range, uint8_t pin);
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
void analogWrite(uint8_t pin, int val);

View File

@ -182,8 +182,9 @@ void ShutterRtc50mS(void)
startWaveformClockCycles(Pin(GPIO_PWM1, i), cc/2, cc/2, 0, -1, 0, false);
#endif // ESP8266
#ifdef ESP32
analogWriteFreq(Shutter[i].pwm_velocity);
analogWrite(Pin(GPIO_PWM1, i), 50);
analogWriteFreq(Shutter[i].pwm_velocity,Pin(GPIO_PWM1, i));
TasmotaGlobal.pwm_value[i] = 512;
PwmApplyGPIO(false);
#endif // ESP32
}
break;
@ -467,7 +468,6 @@ void ShutterDecellerateForStop(uint8_t i)
delay(50);
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.
}
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];
@ -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);
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;
PwmApplyGPIO(false);
#endif // ESP32
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);
@ -635,8 +641,15 @@ 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
analogWriteFreq(PWM_MIN,Pin(GPIO_PWM1, i));
TasmotaGlobal.pwm_value[i] = 0;
PwmApplyGPIO(false);
#endif
RtcSettings.pulse_counter[i] = 0;
break;
#endif