Skip to content

Requests (JSON and NTP) Failures when Frame Buffer Defined on Qualia ESP32-S3 for RGB666 40p TTL TFT #10702

@jmangum

Description

@jmangum

CircuitPython version and board name

Adafruit CircuitPython 10.0.3 on 2025-10-17; Adafruit-Qualia-S3-RGB666 with ESP32S3

Code/REPL

#
# Qualia ESP32-S3 RGB666 40p TFT JSON test
#
import os
import ipaddress
import ssl
import wifi
import socketpool
import adafruit_requests
import time
import adafruit_connection_manager
import adafruit_ntp
import rtc
import supervisor
import json
import microcontroller
# Display libraries
import displayio
import busio
import board
import dotclockframebuffer
from framebufferio import FramebufferDisplay

# URL to fetch JSON from
WxURL = "ENTER YOUR JSON SERVER HERE"

print("\nQualia JSON Test\n")

def json_grab(wxURL):
    # Fetch weather data as JSON from Flask server on gamera...
    got_json = False
    while not got_json:
        try:
            print("Fetching JSON data from %s" % WxURL)
            start_msecs = supervisor.ticks_ms()
            response = requests.get(WxURL)
            stop_msecs = supervisor.ticks_ms()
            # Check for HTTP errors
            if response.status_code != 200:
                print("HTTP Error:", response.status_code)
                raise adafruit_requests.OutOfRetries
            json_data = response.json()
            print("Data received:", json_data)
            print("JSON Flask server grab took: ", (stop_msecs - start_msecs)/1000, "seconds")
            response.close() # Always close the response
            got_json = True
        except (adafruit_requests.OutOfRetries) as e:
            print("Network error:", e)
            print("Retrying connection after 10 seconds...")
            time.sleep(10) # Wait before retrying to avoid spamming
            continue
        except Exception as e:
            print("An unexpected error occurred:", e)
            # Wifi connection might have been interrupted....
            if wifi.radio.ipv4_address == None:
                print(f"Wifi disconnected...reconnecting to {os.getenv('CIRCUITPY_WIFI_SSID')}")
                wifi.radio.connect(os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD"))
                print(f"Connected to {os.getenv('CIRCUITPY_WIFI_SSID')}")
                print(f"My IP address: {wifi.radio.ipv4_address}")
            print("Retrying JSON grab after 30 seconds...")
            time.sleep(30) # Wait before retrying to avoid spamming
            continue
    # Now parse the JSON string...
    json_dict = json_data[0]
    json_dict_extra = {'CO2_TAMB': '20.01', 'CO2_RH': '66.00', 'CO2_PPM': '666',
                'UVS': '5', 'LIGHT': '2345', 'UVI': '0.0834783', 'LUX': '1234.5',
                'PM1P0S': '123', 'PM2P5S': '456', 'PM10S': '789',
                'PM1P0E': '123', 'PM2P5E': '456', 'PM10E': '789',
                'PMG0P3': '12345', 'PMG0P5': '1234', 'PMG1P0': '4567',
                'PMG2P5': '123', 'PMG5P0': '45', 'PMG10': '6'}
    json_dict.update(json_dict_extra)
    for key, value in json_dict.items():
        print(f"{key}: {value}")
    return json_dict

# 4-inch square RGB-666 TFT with capacitive touch settings
displayio.release_displays()
tft_pins = dict(board.TFT_PINS)
tft_timings = {
    "frequency": 16000000,
    "width": 720,
    "height": 720,
    "hsync_pulse_width": 2,
    "hsync_front_porch": 46,
    "hsync_back_porch": 44,
    "vsync_pulse_width": 2,
    "vsync_front_porch": 16,
    "vsync_back_porch": 18,
    "hsync_idle_low": False,
    "vsync_idle_low": False,
    "de_idle_high": False,
    "pclk_active_high": False,
    "pclk_idle_high": False,
}
init_sequence_tl040hds20 = bytes()
board.I2C().deinit()
#i2c = busio.I2C(board.SCL, board.SDA)
i2c = busio.I2C(board.SCL, board.SDA, frequency=100_000)
tft_io_expander = dict(board.TFT_IO_EXPANDER)
#tft_io_expander['i2c_address'] = 0x38 # uncomment for rev B
dotclockframebuffer.ioexpander_send_init_sequence(i2c, init_sequence_tl040hds20, **tft_io_expander)
i2c.deinit()

bitmap = displayio.OnDiskBitmap("/display-ruler-720p.bmp")

# Aha!  Frame buffer setting causes JSON grab failures...  Comment-out to allow JSON grab to work...
fb = dotclockframebuffer.DotClockFramebuffer(**tft_pins, **tft_timings)

display = FramebufferDisplay(fb, auto_refresh=False)

print(f"Connecting to {os.getenv('CIRCUITPY_WIFI_SSID')}")
wifi.radio.connect(os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD"))
print(f"Connected to {os.getenv('CIRCUITPY_WIFI_SSID')}")
print(f"My IP address: {wifi.radio.ipv4_address}")

#pool = socketpool.SocketPool(wifi.radio)
pool = adafruit_connection_manager.get_radio_socketpool(wifi.radio)
requests = adafruit_requests.Session(pool)

# Fetch weather data as JSON from Flask server on gamera...
nap = 15 # sleep time between JSON grabs
while True:
    # JSON grab
    json_dict = json_grab(WxURL)
    print('\nNow sleep for',nap,'seconds...\n')
    time.sleep(nap)

Behavior

Fetching JSON data from [YOUR JSON SERVER]
An unexpected error occurred: [Errno 113] ECONNABORTED
Retrying JSON grab after 30 seconds...

Fetching JSON data from [YOUR JSON SERVER]
An unexpected error occurred: (-2, 'Name or service not known')
Retrying JSON grab after 30 seconds...```



### Description

- This is the RGB666 TTL TFT 720x720 4" square screen with capacitive touch.
- Very erratic (mostly failing) requests to JSON server.  
- Also see very similar behaviour (suspect it is caused by the same frame buffer setting, but have not tested) for NTP requests. 
- Code provided is for the JSON request failures. 
- See two types of error (provided above).  First error (`ECONNABORTED`) is vast majority of the cases observed
- JSON server name used removed from listings above.

### Additional information

Comment-out the `fb = dotclockframebuffer.DotClockFramebuffer(**tft_pins, **tft_timings)` line (and the display setting as it depends on `fb`) and JSON requests are 100% successful.  

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions