PRESTO WiFi demo

I’ve been playing with the new PRESTO board and thought I would share my latest project. It looks at a US website which records world-wide earthquakes. The program downloads the last 10 recoded quakes and displays the more interesting details on the screen. Extracting the data and getting it into a more useful format takes a fair bit of processing but is not too difficult.

Here is a link to the video: https://youtu.be/MOoyETQSido

The code is below:

# Test WIFI network DEMO on Pimoroni PRESTO
# Uses data from https://earthquake.usgs.gov
#   ==== Tony Goodhew 29th Dec 2024 ====
# Shows how to download data from a website, process it to
# extract what you need and display results
# on the 480x480 pixel screen
# Video at https://youtu.be/MOoyETQSido

import time
from random import randint
from presto import Presto
import network
import rp2
import requests
rp2.country("GB")
from secrets import WIFI_SSID, WIFI_PASSWORD

# Setup for the Presto display
presto = Presto(full_res=True)
display = presto.display

WIDTH, HEIGHT = display.get_bounds()

# Create some colours
BLUE = display.create_pen(20,0,255)
WHITE = display.create_pen(255, 255, 255)
RED = display.create_pen(255,0,0)
ORANGE = display.create_pen(245, 165, 4)
GREEN = display.create_pen(0,255,0)
PINK = display.create_pen(250, 125, 180)
CYAN = display.create_pen(0,255,255)
MAGENTA = display.create_pen(255,0,255)
BLACK = display.create_pen(0, 0, 0)
YELLOW = display.create_pen(255, 255, 0)

# A few procedures to be used later
def wait(z): # delay a while
    time.sleep(z)
    
def clean(): # Clear the screen to Black
    display.set_pen(BLACK)
    display.clear()
    presto.update()

# Routine to separate and extract data items from a single downloaded line
def splitup(s):
    string = ""
    items = []

    for p in range(len(s)):
        c = s[p]
#        print(type(c))
        if c != chr(124):
            string = string + c
        else:
            items.append(string)
            string = ""
    items.append(string)        

    # Extract date and time from second item
    dt = items[1]
    date = dt[0:10]
    ttime = dt[11:19]
    return(items,date,ttime)

display.set_font("bitmap8") # Change the font
clean()
display.set_pen(RED)
display.text("EarthQuake",40,200,460,8)
display.set_pen(BLUE)
display.text("Data from: https://earthquake.usgs.gov",70,400,480,2)
display.text("Tony Goodhew, Leicester UK",120,450,480,2)
presto.update()
time.sleep(1)

for p in range(35):
    display.set_pen(BLACK)
    display.rectangle(0,190,480,100)
    xx = randint(0,16)-8
    yy = randint(0,16)-8
    display.set_pen(ORANGE)
    display.text("EarthQuake",40+xx,200+yy,460,8)
    presto.update()
    time.sleep(0.07)
clean()
display.set_pen(RED)
display.text("EarthQuake",40,200,460,8)
presto.update()
time.sleep(0.6)

clean()
display.set_pen(RED)

# Activate WiFi 
wlan = network.WLAN(network.STA_IF)
wlan.active(True)

wlan.connect(WIFI_SSID, WIFI_PASSWORD)
max_wait = 30
while max_wait > 0:
    if wlan.status() < 0 or wlan.status() >= 3:
        break
    max_wait -= 1
    print("Waiting for Wi-Fi connection...")
    display.set_pen(RED)
    display.text("Waiting for Wi-Fi connection...",10,200,460,5)
    presto.update()
    time.sleep(1)

if wlan.status() != 3:
    raise RuntimeError("Network connection failed")
else:
    print("Connected to Wi-Fi network.")
    print(wlan.ifconfig())

clean()
display.set_pen(GREEN)
display.text("Connected to WiFi",50,200,460,5)
display.set_pen(BLUE)
display.text("   Processing",70,260,460,5)
presto.update()

