ESP32-S3 TFT Serial Console on TFT top line

Please tell us which board you are using.
For CircuitPython issues, ask in the Adafruit CircuitPython forum.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
Thosch42
 
Posts: 5
Joined: Sun Jun 04, 2023 7:36 am

ESP32-S3 TFT Serial Console on TFT top line

Post by Thosch42 »

Hi all!
I just startet a little project with a Feather ESP32-S3 TFT and Circuitpython. It's my first Feather board. Surprisingly I found, that the board is printing out the serial console on the tiny TFT right out of the box. That's exactly what I need for my Projekt.
The top line of the display seems to be a kind o status line, with Wi-Fi information, the name of running python script and the CircuitPython version (8.1.0 in my case).
Now my question: The Wi-Fi info shows allways "Wi-Fi: Keine IP" (Wi-Fi: No IP), but the boards definitely is connected to a wifi net and does have an IP. So how can I update this status line?
Thanks in advance.

Thosch

User avatar
mikeysklar
 
Posts: 13936
Joined: Mon Aug 01, 2016 8:10 pm

Re: ESP32-S3 TFT Serial Console on TFT top line

Post by mikeysklar »

Have you uploaded any code to the board? If so can you link to it?

User avatar
Thosch42
 
Posts: 5
Joined: Sun Jun 04, 2023 7:36 am

Re: ESP32-S3 TFT Serial Console on TFT top line

Post by Thosch42 »

mikeysklar wrote: Sun Jun 04, 2023 6:47 pm Have you uploaded any code to the board? If so can you link to it?
Yes, of cause! But this line comes not from my code. It must come from CircuitPython itselfs.

Code: Select all

# Based on:
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

import supervisor
import gc
import time
import microcontroller
import watchdog
import board
import alarm
import digitalio
import adafruit_gps
import json
import ssl
import socketpool
import wifi
import adafruit_minimqtt.adafruit_minimqtt as MQTT
import adafruit_max1704x

known_nets = {
    'xxxx': {'pwd': 'XXXX'},
    'yyyy': {'pwd': 'YYYY'},
    'zzzz': {'pwd': 'ZZZZ'}
}

wdt = microcontroller.watchdog
wdt.timeout = 10
wdt.mode = watchdog.WatchDogMode.RESET
wdt.feed()

# disable auto reload to stop unexpected reloads
supervisor.set_next_code_file(
    filename='code.py', reload_on_error=False, reload_on_success=False)
supervisor.runtime.autoreload = False

def disableInternalPower():
    tftpower = digitalio.DigitalInOut(board.TFT_I2C_POWER)
    tftpower.direction = digitalio.Direction.OUTPUT
    tftpower.value = False

    neopower = digitalio.DigitalInOut(board.NEOPIXEL_POWER)
    neopower.direction = digitalio.Direction.OUTPUT
    neopower.value = False


def format_dop(dop):
    # https://en.wikipedia.org/wiki/Dilution_of_precision_(navigation)
    if dop > 20:
        msg = "Poor"
    elif dop > 10:
        msg = "Fair"
    elif dop > 5:
        msg = "Moderate"
    elif dop > 2:
        msg = "Good"
    elif dop > 1:
        msg = "Excel"
    else:
        msg = "Ideal"
    return f"{msg}"

try:
    from secrets import secrets
except ImportError:
    print("WiFi secrets are kept in secrets.py, please add them there!")
    raise

wdt.feed()
f = open('values.json')
data = json.loads(f.read())
f.close()

button = board.BUTTON
pin_alarm = alarm.pin.PinAlarm(button, value=False, pull=True)
pin = digitalio.DigitalInOut(button)
pin.direction = digitalio.Direction.INPUT
pin.pull = digitalio.Pull.UP

wdt.feed()
print("Scanning for known wifi nets")
networks = []
for network in wifi.radio.start_scanning_networks():
    networks.append(network)
wifi.radio.stop_scanning_networks()
networks = sorted(networks, key=lambda net: net.rssi, reverse=True)
for network in networks:
    print("ssid:", network.ssid, "rssi:", network.rssi)
nets = frozenset([e.ssid for e in networks])
wdt.feed()
known_net_names = frozenset([key for key in known_nets])
net_to_use = list(nets & known_net_names)
wdt.feed()
try:
    net_to_use = net_to_use[0]
    net_properties = known_nets[net_to_use]
    pwd = net_properties['pwd']
    print("Connecting to %s" % net_to_use)
    wifi.radio.connect(net_to_use, pwd)
    print("Connected to {0}! ({1}) ".format(
        net_to_use, wifi.radio.ipv4_address))
except Exception as e:
    print("")
    print('!' * 10)
    print("Failed to connect to any known network.")
    print("Waiting for Watchdog Reset")
    print(e)
    while True:
        continue

wdt.feed()

# Define callback methods which are called when events occur
def connected(client, userdata, flags, rc):
    # This function will be called when the client is connected
    # successfully to the broker.
    wdt.feed()
    print("Connected to www.tick.cemos.net! ")
    
def disconnected(client, userdata, rc):
    # This method is called when the client is disconnected
    wdt.feed()
    print("Disconnected from www.tick.cemos.net!")

# Create a socket pool
pool = socketpool.SocketPool(wifi.radio)
#ssl_context = ssl.create_default_context()

wdt.feed()
# Set up a MiniMQTT Client
mqtt_client = MQTT.MQTT(
    broker=secrets["broker"],
    port=secrets["port"],
    username=secrets["user"],
    password=secrets["pwd"],
    socket_pool=pool,
    ssl_context=ssl_context,
)
wdt.feed()
# Setup the callback methods above
mqtt_client.on_connect = connected
mqtt_client.on_disconnect = disconnected

# Connect the client to the MQTT broker.
print("Connecting to " + secrets["broker"])
mqtt_client.connect()

i2c = board.STEMMA_I2C()  # For using the built-in STEMMA QT connector on a uc

# Create a GPS module instance.
gps = adafruit_gps.GPS_GtopI2C(i2c, debug=False)  # Use I2C interface
gauge = adafruit_max1704x.MAX17048(i2c)
print("Battery Gauge Version: ", hex(gauge.chip_version))

gps.send_command(b'PMTK314,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0')

# Set update rate to once a second (1hz) which is what you typically want.
gps.send_command(b"PMTK220,1000")

# Main loop runs forever printing the location, etc. every second.
last_print = time.monotonic()
while True:
    wdt.feed()
    if not pin.value:
        print("")
        print("Go to Sleep in 5 seconds")
        time.sleep(5)
        disableInternalPower()
        alarm.exit_and_deep_sleep_until_alarms(pin_alarm)
        
    try:
        mqtt_client.loop()
    except:
        if wifi.radio.connected:
            print("+", end="")
            mqtt_client.reconnect()
    gps.update()
    # Every second print out current location details if there's a fix.
    current = time.monotonic()
    if current - last_print >= 1.0:
        last_print = current
        if not gps.has_fix:
            # Try again if we don't have a fix yet.
            print("Waiting for fix...")
            continue
        # We have a fix! (gps.has_fix is true)
        print("")
        print("***************************************")
        print(
            "Fix timestamp: {}/{}/{} {:02}:{:02}:{:02}".format(
                gps.timestamp_utc.tm_mon,  # Grab parts of the time from the
                gps.timestamp_utc.tm_mday,  # struct_time object that holds
                gps.timestamp_utc.tm_year,  # the fix time.  Note you might
                gps.timestamp_utc.tm_hour,  # not get all data like year, day,
                gps.timestamp_utc.tm_min,  # month!
                gps.timestamp_utc.tm_sec,
            )
        )
        print("Latitude: {0:.6f} degrees".format(gps.latitude))
        print("Longitude: {0:.6f} degrees".format(gps.longitude))
        print(f"2D Fix: {gps.has_fix}  3D Fix: {gps.has_3d_fix}")
        if gps.fix_quality is not None:
            print("Fix quality 2D: {} |".format(gps.fix_quality), end=" ")
        if gps.fix_quality_3d is not None:
            print("Fix quality 3D: {}".format(gps.fix_quality_3d))
        if gps.altitude_m is not None:
            print("Alt: {} m".format(gps.altitude_m), end=" ")
        if gps.speed_knots is not None:
            print("Speed: {} km/h".format(gps.speed_knots * 1.852))
        else:
            print("Speed: -- km/h")
        if gps.track_angle_deg is not None:
            print("Track angle: {} degrees".format(gps.track_angle_deg))
        #if gps.horizontal_dilution is not None:
        #    print("Horizontal dilution: {}".format(gps.horizontal_dilution))
        #if gps.height_geoid is not None:
        #    print("Height geoid: {} meters".format(gps.height_geoid))
        if gps.satellites is not None:
            print("# sats: {:2}".format(gps.satellites), end=" ")
        if gps.pdop is not None:
            print(f"P: {format_dop(gps.pdop)}", end=" ")
        if gps.hdop is not None:
            print(f"H: {format_dop(gps.hdop)}", end=" ")
        if gps.vdop is not None:
            print(f"V: {format_dop(gps.vdop)}", end=" ")
        print("")
        print("Batt: %0.2fV - %0.1f%%" %
              (gauge.cell_voltage, gauge.cell_percent), end="")
        gc.collect()
        data['sensors']['lat'] = gps.latitude
        data['sensors']['lon'] = gps.longitude
        data['sensors']['gpsbat_volt'] = gauge.cell_voltage
        data['sensors']['gpsbat_percent'] = gauge.cell_percent
        data['sensors']['vdop'] = gps.vdop
        data['sensors']['hdop'] = gps.hdop
        data['sensors']['pdop'] = gps.pdop
        data['sensors']['height_geoid'] = gps.height_geoid
        data['sensors']['hor_dil'] = gps.horizontal_dilution
        data['sensors']['track'] = gps.track_angle_deg
        if gps.speed_knots is not None:
            data['sensors']['speed'] = gps.speed_knots * 1.852 # convert to km/h
        data['sensors']['altitude'] = gps.altitude_m
        data['sensors']['fix_2D'] = gps.fix_quality
        data['sensors']['fix_3D'] = gps.fix_quality_3d
        try:
            mqtt_client.publish('thecube/Event_005/up', json.dumps(data))
        except Exception as e:
            print("MQTT Error: %s" % e)
            mqtt_client.reconnect()

