[Pico][1.19] Breakout Garden Base + BME688 + 1.54" LCD

Hi how you all doing?

First post, actually second. Just deleted my first post.

Attached is my Shell (pico uf2 1.19) output, returned error when import 240x240 lcd.
Any pointers?
Thank you all in advance.

Tony

MicroPython v1.19 on 2022-07-04; Raspberry Pi Pico with RP2040
Type "help()" for more information.

 from picographics import PicoGraphics, DISPLAY_LCD_240x240

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: can't import name DISPLAY_LCD_240x240

Are you running our custom version of MicroPython? Available from here: Releases · pimoroni/pimoroni-pico · GitHub

(Also I just updated the 240 x 240 square breakout example to work with PicoGraphics - it’s not yet merged in but you can find the updated version here!).

Change the 240x240 to 240X240 and it will work ;)

Hi hel thanks for your time.

Yes, I did download 1.19.0 from that URL. botsel and Dropped onto Rpi2 drive, and the drive disconnected right after(normal?)
I tried on two pico units multiple times and same result. My system (mac and a Pi4) did mention improper drive disconnect everytime, though.

However, I did saw in Thonny’s shell prompt shows MicroPython v.1.19, so I assume dropping that uf2 file went alright. yes?

Thank you, will check it out.

Hi alphanumeric,

No kidding, that did it!
You saved my day!

Thank you

1 Like

It caught me out to, that’s how l knew the fix. Had me scratching my head for a bit.

@alphanumeric

I got a pico, breakout garden base, a 240 SPI LCD, and BME688.
I am trying to get it to work, I got the rest of the code ready (yea from your other post, and hey thanks!)
However the new picographics require to rewrite the display part, and I am just trying to get through this display part, then I believe I am good to go for now.

Well, back to work now, will post result once I got it working. :-)

This is what I did. It needs to be 240X240 in both spots.

import picographics
from picographics import PicoGraphics, DISPLAY_LCD_240X240, PEN_RGB332

display = PicoGraphics(display=DISPLAY_LCD_240X240, rotate=0, pen_type=PEN_RGB332)
display.set_backlight(1.0)

@alphanumeric Thank you again.

I believe I am very close. Hopefully last question.
How would one declare a bme688 breakout sensor in the code if they don’t have to switch sockets, like you did in your other post?

You had:
i2c = PimoroniI2C(sda=(4), scl=(5))
bme = BreakoutBME68X(i2c)

That should be fine, it’s not the socket, its the i2c address. The BME280 had its address jumper cut and was using 0x77 instead of the stock 0x76.
This is what I’m using with a single display and a BME280. Edit the BME280 to the code needed for a BME68X and it will work.

'''
pimoroni-pico-v1.19.0-micropython
pico with lipo shim
pico breakout garden base
2.1" 240x240 color LCD breakout
BME280
'''
import utime
import picographics

from breakout_bme280 import BreakoutBME280
from pimoroni_i2c import PimoroniI2C
from picographics import PicoGraphics, DISPLAY_LCD_240X240, PEN_RGB332

display = PicoGraphics(display=DISPLAY_LCD_240X240, rotate=0, pen_type=PEN_RGB332)
display.set_backlight(1.0)

PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5}
PINS_PICO_EXPLORER = {"sda": 20, "scl": 21}
i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN)

bme = BreakoutBME280(i2c)



# lets set up some pen colors to make drawing easier
tempcolor = display.create_pen(0, 255, 0)  # this colour will get changed in a bit
humidcolor = display.create_pen(0, 255, 0)  # this colour will get changed in a bit
presscolor = display.create_pen(0, 255, 0)  # this colour will get changed in a bit
white = display.create_pen(255, 255, 255)
black = display.create_pen(0, 0, 0)
red = display.create_pen(255, 0, 0)
green = display.create_pen(0, 255, 0)
blue = display.create_pen(0, 0, 255)
yellow = display.create_pen(255, 255, 0)
orange = display.create_pen(255, 140, 0)
grey = display.create_pen(120, 120, 120)
violet = display.create_pen(255, 0, 255)

