Pico Graphics "display.set_pen"?

Ok,
display.set_pen(0) is black
and
display.set_pen(255) is white
How does one figure out what to use for Blue, Green, Yellow etc?

1 Like

To put a bit of context on this, I’m running a custom dual display setup. The following code works, but IMHO, its a bit of a fab.

import time
import pimoroni_bus
import picographics

from picographics import PicoGraphics, DISPLAY_PICO_DISPLAY_2, get_buffer_size, PEN_RGB332
from pimoroni_bus import SPIBus

spibus_R = SPIBus(cs=17, dc=16, sck=18, mosi=19, bl=20)
spibus_L = SPIBus(cs=22, dc=16, sck=18, mosi=19, bl=21)

buffer = bytearray(get_buffer_size(DISPLAY_PICO_DISPLAY_2, PEN_RGB332))

display_R = PicoGraphics(display=DISPLAY_PICO_DISPLAY_2, rotate=90, buffer = buffer, bus=spibus_R, pen_type=PEN_RGB332)
display_L = PicoGraphics(display=DISPLAY_PICO_DISPLAY_2, rotate= 90, buffer = buffer, bus=spibus_L, pen_type=PEN_RGB332)

display_R.set_backlight(1.0)
display_L.set_backlight(1.0)

white = display_R.create_pen(255, 255, 255)
black = display_R.create_pen(0, 0, 0)
red = display_R.create_pen(255, 0, 0)
green = display_R.create_pen(0, 255, 0)
blue = display_R.create_pen(0, 0, 255)
yellow = display_R.create_pen(255, 255, 0)
orange = display_R.create_pen(255, 140, 0)
grey = display_R.create_pen(175, 175, 175)
violet = display_R.create_pen(255, 0, 255)
aqua = display_R.create_pen(255, 0, 255)



display_R.set_font("bitmap8")
display_L.set_font("bitmap8")


while True:
    display_R.set_pen(blue)
    display_R.clear()
    display_R.update()
    display_R.set_pen(0)
    display_R.text("Display R", 10, 10, 240, 5)
    display_R.update()
    display_R.clear()
    
    display_L.set_pen(green)
    display_L.clear()
    display_L.update()
    display_L.set_pen(black)
    display_L.text("Display L", 10, 10, 240, 5)
    display_L.update()
    display_L.clear()
    
    time.sleep(2)

    display_R.set_pen(green)
    display_R.clear()
    display_R.update()
    display_R.set_pen(black)
    display_R.text("Display R Right Side", 10, 10, 240, 5)
    display_R.update()
    display_R.clear()
    
    display_L.set_pen(aqua)
    display_L.clear()
    display_L.update()
    display_L.set_pen(black)
    display_L.text("Display L Left Side", 10, 10, 240, 5)
    display_L.update()
    display_L.clear()
    
    time.sleep(2)
    
    display_R.set_pen(aqua)
    display_R.clear()
    display_R.update()
    display_R.set_pen(black)
    display_R.text("Display R Right Side SPI_0", 10, 10, 240, 5)
    display_R.update()
    display_R.clear()
    
    display_L.set_pen(red)
    display_L.clear()
    display_L.update()
    display_L.set_pen(black)
    display_L.text("Display L Left Side SPI_0", 10, 10, 240, 5)
    display_L.update()
    display_L.clear()
    
    time.sleep(2)
    
    display_R.set_pen(red)
    display_R.clear()
    display_R.update()
    display_R.set_pen(black)
    display_R.text("Display R Right Side SPI_0   cs=(17)", 10, 10, 240, 5)
    display_R.update()
    display_R.clear()
    
    display_L.set_pen(violet)
    display_L.clear()
    display_L.update()
    display_L.set_pen(black)
    display_L.text("Display L Left Side SPI_0   cs=(22)", 10, 10, 240, 5)
    display_L.update()
    display_L.clear()
    
    time.sleep(2)
    
    display_R.set_pen(violet)
    display_R.clear()
    display_R.update()
    display_R.set_pen(black)
    display_R.text("Display R Right Side SPI_0   cs=(17) bl=(20)", 10, 10, 240, 5)
    display_R.update()
    display_R.clear()
    
    display_L.set_pen(yellow)
    display_L.clear()
    display_L.update()
    display_L.set_pen(black)
    display_L.text("Display L Left Side SPI_0   cs=(22) bl=(21)", 10, 10, 240, 5)
    display_L.update()
    display_L.clear()
    
    time.sleep(2)
    
    display_R.set_pen(yellow)
    display_R.clear()
    display_R.update()
    display_R.set_pen(black)
    display_R.text("Display R Right Side SPI_0   cs=(17) bl=(20) 240x320", 10, 10, 240, 5)
    display_R.update()
    display_R.clear()
    
    display_L.set_pen(orange)
    display_L.clear()
    display_L.update()
    display_L.set_pen(black)
    display_L.text("Display L Left Side SPI_0   cs=(22) bl=(21) 240x320", 10, 10, 240, 5)
    display_L.update()
    display_L.clear()
    
    time.sleep(2)
    
    display_R.set_pen(orange)
    display_R.clear()
    display_R.update()
    display_R.set_pen(black)
    display_R.text("Display R Right Side SPI_0   cs=(17) bl=(20) 240x320 Portrait", 10, 10, 240, 5)
    display_R.update()
    display_R.clear()
    
    display_L.set_pen(blue)
    display_L.clear()
    display_L.update()
    display_L.set_pen(black)
    display_L.text("Display L Left Side SPI_0   cs=(22) bl=(21) 240x320 Portrait", 10, 10, 240, 5)
    display_L.update()
    display_L.clear()
    
    time.sleep(2)

Trying to use blue = display.create_pen(0, 0, 255) gets me a display not defined error.
And
display_R.set_pen(0, 0, 255)
gets me a TypeError: function takes 2 positional arguments but 4 were given

I think your existing approach is correct; create_pen creates (and returns) a new palette entry, which you can then use with set_pen.

The palette entries are tied to a specific display instance, so you’ll need to define them both on display_L and display_R (although as you’re sharing the buffer between them maybe it just … works itself out?)

I’m guessing your blue == display.create_pen example blows up because you meant display_L (or _R)

In RGB332 mode you have 2 bits for blue, and 3 bits each for red and green. The following program demonstrates this.

The function converts the ‘normal’ (R,G,B) codes in range 0 - 255 to the reduced range. Try changing the three values at the bottom of the program.

# Colour Control in Pimoroni Graphics
# for Pimoroni Pico Display 2 320x240 pixels in RGB332 mode
# Uses Pimoroni Pico Graphics system
# Tony Goodhew 12th Febrary 2023

import time

from picographics import PicoGraphics, DISPLAY_PICO_DISPLAY_2, get_buffer_size, PEN_RGB332
from pimoroni import RGBLED
# Reduced colours to save RAM
display = PicoGraphics(display=DISPLAY_PICO_DISPLAY_2, pen_type=PEN_RGB332, rotate=0)
display.set_backlight(0.8)
display.set_font("bitmap8") # Lower case included

led = RGBLED(6, 7, 8)
led.set_rgb(0,0,0)     # Turn RGBLED OFF

# ==== Board now setup ====
for i in range(8):
    display.set_pen(2**i)
    for z in range (40):
        display.line(i*40 +z,0,i*40+z,239)
display.update()
time.sleep(3)

def colour(R,G,B): # Convert RGB888 to RGB332
    b = int(B/64)
    g = int(G/32)
    r = int(R/64)
    return b + g * 4 +r * 64

display.set_pen(colour(0,255,0)) # Change the values here (R,G,B)
display.clear()
display.update()

Hope this helps.

1 Like

It’s likely something I shouldn’t get worked up about, just kind of bugs me when things require a bodge to get them to work. And the bodge is because I don’t know the correct way to do it.
blue = display_R.create_pen(0, 0, 255)
display_R.set_pen(blue)
and
display_L.set_pen(blue)
all work.
It started here,
Trying to run dual independent displays on a Pi PICO - Support - Pimoroni Buccaneers
And went to this.
Pi Pico based Weather Station Project - Discussion / Projects - Pimoroni Buccaneers

Right now the Pico Lipo has been replaced with a PICO W. The data will be gotten via MQTT instead of the dedicated sensors.

1 Like

It works because create_pen in RGB332 just looks up the appropriate palette entry, which will be common between both displays.@Tonygo2’s approach makes that clearer (by keying into the known palette rather than going via create_pen).

A part of me wishes set_pen was overloaded to allow you to set the pen directly by RGB values, but I don’t know how easy that sort of thing is in MicroPython…!

1 Like

My method works on both displays by providing the colour value just once.

See the entension;

# Colour Control in Pimoroni Graphics
# for Pimoroni Pico Display 2 320x240 pixels in RGB332 mode
# Uses Pimoroni Pico Graphics system
# Tony Goodhew 12th Febrary 2023

import time

from picographics import PicoGraphics, DISPLAY_PICO_DISPLAY_2, get_buffer_size, PEN_RGB332
from pimoroni import RGBLED
# Reduced colours to save RAM
display = PicoGraphics(display=DISPLAY_PICO_DISPLAY_2, pen_type=PEN_RGB332, rotate=0)
display.set_backlight(0.8)
display.set_font("bitmap8") # Lower case included

led = RGBLED(6, 7, 8)
led.set_rgb(0,0,0)     # Turn RGBLED OFF

# ==== Board now setup ====
for i in range(8):
    display.set_pen(2**i)
    for z in range (40):
        display.line(i*40 +z,0,i*40+z,239)
display.update()
time.sleep(3)

def colour(R,G,B): # Convert RGB888 to RGB332
    b = int(B/64)
    g = int(G/32)
    r = int(R/64)
    return b + g * 4 +r * 64

display.set_pen(colour(0,255,0)) # Change the values here (R,G,B)
display.clear()
display.update()

red = colour(255,0,0)
yellow = colour(255,255,0)
blue = colour(0,0,255)
grey = colour(127,127,127)
display.set_pen(red)
display.clear()
display.update()
time.sleep(2)
display.set_pen(yellow)
display.clear()
display.update()
time.sleep(2)
display.set_pen(grey)
display.clear()
display.update()
time.sleep(2)
display.set_pen(blue)
display.clear()
display.update()
1 Like

Thanks guys. Will have a look see at that code you posted Tony. Just got back from my morning walk with my dog Missy. -10c out there today. According to my portable hand held weather station thingy I posted in the other thread.
Just made a fresh cup of java to work on my python code. ;)

1 Like

Thanks Tony, that fixed things up, and made my coding look more refined / proper. =)

import time
import pimoroni_bus
import picographics

from picographics import PicoGraphics, DISPLAY_PICO_DISPLAY_2, get_buffer_size, PEN_RGB332
from pimoroni_bus import SPIBus

spibus_R = SPIBus(cs=17, dc=16, sck=18, mosi=19, bl=20)
spibus_L = SPIBus(cs=22, dc=16, sck=18, mosi=19, bl=21)

buffer = bytearray(get_buffer_size(DISPLAY_PICO_DISPLAY_2, PEN_RGB332))

display_R = PicoGraphics(display=DISPLAY_PICO_DISPLAY_2, rotate=90, buffer = buffer, bus=spibus_R, pen_type=PEN_RGB332)
display_L = PicoGraphics(display=DISPLAY_PICO_DISPLAY_2, rotate=90, buffer = buffer, bus=spibus_L, pen_type=PEN_RGB332)

display_R.set_backlight(1.0)
display_L.set_backlight(1.0)

def colour(R,G,B): # Convert RGB888 to RGB332
    b = int(B/64)
    g = int(G/32)
    r = int(R/64)
    return b + g * 4 +r * 64


white = colour(255, 255, 255)
black = colour(0, 0, 0)
red = colour(255, 0, 0)
green = colour(0, 255, 0)
blue = colour(0, 0, 255)
yellow = colour(255, 255, 0)
orange = colour(255, 140, 0)
grey = colour(175, 175, 175)
violet = colour(255, 0, 255)
aqua = colour(255, 0, 255)


display_R.set_font("bitmap8")
display_L.set_font("bitmap8")


