Halloween project : "eye-candy" do nothing box with 1.3" round LCD how to generate a waveform to display

I’m working on an eye-candy box for Halloween. I’m going to add the 1.3" round SPI LCD and I want to display a waveform(s). It’s connected to a Pi Pico running micropyhthon (new language for me).

Best case scenario it would look like an old Heathkit oscilloscope display of a sine wave. Kinda fuzzy and green.

I came across Peter Hinch’s Github and wondered if anyone knew how hard it would be to make this work the 1.3" round LCD? I wouldn’t be measuring anything just outputting some random data to plot.

I’m looking at the last 2 images here, the waveform plots (Nyquist and Bode)

@Tonygo2 is the guy to talk to. IMHO anyway.
Raspberry Pi Pico & Pico Explorer Workout : 15 Steps - Instructables

I’ve not got the round version but it appears to be programmed like the square version but does not show all the pixels.
I’m happy to help if you provide more details.
I think you need several cycles with quite large amplitude. Is that correct?

Yes. I was toying with the idea. I suppose the easiest method would be to fire up the Tektronix (2465A) in the corner and just record a short movie and turn it into a GIF.

The round LCD is 240x240. as you mentioned it will cut off the edge, not an issue for my usage. It uses the same ST7789 controller as the square version.

The version on Github uses the SSD1963.
Since this is a potential driver issue vs translating between two language, e.g. c to python, I was thinking that I would just need to go through the code and replace the SSD1963 functions/files with the appropriate ST7789 ones

Here is some code to produce a suggested sine trace in green. It works on my 240x240 Pico Explorer screen. Hope this helps.

# "Oscilloscope Sine trace"
# For 240x240 pixel display
# Tony Goodhew 20 Feb 2022
import picoexplorer as display
import utime, random, math
width = display.get_width()
height = display.get_height()
display_buffer = bytearray(width * height * 2)
display.init(display_buffer)


def horiz(l,t,r):  # left, right , top
    n = r-l+1        # Horizontal line
    for i in range(n):
        display.pixel(l + i, t)

def vert(l,t,b):   # left, top, bottom
    n = b-t+1      # Vertical line
    for i in range(n):
        display.pixel(l, t+i)

def box(l,t,r,b):  # left, top, right, bottom
    horiz(l,t,r)   # Hollow rectangle
    horiz(l,b,r)
    vert(l,t,b)
    vert(r,t,b)

def line(x,y,xx,yy): # (x,y) to (xx,yy)
    if x > xx:
        t = x  # Swap co-ordinates if necessary
        x = xx
        xx = t
        t = y
        y = yy
        yy = t
    if xx-x == 0:  # Avoid div by zero if vertical
        vert(x,min(y,yy),max(y,yy))
    else:          # Draw line one dot at a time L to R
        n=xx-x+1
        grad = float((yy-y)/(xx-x))  # Calculate gradient
        for i in range(n):
            y3 = y + int(grad * i)
            display.pixel(x+i,y3)  # One dot at a time
            
display.set_pen(0,0,0)
display.clear()
display.update()

display.set_pen(0,200,0)
display.text("Drawing Graphs", 20, 70, 200, 4)
display.update()
utime.sleep(2)

display.set_pen(0,0,0)
display.clear()
display.update()
factor = 361 /60 # change the 60 to alter number of cycles
#sine = []
display.set_pen(0,200,0)
horiz(0,120,239)    
display.update()
display.set_pen(0,200,0)
for x in range(0,240):
    y = int ((math.sin(math.radians(x * factor)))* -70) + 120
#    sine.append(element)
    display.pixel(x,y)
#display.text("Sine", 40, 70, 200, 2)
display.update()

Please, let me know how you get on.

1 Like

That should work quite nicely. Thank you.

Yes, thanks Tony. Just had a look see myself, I can see that becoming my new display test file. Retired electronic technician, that brings back lots of memories. =)

The 1.54 240x240 square here.

Looks like the screen corruption has now been fixed with a new UF2 (.18)
Pico Explorer screen corruption and communication crashes - Support - Pimoroni Buccaneers

Great news!

@Tonygo2, I like the drawing code and your other code on the instructables page, it looks good.

I’ve got a Pico Explorer but haven’t used it much yet, I’ve done a little more with the PicoSystem I got. I didn’t realise until today that the MicroPython APIs for those two are very different though I think they might use the same screens. My maths is a bit rusty too, it will take a bit more looking to see how to correctly tweak the waveform :).

I’ve include a quick PicoSystem version below. I cannot remember if you can swap to 240x240 resolution in MicroPython or not without recompiling the UF2 file, so it doesn’t look as good at 120x120 but maybe it could be tweaked some more.

# Based on the demo from here:
# https://forums.pimoroni.com/t/halloween-project-eye-candy-do-nothing-box-with-1-3-round-lcd-how-to-generate-a-waveform-to-display/18914/5
# "Oscilloscope Sine trace"
# For 240x240 pixel display
# Tony Goodhew 20 Feb 2022

# Version for PicoSystem by Kihonkai 06-Mar-2022

import utime, random, math

# Assumes current default of PIXEL_DOUBLE 120x120 from pimoroni / picosystem release build.
# It could be 240x240 without that option
SCREEN_WIDTH = 120
SCREEN_HEIGHT = 120

pen(0,0,0)
clear()
flip() # replaces update()

pen(0,7,0)
text("Drawing Graphs", 20, 70, 200) # no scale, text("Drawing Graphs", 20, 70, 200, 4)
flip()
utime.sleep(2)

pen(0,0,0)
clear()
flip()
factor = 361 /30 # change the 60 to alter number of cycles
#sine = []
pen(0,7,0)
hline(0,60, 120) #replaced horiz(0,60,119)
flip()
pen(0,7,0)
for x in range(0,120):
    y = int ((math.sin(math.radians(x * factor)))* - 45) + 60
#    sine.append(element)
    pixel(x,y)
#display.text("Sine", 40, 70, 200, 2)
flip()

# Only a quick demo, not using the methods for PicoSystem MicroPython code
def update(tick):
    pass

def draw(tick):
    pass

Glad you are making progress.