# ===== Main Loop ====
while True:
    # Access EarthQuake website and get first 10 lines
    response = requests.get("https://earthquake.usgs.gov/fdsnws/event/1/query?format=text&limit=10")

    # Separate into lines
    lines = []
    for x in response.content.splitlines():
        xs = str(x)
#        print(str(xs))
        lines.append(str(x))
    response.close()


    clean()

    events = []
    for i in range(1,11):    
        k = splitup(lines[i]) # This does the major lifting using the proc above
#        print()
#        print(k)
        events.append(k)
    ''' 
    # List of items for information
    names = ['EventID', 'Time', 'Latitude', 'Longitude', 'Depth/km', 'Author', 'Catalog', 'Contributor',
             'ContributorID', 'MagType', 'Magnitude', 'MagAuthor', 'EventLocationName', 'Date', 'Time']
    '''

    # Show recent event high-lights
    for i in range(10):
        clean()
        display.set_pen(CYAN)
        if i == 0:
            display.set_pen(RED) # Most recent quake
            
        k,date,ttime = events[i] # Fetch decoded quake data line

        display.text(date + "  --  " + ttime,30,0,460,4)
        display.set_pen(YELLOW)
        place = k[12]
        place = place[:-1]  # remove final quote character
        display.text(place,0,40,460,4)
        lat = round(float(k[2]),3)
        long = round(float(k[3]),3)
        display.text("Lat/Lon: "+str(lat) + " "+ str(long),0,200,460,4)
        display.text("Magnitude: " + k[10],0,260,460,4)
        display.text("Type: " + k[9],0,320,460,4)
        deep = round(float(k[4]),3)
        display.text("Depth/km: "+ str(deep),0,380,460,4)
        display.set_pen(ORANGE)
        display.text(str(i),460,440,100,4)
        presto.update()
        wait(4)

I’m delighted with this board. Great graphics with so much screen space, plenty of memory, wifi, and i2c port. Software may be Beta but is working well.!

I was surprised to find out how many earthquakes are happening. The RED date and time at the top of the screen is the latest quake and the numbers at the bottom right count quakes backwards.

Comments and discussion welcome. Let’s share our projects to help others.

1 Like

Great work. very impressive. I received my Presto today and am having trouble getting the display to work with a modified BME688 py from enviro samples

Mac, Thank you for your comment.

May I suggest you start a new support post with your BME688 problem explaining what is not happening as expected. Someone with a solution is more likely to see it there.

I’ve added a refinement to the Earthquake program. You can now halt the running by touching the screen. (“Do not start anything you cannot stop!”)

This was not trivial. I needed to break out of nested loops and using time.sleep(4) to put a delay in the loop turns off everything - including touch. The updated code is below.

# Test WIFI network DEMO on Pimoroni PRESTO - Vers 2 with Touch Halt
# Uses data from https://earthquake.usgs.gov
#   ==== Tony Goodhew 30th Dec 2024 ====
# Shows how to download data from a website, process it to
# extract what you need and display results
# on the 480x480 pixel screen
# Video at https://youtu.be/MOoyETQSido

# Touching the screen halts the program

import time
from random import randint
from presto import Presto
import network
import rp2
import requests
rp2.country("GB")
from secrets import WIFI_SSID, WIFI_PASSWORD

# Setup for the Presto display
presto = Presto(full_res=True)
display = presto.display

WIDTH, HEIGHT = display.get_bounds()

touch = presto.touch # Activate touch

# Create some colours
BLUE = display.create_pen(20,0,255)
WHITE = display.create_pen(255, 255, 255)
RED = display.create_pen(255,0,0)
ORANGE = display.create_pen(245, 165, 4)
GREEN = display.create_pen(0,255,0)
PINK = display.create_pen(250, 125, 180)
CYAN = display.create_pen(0,255,255)
MAGENTA = display.create_pen(255,0,255)
BLACK = display.create_pen(0, 0, 0)
YELLOW = display.create_pen(255, 255, 0)

# A few procedures to be used later
def wait(z): # delay a while
    time.sleep(z)
    
def clean(): # Clear the screen to Black
    display.set_pen(BLACK)
    display.clear()
    presto.update()

# Routine to separate and extract data items from a single downloaded line
def splitup(s):
    string = ""
    items = []

    for p in range(len(s)):
        c = s[p]
#        print(type(c))
        if c != chr(124):
            string = string + c
        else:
            items.append(string)
            string = ""
    items.append(string)        

    # Extract date and time from second item
    dt = items[1]
    date = dt[0:10]
    ttime = dt[11:19]
    return(items,date,ttime)

display.set_font("bitmap8") # Change the font
clean()
display.set_pen(RED)
display.text("EarthQuake",40,200,460,8)
display.set_pen(BLUE)
display.text("Data from: https://earthquake.usgs.gov",70,400,480,2)
display.text("Tony Goodhew, Leicester UK",120,450,480,2)
presto.update()
time.sleep(1)

for p in range(35):
    display.set_pen(BLACK)
    display.rectangle(0,190,480,100)
    xx = randint(0,16)-8
    yy = randint(0,16)-8
    display.set_pen(ORANGE)
    display.text("EarthQuake",40+xx,200+yy,460,8)
    presto.update()
    time.sleep(0.07)
clean()
display.set_pen(RED)
display.text("EarthQuake",40,200,460,8)
presto.update()
time.sleep(0.6)

clean()
display.set_pen(RED)

# Activate WiFi 
wlan = network.WLAN(network.STA_IF)
wlan.active(True)

wlan.connect(WIFI_SSID, WIFI_PASSWORD)
max_wait = 30
while max_wait > 0:
    if wlan.status() < 0 or wlan.status() >= 3:
        break
    max_wait -= 1
    print("Waiting for Wi-Fi connection...")
    display.set_pen(RED)
    display.text("Waiting for Wi-Fi connection...",10,200,460,5)
    presto.update()
    time.sleep(1)

if wlan.status() != 3:
    raise RuntimeError("Network connection failed")
else:
    print("Connected to Wi-Fi network.")
    print(wlan.ifconfig())

clean()
display.set_pen(GREEN)
display.text("Connected to WiFi",50,200,460,5)
display.set_pen(BLUE)
display.text("   Processing",70,260,460,5)
presto.update()

# ===== Main Loop ====
running = True # Main loop flag
while running:
    # Access EarthQuake website and get first 10 lines
    response = requests.get("https://earthquake.usgs.gov/fdsnws/event/1/query?format=text&limit=10")

    # Separate into lines
    lines = []
    for x in response.content.splitlines():
        xs = str(x)
#        print(str(xs))
        lines.append(str(x))
    response.close()

    clean()

    events = []
    for i in range(1,11):    
        k = splitup(lines[i]) # This does the major lifting using the proc above
#        print()
#        print(k)
        events.append(k)
    ''' 
    # List of items for information
    names = ['EventID', 'Time', 'Latitude', 'Longitude', 'Depth/km', 'Author', 'Catalog', 'Contributor',
             'ContributorID', 'MagType', 'Magnitude', 'MagAuthor', 'EventLocationName', 'Date', 'Time']
    '''

    # Show recent event high-lights
    for i in range(10):
        clean()
        display.set_pen(CYAN)
        if i == 0:
            display.set_pen(RED) # Most recent quake
            
        k,date,ttime = events[i] # Fetch decoded quake data line

        display.text(date + "  --  " + ttime,30,0,460,4)
        display.set_pen(YELLOW)
        place = k[12]
        place = place[:-1]  # remove final quote character
        display.text(place,0,40,460,4)
        lat = round(float(k[2]),3)
        long = round(float(k[3]),3)
        display.text("Lat/Lon: "+str(lat) + " "+ str(long),0,200,460,4)
        display.text("Magnitude: " + k[10],0,260,460,4)
        display.text("Type: " + k[9],0,320,460,4)
        deep = round(float(k[4]),3)
        display.text("Depth/km: "+ str(deep),0,380,460,4)
        display.set_pen(ORANGE)
        display.text(str(i),460,440,100,4)
        presto.update()

        # Time delay loop - Cannot use time.sleep()
        # Touching the screen halts the program
        deadline = time.ticks_ms() + 3000
        while time.ticks_ms() < deadline:
            touch.poll()
            if touch.state:
                clean()
                presto.update()
                running = False # Reset flag to finish main loop
                i = 10
                break  # Out of while loop
        if running == False:
            break  # Out of counted 'i' loop
        
print("\nTerminated by screen touch")

2 Likes

Thanks for sharing this demo Tony, it will help with the project I have in mind.

I received my Presto today, I want to try using the Piezo speaker to make a sound when a new alert comes in. Have you tried using the Piezo speaker?

If you look at the schematic it is on GPIO pin 43

I tried changing this demo from Cytronic but it is very quiet (much to the delight of my wife, who hates computer generated ‘tunes’.)

###  This example code uses: Maker Pi Pico ;; Reference: www.cytron.io/p-maker-pi-pico

import machine
import utime
from pitches import *

# Melody Mario

#buzzer = machine.PWM(machine.Pin(18))  # set pin 18 as PWM OUTPUT

buzzer = machine.PWM(machine.Pin(43))  # set pin 43 as PWM OUTPUT PRESTO

# mario notes
mario = [E7, E7, 0, E7, 0, C7, E7, 0, G7, 0, 0, 0, G6, 0, 0, 0, C7, 0, 0, G6, 0, 0, E6, 0, 0, A6, 0, B6, 0, AS6, A6, 0, G6, E7, 0, G7, A7, 0, F7, G7, 0, E7, 0,C7, D7, B6, 0, 0, C7, 0, 0, G6, 0, 0, E6, 0, 0, A6, 0, B6, 0, AS6, A6, 0, G6, E7, 0, G7, A7, 0, F7, G7, 0, E7, 0,C7, D7, B6, 0, 0]

for i in mario:
    if i == 0:
        buzzer.duty_u16(0)            # 0% duty cycle
    else:
        buzzer.freq(i)                # set frequency (notes)
    #    buzzer.duty_u16(19660)        # 30% duty cycle
        buzzer.duty_u16(60000)        # Louder - but not much
    utime.sleep(0.15)

It needs the following stored library, pitches.py:

B0  = 31
C1  = 33
CS1 = 35
D1  = 37
DS1 = 39
E1  = 41
F1  = 44
FS1 = 46
G1  = 49
GS1 = 52
A1  = 55
AS1 = 58
B1  = 62
C2  = 65
CS2 = 69
D2  = 73
DS2 = 78
E2  = 82
F2  = 87
FS2 = 93
G2  = 98
GS2 = 104
A2  = 110
AS2 = 117
B2  = 123
C3  = 131
CS3 = 139
D3  = 147
DS3 = 156
E3  = 165
F3  = 175
FS3 = 185
G3  = 196
GS3 = 208
A3  = 220
AS3 = 233
B3  = 247
C4  = 262
CS4 = 277
D4  = 294
DS4 = 311
E4  = 330
F4  = 349
FS4 = 370
G4  = 392
GS4 = 415
A4  = 440
AS4 = 466
B4  = 494
C5  = 523
CS5 = 554
D5  = 587
DS5 = 622
E5  = 659
F5  = 698
FS5 = 740
G5  = 784
GS5 = 831
A5  = 880
AS5 = 932
B5  = 988
C6  = 1047
CS6 = 1109
D6  = 1175
DS6 = 1245
E6  = 1319
F6  = 1397
FS6 = 1480
G6  = 1568
GS6 = 1661
A6  = 1760
AS6 = 1865
B6  = 1976
C7  = 2093
CS7 = 2217
D7  = 2349
DS7 = 2489
E7  = 2637
F7  = 2794
FS7 = 2960
G7  = 3136
GS7 = 3322
A7  = 3520
AS7 = 3729
B7  = 3951
C8  = 4186
CS8 = 4435
D8  = 4699
DS8 = 4978

Cannot find any other info at the moment.

1 Like

That worked, perfect, thanks Tony. Agree it is quiet, but it will be fine for a discreet notification sound.