User avatar
Thosch42
 
Posts: 5
Joined: Sun Jun 04, 2023 7:36 am

Re: ESP32-S3 TFT Serial Console on TFT top line

Post by Thosch42 »

Possibly I need to clarify my problem. This is how my display looks.
Disp1.jpg
Disp1.jpg (866.19 KiB) Viewed 107 times
The yellow marked line comes not from my code. I like to know, how I can update the Wi-Fi info in this line.

Thanks in advance,
Thomas

User avatar
mikeysklar
 
Posts: 13936
Joined: Mon Aug 01, 2016 8:10 pm

Re: ESP32-S3 TFT Serial Console on TFT top line

Post by mikeysklar »

Thomas,

The first line is standard REPL console output when a CircuitPython device boots. It is not something you can customize without rebuilding CircuitPython but you can disable it.

Code: Select all

CircuitPython Emoji : Keine IP | code.py | 8.1.0
You have two options. Leave things the way they are where all your REPL output to the TFT as you are currently doing or switch to using displayio. Using displayio allows you to toggle the REPL on and off.

# disable REPL output to the TFT

Code: Select all

import displayio
board.DISPLAY.root_group = displayio.Group()
# enable REPL output to the TFT

Code: Select all

import displayio
board.DISPLAY.root_group = displayio.CIRCUITPYTHON_TERMINAL

User avatar
Thosch42
 
Posts: 5
Joined: Sun Jun 04, 2023 7:36 am

Re: ESP32-S3 TFT Serial Console on TFT top line

Post by Thosch42 »

Hi!
Ok, that's clear. I don't want to customize this output. I just want, that the output is correct. In particular, that the current IP address is displayed. That's all.
Therefor was my question, how to force an update of this line.

Greetings,
Thomas

User avatar
mikeysklar
 
Posts: 13936
Joined: Mon Aug 01, 2016 8:10 pm

Re: ESP32-S3 TFT Serial Console on TFT top line

Post by mikeysklar »

Since you only want to add the IP address to the output you can print it just before the row of '*' after GPX fix.

Code: Select all

print("ip address: " + wifi.radio.ipv4_address)

User avatar
Thosch42
 
Posts: 5
Joined: Sun Jun 04, 2023 7:36 am

Re: ESP32-S3 TFT Serial Console on TFT top line

Post by Thosch42 »

Of corse I could just print the IP address. But for what reason prints the REPL this faulty information? I just like to understand it and ideally fix it.

Locked
Please be positive and constructive with your questions and comments.

Return to “Feather - Adafruit's lightweight platform”