esphome / issues

Issue Tracker for ESPHome
https://esphome.io/
293 stars 36 forks source link

ST7735 appears to cause ESP8266 to fail to connect to Wifi #2128

Open JamiePhonic opened 3 years ago

JamiePhonic commented 3 years ago

Operating environment/Installation (Hass.io/Docker/pip/etc.):

Hass.io 2021.6.4 ESP8266 (NodeMCU v3 & Wemos B1 Mini)

Lolin NodeMCU v3

Chip Info:

ESPHome V1.19.4 (Stable)

Affected component:

ST7735: https://www.esphome.io/components/display/st7735.html

Description of problem: I cant quite figure out why, but when using (essentially) the same YAML config with the ST7735 display and with a PCF8574, the code will comple just fine on both, and will run on the ESP8266, however the one using the ST7735 will constantly fail to connect to Wi-Fi with: reason='Auth Expired'

The Lambda code isnt exactly "pretty" but it does work just fine with the PCF8574. (i've added comments to explain what it's doing) It "runs" with the ST7735 (the time and date will show on the TFT and update as expected) but the device will never connect to Wi-Fi

Problem-relevant YAML-configuration entries:

substitutions:
  device_name: lcd_test
  device_pretty_name: LCD Test

esphome:
  name: ${device_name}
  platform: ESP8266
  board: nodemcuv2

wifi:
  ssid: !secret ssid_name
  password: !secret ssid_pass
  fast_connect: true
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "${device_pretty_name} Direct"
  #use_address: led_strip.local

captive_portal:

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

font:
  - file: "fonts/arial.ttf"
    id: arial
    size: 18

globals:
  - id: display_width
    type: int
    restore_value: no
    initial_value: '160'
  - id: Li
    type: int
    restore_value: no
    initial_value: '0'
  - id: Le
    type: int
    restore_value: no
    initial_value: '0'

text_sensor:
  #Query HA for data from the sensor: sensor.front_bedroom_temperature
  - platform: homeassistant
    entity_id: media_player.bedroom
    id: bedroom_media_state
  - platform: homeassistant
    entity_id: media_player.bedroom
    id: bedroom_media_type
    attribute: media_content_type
  - platform: homeassistant
    entity_id: sensor.bedroom_media_title
    id: bedroom_media_title
    on_value:
      then:
        - lambda: |-
            id(Li) = 0;
            id(Le) = 0;
  - platform: homeassistant
    entity_id: sensor.bedroom_media_name
    id: bedroom_media_name
    on_value:
      then:
        - lambda: |-
            id(Li) = 0;
            id(Le) = 0;

  # Li = Line Increment, Le = Line End

time:
  - platform: sntp
    id: my_time

spi:
  clk_pin: D5
  miso_pin: D6
  mosi_pin: D7

display:
  - platform: st7735
    model: "INITR_BLACKTAB"
    reset_pin: D1
    cs_pin: D4
    dc_pin: D2
    rotation: 90
    device_width: 128
    device_height: 160
    col_start: 0
    row_start: 0
    eight_bit_color: true
    update_interval: 1s
    id: my_lcd_display
    lambda: |-
      // Setup variables from HA for easier accessability
      std::string media_state = id(bedroom_media_state).state;
      std::string media_type = id(bedroom_media_type).state;
      std::string media_title = id(bedroom_media_title).state;
      std::string media_name = id(bedroom_media_name).state;
      //Get lenghts of strings
      int media_title_length = media_title.length();
      int media_name_length = media_name.length();
      int media_max_length = 0;
      int media_length_diff = 0;

      if (media_title_length > 20) {
        media_title = media_title + ' ';
        media_title_length ++;
      } else if (media_name_length > 20) {
        media_name = media_name + ' ';
        media_name_length ++;
      }

      // find which variable is longer: name or title? This is needed to pad one to the length of the other in case both are bigger than the display.
      // If name is bigger, set media_max_length to media_name_length and media_length_diff to media_name_length - media_title_length
      if (media_name_length > media_title_length) {
        media_max_length = media_name_length;
        media_length_diff = media_name_length - media_title_length;
      // Otherwise, If title is bigger, set media_max_length to media_title_length and media_length_diff to media_title_length - media_name_length
      } else if (media_title_length > media_name_length) {
        media_max_length = media_title_length;
        media_length_diff = media_title_length - media_name_length;
      }

      // If nothing is playing, just show the time
      if ((media_state == "") | (media_state == "off")) {
        id(Li) = 0;
        id(Le) = 0;
        //print the first 2 lines; line 1 is the current 12 hour time, line 2 is the current date in "dd MMM YYYY" format
        it.strftime(0,0,id(arial),"%I:%M:%S %p", id(my_time).now());
        it.strftime(0,25,id(arial),"%d %B %Y", id(my_time).now());

      // If state is "unavailable" then the sensor we're pulling data from must be offline  
      } else if (media_state == "unavailable") {
        id(Li) = 0;
        id(Le) = 0;
        //print the first 2 lines; line 1 is the current 12 hour time, line 2 is the current date in "dd MMM YYYY" format
        it.strftime(0,0,id(arial),"%I:%M:%S %p", id(my_time).now());
        it.strftime(0,25,id(arial),"%d %B %Y", id(my_time).now());
        it.print(0,50,id(arial),"Check Connection!");

      } else {

        // If state is playing, print playing, if its paused, print paused
        if (media_state == "playing") {
          it.print(0,0,id(arial),"Now Playing:");
        } else if (media_state == "paused") {
          it.print(0,0,id(arial),"Paused:");
        }

        // Uncomment this to display the difference in length of the name and title on the 4th line of the display (debugging)
        //it.print(0,50,id(arial),"Diff: " + to_string(media_length_diff));

        // If the type is music or tvshow
        if ((media_type == "music") | (media_type == "tvshow")) {

          // If both the name and title are display_width characters or less, just display them
          if ((media_name_length <= id(display_width)) & (media_title_length <= id(display_width))) {
            it.print(0,1,id(arial),media_name.c_str());
            it.print(0,25,id(arial),media_title.c_str());

          // If both the name and title are greater than display_width characters
          } else if ((media_name_length > id(display_width)) & (media_title_length > id(display_width))) {

            // If media_name_length is bigger than media_title_length, append media_length_diff spaces to media_title_length
            if (media_name_length > media_title_length) {
              media_title.append((media_length_diff), ' ');
            } else 
            // If media_title_length is bigger than media_name_length, append media_length_diff spaces to media_name_length
            if (media_title_length > media_name_length) {
              media_name.append((media_length_diff), ' ');
            }

            // Starting from Character Li; display the next display_width characters
            it.print(0,25,id(arial),media_name.substr(id(Li),id(display_width)).c_str());
            it.print(0,50,id(arial),media_title.substr(id(Li),id(display_width)).c_str());
            // Add 2 to Li
            id(Li) += 2;
            // If Li is bigger than media_max_length, reset it to 0
            if (id(Li) > media_max_length - id(display_width)){
              it.print(0,25,id(arial),media_name.substr((media_max_length - id(display_width)),id(display_width)).c_str());
              it.print(0,50,id(arial),media_title.substr((media_max_length - id(display_width)),id(display_width)).c_str());
              id(Le) ++;
              if (id(Le) > 1) {
                id(Li) = 0;
                id(Le) = 0;
              }

            }

          // If media_name is bigger than display_width but media_title is less than display_width
          } else if ((media_name_length > id(display_width)) & (media_title_length <= id(display_width))) {

            // Starting from Character Li; display the next display_width characters from media_name
            it.print(0,25,id(arial),media_name.substr(id(Li),id(display_width)).c_str());
            id(Li) += 2;
            // If Li is bigger than media_max_length, reset it to 0
            if (id(Li) > media_max_length - id(display_width)){
              it.print(0,25,id(arial),media_name.substr((media_max_length - id(display_width)),id(display_width)).c_str());
              id(Le) ++;
              if (id(Le) > 1) {
                id(Li) = 0;
                id(Le) = 0;
              }
            }
            // Print media_title as is
            it.print(0,50,id(arial),media_title.c_str());

          // If media_title is bigger than display_width but media_name is less than display_width  
          } else if ((media_name_length <= id(display_width)) & (media_title_length > id(display_width))) {

            // Print media_name as is
            it.print(0,25,id(arial),media_name.c_str());
            // Starting from Character Li; display the next display_width characters from media_title
            it.print(0,50,id(arial),media_title.substr(id(Li),id(display_width)).c_str());
            id(Li) += 2;
            // If Li is bigger than media_max_length, reset it to 0
            if (id(Li) > media_max_length - id(display_width)){
              it.print(0,50,id(arial),media_title.substr((media_max_length - id(display_width)),id(display_width)).c_str());
              id(Le) ++;
              if (id(Le) > 1) {
                id(Li) = 0;
                id(Le) = 0;
              }
            }
          }

        // If the type is movie or game, it won't have a name, only a title
        } else if ((media_type == "movie") | (media_type == "game")){

          // If media_title is less than or equal to display_width, print as is
          if (media_title_length <= id(display_width)) {
            it.print(0,25,id(arial),media_title.c_str());

          } else {

            // Starting from Character Li; display the next display_width characters from media_title
            it.print(0,25,id(arial),media_title.substr(id(Li),id(display_width)).c_str());
            id(Li) += 2;
            // If Li is bigger than media_max_length, reset it to 0
            if (id(Li) > media_max_length - id(display_width)){
              it.print(0,25,id(arial),media_title.substr((media_max_length - id(display_width)),id(display_width)).c_str());
              id(Le) ++;
              if (id(Le) > 1) {
                id(Li) = 0;
                id(Le) = 0;
              }
            }
          }
        }
      }

Logs (if applicable):

[17:40:03]rl[I][logger:170]: Log initialized
[17:40:03][C][ota:366]: There have been 1 suspected unsuccessful boot attempts.
[17:40:03][I][app:029]: Running through setup()...
[17:40:03][C][spi:022]: Setting up SPI bus...
[17:40:03][C][st7735:235]: Setting up ST7735...
[17:40:04][D][st7735:247]:   START
[17:40:04][C][st7735:372]: ST7735
[17:40:04][C][st7735:372]:   Rotations: 90 °
[17:40:04][C][st7735:372]:   Dimensions: 160px x 128px
[17:40:04][C][st7735:373]:   Model: ST7735 BLACKTAB
[17:40:04][C][st7735:374]:   CS Pin: GPIO2 (Mode: OUTPUT)
[17:40:04][C][st7735:375]:   DC Pin: GPIO4 (Mode: OUTPUT)
[17:40:04][C][st7735:376]:   Reset Pin: GPIO5 (Mode: OUTPUT)
[17:40:04][D][st7735:377]:   Buffer Size: 20480
[17:40:04][D][st7735:378]:   Height: 160
[17:40:04][D][st7735:379]:   Width: 128
[17:40:04][D][st7735:380]:   ColStart: 0
[17:40:04][D][st7735:381]:   RowStart: 0
[17:40:04][C][st7735:382]:   Update Interval: 1.0s
[17:40:04][D][st7735:249]:   END
[17:40:05][C][wifi:033]: Setting up WiFi...
[17:40:05][I][wifi:194]: WiFi Connecting to 'REDACTED'...
[17:40:10][W][wifi_esp8266:444]: Event: Disconnected ssid='REDACTED' bssid=8A:2A:A8:14:2A:C3 reason='Auth Expired'
[17:40:10][W][wifi:485]: Error while connecting to network.
[17:40:10][W][wifi:522]: Restarting WiFi adapter...

Last 4 lines repeat indefinetly...

Additional information and things you've tried: Changing wifi details to connect to other AP's (Mobile hostspot) without success.

JamiePhonic commented 3 years ago

Update: I can confirm this exact same yaml config runs without issues on the ESP-Wroom-32 (Just updating the platform and board)

adamcodemaker commented 3 years ago

I also have similar problems on nodemcu v3 On ESP-Wroom-32 it runs ok.

duchenpaul commented 3 years ago

I can confirm this bug, here is my configure:

esphome:
  name: $device_name
  platform: ESP8266
  board: $board_model
  build_path: build/$device_name
  # esp8266_restore_from_flash: yes

substitutions:
  board_model: nodemcuv2
  device_name: helloworld
  wifi_ssid: !secret wifi_ssid
  wifi_password: !secret wifi_password
  wifi_fast_connect: "true"
  wifi_reboot_timeout: 600s
  ota_password: !secret ota_password
  api_reboot_timeout: 600s

wifi:
  ssid: $wifi_ssid
  password: $wifi_password
  #  manual_ip:
  #    static_ip: 192.168.178.230
  #    gateway: 192.168.178.1
  #    subnet: 255.255.255.0
  #    dns1: 1.1.1.1
  #    dns2: 1.2.2.1
  #----------------------------------------------------
  domain: .local
  reboot_timeout: $wifi_reboot_timeout
  power_save_mode: none
  fast_connect: $wifi_fast_connect
  ap:
    ssid: $device_name
    password: $wifi_password
    ap_timeout: 30s

captive_portal:

#--------------------------------------------
web_server:
  port: 80
  css_url: https://esphome.io/_static/webserver-v1.min.css
  js_url: https://esphome.io/_static/webserver-v1.min.js
#----------------------------------------------------

# Enable logging
logger:
  # hardware_uart: UART0
  level: DEBUG
  baud_rate: 115200

status_led:
  pin:
    number: GPIO2
    inverted: True

api:
  password: $ota_password

ota:
  password: $ota_password

