LuckFox Pico ProでUbuntuを使ってみる

Adafruit Blinkaライブラリ

python-peripheryは素晴らしいライブラリですが、基本的なデバイスのアクセスしかサポートしていないので、いろいろ作り込む必要 が有ります。
こちらにPython GPIOライブラリのAdafruit-Blinkaが公開されています。
このAdafruit-BlinkaライブラリをベースにしたAdafruit CircuitPythonライブラリと言うライブラリが有ります。
こ ちらにライブラリの一覧が公開されています。
2024年時点で利用可能なライブラリは 273 個もあります。
これらのリポジトリを見ると全てのリポジトリのrequirements.txtにAdafruit-Blinkaが登録されています。
つまりこれらのライブラリは全てAdafruit-Blinkaをベースに構築されています。
Adafruit-Blinkaが対応しているボードでは、これらのライブラリを利用することができます。

残念ながらこのライブラリは、LuckFoxシリーズに対応していませんでした。
このライブラリへの対応を追加するだけで 273 個のライブラリが使えるようになるのは魅力です。
そこで、Adafruit-BlinkaのサポートにLucxFox Pico Maxを追加し、リポジトリに反映しました。
8.44.0以降、インストール方法が変わり、gccとg++が動く環境が必要になりました。
デフォルトでインストールされているg++11は壊れているので、g++12/g++10/g++9をインストールして、
バージョンを切り替えて8.44.0をインストールしてみましたが、どのコンパイラーを使ってもエラーになります。
原因が分かりません。
$ sudo apt install python3-pip python3-setuptools

$ python3 -m pip -V
pip 18.1 from /usr/lib/python3/dist-packages/pip (python 3.7)

$ python3 -m pip install -U pip

$ python3 -m pip -V
pip 20.3.1 from /home/orangepi/.local/lib/python3.7/site-packages/pip (python 3.7)

$ sudo apt install g++-12

$ sudo apt install g++-10

$ sudo apt install g++-9

$ sudo apt --reinstall install libc6-dev

$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 12

$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 11

$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 10

$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 9

$ sudo update-alternatives --config gcc
There are 4 choices for the alternative gcc (providing /usr/bin/gcc).

  Selection    Path             Priority   Status
------------------------------------------------------------
* 0            /usr/bin/gcc-12   12        auto mode
  1            /usr/bin/gcc-10   10        manual mode
  2            /usr/bin/gcc-11   11        manual mode
  3            /usr/bin/gcc-12   12        manual mode
  4            /usr/bin/gcc-9    9         manual mode

Press <enter> to keep the current choice[*], or type selection number:

$ python3 -m pip install Adafruit-Blinka
Defaulting to user installation because normal site-packages is not writeable
Collecting Adafruit-Blinka
  Using cached Adafruit_Blinka-8.45.0-py3-none-any.whl
Collecting Adafruit-PlatformDetect>=3.70.1 (from Adafruit-Blinka)
  Using cached Adafruit_PlatformDetect-3.71.0-py3-none-any.whl.metadata (3.8 kB)
Collecting Adafruit-PureIO>=1.1.7 (from Adafruit-Blinka)
  Using cached Adafruit_PureIO-1.1.11-py3-none-any.whl.metadata (3.0 kB)
Collecting adafruit-circuitpython-typing (from Adafruit-Blinka)
  Using cached adafruit_circuitpython_typing-1.10.3-py3-none-any.whl.metadata (3.2 kB)
Collecting binho-host-adapter>=0.1.6 (from Adafruit-Blinka)
  Using cached binho_host_adapter-0.1.6-py3-none-any.whl.metadata (2.0 kB)
Collecting numpy>=1.21.5 (from Adafruit-Blinka)
  Using cached numpy-2.0.0-cp310-cp310-linux_armv7l.whl
Collecting pyftdi>=0.40.0 (from Adafruit-Blinka)
  Using cached pyftdi-0.55.4-py3-none-any.whl.metadata (3.2 kB)
Collecting sysv-ipc>=1.1.0 (from Adafruit-Blinka)
  Using cached sysv_ipc-1.1.0.tar.gz (99 kB)
  Preparing metadata (setup.py) ... done
Collecting pyserial (from binho-host-adapter>=0.1.6->Adafruit-Blinka)
  Using cached pyserial-3.5-py2.py3-none-any.whl.metadata (1.6 kB)
Collecting pyusb!=1.2.0,>=1.0.0 (from pyftdi>=0.40.0->Adafruit-Blinka)
  Using cached pyusb-1.2.1-py3-none-any.whl.metadata (2.2 kB)
Collecting adafruit-circuitpython-busdevice (from adafruit-circuitpython-typing->Adafruit-Blinka)
  Using cached adafruit_circuitpython_busdevice-5.2.9-py3-none-any.whl.metadata (4.0 kB)
Collecting adafruit-circuitpython-requests (from adafruit-circuitpython-typing->Adafruit-Blinka)
  Using cached adafruit_circuitpython_requests-4.1.1-py3-none-any.whl.metadata (3.5 kB)
Collecting typing-extensions~=4.0 (from adafruit-circuitpython-typing->Adafruit-Blinka)
  Using cached typing_extensions-4.12.2-py3-none-any.whl.metadata (3.0 kB)
Collecting Adafruit-Circuitpython-ConnectionManager (from adafruit-circuitpython-requests->adafruit-circuitpython-typing->Adafruit-Blinka)
  Using cached adafruit_circuitpython_connectionmanager-3.1.1-py3-none-any.whl.metadata (4.5 kB)
Using cached Adafruit_PlatformDetect-3.71.0-py3-none-any.whl (24 kB)
Using cached Adafruit_PureIO-1.1.11-py3-none-any.whl (10 kB)
Using cached binho_host_adapter-0.1.6-py3-none-any.whl (10 kB)
Using cached pyftdi-0.55.4-py3-none-any.whl (145 kB)
Using cached adafruit_circuitpython_typing-1.10.3-py3-none-any.whl (11 kB)
Using cached pyserial-3.5-py2.py3-none-any.whl (90 kB)
Using cached pyusb-1.2.1-py3-none-any.whl (58 kB)
Using cached typing_extensions-4.12.2-py3-none-any.whl (37 kB)
Using cached adafruit_circuitpython_busdevice-5.2.9-py3-none-any.whl (7.5 kB)
Using cached adafruit_circuitpython_requests-4.1.1-py3-none-any.whl (10 kB)
Using cached adafruit_circuitpython_connectionmanager-3.1.1-py3-none-any.whl (7.8 kB)
Building wheels for collected packages: sysv-ipc
  Building wheel for sysv-ipc (setup.py) ... error
  error: subprocess-exited-with-error

  × python setup.py bdist_wheel did not run successfully.
  x exit code: 1
  mq> [17 lines of output]
      running bdist_wheel
      running build
      running build_ext
      building 'sysv_ipc' extension
      creating build
      creating build/temp.linux-armv7l-3.10
      arm-linux-gnueabihf-gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.10 -c common.c -o build/temp.linux-armv7l-3.10/common.o
      arm-linux-gnueabihf-gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.10 -c memory.c -o build/temp.linux-armv7l-3.10/memory.o
      arm-linux-gnueabihf-gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.10 -c mq.c -o build/temp.linux-armv7l-3.10/mq.o
      arm-linux-gnueabihf-gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.10 -c semaphore.c -o build/temp.linux-armv7l-3.10/semaphore.o
      arm-linux-gnueabihf-gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.10 -c sysv_ipc_module.c -o build/temp.linux-armv7l-3.10/sysv_ipc_module.o
      creating build/lib.linux-armv7l-3.10
      arm-linux-gnueabihf-gcc -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -g -fwrapv -O2 -Wl,-Bsymbolic-functions -g -fwrapv -O2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 build/temp.linux-armv7l-3.10/common.o build/temp.linux-armv7l-3.10/memory.o build/temp.linux-armv7l-3.10/mq.o build/temp.linux-armv7l-3.10/semaphore.o build/temp.linux-armv7l-3.10/sysv_ipc_module.o -o build/lib.linux-armv7l-3.10/sysv_ipc.cpython-310-arm-linux-gnueabihf.so
      /usr/bin/ld: cannot find -lgcc: No such file or directory
      /usr/bin/ld: cannot find -lgcc: No such file or directory
      collect2: error: ld returned 1 exit status
      error: command '/usr/bin/arm-linux-gnueabihf-gcc' failed with exit code 1
      [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for sysv-ipc
  Running setup.py clean for sysv-ipc
Failed to build sysv-ipc
ERROR: ERROR: Failed to build installable wheels for some pyproject.toml based projects (sysv-ipc)


インストールできない原因が不明なので、8.43.0をインストールする必要が有ります。
$ sudo apt install python3-pip python3-setuptools

$ python3 -m pip -V
pip 18.1 from /usr/lib/python3/dist-packages/pip (python 3.7)

$ python3 -m pip install -U pip

$ python3 -m pip -V
pip 20.3.1 from /home/orangepi/.local/lib/python3.7/site-packages/pip (python 3.7)

$ python3 -m pip install Adafruit-Blinka==8.43.0

pipの実行時に以下の証明書エラーになる事が有ります。
$ python3 -m pip install -U pip
Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: pip in ./.local/lib/python3.10/site-packages (24.0)
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate is not yet valid (_ssl.c:1007)'))': /simple/pip/
WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate is not yet valid (_ssl.c:1007)'))': /simple/pip/
WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate is not yet valid (_ssl.c:1007)'))': /simple/pip/
WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate is not yet valid (_ssl.c:1007)'))': /simple/pip/
WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate is not yet valid (_ssl.c:1007)'))': /simple/pip/
Could not fetch URL https://pypi.org/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/pip/ (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate is not yet valid (_ssl.c:1007)'))) - skipping

その場合の解決策がこちらに 有ります。
Linuxの場合は$HOME/.config/pip/pip.confを作って、そこに以下を記載すれば解決します。
$ cat $HOME/.config/pip/pip.conf
[global]
trusted-host = pypi.python.org
               pypi.org
               files.pythonhosted.org



手始めにこ ちらのライブラリをインストールしてBMP280から温度を読み出してみました。
このライブラリはI2C/SPI両方に対応しています。
これがI2Cインタフェースを使う場合のスクリプト(bmp280-i2c.py)です。
#!/usr/bin/python
#-*- encoding: utf-8 -*-
import time
import board
# import digitalio # For use with SPI
import adafruit_bmp280

# Create sensor object, communicating over the board's default I2C bus
i2c = board.I2C()   # uses board.SCL and board.SDA
bmp280 = adafruit_bmp280.Adafruit_BMP280_I2C(i2c, 0x76)

# OR Create sensor object, communicating over the board's default SPI bus
# spi = board.SPI()
# bmp_cs = digitalio.DigitalInOut(board.D10)
# bmp280 = adafruit_bmp280.Adafruit_BMP280_SPI(spi, bmp_cs)

# change this to match the location's pressure (hPa) at sea level
bmp280.sea_level_pressure = 1013.25

while True:
    print("\nTemperature: %0.1f C" % bmp280.temperature)
    print("Pressure: %0.1f hPa" % bmp280.pressure)
    print("Altitude = %0.2f meters" % bmp280.altitude)
    time.sleep(2)

Luckfox PicoのI2CはGPIO58(SDA)/GPIO59(SCL)です。
$ sudo -E python3 bmp280-i2c.py

Temperature: 27.3 C
Pressure: 1013.9 hPa
Altitude = -5.68 meters

Temperature: 27.3 C
Pressure: 1014.0 hPa
Altitude = -5.88 meters

Temperature: 27.3 C
Pressure: 1013.9 hPa
Altitude = -5.72 meters



これがSPIインタフェースを使う場合のスクリプト(bmp280-spi.py)です。
#!/usr/bin/python
#-*- encoding: utf-8 -*-
import time
import board
import digitalio # For use with SPI
import adafruit_bmp280

# Create sensor object, communicating over the board's default I2C bus
#i2c = board.I2C()       # uses board.SCL and board.SDA
#bmp280 = adafruit_bmp280.Adafruit_BMP280_I2C(i2c, 0x76)

# OR Create sensor object, communicating over the board's default SPI bus
spi = board.SPI()
#bmp_cs = digitalio.DigitalInOut(board.G73)
bmp_cs = digitalio.DigitalInOut(board.G72)
bmp280 = adafruit_bmp280.Adafruit_BMP280_SPI(spi, bmp_cs)

# change this to match the location's pressure (hPa) at sea level
bmp280.sea_level_pressure = 1013.25

while True:
        print("\nTemperature: %0.1f C" % bmp280.temperature)
        print("Pressure: %0.1f hPa" % bmp280.pressure)
        print("Altitude = %0.2f meters" % bmp280.altitude)
        time.sleep(2)

Luckfox PicoのSPIはGPIO49(SCLK)/GPIO50(MOSI)/GPIO51(MISO)です。
CSにはGPIO72を使いました。
$ sudo -E python3 bmp280-spi.py

Temperature: 27.3 C
Pressure: 1015.7 hPa
Altitude = -20.31 meters

Temperature: 27.3 C
Pressure: 1015.7 hPa
Altitude = -20.46 meters

Temperature: 27.3 C
Pressure: 1015.7 hPa
Altitude = -20.53 meters



Adafruit_CircuitPython_SSD1306のこ ちらのサンプルを動かしてみました。
このサンプルを実行するためには、こ ちらのフレームバッファライブラリのサンプルに含まれるフォントファイルが必要になります。
インストールは以下の手順です。
$ python3 -m pip install adafruit-circuitpython-ssd1306

$ git clone https://github.com/adafruit/Adafruit_CircuitPython_SSD1306
$ git clone https://github.com/adafruit/Adafruit_CircuitPython_framebuf
$ cp $HOME/Adafruit_CircuitPython_framebuf/examples/font5x8.bin $HOME/Adafruit_CircuitPython_SSD1306/examples/

$ cd $HOME/Adafruit_CircuitPython_SSD1306/examples/

$ vi ssd1306_framebuftest.py

#reset_pin = DigitalInOut(board.D5)
#display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x3C, reset=reset_pin)
display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x3C)