# converts the temperature into a description and pen colour
def describe_temperature(temperature):
    global tempcolor
    if temperature < 0:
        description = "very cold"
        tempcolor = blue
    elif 0 <= temperature < 12:
        description = "cold"
        tempcolor = yellow
    elif 12 <= temperature < 17:
        description = "cool"
        tempcolor = green
    elif 17 <= temperature < 25:
        description = "warm"
        tempcolor = green      
    elif 25 <= temperature < 30:
        description = "hot"
        tempcolor = orange
    elif temperature >= 30:
        description = "very hot"
        tempcolor = red
    else:
        description = ""
        tempcolor = black
    return description

min_temp = None
max_temp = None


# converts humidity into good/bad description and pen color
def describe_humidity(humidity):
    global humidcolor
    if humidity < 30:
        description = "low dry"
        humidcolor = orange
    elif 30 <= humidity < 61:
        description = "ok"
        humidcolor = green
    elif 61 <= humidity < 81:
        description = "high"
        humidcolor = yellow
    elif humidity >= 81:
        description = "very high"
        humidcolor = red        
    else:
        description = ""
        humidcolor = black        
    return description


# converts pressure into barometer-type description and pen color
def describe_pressure(pressure):
    global presscolor
    if pressure < 982:
        description = "very low"
        presscolor = red
    elif 982 <= pressure < 1004:
        description = "low"
        presscolor = yellow
    elif 1004 <= pressure < 1026:
        description = "unsettled"
        presscolor = green
    elif 1026 <= pressure < 1048:
        description = "high"
        presscolor = blue
    elif pressure >= 1048:
        description = "very high"
        presscolor = orange
    else:
        description = ""
        presscolor = black
    return description


start_time = utime.time()

while True:
    
    time_elapsed = utime.time() - start_time
    
    # read the sensors
    temperature, pressure, humidity = bme.read() 
            
    # convert pressure to mb
    pressuremb = pressure / 100
    
    # draw a barometer
    display.set_pen(grey)
    display.circle(200, 190, 20)
    display.rectangle(190, 14, 23, 160)
    display.set_pen(presscolor)
    display.circle(200, 190, 10)
    barometerheight = int((pressuremb - 960) * 1.4)
    if barometerheight > 150:
        barometerheight = 150
    if barometerheight < 1:
        barometerheight = 1
    display.rectangle(196, 60 + 120 - barometerheight, 10, barometerheight)
    
    # drawing the pressure reading
    display.set_pen(presscolor)
    display.text('{:.0f}'.format(pressuremb) + 'mb', 10, 140, 240, 5)
    display.set_pen(white)
    display.text(describe_pressure(pressuremb), 10, 170, 240, 3)
    display.set_pen(white)
    
    # and the humidity reading
    display.set_pen(humidcolor)
    display.text('{:.0f}'.format(int(humidity)) + '%', 10, 85, 240, 5)
    display.set_pen(white)
    display.text(describe_humidity(int(humidity)), 10, 115, 240, 3)
        
    # and the temperature reading
    display.set_pen(tempcolor)
    display.text('{:.1f}'.format(temperature) + '`c', 10, 10, 240, 5)
    display.set_pen(white)
    display.text(describe_temperature(temperature), 10, 40, 240, 3)
    
    # and the min max temperature readings
    if time_elapsed > 15:
        if min_temp is not None and max_temp is not None:
            if temperature < min_temp:
                min_temp = int(temperature)
            elif temperature > max_temp:
                max_temp = int(temperature)
        else:
            min_temp = int(temperature)
            max_temp = int(temperature)
            
    if min_temp is not None and max_temp is not None:
        min_string = ('{:.0f}'.format(min_temp))
        max_string = ('{:.0f}'.format(max_temp))
        range_string = (min_string) + ' - ' + (max_string)
    else:
        range_string = ""
        
    display.set_pen(white)
    display.text(range_string, 10, 60, 240, 3)
           
    # time to update the display
    display.update()
    utime.sleep(1)
    display.set_pen(black)
    display.clear()
        
     

It’s working~!!! Tears of joy.
Going to figure out how to make that code box in reply.
Would like to post the code to share, and figure out a way to upload a pic,too. :-)

Code tags are 3 ` at the top of your code and 3 more at the end. It’s the ~ key under the esc key.
To add a picture just drag and drop into your post.

1 Like

Thanks for helping @alphanumeric @hel
Below is the code.

pico + uf2 v.1.19
Breakout Garden Base
1.54" breakout LCD 240X240
BME688 4in1 breakout sensor

'''
pimoroni-pico-v1.19.0-micropython
pico breakout garden base
1.54" 240x240 color LCD breakout
BME6884in1 breakout
'''
import utime
import picographics

from breakout_bme68x import BreakoutBME68X
from pimoroni_i2c import PimoroniI2C
from picographics import PicoGraphics, DISPLAY_LCD_240X240, PEN_RGB332

display = PicoGraphics(display=DISPLAY_LCD_240X240, rotate=0, pen_type=PEN_RGB332)
display.set_backlight(0.5)

PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5}
i2c = PimoroniI2C(**PINS_BREAKOUT_GARDEN)

bme = BreakoutBME68X(i2c)

grey = display.create_pen(120, 120, 120)
violet = display.create_pen(255, 0, 255)

# lets set up some pen colors to make drawing easier
tempcolor = display.create_pen(0, 255, 0)  # this colour will get changed in a bit
humidcolor = display.create_pen(0, 255, 0)  # this colour will get changed in a bit
presscolor = display.create_pen(0, 255, 0)  # this colour will get changed in a bit
white = display.create_pen(255, 255, 255)
black = display.create_pen(0, 0, 0)
red = display.create_pen(255, 0, 0)
green = display.create_pen(0, 255, 0)
blue = display.create_pen(0, 0, 255)
yellow = display.create_pen(255, 255, 0)
orange = display.create_pen(255, 140, 0)


# converts the temperature into a description and pen colour
def describe_temperature(temperature):
    global tempcolor
    if temperature < 0:
        description = "very cold"
        tempcolor = blue
    elif 0 <= temperature < 12:
        description = "cold"
        tempcolor = yellow
    elif 12 <= temperature < 17:
        description = "cool"
        tempcolor = green
    elif 17 <= temperature < 25:
        description = "warm"
        tempcolor = green      
    elif 25 <= temperature < 30:
        description = "hot"
        tempcolor = orange
    elif temperature >= 30:
        description = "very hot"
        tempcolor = red
    else:
        description = ""
        tempcolor = black
    return description

min_temp = None
max_temp = None


# converts humidity into good/bad description and pen color
def describe_humidity(humidity):
    global humidcolor
    if humidity < 30:
        description = "low dry"
        humidcolor = orange
    elif 30 <= humidity < 61:
        description = "ok"
        humidcolor = green
    elif 61 <= humidity < 81:
        description = "high"
        humidcolor = yellow
    elif humidity >= 81:
        description = "very high"
        humidcolor = red        
    else:
        description = ""
        humidcolor = black        
    return description


# converts pressure into barometer-type description and pen color
def describe_pressure(pressure):
    global presscolor
    if pressure < 982:
        description = "very low"
        presscolor = red
    elif 982 <= pressure < 1004:
        description = "low"
        presscolor = yellow
    elif 1004 <= pressure < 1026:
        description = "unsettled"
        presscolor = green
    elif 1026 <= pressure < 1048:
        description = "high"
        presscolor = blue
    elif pressure >= 1048:
        description = "very high"
        presscolor = orange
    else:
        description = ""
        presscolor = black
    return description


start_time = utime.time()

while True:
    
    time_elapsed = utime.time() - start_time
    
    # read the sensors
    temperature, pressure, humidity, gas_resistance, status, gas_index, meas_index = bme.read()
            
    # convert pressure to mb
    pressuremb = pressure / 100
    
    # draw a barometer
    display.set_pen(grey)
    display.circle(200, 190, 20)
    display.rectangle(190, 14, 23, 160)
    display.set_pen(presscolor)
    display.circle(200, 190, 10)
    barometerheight = int((pressuremb - 960) * 1.4)
    if barometerheight > 150:
        barometerheight = 150
    if barometerheight < 1:
        barometerheight = 1
    display.rectangle(196, 60 + 120 - barometerheight, 10, barometerheight)
    
    # drawing the pressure reading
    display.set_pen(presscolor)
    display.text('{:.0f}'.format(pressuremb) + 'mb', 10, 140, 240, 5)
    display.set_pen(white)
    display.text(describe_pressure(pressuremb), 10, 170, 240, 3)
    display.set_pen(white)
    
    # and the humidity reading
    display.set_pen(humidcolor)
    display.text('{:.0f}'.format(int(humidity)) + '%', 10, 85, 240, 5)
    display.set_pen(white)
    display.text(describe_humidity(int(humidity)), 10, 115, 240, 3)
        
    # and the temperature reading
    display.set_pen(tempcolor)
    display.text('{:.1f}'.format(temperature) + '`c', 10, 10, 240, 5)
    display.set_pen(white)
    display.text(describe_temperature(temperature), 10, 40, 240, 3)
    
    # and the min max temperature readings
    if time_elapsed > 15:
        if min_temp is not None and max_temp is not None:
            if temperature < min_temp:
                min_temp = int(temperature)
            elif temperature > max_temp:
                max_temp = int(temperature)
        else:
            min_temp = int(temperature)
            max_temp = int(temperature)
            
    if min_temp is not None and max_temp is not None:
        min_string = ('{:.0f}'.format(min_temp))
        max_string = ('{:.0f}'.format(max_temp))
        range_string = (min_string) + ' - ' + (max_string)
    else:
        range_string = ""
        
    display.set_pen(white)
    display.text(range_string, 10, 60, 240, 3)
           
    # time to update the display
    display.update()
    utime.sleep(1)
    display.set_pen(black)
    display.clear()

I got a SCD41 breakout too.
Next, try to add it into current setup and display it. :-)

I tried upload photo, I guess my current forum level is not there yet. Maybe later~

If you reduce the size of the text, you can reduce the spacing between lines of text to get more lines of text. That or take out the min max temperature.

The last number in the display text line is the text size. Change the 5 to 4 and it gets smaller etc. The first two numbers are the position.

1 Like

Actually, you should have some empty space at the bottom, where I have my battery state displayed.

@alphanumeric

Got it, thanks for the pointers. I will dance with them this time.
The min max temp is a keeper. I will probably let go of the barometer and descriptions, leaving only fixed color numbers and symbols. Enlarge them to fit the screen, and the cherry on top for me would be a JPG background.

By the way, the picographic display.text() in above code takes 5 variables. But their documents mention 7 variables. Are they the same display.text ?
How do I know which one I am working with? How would one skip the variables in between?

Drawing Text

Write some text:

display.text(text, x, y, wordwrap, scale, angle, spacing)

    text - the text string to draw
    x - the destination X coordinate
    y - the destination Y coordinate
    wordwrap - number of pixels width before trying to break text into multiple lines
    scale - size
    angle - rotation angle (Vector only!)
    spacing - letter spacing

Text scale can be a whole number (integer) for Bitmap fonts, or a decimal (float) for Vector (Hershey) fonts.

You don’t need all 7 of them, I’ve been dropping the wordwrap. If you leave some out you do need to specify what the next one is though, for example.
display.text(Hello, 0, 10, 240, 5)
becomes
display.text(Hello, 0, 10, scale = 5)
Both will work. eventually I’m going to try and migrate all my code to the second one.

The lowest bit of text your displaying should be
display.text(describe_pressure(pressuremb), 10, 170, 240, 3)
That’s at 170, you can go down as far as 240. Go farther than 240 and it will be off the bottom of the screen.

2 Likes