Encoder - ESP8266(WEMOS D1) - PWM

I’ve been tormenting the unfortunate code all evening, getting lost in three pines))) Even gpt4 didn’t help me. :rofl:
The goal is still to study (perhaps in the future I would like to make a reference voltage regulator for TL494 and there are many other ideas, but for this you need to adjust the borehole) but first, I want to figure out how to smoothly adjust the borehole of the PWM signal with a given current frequency using the encoder: one click clockwise +1% fill, and -1% counterclockwise rotation . While some nonsense is being obtained , when rotating in both directions , only a decrease in filling occurs, if you turn sharply clockwise, it can only start to increase %, regardless of which way to rotate , until you turn the encoder sharply again , which can switch the direction of adjustment Here is my code and a little bit of logs :

esphome:
  name: "esphome-web-2"
  friendly_name: Wemos d2

esp8266:
  board: d1_mini

logger:
  level: DEBUG 

api:

ota:
  - platform: esphome

wifi:
  networks:
    - ssid: Pro4
      password: Milk33kg

sensor:
  - platform: rotary_encoder
    id: my_encoder
    name: "Rotary Encoder"
    pin_a: D1
    pin_b: D2
    resolution: 1
    on_value:
      then:
        - lambda: |-
            float current_level = id(pwm_level);
            current_level += (x > 0) ? 1.0 : -1.0;  // Увеличиваем или уменьшаем уровень
            current_level = clamp(current_level, 0.0f, 100.0f);  // Ограничиваем уровень от 0 до 100%
            id(pwm_level) = current_level;  // Обновляем уровень заполнения
            id(my_pwm_output).set_level(current_level / 100.0f);  // Устанавливаем новый уровень (0.0 до 1.0)
            // Логирование для отладки
            ESP_LOGD("custom", "Current level: %f, Encoder value: %d", current_level, x);

globals:
  - id: pwm_level
    type: float
    restore_value: no
    initial_value: '50.0'  # Начальное значение уровня

output:
  - platform: esp8266_pwm
    id: my_pwm_output
    pin: D5
    frequency: 1000 Hz  # Фиксированная частота
    inverted: false

switch:
  - platform: template
    name: "PWM Signal"
    turn_on_action:
      - output.set_level: 
          id: my_pwm_output
          level: 0.0
[01:48:48][D][sensor:093]: 'Rotary Encoder': Sending state -10.00000 steps with 0 decimals of accuracy
[01:48:48][D][custom:037]: Current level: 19.000000, Encoder value: 0
[01:48:48][D][sensor:093]: 'Rotary Encoder': Sending state -11.00000 steps with 0 decimals of accuracy
[01:48:48][D][custom:037]: Current level: 18.000000, Encoder value: 0
[01:48:48][D][sensor:093]: 'Rotary Encoder': Sending state -12.00000 steps with 0 decimals of accuracy
[01:48:48][D][custom:037]: Current level: 17.000000, Encoder value: 0
[01:48:48][D][sensor:093]: 'Rotary Encoder': Sending state -13.00000 steps with 0 decimals of accuracy
[01:48:48][D][custom:037]: Current level: 16.000000, Encoder value: 0
[01:48:49][D][sensor:093]: 'Rotary Encoder': Sending state -14.00000 steps with 0 decimals of accuracy
[01:48:49][D][custom:037]: Current level: 15.000000, Encoder value: 0
[01:48:49][D][sensor:093]: 'Rotary Encoder': Sending state -15.00000 steps with 0 decimals of accuracy
[01:48:49][D][custom:037]: Current level: 14.000000, Encoder value: 0
[01:48:50][D][sensor:093]: 'Rotary Encoder': Sending state -14.00000 steps with 0 decimals of accuracy
[01:48:50][D][custom:037]: Current level: 13.000000, Encoder value: 0
[01:48:51][D][sensor:093]: 'Rotary Encoder': Sending state -13.00000 steps with 0 decimals of accuracy
[01:48:51][D][custom:037]: Current level: 12.000000, Encoder value: 0
[01:48:51][D][sensor:093]: 'Rotary Encoder': Sending state -12.00000 steps with 0 decimals of accuracy
[01:48:51][D][custom:037]: Current level: 11.000000, Encoder value: 0
[01:48:51][D][sensor:093]: 'Rotary Encoder': Sending state -11.00000 steps with 0 decimals of accuracy
[01:48:51][D][custom:037]: Current level: 10.000000, Encoder value: 0
[01:48:52][D][sensor:093]: 'Rotary Encoder': Sending state -10.00000 steps with 0 decimals of accuracy
[01:48:52][D][custom:037]: Current level: 9.000000, Encoder value: 0
[01:48:52][D][sensor:093]: 'Rotary Encoder': Sending state -9.00000 steps with 0 decimals of accuracy
[01:48:52][D][custom:037]: Current level: 8.000000, Encoder value: 0
[01:48:52][D][sensor:093]: 'Rotary Encoder': Sending state -8.00000 steps with 0 decimals of accuracy
[01:48:52][D][custom:037]: Current level: 7.000000, Encoder value: 0
[01:48:54][D][sensor:093]: 'Rotary Encoder': Sending state -9.00000 steps with 0 decimals of accuracy
[01:48:54][D][custom:037]: Current level: 6.000000, Encoder value: 0
[01:48:54][D][sensor:093]: 'Rotary Encoder': Sending state -10.00000 steps with 0 decimals of accuracy
[01:48:55][D][custom:037]: Current level: 5.000000, Encoder value: 0
[01:48:55][D][sensor:093]: 'Rotary Encoder': Sending state -11.00000 steps with 0 decimals of accuracy
[01:48:55][D][custom:037]: Current level: 4.000000, Encoder value: 0
[01:48:55][D][sensor:093]: 'Rotary Encoder': Sending state -12.00000 steps with 0 decimals of accuracy
[01:48:55][D][custom:037]: Current level: 3.000000, Encoder value: 0
[01:48:55][D][sensor:093]: 'Rotary Encoder': Sending state -13.00000 steps with 0 decimals of accuracy
[01:48:55][D][custom:037]: Current level: 2.000000, Encoder value: 0