$ sudo -E python3 ./ssd1306_framebuftest.py

手元のモジュールにはRESETピンが無いので、RESETピンの指定は無効にしました。




LuckFox Pico Miniにも対応しました。






こ ちらにSPIインタフェースのW5500を利用するライブラリが公開されています。
issuesを検索したらW5200でも使えるみたいです。
こ ちらのサンプルを少し変更してLuckfoxで試してみました。
変更したのは以下の部分で、WIZNET5Kのインスタンス生成時にcs、reset、macを追加しています。
cs_pin = digitalio.DigitalInOut(board.G72)
reset_pin = digitalio.DigitalInOut(board.G73)
spi_bus = busio.SPI(board.SCLK, MOSI=board.MOSI, MISO=board.MISO)

# Initialize ethernet interface with DHCP
#eth = WIZNET5K(spi_bus, cs)
eth = WIZNET5K(spi_bus, cs=cs_pin, reset=reset_pin, mac='DE:AD:BE:EF:FE:ED')

このライブラリはHelperライブラリとしてこ ちらのライブラリを利用します。
このライブラリの中のcp_version = sys.implementation[1]がエラーになります。
Luckfoxではsys.implementationはlistではなくnamespaceとなっています。
sys.implementation=namespace(name='cpython', cache_tag='cpython-310', version=sys.version_info(major=3, minor=10, micro=12, releaselevel='final', serial=0), hexversion=50990320, _multiarch='arm-linux-gnueabihf')