while True:
    display_R.set_pen(blue)
    display_R.clear()
    display_R.update()
    display_R.set_pen(black)
    display_R.text("Display R", 10, 10, 240, 5)
    display_R.update()
    display_R.clear()
    
    display_L.set_pen(green)
    display_L.clear()
    display_L.update()
    display_L.set_pen(black)
    display_L.text("Display L", 10, 10, 240, 5)
    display_L.update()
    display_L.clear()
    
    time.sleep(2)
    
    display_R.set_pen(green)
    display_R.clear()
    display_R.update()
    display_R.set_pen(black)
    display_R.text("Display R Right Side", 10, 10, 240, 5)
    display_R.update()
    display_R.clear()
    
    display_L.set_pen(aqua)
    display_L.clear()
    display_L.update()
    display_L.set_pen(black)
    display_L.text("Display L Left Side", 10, 10, 240, 5)
    display_L.update()
    display_L.clear()
    
    time.sleep(2)
    
    display_R.set_pen(aqua)
    display_R.clear()
    display_R.update()
    display_R.set_pen(black)
    display_R.text("Display R Right Side SPI_0", 10, 10, 240, 5)
    display_R.update()
    display_R.clear()
    
    display_L.set_pen(red)
    display_L.clear()
    display_L.update()
    display_L.set_pen(black)
    display_L.text("Display L Left Side SPI_0", 10, 10, 240, 5)
    display_L.update()
    display_L.clear()
    
    time.sleep(2)
    
    display_R.set_pen(red)
    display_R.clear()
    display_R.update()
    display_R.set_pen(black)
    display_R.text("Display R Right Side SPI_0   cs=(17)", 10, 10, 240, 5)
    display_R.update()
    display_R.clear()
    
    display_L.set_pen(violet)
    display_L.clear()
    display_L.update()
    display_L.set_pen(black)
    display_L.text("Display L Left Side SPI_0   cs=(22)", 10, 10, 240, 5)
    display_L.update()
    display_L.clear()
    
    time.sleep(2)
    
    display_R.set_pen(violet)
    display_R.clear()
    display_R.update()
    display_R.set_pen(black)
    display_R.text("Display R Right Side SPI_0   cs=(17) bl=(20)", 10, 10, 240, 5)
    display_R.update()
    display_R.clear()
    
    display_L.set_pen(yellow)
    display_L.clear()
    display_L.update()
    display_L.set_pen(black)
    display_L.text("Display L Left Side SPI_0   cs=(22) bl=(21)", 10, 10, 240, 5)
    display_L.update()
    display_L.clear()
    
    time.sleep(2)
    
    display_R.set_pen(yellow)
    display_R.clear()
    display_R.update()
    display_R.set_pen(black)
    display_R.text("Display 1 Right Side SPI_0   cs=(17) bl=(20) 240x320", 10, 10, 240, 5)
    display_R.update()
    display_R.clear()
    
    display_L.set_pen(orange)
    display_L.clear()
    display_L.update()
    display_L.set_pen(black)
    display_L.text("Display 2 Left Side SPI_0   cs=(22) bl=(21) 240x320", 10, 10, 240, 5)
    display_L.update()
    display_L.clear()
    
    time.sleep(2)
    
    display_R.set_pen(orange)
    display_R.clear()
    display_R.update()
    display_R.set_pen(black)
    display_R.text("Display 1 Right Side SPI_0   cs=(17) bl=(20) 240x320 Portrait", 10, 10, 240, 5)
    display_R.update()
    display_R.clear()
    
    display_L.set_pen(blue)
    display_L.clear()
    display_L.update()
    display_L.set_pen(black)
    display_L.text("Display 2 Left Side SPI_0   cs=(22) bl=(21) 240x320 Portrait", 10, 10, 240, 5)
    display_L.update()
    display_L.clear()
    
    time.sleep(2)    
1 Like

Here is the program running with RGB565 colours

# RGB565 version
# Tony Goodhew 12 Feb 2023
import time
import pimoroni_bus
import picographics

from picographics import PicoGraphics, DISPLAY_PICO_DISPLAY_2, get_buffer_size, PEN_RGB565
from pimoroni_bus import SPIBus

spibus_R = SPIBus(cs=17, dc=16, sck=18, mosi=19, bl=20)
spibus_L = SPIBus(cs=22, dc=16, sck=18, mosi=19, bl=21)

buffer = bytearray(get_buffer_size(DISPLAY_PICO_DISPLAY_2, PEN_RGB565))

display_R = PicoGraphics(display=DISPLAY_PICO_DISPLAY_2, rotate=90, buffer = buffer, bus=spibus_R, pen_type=PEN_RGB565)
display_L = PicoGraphics(display=DISPLAY_PICO_DISPLAY_2, rotate=90, buffer = buffer, bus=spibus_L, pen_type=PEN_RGB565)

display_R.set_backlight(1.0)
display_L.set_backlight(1.0)

def colour(R,G,B): # Convert RGB888 to RGB565
    return (((G&0b00011100)<<3) +((B&0b11111000)>>3)<<8) + (R&0b11111000)+((G&0b11100000)>>5)


white = colour(255, 255, 255)
black = colour(0, 0, 0)
red = colour(255, 0, 0)
green = colour(0, 255, 0)
blue = colour(0, 0, 255)
yellow = colour(255, 255, 0)
orange = colour(255, 140, 0)
grey = colour(175, 175, 175)
violet = colour(255, 0, 255)
aqua = colour(255, 0, 255)