Clarification arrived : :grinning:
The encoder needs to go to 0, that is : in the logs ([02:39:57][D][sensor:093]: ‘Rotary Encoder’: Sending state 0.00000 steps with 0 decimals of accuracy ) I make one hundred clicks of the encoder clockwise and 100% filling is set, then I make 100 clicks counterclockwise and only at 101 clicks the purity begins to decrease and only at 200 clicks counterclockwise the filling will be 0 . And let’s say I take 200 more steps counterclockwise, then I will need to take 301 steps clockwise to start increasing the filling again, and then there will only be 1%,302 steps 2%, 400 steps 100% …

Instead of the lambda you have for trying to count depending on direction turned, why don’t you calculate those values using on_clockwise: and on_anticlockwise:? Then it doesn’t matter if you are at zero to start.

1 Like

I have just solved the problem, while everything is working I will test it)))
I needed to track not the value of the encoder steps, but the increment or decrease of successive values during rotation)))

esphome:
  name: "esphome-web-2"
  friendly_name: Wemos d2

esp8266:
  board: d1_mini

logger:
  level: DEBUG 

api:

ota:
  - platform: esphome

wifi:
  networks:
    - ssid: Pro4
      password: Milk33kg

sensor:
  - platform: rotary_encoder
    id: my_encoder
    name: "Rotary Encoder"
    pin_a: D1
    pin_b: D2
    resolution: 1
    on_value:
      then:
        - lambda: |-
            static int previous_value = 0;  
            int current_value = x;  
            
            
            ESP_LOGD("custom", "Current value: %d, Previous value: %d", current_value, previous_value);
            
            float current_level = id(pwm_level);
            
            
            if (current_value > previous_value) {
                current_level += 1.0;
            } else if (current_value < previous_value) {
                current_level -= 1.0; 
            }
            
          
            current_level = clamp(current_level, 0.0f, 100.0f);
            id(pwm_level) = current_level;  
            id(my_pwm_output).set_level(current_level / 100.0f);  

            
            previous_value = current_value;

            
            ESP_LOGD("custom", "Current level: %f", current_level);

globals:
  - id: pwm_level
    type: float
    restore_value: no
    initial_value: '50.0' 

output:
  - platform: esp8266_pwm
    id: my_pwm_output
    pin: D5
    frequency: 10000 Hz 
    inverted: false

switch:
  - platform: template
    name: "PWM Signal"
    turn_on_action:
      - output.set_level: 
          id: my_pwm_output
          level: 0.0