そこで、この部分をコメントアウトしました。
この変更については、現在Adafruitに問合せしています。
$ vi $HOME/.local/lib/python3.10/site-packages/adafruit_connection_manager.py


            # Note: At this time, SSL/TLS connections are not supported by older
            # versions of the Wiznet5k library or on boards withouut the ssl module
            # see https://docs.circuitpython.org/en/latest/shared-bindings/support_matrix.html
            ssl_context = None

            """
            cp_version = sys.implementation[1]
            if pool.SOCK_STREAM == 1 and cp_version >= WIZNET5K_SSL_SUPPORT_VERSION:
                try:
                    import ssl  # pylint: disable=import-outside-toplevel

                    ssl_context = ssl.create_default_context()
                except ImportError:
                    # if SSL not on board, default to fake_ssl_context
                    pass

            """

こちらこちらの サイトの情報が正しくferchできました。
$ sudo -E python3 wiznet5k_simpletest.py
Wiznet5k WebClient Test
Chip Version: w5500
MAC Address: ['0xde', '0xad', '0xbe', '0xef', '0xfe', '0xed']
My IP address is: 192.168.10.145
IP lookup adafruit.com: 104.20.39.240
Fetching text from http://wifitest.adafruit.com/testwifi/index.html
----------------------------------------
This is a test of Adafruit WiFi!
If you can read this, its working :)
----------------------------------------

Fetching json from http://api.coindesk.com/v1/bpi/currentprice/USD.json
----------------------------------------
{'time': {'updated': 'Jun 8, 2024 22:23:59 UTC', 'updatedISO': '2024-06-08T22:23:59+00:00', 'updateduk': 'Jun 8, 2024 at 23:23 BST'}, 'disclaimer': 'This data was produced from the CoinDesk Bitcoin Price Index (USD). Non-USD currency data converted using hourly conversion rate from openexchangerates.org', 'bpi': {'USD': {'code': 'USD', 'rate': '69,435.326', 'description': 'United States Dollar', 'rate_float': 69435.3264}}}
----------------------------------------
Done!

Ethernetの無いモデルでEthernetが使えるようになりますが、W5500は$4ぐらいの追加コストが必要になります。
Ethernetの無いモデル + W5500は、送料を考えるとPico Proよりも高価になるかもしれません。

以下は2024年6月時点のこちらの オフィシャルサイトでの価格です。
オフィシャルサイトで購入すると、一個口あたり$5.00の送料が掛かります。
送料は一個口あたりの送料で、同時に複数個購入しても$5.00です。
1個だけ購入する場合は、AliExpressの方が安い場合が有ります。
Model Memory NAND FLASH Network Price Shipping
Pico 64MB

$6.99 $5.00
Pico Mini-A 64MB

$6.99 $5.00
Pico Mini-B 64MB 128MB
$8.99 $5.00
Pico Plus 64MB 128MB Ethernet $9.99 $5.00
Pico Pro 128MB 256MB Ethernet $12.99 $5.00
Pico Max 256MB 256MB Ethernet $14.99 $5.00