display_R.set_font("bitmap8")
display_L.set_font("bitmap8")


while True:
    display_R.set_pen(blue)
    display_R.clear()
    display_R.update()
    display_R.set_pen(black)
    display_R.text("Display R", 10, 10, 240, 5)
    display_R.update()
    display_R.clear()
    
    display_L.set_pen(green)
    display_L.clear()
    display_L.update()
    display_L.set_pen(black)
    display_L.text("Display L", 10, 10, 240, 5)
    display_L.update()
    display_L.clear()
    
    time.sleep(2)
    
    display_R.set_pen(green)
    display_R.clear()
    display_R.update()
    display_R.set_pen(black)
    display_R.text("Display R Right Side", 10, 10, 240, 5)
    display_R.update()
    display_R.clear()
    
    display_L.set_pen(aqua)
    display_L.clear()
    display_L.update()
    display_L.set_pen(black)
    display_L.text("Display L Left Side", 10, 10, 240, 5)
    display_L.update()
    display_L.clear()
    
    time.sleep(2)
    
    display_R.set_pen(aqua)
    display_R.clear()
    display_R.update()
    display_R.set_pen(black)
    display_R.text("Display R Right Side SPI_0", 10, 10, 240, 5)
    display_R.update()
    display_R.clear()
    
    display_L.set_pen(red)
    display_L.clear()
    display_L.update()
    display_L.set_pen(black)
    display_L.text("Display L Left Side SPI_0", 10, 10, 240, 5)
    display_L.update()
    display_L.clear()
    
    time.sleep(2)
    
    display_R.set_pen(red)
    display_R.clear()
    display_R.update()
    display_R.set_pen(black)
    display_R.text("Display R Right Side SPI_0   cs=(17)", 10, 10, 240, 5)
    display_R.update()
    display_R.clear()
    
    display_L.set_pen(violet)
    display_L.clear()
    display_L.update()
    display_L.set_pen(black)
    display_L.text("Display L Left Side SPI_0   cs=(22)", 10, 10, 240, 5)
    display_L.update()
    display_L.clear()
    
    time.sleep(2)
    
    display_R.set_pen(violet)
    display_R.clear()
    display_R.update()
    display_R.set_pen(black)
    display_R.text("Display R Right Side SPI_0   cs=(17) bl=(20)", 10, 10, 240, 5)
    display_R.update()
    display_R.clear()
    
    display_L.set_pen(yellow)
    display_L.clear()
    display_L.update()
    display_L.set_pen(black)
    display_L.text("Display L Left Side SPI_0   cs=(22) bl=(21)", 10, 10, 240, 5)
    display_L.update()
    display_L.clear()
    
    time.sleep(2)
    
    display_R.set_pen(yellow)
    display_R.clear()
    display_R.update()
    display_R.set_pen(black)
    display_R.text("Display 1 Right Side SPI_0   cs=(17) bl=(20) 240x320", 10, 10, 240, 5)
    display_R.update()
    display_R.clear()
    
    display_L.set_pen(orange)
    display_L.clear()
    display_L.update()
    display_L.set_pen(black)
    display_L.text("Display 2 Left Side SPI_0   cs=(22) bl=(21) 240x320", 10, 10, 240, 5)
    display_L.update()
    display_L.clear()
    
    time.sleep(2)
    
    display_R.set_pen(orange)
    display_R.clear()
    display_R.update()
    display_R.set_pen(black)
    display_R.text("Display 1 Right Side SPI_0   cs=(17) bl=(20) 240x320 Portrait", 10, 10, 240, 5)
    display_R.update()
    display_R.clear()
    
    display_L.set_pen(blue)
    display_L.clear()
    display_L.update()
    display_L.set_pen(black)
    display_L.text("Display 2 Left Side SPI_0   cs=(22) bl=(21) 240x320 Portrait", 10, 10, 240, 5)
    display_L.update()
    display_L.clear()
    
    time.sleep(2) 

Just getting curious: which „weather thingy“?
Sounds like the very next project for me!
Will search later, if you haven’t time to provide a link.
Cheers!

I do believe it was this.
Guess what I built? - Discussion - Pimoroni Buccaneers

I now have a Tufty version of it. There is a pic of that in that thread too.

1 Like

Oh ZAP! 🤩🤩🤩

This looks great!
Didn’t have time yet to look up myself, thanks for the link! Now singable to work longer today to be able to afford this thingy!

The Hitchhiker