spi:
  clk_pin: D5
  mosi_pin: D6
  # miso_pin: D6

display:
  - platform: st7735
    cs_pin: D8
    dc_pin: D7
    reset_pin: D3

    model: "INITR_18BLACKTAB"
    device_width: 128
    device_height: 160
    col_start: 0
    row_start: 0
    eight_bit_color: true
    lambda: |-
      it.fill(Color::BLACK);
      it.rectangle(0,  0, it.get_width()/2, it.get_height()/2, id(my_red));

color:
  - id: my_red
    red: 100%
    green: 3%
    blue: 5%
grego1981 commented 2 years ago

Same behaviour with ESP8266 nodemcu which does not connect if an amg8833 sensor is connected of a VL53L0X or any other sensor using SDA SCL pins. The same code works if the hardware is not connected. The example config for every hardware (without ESPHome that is) work just fine to the same wifi setup.

cbulock commented 2 years ago

Just duplicated this same issue. Using a Wemos D1 Mini and once I add the config for the ST7735, I start seeing wifi connection timeouts.

abanchieri commented 2 years ago

I believe I have the same (or exceptionally similar) issue.

In my case I am trying to connect a 20x4 LCD display using ESPHome. I have tried both an ESP8266 D1 Mini and an ESP8266 NodeMCU. I intend to connect the display is connected through a PCF8474 module.

My YAML file is as follows (set up for the NodeMCU test case)

esphome:
  name: sprinkler
  platform: ESP8266
#  board: d1_mini
  board: nodemcuv2

substitutions:
  devicename: sprinkler
  friendly_name: sprinkler

wifi:
  networks:
    - ssid: !secret wifi_ssid          
      password: !secret wifi_password  
  ap:
    ssid: "AP_${devicename}"

# Enable the captive portal for inital WiFi setup
captive_portal:

# Enable logging
logger:
  level: VERY_VERBOSE
  # level: VERBOSE

# Enable Home Assistant API
api:

# Enable OTA upgrade
ota:
  password: !secret ESPHome_OTA_password

time:
  - platform: homeassistant
    id: homeassistant_time  

binary_sensor:
  - platform: status
    name: "${friendly_name} Status"

i2c:
  sda: D2
  scl: D1

display:
  - platform: lcd_pcf8574
    dimensions: 20x4
    address: 0x27 
    lambda: |-
      it.strftime(2,0, "%H:%M:%S", id(homeassistant_time).now());
blounolito commented 2 years ago

I have the exact same problem,

It looks like screens / I2C devices mess up with the WiFi connexion.

Some logs ;

[23:41:52][W][wifi:572]: Restarting WiFi adapter... [23:41:53][I][wifi:248]: WiFi Connecting to 'mine'... [23:41:55][W][wifi_esp8266:482]: Event: Disconnected ssid='mine' bssid=MAC reason='Auth Expired' [23:41:55][W][wifi:536]: Error while connecting to network. [23:41:55][W][wifi:572]: Restarting WiFi adapter... [23:42:00][D][wifi:373]: Starting scan... [23:42:07][D][wifi:388]: Found networks: [23:42:07][I][wifi:431]: - ... WiFi networks list [23:42:07][I][wifi:248]: WiFi Connecting to 'mine'... [23:42:09][W][wifi_esp8266:482]: Event: Disconnected ssid='mine' bssid=MAC reason='Auth Expired' [23:42:09][W][wifi:536]: Error while connecting to network. [23:42:09][W][wifi:572]: Restarting WiFi adapter... [23:42:10][I][wifi:248]: WiFi Connecting to 'mine'...

Board ; ESP8266 (Nodemcu) Configuration ; the one in this cookbook, exactly the same (delta fonts used and sensors names) : https://esphome.io/cookbook/display_time_temp_oled.html

I have other similar boards with and without using I2C, they are running fine. The most complex of them exploit I2C to use an Arduino Nano as a GPIO expander, so I guess the underlying problem is in I2C + OLED / TFT.

schinckel commented 2 years ago

Try changing your display's update_interval.

Setting this to 2s enabled my device to connect to my WiFi.

ssieb commented 2 years ago

Try increasing the i2c frequency. That has been a common solution.

ax42 commented 1 year ago

Same issue for me -- Wemos D1 with a 4x20 display via lcd_pcf8574 gives the auth error on WiFi.

Can confirm that increasing the i2c bus speed from the default 50kHz ixes the issue:

i2c:
  sda: GPIO4
  scl: GPIO5
  frequency: 100kHz
eherranzr commented 3 months ago

Seeing something similar in #5890 Tried increasing i2c frequency and display's update_interval but did not solve the issue