Kate is a feature-packed text editor, lets you to edit and view many files at the same time, both in tabs and split views, and comes with a wide variety of plugins, including an embedded terminal that lets you launch console commands directly from Kate, powerful search and replace plugins, and a preview plugin that can show you what your MD, HTML and even SVG will look like.
To install Kate on Raspberry i: $ sudo apt install kate
This video show how to download, install and run openEuler on Raspberry Pi,
and switch language to English. Tested on Raspberry Pi 4B/4G with 7 inch mini
HDMI LCD. Chinese is set system language by default, this video also show how
to switch to English.
Download openEuler image for Raspberry Pi (prepare on Raspberry Pi)
Select the image to download, in my test: openEuler 20.03 LTS SP1 alpha4 (DDE
desktop and Chinese input method),
openEuler-20.03-LTS-SP1-DDE-raspi-aarch64-alpha4.img.xz.
Extract the downloaded file. Then we can write the extracted image on microSD
using Raspberry Pi Imager.
Then you can boot-up Raspberry Pi with the microSD.
User and password:
The image pre-set with System user/password: -
root/openeuler - pi/raspberry
DDE cannot log in with root account,
you can login user pi using password "raspberry".
FYI: the microSD I used in this test is 128G Samsung Evo Plus:
openEuler
is an innovative platform nurtured by community collaboration. It aims to
build a unified and open OS that supports multiple processor architectures,
and to advance the hardware/software application ecosystem.
This video show how to install openEuler in VirtualBox 6.1/Windows 10.
It's very straightforward to install openEuler in VirtualBox. But
there are no desktop environment by default. Deepin Desktop Environment
(DDE) can be installed using dnf (a Linux software package management
tool).
Most probably you cannot run dnf, fail with error [Could not resolve
host: repo.openeuler.org], as shown in the video.
With
bluepy installed, this exercise implement BLE client side on Raspberry Pi using Python,
connect to ESP32 BLE uart server, send and receive data in between.
Prepare ESP32 BLE_uart
ESP32 side (NodeMCU ESP-32S) is programmed in Arduino framework.
In Arduino IDE - Open Examples > ESP32 BLE Arduino > BLE_uart in
Arduino IDE, and upload to ESP32 board.
It's a BLE setup as server, wait connection. Once connected, send data to
client repeatedly and display received data to Serial Monitor.
Test with nRF Connect App
To verify the function of ESP32 BLE_art on Android device, install nRF Connect for Mobile App
by Nordic Semiconductor ASA.
Simple test Python code -
Automatically connect to BLE_uart, send and receive data repeatedly.
ex_bluepy_uart.py
from bluepy import btle
import time
class MyDelegate(btle.DefaultDelegate):
def __init__(self):
btle.DefaultDelegate.__init__(self)
# ... initialise here
def handleNotification(self, cHandle, data):
#print("\n- handleNotification -\n")
print(data)
# ... perhaps check cHandle
# ... process 'data'
# Initialisation -------
p = btle.Peripheral("3c:71:bf:0d:dd:6a") #NodeMCU-32S
#p = btle.Peripheral("24:0a:c4:e8:0f:9a") #ESP32-DevKitC V4
# Setup to turn notifications on, e.g.
svc = p.getServiceByUUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")
ch_Tx = svc.getCharacteristics("6E400002-B5A3-F393-E0A9-E50E24DCCA9E")[0]
ch_Rx = svc.getCharacteristics("6E400003-B5A3-F393-E0A9-E50E24DCCA9E")[0]
p.setDelegate( MyDelegate())
setup_data = b"\x01\00"
p.writeCharacteristic(ch_Rx.valHandle+1, setup_data)
lasttime = time.localtime()
while True:
"""
if p.waitForNotifications(1.0):
pass #continue
print("Waiting...")
"""
nowtime = time.localtime()
if(nowtime > lasttime):
lasttime = nowtime
stringtime = time.strftime("%H:%M:%S", nowtime)
btime = bytes(stringtime, 'utf-8')
try:
ch_Tx.write(btime, True)
except btle.BTLEException:
print("btle.BTLEException");
#print(stringtime)
#ch_Tx.write(b'wait...', True)
# Perhaps do something else here
Python code with PyQt5 GUI -
- Click "Start BLE" button to connect to BLE_uart.
- Display received data on QPlainTextEdit, and send user entered data to
BLE
Now, replace ESP32 with Arduino Nano RP2040 Connect, running following
code using ArduinoBLE library. Please note that you have to modify
Python code to match with Arduino Nano RP2040 Connect's MAC address.
BLE_peripheral_uart.ino
/*
* BLE_peripheral_uart:
* modifid from Examples > ArduinoBLE > Peripheral > CallbackLED
*
* Bi-direction BLE communication between Raspberry Pi/Python (with PyQt5 GUI)
* and ESP32/Arduino Naon RP2040 Connect
* http://helloraspberrypi.blogspot.com/2021/08/bi-direction-ble-communication-between.html
*
*/
#include <ArduinoBLE.h>
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
//BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // create service
BLEService uartService(SERVICE_UUID); // create service
// create switch characteristic and allow remote device to read and write
//BLEByteCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
BLEStringCharacteristic rxCharacteristic(CHARACTERISTIC_UUID_RX, BLEWrite, 30);
BLEStringCharacteristic txCharacteristic(CHARACTERISTIC_UUID_TX, BLENotify, 30);
// const int ledPin = LED_BUILTIN; // pin to use for the LED
void setup() {
Serial.begin(115200);
while (!Serial);
// pinMode(ledPin, OUTPUT); // use the LED pin as an output
// begin initialization
if (!BLE.begin()) {
Serial.println("starting BLE failed!");
while (1);
}
// set the local name peripheral advertises
BLE.setLocalName("BLE_peripheral_uart");
// set the UUID for the service this peripheral advertises
BLE.setAdvertisedService(uartService);
// add the characteristic to the service
uartService.addCharacteristic(rxCharacteristic);
uartService.addCharacteristic(txCharacteristic);
// add service
BLE.addService(uartService);
// assign event handlers for connected, disconnected to peripheral
BLE.setEventHandler(BLEConnected, blePeripheralConnectHandler);
BLE.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler);
// assign event handlers for characteristic
rxCharacteristic.setEventHandler(BLEWritten, rxCharacteristicWritten);
// set an initial value for the characteristic
rxCharacteristic.setValue("BLE_peripheral_uart");
// start advertising
BLE.advertise();
Serial.println(("Bluetooth device active, waiting for connections..."));
Serial.println(BLE.address());
}
void loop() {
// poll for BLE events
BLE.poll();
}
void blePeripheralConnectHandler(BLEDevice central) {
// central connected event handler
Serial.print("Connected event, central: ");
Serial.println(central.address());
}
void blePeripheralDisconnectHandler(BLEDevice central) {
// central disconnected event handler
Serial.print("Disconnected event, central: ");
Serial.println(central.address());
}
void rxCharacteristicWritten(BLEDevice central, BLECharacteristic characteristic) {
// central wrote new value to characteristic, update LED
Serial.print("Characteristic event, written: ");
Serial.println("len=" +
String(rxCharacteristic.valueLength()));
String valString = rxCharacteristic.value();
Serial.println(valString);
valString.toUpperCase();
Serial.println(valString);
txCharacteristic.setValue(valString);
}
This post show how to connect OV7670/OV2640 0.3-Megapixel Camera Module to
Raspberry Pi Pico (in CircuitPython 7.0.0 alpha 6), display on ST7789 SPI IPS
screen; running example ov2640_jpeg_sd_pico_st7789_2in.py.
ov7670:
It's library named adafruit_ov7670.mpy and example
named ov7670_displayio_pico_st7789_2in.py in CircuitPython Bundle
Libraries. I tried to run it on Pico with current stable CircuitPython
6.3.0. But fail with error of:
ImportError: cannot import name Colorspace
Then I tried on CircuitPython 7.0.0 alpha 6.
The connection between Pico and ov7670 camera module and st7789 SPI IPS
display follow the ov7670_displayio_pico_st7789_2in.py example. But I have
to add reset pin for display.
Connection:
Connection between Pico and ov7670 cam module
=============================================
+-----------+
3V3 |3V3 DGND| GND
GP9 |SCL SDA | GP8
GP7 |VS HS| GP21
GP11 |PLK XLK | GP20
GP19 |D7 D6 | GP18
GP17 |D5 D4 | GP16
GP15 |D3 D2 | GP14
GP13 |D1 D0 | GP12
GP10 |RET PWDN|
+-----------+
*SCL/SDA are I2C control pin, pull-up resistors are needed.
I use 2K ohm resistor for it.
Connection between Pico and ST7789 SPI IPS
==========================================
3V3 BLK
GP1 CS
GP0 DC
GP4 RES
GP3 SDA
GP2 SCL
3V3 VCC
GND GND
Makesure Raspberry Pi Pico is installed with CircuitPython 7.0.0 alpha 6,
download the matched bundle libraries 7.x. Copy adafruit_st7789.mpy
and adafruit_ov7670.mpy from lib folder to Pico CIRCUITPY lib folder.
Modify ov7670_displayio_pico_st7789_2in.py from examples folder to add
reset pin to GP4, as shown in above screenshot.
remark:
In my test, once the program ran and stopped, to re-run it, have to disconnect
and reconnect USB to Pico.
ov2640:
My ov2640 module have same pin assignment in ov7670, aligned to top with D0/D1
opened.
"""
Example of CircuitPython/RaspberryPi Pico
to display on 2.0" IPS 240x320 (RGB) screen
with ST7789 driver via SPI interface.
Connection between Pico and
the IPS screen, with ST7789 SPI interface.
3V3 - BLK (backlight, always on)
GP11 - CS
GP12 - DC
GP13 - RES
GP15 - SDA
GP14 - SCL
3V3 - VCC
GND - GND
"""
import os
import board
import time
import terminalio
import displayio
import busio
from adafruit_display_text import label
#from adafruit_st7789 import ST7789
import adafruit_st7789
print("==============================")
print(os.uname())
print("Hello Raspberry Pi Pico/CircuitPython ST7789 SPI IPS Display")
print(adafruit_st7789.__name__ + " version: " + adafruit_st7789.__version__)
print()
# Release any resources currently in use for the displays
displayio.release_displays()
tft_cs = board.GP11
tft_dc = board.GP12
tft_res = board.GP13
spi_mosi = board.GP15
spi_clk = board.GP14
"""
classbusio.SPI(clock: microcontroller.Pin,
MOSI: Optional[microcontroller.Pin] = None,
MISO: Optional[microcontroller.Pin] = None)
"""
spi = busio.SPI(spi_clk, MOSI=spi_mosi)
display_bus = displayio.FourWire(
spi, command=tft_dc, chip_select=tft_cs, reset=tft_res
)
display = adafruit_st7789.ST7789(display_bus,
width=240, height=320)
# Make the display context
splash = displayio.Group(max_size=10)
display.show(splash)
color_bitmap = displayio.Bitmap(135, 240, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0x00FF00
bg_sprite = displayio.TileGrid(color_bitmap,
pixel_shader=color_palette, x=0, y=0)
splash.append(bg_sprite)
# Draw a smaller inner rectangle
inner_bitmap = displayio.Bitmap(133, 238, 1)
inner_palette = displayio.Palette(1)
inner_palette[0] = 0x0000FF
inner_sprite = displayio.TileGrid(inner_bitmap,
pixel_shader=inner_palette, x=1, y=1)
splash.append(inner_sprite)
# Draw a label
text_group1 = displayio.Group(max_size=10, scale=2, x=20, y=40)
text1 = "RPi Pico"
text_area1 = label.Label(terminalio.FONT, text=text1, color=0xFF0000)
text_group1.append(text_area1) # Subgroup for text scaling
# Draw a label
text_group2 = displayio.Group(max_size=10, scale=1, x=20, y=60)
text2 = "CircuitPython"
text_area2 = label.Label(terminalio.FONT, text=text2, color=0xFFFFFF)
text_group2.append(text_area2) # Subgroup for text scaling
# Draw a label
text_group3 = displayio.Group(max_size=10, scale=1, x=20, y=100)
text3 = adafruit_st7789.__name__
text_area3 = label.Label(terminalio.FONT, text=text3, color=0x0000000)
text_group3.append(text_area3) # Subgroup for text scaling
# Draw a label
text_group4 = displayio.Group(max_size=10, scale=2, x=20, y=120)
text4 = adafruit_st7789.__version__
text_area4 = label.Label(terminalio.FONT, text=text4, color=0x000000)
text_group4.append(text_area4) # Subgroup for text scaling
splash.append(text_group1)
splash.append(text_group2)
splash.append(text_group3)
splash.append(text_group4)
time.sleep(3.0)
rot = 0
while True:
time.sleep(5.0)
rot = rot + 90
if (rot>=360):
rot =0
display.rotation = rot
cpyPico_spiST7789_bitmap_320.py
"""
Example of CircuitPython/Raspberry Pi Pico
to display on 2.0" IPS 240x320 (RGB) screen
with ST7789 driver via SPI interface.
Connection between Pico and
the IPS screen, with ST7789 SPI interface.
3V3 - BLK (backlight, always on)
GP11 - CS
GP12 - DC
GP13 - RES
GP15 - SDA
GP14 - SCL
3V3 - VCC
GND - GND
"""
import os
import board
import time
import terminalio
import displayio
import busio
from adafruit_display_text import label
import adafruit_st7789
print("==============================")
print(os.uname())
print("Hello Raspberry Pi Pico/CircuitPython ST7789 SPI IPS Display")
print(adafruit_st7789.__name__ + " version: " + adafruit_st7789.__version__)
print()
# Release any resources currently in use for the displays
displayio.release_displays()
tft_cs = board.GP11
tft_dc = board.GP12
tft_res = board.GP13
spi_mosi = board.GP15
spi_clk = board.GP14
"""
classbusio.SPI(clock: microcontroller.Pin,
MOSI: Optional[microcontroller.Pin] = None,
MISO: Optional[microcontroller.Pin] = None)
"""
spi = busio.SPI(spi_clk, MOSI=spi_mosi)
display_bus = displayio.FourWire(
spi, command=tft_dc, chip_select=tft_cs, reset=tft_res
)
display = adafruit_st7789.ST7789(display_bus,
width=240, height=320)
display.rotation = 270
group = displayio.Group(max_size=10)
display.show(group)
bitmap_width = 320
bitmap_height = 240
bitmap = displayio.Bitmap(bitmap_width, bitmap_height, bitmap_height)
palette = displayio.Palette(bitmap_height)
for p in range(bitmap_height):
palette[p] = (0x010000*p) + (0x0100*p) + p
for y in range(bitmap_height):
for x in range(bitmap_width):
bitmap[x,y] = y
tileGrid = displayio.TileGrid(bitmap, pixel_shader=palette, x=0, y=0)
group.append(tileGrid)
time.sleep(3.0)
while True:
for p in range(bitmap_height):
palette[p] = p
time.sleep(3.0)
for p in range(bitmap_height):
palette[p] = 0x0100 * p
time.sleep(3.0)
for p in range(bitmap_height):
palette[p] = 0x010000 * p
time.sleep(3.0)
cpyPico_spiST7789_shape_320.py
"""
Example of CircuitPython/Raspberry Pi Pico
to display on 2.0" IPS 240x320 (RGB) screen
with ST7789 driver via SPI interface.
modify example from:
https://circuitpython.readthedocs.io/projects/display-shapes/en/latest/index.html
Connection between Pico and
the IPS screen, with ST7789 SPI interface.
3V3 - BLK (backlight, always on)
GP11 - CS
GP12 - DC
GP13 - RES
GP15 - SDA
GP14 - SCL
3V3 - VCC
GND - GND
"""
import os
import board
import time
import terminalio
import displayio
import busio
import adafruit_st7789
from adafruit_display_shapes.rect import Rect
from adafruit_display_shapes.circle import Circle
from adafruit_display_shapes.roundrect import RoundRect
from adafruit_display_shapes.triangle import Triangle
print("==============================")
print(os.uname())
print("Hello Raspberry Pi Pico/CircuitPython ST7789 SPI IPS Display")
print(adafruit_st7789.__name__ + " version: " + adafruit_st7789.__version__)
print()
# Release any resources currently in use for the displays
displayio.release_displays()
tft_cs = board.GP11
tft_dc = board.GP12
tft_res = board.GP13
spi_mosi = board.GP15
spi_clk = board.GP14
"""
classbusio.SPI(clock: microcontroller.Pin,
MOSI: Optional[microcontroller.Pin] = None,
MISO: Optional[microcontroller.Pin] = None)
"""
spi = busio.SPI(spi_clk, MOSI=spi_mosi)
display_bus = displayio.FourWire(
spi, command=tft_dc, chip_select=tft_cs, reset=tft_res
)
display = adafruit_st7789.ST7789(display_bus,
width=240, height=320)
display.rotation = 270
splash = displayio.Group()
display.show(splash)
color_bitmap = displayio.Bitmap(320, 240, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0xFFFFFF
bg_sprite = displayio.TileGrid(color_bitmap, pixel_shader=color_palette, x=0, y=0)
splash.append(bg_sprite)
triangle = Triangle(170, 50, 120, 140, 210, 160, fill=0x00FF00, outline=0xFF00FF)
splash.append(triangle)
rect = Rect(80, 20, 41, 41, fill=0x0)
splash.append(rect)
circle = Circle(100, 100, 20, fill=0x00FF00, outline=0xFF00FF)
splash.append(circle)
rect2 = Rect(50, 100, 61, 81, outline=0x0, stroke=3)
splash.append(rect2)
roundrect = RoundRect(10, 10, 61, 81, 10, fill=0x0, outline=0xFF00FF, stroke=6)
splash.append(roundrect)
while True:
pass
"""
Example of CircuitPython/RaspberryPi Pico
to display on 2.0" IPS 240x320 (RGB) screen
with ST7789 driver via SPI interface.
Connection between Pico and
the IPS screen, with ST7789 SPI interface.
3V3 - BLK (backlight, always on)
GP11 - CS
GP12 - DC
GP13 - RES
GP15 - SDA
GP14 - SCL
3V3 - VCC
GND - GND
"""
import os
import board
import time
import terminalio
import displayio
import busio
from adafruit_display_text import label
#from adafruit_st7789 import ST7789
import adafruit_st7789
print("==============================")
print(os.uname())
print("Hello Raspberry Pi Pico/CircuitPython ST7789 SPI IPS Display")
print(adafruit_st7789.__name__ + " version: " + adafruit_st7789.__version__)
print()
# Release any resources currently in use for the displays
displayio.release_displays()
tft_cs = board.GP11
tft_dc = board.GP12
tft_res = board.GP13
spi_mosi = board.GP15
spi_clk = board.GP14
"""
classbusio.SPI(clock: microcontroller.Pin,
MOSI: Optional[microcontroller.Pin] = None,
MISO: Optional[microcontroller.Pin] = None)
"""
spi = busio.SPI(spi_clk, MOSI=spi_mosi)
display_bus = displayio.FourWire(
spi, command=tft_dc, chip_select=tft_cs, reset=tft_res
)
display = adafruit_st7789.ST7789(display_bus,
width=240, height=240, rowstart=80)
# Make the display context
splash = displayio.Group(max_size=10)
display.show(splash)
color_bitmap = displayio.Bitmap(135, 240, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0x00FF00
bg_sprite = displayio.TileGrid(color_bitmap,
pixel_shader=color_palette, x=0, y=0)
splash.append(bg_sprite)
# Draw a smaller inner rectangle
inner_bitmap = displayio.Bitmap(133, 238, 1)
inner_palette = displayio.Palette(1)
inner_palette[0] = 0x0000FF
inner_sprite = displayio.TileGrid(inner_bitmap,
pixel_shader=inner_palette, x=1, y=1)
splash.append(inner_sprite)
# Draw a label
text_group1 = displayio.Group(max_size=10, scale=2, x=20, y=40)
text1 = "RPi Pico"
text_area1 = label.Label(terminalio.FONT, text=text1, color=0xFF0000)
text_group1.append(text_area1) # Subgroup for text scaling
# Draw a label
text_group2 = displayio.Group(max_size=10, scale=1, x=20, y=60)
text2 = "CircuitPython"
text_area2 = label.Label(terminalio.FONT, text=text2, color=0xFFFFFF)
text_group2.append(text_area2) # Subgroup for text scaling
# Draw a label
text_group3 = displayio.Group(max_size=10, scale=1, x=20, y=100)
text3 = adafruit_st7789.__name__
text_area3 = label.Label(terminalio.FONT, text=text3, color=0x0000000)
text_group3.append(text_area3) # Subgroup for text scaling
# Draw a label
text_group4 = displayio.Group(max_size=10, scale=2, x=20, y=120)
text4 = adafruit_st7789.__version__
text_area4 = label.Label(terminalio.FONT, text=text4, color=0x000000)
text_group4.append(text_area4) # Subgroup for text scaling
splash.append(text_group1)
splash.append(text_group2)
splash.append(text_group3)
splash.append(text_group4)
time.sleep(3.0)
rot = 0
while True:
time.sleep(5.0)
rot = rot + 90
if (rot>=360):
rot =0
display.rotation = rot
cpyPico_spiST7789_bitmap_240.py
"""
Example of CircuitPython/Raspberry Pi Pico
to display on 2.0" IPS 240x320 (RGB) screen
with ST7789 driver via SPI interface.
Connection between Pico and
the IPS screen, with ST7789 SPI interface.
3V3 - BLK (backlight, always on)
GP11 - CS
GP12 - DC
GP13 - RES
GP15 - SDA
GP14 - SCL
3V3 - VCC
GND - GND
"""
import os
import board
import time
import terminalio
import displayio
import busio
from adafruit_display_text import label
import adafruit_st7789
print("==============================")
print(os.uname())
print("Hello Raspberry Pi Pico/CircuitPython ST7789 SPI IPS Display")
print(adafruit_st7789.__name__ + " version: " + adafruit_st7789.__version__)
print()
# Release any resources currently in use for the displays
displayio.release_displays()
tft_cs = board.GP11
tft_dc = board.GP12
tft_res = board.GP13
spi_mosi = board.GP15
spi_clk = board.GP14
"""
classbusio.SPI(clock: microcontroller.Pin,
MOSI: Optional[microcontroller.Pin] = None,
MISO: Optional[microcontroller.Pin] = None)
"""
spi = busio.SPI(spi_clk, MOSI=spi_mosi)
display_bus = displayio.FourWire(
spi, command=tft_dc, chip_select=tft_cs, reset=tft_res
)
display = adafruit_st7789.ST7789(display_bus,
width=240, height=240, rowstart=80)
display.rotation = 270
group = displayio.Group(max_size=10)
display.show(group)
bitmap_width = 240
bitmap_height = 240
bitmap = displayio.Bitmap(bitmap_width, bitmap_height, bitmap_height)
palette = displayio.Palette(bitmap_height)
for p in range(bitmap_height):
palette[p] = (0x010000*p) + (0x0100*p) + p
for y in range(bitmap_height):
for x in range(bitmap_width):
bitmap[x,y] = y
tileGrid = displayio.TileGrid(bitmap, pixel_shader=palette, x=0, y=0)
group.append(tileGrid)
time.sleep(3.0)
while True:
for p in range(bitmap_height):
palette[p] = p
time.sleep(3.0)
for p in range(bitmap_height):
palette[p] = 0x0100 * p
time.sleep(3.0)
for p in range(bitmap_height):
palette[p] = 0x010000 * p
time.sleep(3.0)
cpyPico_spiST7789_shape_240.py
"""
Example of CircuitPython/Raspberry Pi Pico
to display on 2.0" IPS 240x320 (RGB) screen
with ST7789 driver via SPI interface.
modify example from:
https://circuitpython.readthedocs.io/projects/display-shapes/en/latest/index.html
Connection between Pico and
the IPS screen, with ST7789 SPI interface.
3V3 - BLK (backlight, always on)
GP11 - CS
GP12 - DC
GP13 - RES
GP15 - SDA
GP14 - SCL
3V3 - VCC
GND - GND
"""
import os
import board
import time
import terminalio
import displayio
import busio
import adafruit_st7789
from adafruit_display_shapes.rect import Rect
from adafruit_display_shapes.circle import Circle
from adafruit_display_shapes.roundrect import RoundRect
from adafruit_display_shapes.triangle import Triangle
print("==============================")
print(os.uname())
print("Hello Raspberry Pi Pico/CircuitPython ST7789 SPI IPS Display")
print(adafruit_st7789.__name__ + " version: " + adafruit_st7789.__version__)
print()
# Release any resources currently in use for the displays
displayio.release_displays()
tft_cs = board.GP11
tft_dc = board.GP12
tft_res = board.GP13
spi_mosi = board.GP15
spi_clk = board.GP14
"""
classbusio.SPI(clock: microcontroller.Pin,
MOSI: Optional[microcontroller.Pin] = None,
MISO: Optional[microcontroller.Pin] = None)
"""
spi = busio.SPI(spi_clk, MOSI=spi_mosi)
display_bus = displayio.FourWire(
spi, command=tft_dc, chip_select=tft_cs, reset=tft_res
)
display = adafruit_st7789.ST7789(display_bus,
width=240, height=240, rowstart=80)
display.rotation = 270
splash = displayio.Group()
display.show(splash)
color_bitmap = displayio.Bitmap(240, 240, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0xFFFFFF
bg_sprite = displayio.TileGrid(color_bitmap, pixel_shader=color_palette, x=0, y=0)
splash.append(bg_sprite)
triangle = Triangle(170, 50, 120, 140, 210, 160, fill=0x00FF00, outline=0xFF00FF)
splash.append(triangle)
rect = Rect(80, 20, 41, 41, fill=0x0)
splash.append(rect)
circle = Circle(100, 100, 20, fill=0x00FF00, outline=0xFF00FF)
splash.append(circle)
rect2 = Rect(50, 100, 61, 81, outline=0x0, stroke=3)
splash.append(rect2)
roundrect = RoundRect(10, 10, 61, 81, 10, fill=0x0, outline=0xFF00FF, stroke=6)
splash.append(roundrect)
while True:
pass
There are two examples in bluepy, scanner and notification. Here how I modify
it for Python3 working on Raspberry Pi, work with ESP32 BLE_uart example.
scanner.py
from bluepy.btle import Scanner, DefaultDelegate
class ScanDelegate(DefaultDelegate):
def __init__(self):
DefaultDelegate.__init__(self)
def handleDiscovery(self, dev, isNewDev, isNewData):
if isNewDev:
print("Discovered device", dev.addr)
elif isNewData:
print("Received new data from", dev.addr)
scanner = Scanner().withDelegate(ScanDelegate())
devices = scanner.scan(10.0)
for dev in devices:
print("Device %s (%s), RSSI=%d dB" % (dev.addr, dev.addrType, dev.rssi))
for (adtype, desc, value) in dev.getScanData():
print(" %s = %s" % (desc, value))
notification.py
from bluepy import btle
class MyDelegate(btle.DefaultDelegate):
def __init__(self):
btle.DefaultDelegate.__init__(self)
# ... initialise here
def handleNotification(self, cHandle, data):
print("\n- handleNotification -\n")
print(data)
# ... perhaps check cHandle
# ... process 'data'
# Initialisation -------
p = btle.Peripheral("3c:71:bf:0d:dd:6a")
p.setDelegate( MyDelegate() )
# Setup to turn notifications on, e.g.
svc = p.getServiceByUUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")
ch = svc.getCharacteristics("6E400003-B5A3-F393-E0A9-E50E24DCCA9E")[0]
# ch.write( setup_data )
setup_data = b"\x01\00"
p.writeCharacteristic(ch.valHandle+1, setup_data)
# Main loop --------
while True:
if p.waitForNotifications(1.0):
# handleNotification() was called
continue
print("Waiting...")
# Perhaps do something else here
With Arduino Mbed OS RP2040 Boards on Arduino IDE, this post show how to connect 128x160 ST7735 SPI TFT to Raspberry Pi Pico,
and control with TFT_eSPI library in Arduino framework.
The library used is
Bodmer/TFT_eSPI, a Arduino and PlatformIO IDE compatible TFT library optimised for the
Raspberry Pi Pico (RP2040), STM32, ESP8266 and ESP32 that supports different
driver chips.
To install TFT_eSPI in Arduino IDE, simple open Library Manager, search and
install TFT_eSPI by Bodmer.
Take a note on the Tips section in the TFT_eSPI Library page: If you load a new copy of TFT_eSPI then it will overwrite your setups if
they are kept within the TFT_eSPI folder. One way around this is to create
a new folder in your Arduino library folder called "TFT_eSPI_Setups". You
then place your custom setup.h files in there. After an upgrade simply
edit the User_Setup_Select.h file to point to your custom setup file.
Here is how I practice it:
- create a new folder in your Arduino library folder called
"TFT_eSPI_Setups".
- copy TFT_eSPI/User_Setups/Setup60_RP2040_ILI9341.h to new created
"TFT_eSPI_Setups" folder, rename as Setup60_RP2040_ST7735.h.
- Edit Setup60_RP2040_ST7735.h for ST7735:
// USER DEFINED SETTINGS
// Set driver type, fonts to be loaded, pins used and SPI control method etc
//
// See the User_Setup_Select.h file if you wish to be able to define multiple
// setups and then easily select which setup file is used by the compiler.
//
// If this file is edited correctly then all the library example sketches should
// run without the need to make any more changes for a particular hardware setup!
// Note that some sketches are designed for a particular TFT pixel width/height
// ##################################################################################
//
// Section 1. Call up the right driver file and any options for it
//
// ##################################################################################
// Tell the library to use 8 bit parallel mode (otherwise SPI is assumed)
//#define TFT_PARALLEL_8_BIT
// Display type - only define if RPi display
#define RPI_DISPLAY_TYPE // 20MHz maximum SPI
// Only define one driver, the other ones must be commented out
//#define ILI9341_DRIVER
#define ST7735_DRIVER // Define additional parameters below for this display
//#define ILI9163_DRIVER // Define additional parameters below for this display
//#define S6D02A1_DRIVER
//#define RPI_ILI9486_DRIVER // 20MHz maximum SPI
//#define HX8357D_DRIVER
//#define ILI9481_DRIVER
//#define ILI9486_DRIVER
//#define ILI9488_DRIVER // WARNING: Do not connect ILI9488 display SDO to MISO if other devices share the SPI bus (TFT SDO does NOT tristate when CS is high)
//#define ST7789_DRIVER // Full configuration option, define additional parameters below for this display
//#define ST7789_2_DRIVER // Minimal configuration option, define additional parameters below for this display
//#define R61581_DRIVER
//#define RM68140_DRIVER
//#define ST7796_DRIVER
//#define SSD1963_480_DRIVER
//#define SSD1963_800_DRIVER
//#define SSD1963_800ALT_DRIVER
//#define ILI9225_DRIVER
// Some displays support SPI reads via the MISO pin, other displays have a single
// bi-directional SDA pin and the library will try to read this via the MOSI line.
// To use the SDA line for reading data from the TFT uncomment the following line:
// #define TFT_SDA_READ // This option is for ESP32 ONLY, tested with ST7789 display only
// For ST7735, ST7789 and ILI9341 ONLY, define the colour order IF the blue and red are swapped on your display
// Try ONE option at a time to find the correct colour order for your display
#define TFT_RGB_ORDER TFT_RGB // Colour order Red-Green-Blue
// #define TFT_RGB_ORDER TFT_BGR // Colour order Blue-Green-Red
// For ST7789, ST7735 and ILI9163 ONLY, define the pixel width and height in portrait orientation
// #define TFT_WIDTH 80
#define TFT_WIDTH 128
// #define TFT_WIDTH 240 // ST7789 240 x 240 and 240 x 320
#define TFT_HEIGHT 160
// #define TFT_HEIGHT 128
// #define TFT_HEIGHT 240 // ST7789 240 x 240
// #define TFT_HEIGHT 320 // ST7789 240 x 320
// For ST7735 ONLY, define the type of display, originally this was based on the
// colour of the tab on the screen protector film but this is not always true, so try
// out the different options below if the screen does not display graphics correctly,
// e.g. colours wrong, mirror images, or tray pixels at the edges.
// Comment out ALL BUT ONE of these options for a ST7735 display driver, save this
// this User_Setup file, then rebuild and upload the sketch to the board again:
//#define ST7735_INITB
#define ST7735_GREENTAB
// #define ST7735_GREENTAB2
// #define ST7735_GREENTAB3
// #define ST7735_GREENTAB128 // For 128 x 128 display
// #define ST7735_GREENTAB160x80 // For 160 x 80 display (BGR, inverted, 26 offset)
// #define ST7735_REDTAB
// #define ST7735_BLACKTAB
// #define ST7735_REDTAB160x80 // For 160 x 80 display with 24 pixel offset
// If colours are inverted (white shows as black) then uncomment one of the next
// 2 lines try both options, one of the options should correct the inversion.
// #define TFT_INVERSION_ON
// #define TFT_INVERSION_OFF
// ##################################################################################
//
// Section 2. Define the pins that are used to interface with the display here
//
// ##################################################################################
// If a backlight control signal is available then define the TFT_BL pin in Section 2
// below. The backlight will be turned ON when tft.begin() is called, but the library
// needs to know if the LEDs are ON with the pin HIGH or LOW. If the LEDs are to be
// driven with a PWM signal or turned OFF/ON then this must be handled by the user
// sketch. e.g. with digitalWrite(TFT_BL, LOW);
// #define TFT_BL 32 // LED back-light control pin
// #define TFT_BACKLIGHT_ON HIGH // Level to turn ON back-light (HIGH or LOW)
// We must use hardware SPI, a minimum of 3 GPIO pins is needed.
// Typical setup for the RP2040 is :
//
// Display SDO/MISO to RP2040 pin D0 (or leave disconnected if not reading TFT)
// Display LED to RP2040 pin 3V3 or 5V
// Display SCK to RP2040 pin D2
// Display SDI/MOSI to RP2040 pin D3
// Display DC (RS/AO)to RP2040 pin D18 (can use another pin if desired)
// Display RESET to RP2040 pin D19 (can use another pin if desired)
// Display CS to RP2040 pin D20 (can use another pin if desired, or GND, see below)
// Display GND to RP2040 pin GND (0V)
// Display VCC to RP2040 5V or 3.3V (5v if display has a 5V to 3.3V regulator fitted)
//
// The DC (Data Command) pin may be labelled AO or RS (Register Select)
//
// With some displays such as the ILI9341 the TFT CS pin can be connected to GND if no more
// SPI devices (e.g. an SD Card) are connected, in this case comment out the #define TFT_CS
// line below so it is NOT defined. Other displays such at the ST7735 require the TFT CS pin
// to be toggled during setup, so in these cases the TFT_CS line must be defined and connected.
// For the Pico use these #define lines
#define TFT_MISO 0
#define TFT_MOSI 3
#define TFT_SCLK 2
#define TFT_CS 20 // Chip select control pin
#define TFT_DC 18 // Data Command control pin
#define TFT_RST 19 // Reset pin (could connect to Arduino RESET pin)
//#define TFT_BL // LED back-light
//#define TOUCH_CS 21 // Chip select pin (T_CS) of touch screen
// ##################################################################################
//
// Section 3. Define the fonts that are to be used here
//
// ##################################################################################
// Comment out the #defines below with // to stop that font being loaded
// The ESP8366 and ESP32 have plenty of memory so commenting out fonts is not
// normally necessary. If all fonts are loaded the extra FLASH space required is
// about 17Kbytes. To save FLASH space only enable the fonts you need!
#define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
#define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
//#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
#define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
// Comment out the #define below to stop the SPIFFS filing system and smooth font code being loaded
// this will save ~20kbytes of FLASH
#define SMOOTH_FONT
// ##################################################################################
//
// Section 4. Other options
//
// ##################################################################################
// Define the SPI clock frequency, this affects the graphics rendering speed. Too
// fast and the TFT driver will not keep up and display corruption appears.
// With an ILI9341 display 40MHz works OK, 80MHz sometimes fails
// With a ST7735 display more than 27MHz may not work (spurious pixels and lines)
// With an ILI9163 display 27 MHz works OK.
// #define SPI_FREQUENCY 1000000
// #define SPI_FREQUENCY 5000000
// #define SPI_FREQUENCY 10000000
// #define SPI_FREQUENCY 20000000
// #define SPI_FREQUENCY 32000000
#define SPI_FREQUENCY 70000000
// Optional reduced SPI frequency for reading TFT
#define SPI_READ_FREQUENCY 20000000
// The XPT2046 requires a lower SPI clock rate of 2.5MHz so we define that here:
#define SPI_TOUCH_FREQUENCY 2500000
- Edit the User_Setup_Select.h file to point to the custom setup file,
Setup60_RP2040_ST7735.h.
With ArduinoCore-mbed Release 2.0.0, Arduino now support Raspberry Pi Pico officially. To program Raspberry
Pi Pico in Arduino framework, install Arduino Mbed OS RP2040 Boards
in Arduino IDE's Library Manager.
In my usage scenario: The Raspberry Pi 4B/8G is installed with HQ Camera Module
(mount with manual focus lens). Remote control with Android with xrdp/Microsoft
Remote Desktop. Such that I can control and change setting on remote Android
device running Python code, adjust focus/aperture on the lens, and check the
effect on local HDMI preview at real-time.