LuckFox Pico MiniでUbuntuを使ってみる

PythonからのNetwork通信

LuckFox Pico Miniにはネットワークの機能が有りません。
この様なEthernetデバイスを$3程度で入手することができます。


Miniボードにはこのデバイスを接続するためのランドが赤枠の場所に準備されていますが、
写真の様に不完全なランドになっていて、はんだ付けしても完全には固定されません。
また、64Mメモリでまともに動くのかどうか怪しいです。


Miniボードには2組のUARTデバイス(/dev/ttyS3と/dev/ttyS4)が有ります。
一番簡単なのはHC-05/06モジュールを使ったBluetooth通信です。
これらはシリアル通信を無線化するデバイスで、UARTへの入出力をそのまま無線化することができます。
HC05+HC06+送料で$9程度で入手可能ですが、Bluetoothなので1対1の通信となります。
$9を追加するなら、最初からEthernetが付いているPico Proを買った方が安いです。

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

$6.99
Pico Mini-A 64MB

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

PicoボードはUSBポートから給電しますが、VBUSポートからの給電も可能です。
SDKが公開されていますので、SDKを使ってUbuntuをゴニョゴニョとカスタイマイズすれば、
USB-WiFiドングルを使ったWiFi通信ができるかもしれませんが、私には敷居が高いです。

そこで、ESP8266(ESP01)をWiFiモデムとして使うことにしました。
ソースはこちらで公 開しています。
PySerialが動けば、どんなボードでも使えます。
UART通信なのでMQTTのPubとSubが同時に動けないのが残念です。




こ ちらにAdafruit-Blinkaで利用できるドライバーやヘルパーライブラリの一覧が有ります。
その中に、こ ちらのEthernetドライバーが含まれています。
このEthernetドライバーは、SPI接続のW5500モジュールのためのドライバーです。

Adafruit-BlinkaはAdafruit CircuitPythonを前提としたライブラリです。
Linuxで動作するpythonはCpythonなので、これらのドライバーやライブラリは、
Cpythonでも正しく動作するものと、Cpythonでは動作しないものが有ります。
一部のヘルパーライブラリは、Cpython環境ではインストールすらできないものも有ります。

そこで、このEthenetライブラリをCpython環境で試してみました。
PicoMini本体よりもEthernetモジュールの方が大きいです。


PicoMiniとの接続は以下の通りです。
W5500 PicoMini
MISO GPIO51
MOSI GPIO50
SCLK GPIO49
RST GPIO55
RCS GPIO54

こ ちらの公式サンプルを少し変更することでPicoMiniでも動くことが分かりました。
# Adafruit_CircuitPython_Wiznet5k example for LuckFox Pico Mini

"""
W5500  Pico
MISO   GPIO51
MOSI   GPIO50
SCLK   GPIO49
RST    GPIO55
RCS    GPIO54
"""

import board
import busio
import digitalio
import adafruit_connection_manager
import adafruit_requests
from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K

print("Wiznet5k WebClient Test")

TEXT_URL = "http://wifitest.adafruit.com/testwifi/index.html"
#JSON_URL = "http://api.coindesk.com/v1/bpi/currentprice/USD.json"
JSON_URL = "http://httpbin.org/delay/3"

# For LuckFox Pico Mini
cs_pin = digitalio.DigitalInOut(board.G54)
reset_pin = digitalio.DigitalInOut(board.G55)
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')

# Initialize a requests session
pool = adafruit_connection_manager.get_radio_socketpool(eth)
ssl_context = adafruit_connection_manager.get_radio_ssl_context(eth)
requests = adafruit_requests.Session(pool, ssl_context)

print("Chip Version:", eth.chip)
print("MAC Address:", [hex(i) for i in eth.mac_address])
print("My IP address is:", eth.pretty_ip(eth.ip_address))
print("IP lookup adafruit.com: %s" % eth.pretty_ip(eth.get_host_by_name("adafruiit.com")))


# eth._debug = True
print("Fetching text from", TEXT_URL)
r = requests.get(TEXT_URL)
print("-" * 40)
print(r.text)
print("-" * 40)
r.close()

print()
print("Fetching json from", JSON_URL)
r = requests.get(JSON_URL)
print("-" * 40)
print(r.json())
print("-" * 40)
r.close()

print("Done!")

adafruit_connection_manager()の戻り値を確認してみました。
import board
import busio
import digitalio
import adafruit_connection_manager
from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K

#Port Number
PORT = 5000

# Initialize module
cs_pin = digitalio.DigitalInOut(board.G54)
reset_pin = digitalio.DigitalInOut(board.G55)
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')

# Initialize socket
socket = adafruit_connection_manager.get_radio_socketpool(eth)
print(dir(socket))

target_ip = "192.168.10.46"
target_port = 8080
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((target_ip,target_port))
client.send(b"Data by TCP Client!!")
client.close()

これがその結果です。
socket通信に必要な関数や定義が含まれています。
$ sudo -E python3 main.py
['AF_INET', 'SOCK_DGRAM', 'SOCK_STREAM', 'SOL_SOCKET', 'SO_REUSEADDR', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_default_socket_timeout', '_interface', '_is_ipv4_string', 'getaddrinfo', 'getdefaulttimeout', 'gethostbyname', 'htonl', 'htons', 'inet_aton', 'inet_ntoa', 'setdefaulttimeout', 'socket']

Linux-PCで以下のサーバースクリプトを起動しておくと、ちゃんとサーバー側にメッセージが届きます。
Pico Miniでpython-socketを使ったコードが全て動くはずです。
#!/bin/bash
#This script requires netcat or socat
#set -x

# trap ctrl-c and call ctrl_c()
trap ctrl_c SIGINT

function ctrl_c() {
        #echo "** Trapped CTRL-C"
        RUNNING=0
}

PORT=8080
RUNNING=1
while [ $RUNNING -eq 1 ]
do
        # using netcat
        netcat -l ${PORT}
        # using socat
        #socat tcp-listen:${PORT},reuseaddr stdout
        echo
done

続く...