0%

In my previous blog about Maix Bit, we covered camera sensor, lcd display, and SPI with logic analyzer. However, WiFi is NEVER talked about.

1. Cable Connection

1.1 Pin Definitions of ESP32-C3 Super Mini

Cited from First Look at the Super Mini ESP32-C3:

Pin Definitions of ESP32-C3 Super Mini

1.2 Sipeed MaixBit Datasheet

Please refer to Sipeed MaixBit Datasheet V2.0.

The key thing to keep in mind is: pin 26, 27, 28, 29 are reserved for TF card by default. Cited from Sipeed MaixBit Datasheet V2.0 as:

Maix Bit V2.0 Slik K210 IO Function Remark
26 IO26 SPI0_MISO Reserved for TF Card
27 IO27 SPI0_SCLK Reserved for TF Card
28 IO28 SPI0_MOSI Reserved for TF Card
29 IO29 SPI0_CS0 Reserved for TF Card

Therefore, in my test, I’m going to use the pins 22,23,24,25 and 21 (optional) instead, and summarized in the NEXT section.

1.3 Wired Connection Between Maix Bit board and ESP32-C3 Super Mini

Signal Maix Bit Direction ESP32-C3 Super Mini Description Typical Wire Color Notes
GND GND Shared GND Ground reference Black Must be common between boards
SCLK (SCK) 22 ==> 4 SPI clock yellow Clock lines are often yellow
MISO 23 <== 5 Master In, Slave Out green Data from ESP32-C3 Super Mini to MaixBit
MOSI 24 ==> 6 Master Out, Slave In blue Data from MaixBit to ESP32-C3 Super Mini
CS (SS) 25 ==> 7 Chip Select (active low) purple One CS per SPI slave
RDY 21 <== 10 Ready / Flow-control signal white Optional but recommended

Cable Connection - Maix Bit

2. Hardware Info

2.1 lsusb

1
2
Bus 009 Device 033: ID 303a:1001 Espressif USB JTAG/serial debug unit
Bus 009 Device 034: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC

2.2 kflash and esptool

kflash and esptool

Clearly,

3. Flash

3.1 kflash MaixPy-v1 onto Maix Bit

kflash MaixPy-v1 onto Maix Bit

3.2 esptool onto ESP32-C3 Super Mini

idf.py set-target esp32c3 partitions.csv
set-target partitions.csv
idf.py build flash and monitor
set-target flash

monitor

1. Breif Summary

In my previous two MaixDuino blog posts MaixDuino 1 and MaixDuino 2, flashing was done using the Arduino IDE. In hindsight, this was neither necessary nor particularly convenient. Especially after flashing the Sipeed official firmware MaixPy-v1 onto the MaixDuino board, there is no real need to rely on the Arduino IDE anymore.

This blog post continues the MaixDuino exploration and completes two experiments:

  • A very simple implementation of dual-camera image capture on the MaixDuino board, with alternating display on the onboard LCD screen (Refer to LCD API), without relying on Arduino IDE at all;

  • Streaming the stereo camera images over the MaixDuino’s onboard Wi-Fi to a remote display endpoint.

2. Cable Connection

Maix Bit board Connected to a ESP32-C3 Super Mini MaixDuino board Already Embedded a ESP32-WROOM-32
Cable Connection - Maix Bit Cable Connection - MaixDuino

3. Stream From Two Cameras

3.1 Flash MaixPy-v1 Onto /dev/ttyUSB0

MaixPy-v1 kflash MaixDuino

3.2 Flash Maixduino_esp32_fimware Onto /dev/ttyUSB1 (Optional)

  • Clearly, there is a typo here Maixduino_esp32_fimware
  • Since this is Optional, I just have this step ignored for now.

3.3 Python Scripts For Streaming Two Cameras

The full Python scripts of streaming from 2 cameras can be found in my this Github Repo maixduino_stereocam_esp32:

MaixPy-v1 ampy 2 Cameras and LCD

3.4 Demonstration on LCD

One Image Captured From Left Camera One Image Captured From Right Camera
Left Camera Image Right Camera Image

4. WiFi

None of my previous 3 blogs talked about WiFi.

MaixDuino‘s Sipeed-M1 uses the FIXED hard SPI1 to communicate with its onboard ESP32-WROOM-32, where you need to use network.ESP32_SPI for communication via WiFi, as follows:

1
2
3
4
5
6
7
8
9
nic = network.ESP32_SPI(
cs=gh(gpiohs["cs"]),
rst=gh(gpiohs["rst"]),
rdy=gh(gpiohs["rdy"]),
mosi=gh(gpiohs["mosi"]),
miso=gh(gpiohs["miso"]),
sclk=gh(gpiohs["sclk"]),
spi=1,
)

4.1 Python Scripts

4.2 Demonstration

4.2.1 MaixPy REPL

MaixPy-v1 REPL MaixDuino WiFi Successful

4.2.2 Camera with LCD

4.2.3 On Remote PC

How time flies. It is ALREADY 2026.

I had never realized before that the JeVois-Pro actually has such powerful computing capability. Today, while digging through some of my old gears, I suddenly came to realize that in addition to the 5 TOPs of computing capability on the SoC itself, my JeVois-Pro also has a Google Coral M.2 Accelerator A+E key installed, adding another 4 TOPs of computing power.

From my earlier blog about JeVois-Pro, it’s clear that I never really took full advantage of the computing power of the JeVois-Pro, and I also didn’t succeed in turning the JeVois-Pro into an RTSP server. However, in this blog post, I will carry out a comprehensive test.

1. JeVois-Pro Hardware

Top View Bottom View
JeVois Pro Top JeVois Pro Bottom
JeVois-Pro Camera IMX290 Google Coral M.2 Accelerator A+E key
JeVois Pro IMX290 [Google Coral] [M.2 Accelerator A+E key]
JeVois-Pro Assembled
JeVois Pro Assembled

2. Some Command Lines

2.1 neofetch

neofetch

2.2 lscpu

lscpu

2.3 lspci

lspci

2.4 TFLite is now LiteRT

tflite

3.

I’m back from China and now in Greater Vancouver, celebrating Christmas. 😍❤️😊

Today, let me continue my second blog post about Jetson AGX Xavier.

1. About This Project

The following two illustrations were generated with the assistance of DeepSeek.

1.1 Complete System Architecture

Complete System Architecture

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
flowchart TD
A[YouTube Live Stream] --> B[FFmpeg RTMP Receiver]
B --> C[RTSP Stream rtsp://127.0.0.1:8554/yt]

C --> D[Mediamtx RTSP Server]

D --> E[Original Stream HLS Conversion]
E --> F[Original HLS Stream<br>/hls/yt/]

D --> G{AI Processing Branch}

G --> H[DeepStream AI Processing]
H --> I[AI Processed RTSP Stream<br>rtsp://127.0.0.1:8554/ai]

I --> J[AI Stream HLS Conversion]
J --> K[AI HLS Stream<br>/hls/ai/]

F --> L[Nginx Web Server]
K --> L

L --> M[User Access<br>https://live.visionmisc.com]

subgraph "Systemd Service Management"
S1[mediamtx.service]
S2[yt-hls-converter.service]
S3[deepstream-ai.service]
S4[ai-hls-converter.service]
S5[nginx.service]
end

S1 --> D
S2 --> E
S3 --> H
S4 --> J
S5 --> L

1.2 System Features Summary

Complete System Architecture

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
mindmap
root(Real-time AI Video Processing System)

Architecture Features
Modular Design
Independent Service Components
Loose Coupling
Easy to Extend
Real-time Processing
Low Latency Pipeline
Parallel Processing
Streaming Architecture

Technology Stack
Deep Learning
DeepStream SDK
YOLOv3-tiny Model
NVIDIA GPU Acceleration
Streaming Media
RTSP Protocol
HLS Delivery
Mediamtx Server
System Management
Systemd Services
Auto-restart
Log Monitoring

Functional Features
Dual Stream Output
Original Video Stream
AI Processed Stream
Real-time Detection
Object Recognition
Bounding Box Annotation
Multi-class Detection
Web Interface
Responsive Design
Real-time Status
Stream Switching

Deployment Advantages
One-click Installation
Auto Configuration
Easy Maintenance
Resource Efficient

1.3 Key Systemd Services

1
2
3
4
5
6
7
8
9
➜  system systemctl list-units --type=service --state=active | grep -E "(mediamtx|hls|deepstream|mtx)"

ai-hls-converter.service loaded active running AI RTSP to HLS Converter
deepstream-ai.service loaded active running DeepStream AI Processing
mediamtx.service loaded active running MediaMTX (RTSP/HLS/WebRTC Media Server)
youtube-to-mtx@lvision.service loaded active running YouTube -> MediaMTX RTSP Publisher (yt) for user lvision
yt-hls-converter.service loaded active running YouTube RTSP to HLS Converter
➜ system

1.3.2 mediamtx.service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
➜  system cat mediamtx.service
[Unit]
Description=MediaMTX (RTSP/HLS/WebRTC Media Server)
After=network-online.target
Wants=network-online.target
# Add this line to allow other services to declare dependencies
Before=yt-hls-converter.service ai-hls-converter.service deepstream-ai.service

[Service]
Type=simple
# Add user/group to maintain consistency with other services
User=lvision
Group=lvision
# Add environment variables to ensure correct working environment
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

ExecStart=/opt/mediamtx/mediamtx /opt/mediamtx/mediamtx.yml
WorkingDirectory=/opt/mediamtx

# Adjust restart policy - keep your choice, but consider stricter restart
Restart=on-failure
RestartSec=2
# Add startup timeout - mediamtx starts quickly, but just in case
TimeoutStartSec=10

# Log configuration
StandardOutput=journal
StandardError=journal
SyslogIdentifier=mediamtx

# Security hardening (keep your settings)
NoNewPrivileges=true
PrivateTmp=true
# Optional additional security settings
ProtectSystem=strict
ReadWritePaths=/opt/mediamtx /tmp

[Install]
WantedBy=multi-user.target

1.3.3 yt-hls-converter.service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
➜  system cat yt-hls-converter.service
[Unit]
Description=YouTube RTSP to HLS Converter
After=network.target mediamtx.service
Wants=mediamtx.service
# If you want to start only after /yt path is ready, you can add:
# After=mediamtx.service
# BindsTo=mediamtx.service

[Service]
Type=simple
User=lvision
Group=lvision
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# Wait for mediamtx to fully start
# ExecStartPre=/bin/sleep 5
ExecStart=/usr/local/bin/rtsp_to_hls_yt.sh

Restart=always
RestartSec=5

StandardOutput=journal
StandardError=journal
SyslogIdentifier=yt-hls-converter

[Install]
WantedBy=multi-user.target

1.3.4 ai-hls-converter.service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
➜  system cat ai-hls-converter.service 
[Unit]
Description=AI RTSP to HLS Converter
# Key Modification 1: Add the dependency of deepstream-ai.service
After=deepstream-ai.service mediamtx.service network.target
Wants=deepstream-ai.service mediamtx.service
# If you want to start only after /ai path is ready, you can add:
# After=mediamtx.service
# BindsTo=mediamtx.service

[Service]
Type=simple
User=lvision
Group=lvision
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# Key Modification 2: Wait for deepstream-ai to fully start (takes longer)
# ExecStartPre=/bin/sleep 10
ExecStart=/usr/local/bin/rtsp_to_hls_ai.sh

Restart=always
RestartSec=5

StandardOutput=journal
StandardError=journal
# Key Modification 3: different SyslogIdentifier
SyslogIdentifier=ai-hls-converter

[Install]
WantedBy=multi-user.target
➜ system

1.3.5 deepstream-ai.service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
➜  system cat deepstream-ai.service 
[Unit]
Description=DeepStream AI Processing
After=mediamtx.service
Wants=mediamtx.service
Requires=mediamtx.service

[Service]
Type=simple
User=lvision
Group=lvision
Environment="LD_LIBRARY_PATH=/opt/nvidia/deepstream/deepstream-6.3/lib:/usr/local/cuda/lib64"
Environment="GST_DEBUG=WARNING"
Environment="NVBUF_TRANSFORM_USE_EGL=0"
Environment="__GLX_VENDOR_LIBRARY_NAME=nvidia"
WorkingDirectory=/opt/vision
ExecStart=/usr/bin/python3 /opt/vision/yt_ai_app.py -i rtsp://127.0.0.1:8554/yt -o rtsp://127.0.0.1:8554/ai -c /opt/nvidia/deepstream/deepstream-6.3/sources/objectDetector_Yolo/config_infer_primary_yoloV3_tiny.txt
Restart=always
RestartSec=10

StandardOutput=journal
StandardError=journal
SupplementaryGroups=video
Nice=-5

[Install]
WantedBy=multi-user.target

1.4 Configurations and Running Scripts

1.4.1 MediaMTX

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
➜  system tail -n 40 /opt/mediamtx/mediamtx.yml

# It's possible to use regular expressions by using a tilde as prefix,
# for example "~^(test1|test2)$" will match both "test1" and "test2",
# for example "~^prefix" will match all paths that start with "prefix".
paths:
# example:
# my_camera:
# source: rtsp://my_camera
yt:
runOnDemand: /usr/local/bin/youtube_to_mtx.sh
runOnDemandRestart: yes
runOnDemandStartTimeout: 30s
runOnDemandCloseAfter: 10s

ai:
runOnDemand: /usr/local/bin/rtsp_to_hls_ai.sh
runOnDemandRestart: yes
runOnDemandStartTimeout: 30s
runOnDemandCloseAfter: 10s

......

# Settings under path "all_others" are applied to all paths that
# do not match another entry.
all_others:
➜ system

1.4.2 youtube_to_mtx.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
➜  ~ cat /usr/local/bin/youtube_to_mtx.sh
#!/usr/bin/env bash
set -euo pipefail

# Fixed YouTube URL
YOUTUBE_URL="https://youtu.be/57w2gYXjRic"
MTX_RTSP="rtsp://127.0.0.1:8554/yt"

# Log to stderr (mediamtx will capture)
echo "=== YouTube Stream Start $(date) ===" >&2
echo "Source: $YOUTUBE_URL" >&2
echo "Destination: $MTX_RTSP" >&2

# Get best stream URL (filter out warning messages)
echo "Fetching stream URL..." >&2
STREAM_URL=$(yt-dlp -f "best[height<=1080]" -g "$YOUTUBE_URL" 2>/dev/null | grep -E "^https?://" | head -1)

if [ -z "$STREAM_URL" ]; then
echo "Error: Unable to fetch stream URL" >&2
# Debug: show full output
echo "Attempting to fetch stream URL (with debugging):" >&2
yt-dlp -f "best[height<=1080]" -g "$YOUTUBE_URL" >&2
exit 1
fi

echo "Stream URL fetched successfully" >&2
echo "Starting stream to MediaMTX..." >&2

# Key: Copy video stream directly, no re-encoding (save resources)
exec ffmpeg -hide_banner -loglevel warning \
-re \
-i "$STREAM_URL" \
-c:v copy \
-an \
-f rtsp \
-rtsp_transport tcp \
"$MTX_RTSP"

1.4.3 rtsp_to_hls_ai.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
➜  ~ cat /usr/local/bin/rtsp_to_hls_ai.sh
#!/usr/bin/env bash
set -euo pipefail

# Modification 1: RTSP URL points to AI stream
RTSP_URL="rtsp://127.0.0.1:8554/ai"
# Modification 2: HLS directory points to ai
HLS_DIR="/var/www/live.visionmisc.com/html/hls/ai"
HLS_M3U8="${HLS_DIR}/index.m3u8"
# Modification 3: log file is now named as AI version
LOG_FILE="/home/lvision/logs/rtsp_to_hls_ai.log"

# Create directories
mkdir -p "${HLS_DIR}"
mkdir -p "$(dirname "${LOG_FILE}")" # 这会创建 /home/lvision/logs/

# Simple logging function
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "${LOG_FILE}"
}

log "=== Starting AI RTSP -> HLS Converter ==="

# Clean up old files
find "${HLS_DIR}" -name "*.ts" -delete 2>/dev/null || true
rm -f "${HLS_M3U8}" 2>/dev/null || true

# Added: Wait for AI RTSP stream to be ready (DeepStream may need time to start)
log "Waiting for AI RTSP stream to be ready..."
MAX_WAIT=60
for i in $(seq 1 $MAX_WAIT); do
if timeout 2s ffprobe -rtsp_transport tcp "${RTSP_URL}" 2>&1 | grep -q "Stream.*Video"; then
log "AI RTSP stream is ready (waited ${i} seconds)"
break
fi
if [ $i -eq $MAX_WAIT ]; then
log "Warning: AI RTSP stream not ready within ${MAX_WAIT} seconds, but will continue trying"
fi
sleep 1
done

# Simple logging function
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "${LOG_FILE}"
}


# Main loop
while true; do
log "Attempting to connect to AI RTSP stream: $RTSP_URL"

log "Starting HLS conversion for AI stream..."
if ffmpeg -hide_banner -loglevel warning \
-rtsp_transport tcp \
-i "${RTSP_URL}" \
-an \
-c:v copy \
-f hls \
-hls_time 2 \
-hls_list_size 6 \
-hls_flags delete_segments+append_list \
-hls_segment_filename "${HLS_DIR}/segment_%05d.ts" \
"${HLS_M3U8}" 2>&1 | grep -E "(Stream|Opening|error|failed)" | head -2; then
log "AI stream conversion process reported an error"
else
log "AI stream conversion loop ended or interrupted, preparing to retry..."
fi

log "Waiting 5 seconds before retrying connection..."
sleep 5
done
➜ ~

2. Demonstration

Pedestrian Detection Based on DeepStream 6.3 YoloV3-Tiny on a NVidia Jetson AGX Xavier
Pedestrian Detection Based on DeepStream-6.3 YoloV3-Tiny on a NVidia AGX Xavier
Car Detected Based on DeepStream 6.3 YoloV3-Tiny on a NVidia Jetson AGX Xavier
Car Detected Based on DeepStream-6.3 YoloV3-Tiny on a NVidia AGX Xavier

🔴 AI Vision Live - Longer Vision Technology

🚀 AI Vision Live

Two of my previous blogs have been talking about Hailo, respectively:

Since I’m now back to Vancouver for Christmas, let me write my 3rd blog about Hailo today.

1. Some Updates

1.1 Switched To Using Hailo PCIE M.2 Hat.

Top View of Raspberry Pi 5 Hailo PCIE M.2 Hat
hailo hat top view
Side View of Raspberry Pi 5 Hailo PCIE M.2 Hat
hailo hat side view

1.2 Raspberry Pi 5 Enviroment fastfetch

Raspberry Pi 5 FastFetch

1.3 Hailo 4.23.0 Released

Good news !!! Hailo 4.23.0 has been released, and it supports Raspberry Pi 5 with native Python 3.13.5 installation, which is incredibly convenient. The only thing to remember: make sure to install DKMS by sudo apt install dkms.

Please visit Hailo Software Downloads to download and install the following three MUST software packages:

1.3.1 HailoRT – Ubuntu package (deb) for arm64 hailort_4.23.0_arm64.deb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
➜  ~ dpkg -L hailort
/.
/etc
/etc/default
/etc/default/hailort_service
/lib
/lib/systemd
/lib/systemd/system
/lib/systemd/system/hailort.service
/usr
/usr/bin
/usr/bin/hailortcli
/usr/include
/usr/include/gstreamer-1.0
/usr/include/gstreamer-1.0/gst
/usr/include/gstreamer-1.0/gst/hailo
/usr/include/gstreamer-1.0/gst/hailo/include
/usr/include/gstreamer-1.0/gst/hailo/include/hailo_gst.h
/usr/include/gstreamer-1.0/gst/hailo/tensor_meta.hpp
/usr/include/hailo
/usr/include/hailo/buffer.hpp
/usr/include/hailo/device.hpp
/usr/include/hailo/dma_mapped_buffer.hpp
/usr/include/hailo/event.hpp
/usr/include/hailo/expected.hpp
/usr/include/hailo/genai
/usr/include/hailo/genai/common.hpp
/usr/include/hailo/genai/llm
/usr/include/hailo/genai/llm/llm.hpp
/usr/include/hailo/genai/text2image
/usr/include/hailo/genai/text2image/text2image.hpp
/usr/include/hailo/genai/vdevice_genai.hpp
/usr/include/hailo/hailo_gst_tensor_metadata.hpp
/usr/include/hailo/hailo_session.hpp
/usr/include/hailo/hailort.h
/usr/include/hailo/hailort.hpp
/usr/include/hailo/hailort_common.hpp
/usr/include/hailo/hailort_defaults.hpp
/usr/include/hailo/hailort_dma-heap.h
/usr/include/hailo/hef.hpp
/usr/include/hailo/infer_model.hpp
/usr/include/hailo/inference_pipeline.hpp
/usr/include/hailo/network_group.hpp
/usr/include/hailo/network_rate_calculator.hpp
/usr/include/hailo/platform.h
/usr/include/hailo/quantization.hpp
/usr/include/hailo/runtime_statistics.hpp
/usr/include/hailo/stream.hpp
/usr/include/hailo/transform.hpp
/usr/include/hailo/vdevice.hpp
/usr/include/hailo/vstream.hpp
/usr/lib
/usr/lib/aarch64-linux-gnu
/usr/lib/aarch64-linux-gnu/gstreamer-1.0
/usr/lib/aarch64-linux-gnu/gstreamer-1.0/libgsthailo.so
/usr/lib/cmake
/usr/lib/cmake/HailoRT
/usr/lib/cmake/HailoRT/HailoRTConfig.cmake
/usr/lib/cmake/HailoRT/HailoRTConfigVersion.cmake
/usr/lib/cmake/HailoRT/HailoRTTargets-release.cmake
/usr/lib/cmake/HailoRT/HailoRTTargets.cmake
/usr/lib/libhailort.so.4.23.0
/usr/local
/usr/local/bin
/usr/local/bin/hailort_service
/usr/share
/usr/share/doc
/usr/share/doc/hailort
/usr/share/doc/hailort/copyright
➜ ~

1.3.2 HailoRT – PCIe driver Ubuntu package (deb) hailort-pcie-driver_4.23.0_all.deb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
➜  ~ dpkg -L hailort-pcie-driver
/.
/lib
/lib/firmware
/lib/firmware/hailo
/lib/firmware/hailo/hailo8_fw.4.23.0.bin
/lib/udev
/lib/udev/rules.d
/lib/udev/rules.d/51-hailo-udev.rules
/share
/share/opt
/share/opt/hailo
/share/opt/hailo/common
/share/opt/hailo/common/fw_operation.c
/share/opt/hailo/common/fw_operation.h
/share/opt/hailo/common/fw_validation.c
/share/opt/hailo/common/fw_validation.h
/share/opt/hailo/common/hailo_ioctl_common.h
/share/opt/hailo/common/hailo_resource.c
/share/opt/hailo/common/hailo_resource.h
/share/opt/hailo/common/pcie_common.c
/share/opt/hailo/common/pcie_common.h
/share/opt/hailo/common/soc_structs.h
/share/opt/hailo/common/utils.h
/share/opt/hailo/common/vdma_common.c
/share/opt/hailo/common/vdma_common.h
/share/opt/hailo/linux
/share/opt/hailo/linux/pcie
/share/opt/hailo/linux/pcie/51-hailo-udev.rules
/share/opt/hailo/linux/pcie/Kbuild
/share/opt/hailo/linux/pcie/Makefile
/share/opt/hailo/linux/pcie/Readme.md
/share/opt/hailo/linux/pcie/dkms.conf.in
/share/opt/hailo/linux/pcie/dkms_uninstall.sh
/share/opt/hailo/linux/pcie/hailo_pci.conf
/share/opt/hailo/linux/pcie/src
/share/opt/hailo/linux/pcie/src/fops.c
/share/opt/hailo/linux/pcie/src/fops.h
/share/opt/hailo/linux/pcie/src/nnc.c
/share/opt/hailo/linux/pcie/src/nnc.h
/share/opt/hailo/linux/pcie/src/pcie.c
/share/opt/hailo/linux/pcie/src/pcie.h
/share/opt/hailo/linux/pcie/src/soc.c
/share/opt/hailo/linux/pcie/src/soc.h
/share/opt/hailo/linux/pcie/src/sysfs.c
/share/opt/hailo/linux/pcie/src/sysfs.h
/share/opt/hailo/linux/pcie/tools
/share/opt/hailo/linux/pcie/tools/hailo_load.sh
/share/opt/hailo/linux/pcie/tools/hailo_pci_driver_dkms_remove.sh
/share/opt/hailo/linux/pcie/tools/hailo_unload.sh
/share/opt/hailo/linux/utils
/share/opt/hailo/linux/utils/compact.h
/share/opt/hailo/linux/utils/fw_common.h
/share/opt/hailo/linux/utils/integrated_nnc_utils.c
/share/opt/hailo/linux/utils/integrated_nnc_utils.h
/share/opt/hailo/linux/utils/logs.c
/share/opt/hailo/linux/utils/logs.h
/share/opt/hailo/linux/vdma
/share/opt/hailo/linux/vdma/ioctl.c
/share/opt/hailo/linux/vdma/ioctl.h
/share/opt/hailo/linux/vdma/memory.c
/share/opt/hailo/linux/vdma/memory.h
/share/opt/hailo/linux/vdma/vdma.c
/share/opt/hailo/linux/vdma/vdma.h
/usr
/usr/share
/usr/share/doc
/usr/share/doc/hailort
/usr/share/doc/hailort/hailo_firmware_eula
➜ ~

1.3.3 HailoRT – Python package (whl) for Python 3.13, aarch64 hailort-4.23.0-cp313-cp313-linux_aarch64.whl

1.3.4 TAPPAS Python Binding (Optional)

1
2
3
➜  ~ pip list | rg hailo
hailort 4.23.0
➜ ~

Finally, let’s test if Hailo is correctly configured on our Raspberry Pi 5.

Hailo Configuration

2. Models

2.1 Prepare HAILO8L Models

2.2 hailortcli run *.hefs

hailortcli run Tests

3. Demonstration

3.1 On My Cellphone

Live Stream - Deep Night Beautiful Vancouver Live Stream - Beautiful Dublin Live Stream - Bears In Katmai Nation Park, Alaska
Deep Night Beautiful Vancouver Beautiful Dublin Bears In Katmai Park

3.2 From My Desktop

Have fun

Good new. I’m flying back to China for some traditional Chinese food - 热干面 😍❤️😊
In my first blog post about Jetson AGX Xavier early in year 2021, I just did a very simple demo with any industrial camera using Aravis. Today, I’m going to make full use of the CUDA GPU Compute Capability of my Jetson AGX Xavier, running DeepStream to live cam stream the city of Vancouver and twitter it out.

By the way, I forget to mention my this blog Kinect 2 on Jetson AGX Xavier.

1. Environment

1.1 neofetch

Neofetch

1.2 jtop

jtop

1.3 tegrastats and jetson_release

tegrastats and jetson_release

2. DeepStream

2.1 Install DeepStream On Jetson AGX Xavier

You first have to find the corresponding DeepStream version from its official website DeepStream. Since I’m using a Jetson AGX Xavier, I’d choose DeepStream 6.3 and have it installed on my device.

DeepStream 6.3

2.2 Set Up Configuration

Configuration

2.3 Model Configuration

Model Configuration

2.4 Demonstration

Process On a Video without Using deepstream Command
Run It
Results of Detection
One Resultant Frame

2.5 Conclusion

DeepStream 6.3 does not provide an out-of-the-box sample for rendering different object classes with different bounding box colors.

In DeepStream 6.3, deepstream-app uses the default nvdsosd behavior, which applies a single bounding box style to ALL detected objects.

The application-level configuration parser does not support class-wise color mapping, and nvdsosd color customization is not exposed through deepstream-app config files.

As a result, rendering different colors for different object classes requires custom OSD logic or a modified application, rather than configuration-only changes.

Hailo Technologies Ltd. is indeed a semiconductor high-tech company based in Tel Aviv, Israel. Although this blog focuses on the Israeli product Hailo-8L Entry-Level AI Accelerator, I would like to take this opportunity to celebrate the successful holding of 2025 China Victory Day Parade.

In my first blog post about Hailo last year, not using a Docker container to create a Python 3.10 environment caused me significant troubles, and I actually failed to complete the demonstration. Today, we are going to walk through the entire Hailo process again.

1. Raspberry Pi 5 Enviroment

1.1 neofetch

Raspberry Pi 5 Environment

1.2 Package Installation

Please visit Hailo Software Downloads to download and install the following three MUST software packages:

  • HailoRT – Ubuntu package (deb) for arm64
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
➜  dpkg -L hailort            
/.
/etc
/etc/default
/etc/default/hailort_service
/lib
/lib/systemd
/lib/systemd/system
/lib/systemd/system/hailort.service
/usr
/usr/bin
/usr/bin/hailortcli
/usr/include
/usr/include/gstreamer-1.0
/usr/include/gstreamer-1.0/gst
/usr/include/gstreamer-1.0/gst/hailo
/usr/include/gstreamer-1.0/gst/hailo/include
/usr/include/gstreamer-1.0/gst/hailo/include/hailo_gst.h
/usr/include/gstreamer-1.0/gst/hailo/tensor_meta.hpp
/usr/include/hailo
/usr/include/hailo/buffer.hpp
/usr/include/hailo/device.hpp
/usr/include/hailo/dma_mapped_buffer.hpp
/usr/include/hailo/event.hpp
/usr/include/hailo/expected.hpp
/usr/include/hailo/genai
/usr/include/hailo/genai/common.hpp
/usr/include/hailo/genai/llm
/usr/include/hailo/genai/llm/llm.hpp
/usr/include/hailo/genai/text2image
/usr/include/hailo/genai/text2image/text2image.hpp
/usr/include/hailo/genai/vdevice_genai.hpp
/usr/include/hailo/hailo_gst_tensor_metadata.hpp
/usr/include/hailo/hailo_session.hpp
/usr/include/hailo/hailort.h
/usr/include/hailo/hailort.hpp
/usr/include/hailo/hailort_common.hpp
/usr/include/hailo/hailort_defaults.hpp
/usr/include/hailo/hailort_dma-heap.h
/usr/include/hailo/hef.hpp
/usr/include/hailo/infer_model.hpp
/usr/include/hailo/inference_pipeline.hpp
/usr/include/hailo/network_group.hpp
/usr/include/hailo/network_rate_calculator.hpp
/usr/include/hailo/platform.h
/usr/include/hailo/quantization.hpp
/usr/include/hailo/runtime_statistics.hpp
/usr/include/hailo/stream.hpp
/usr/include/hailo/transform.hpp
/usr/include/hailo/vdevice.hpp
/usr/include/hailo/vstream.hpp
/usr/lib
/usr/lib/aarch64-linux-gnu
/usr/lib/aarch64-linux-gnu/gstreamer-1.0
/usr/lib/aarch64-linux-gnu/gstreamer-1.0/libgsthailo.so
/usr/lib/cmake
/usr/lib/cmake/HailoRT
/usr/lib/cmake/HailoRT/HailoRTConfig.cmake
/usr/lib/cmake/HailoRT/HailoRTConfigVersion.cmake
/usr/lib/cmake/HailoRT/HailoRTTargets-release.cmake
/usr/lib/cmake/HailoRT/HailoRTTargets.cmake
/usr/lib/libhailort.so.4.22.0
/usr/local
/usr/local/bin
/usr/local/bin/hailort_service
/usr/share
/usr/share/doc
/usr/share/doc/hailort
/usr/share/doc/hailort/copyright

  • HailoRT – PCIe driver Ubuntu package (deb)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
➜  ~ dpkg -L hailort-pcie-driver
/.
/lib
/lib/firmware
/lib/firmware/hailo
/lib/firmware/hailo/hailo8_fw.4.22.0.bin
/lib/udev
/lib/udev/rules.d
/lib/udev/rules.d/51-hailo-udev.rules
/share
/share/opt
/share/opt/hailo
/share/opt/hailo/common
/share/opt/hailo/common/fw_operation.c
/share/opt/hailo/common/fw_operation.h
/share/opt/hailo/common/fw_validation.c
/share/opt/hailo/common/fw_validation.h
/share/opt/hailo/common/hailo_ioctl_common.h
/share/opt/hailo/common/hailo_resource.c
/share/opt/hailo/common/hailo_resource.h
/share/opt/hailo/common/pcie_common.c
/share/opt/hailo/common/pcie_common.h
/share/opt/hailo/common/soc_structs.h
/share/opt/hailo/common/utils.h
/share/opt/hailo/common/vdma_common.c
/share/opt/hailo/common/vdma_common.h
/share/opt/hailo/linux
/share/opt/hailo/linux/pcie
/share/opt/hailo/linux/pcie/51-hailo-udev.rules
/share/opt/hailo/linux/pcie/Kbuild
/share/opt/hailo/linux/pcie/Makefile
/share/opt/hailo/linux/pcie/Readme.md
/share/opt/hailo/linux/pcie/dkms.conf.in
/share/opt/hailo/linux/pcie/dkms_uninstall.sh
/share/opt/hailo/linux/pcie/hailo_pci.conf
/share/opt/hailo/linux/pcie/src
/share/opt/hailo/linux/pcie/src/fops.c
/share/opt/hailo/linux/pcie/src/fops.h
/share/opt/hailo/linux/pcie/src/nnc.c
/share/opt/hailo/linux/pcie/src/nnc.h
/share/opt/hailo/linux/pcie/src/pcie.c
/share/opt/hailo/linux/pcie/src/pcie.h
/share/opt/hailo/linux/pcie/src/soc.c
/share/opt/hailo/linux/pcie/src/soc.h
/share/opt/hailo/linux/pcie/src/sysfs.c
/share/opt/hailo/linux/pcie/src/sysfs.h
/share/opt/hailo/linux/pcie/tools
/share/opt/hailo/linux/pcie/tools/hailo_load.sh
/share/opt/hailo/linux/pcie/tools/hailo_pci_driver_dkms_remove.sh
/share/opt/hailo/linux/pcie/tools/hailo_unload.sh
/share/opt/hailo/linux/utils
/share/opt/hailo/linux/utils/compact.h
/share/opt/hailo/linux/utils/fw_common.h
/share/opt/hailo/linux/utils/integrated_nnc_utils.c
/share/opt/hailo/linux/utils/integrated_nnc_utils.h
/share/opt/hailo/linux/utils/logs.c
/share/opt/hailo/linux/utils/logs.h
/share/opt/hailo/linux/vdma
/share/opt/hailo/linux/vdma/ioctl.c
/share/opt/hailo/linux/vdma/ioctl.h
/share/opt/hailo/linux/vdma/memory.c
/share/opt/hailo/linux/vdma/memory.h
/share/opt/hailo/linux/vdma/vdma.c
/share/opt/hailo/linux/vdma/vdma.h
/usr
/usr/share
/usr/share/doc
/usr/share/doc/hailort
/usr/share/doc/hailort/hailo_firmware_eula
➜ ~
  • HailoRT – Python package (whl) for Python 3.11, aarch64

  • TAPPAS Python Binding (Optional)

1
2
3
4
➜  ~ pip list | grep hailo
hailo-tappas-core-python-binding 5.0.0
hailort 4.22.0
➜ ~

Note: Since my Raspberry Pi 5 comes with Python 3.11 pre-installed, I have selected the Python 3.11 version. You should choose the appropriate version that matches your Python environment for installation.

Please also guarantee the software you installed are compatible with each other. As shown in the following, I’m using the newest compatible versions.

Release versions compatibility

Finally, let’s test if Hailo is correctly configured on our Raspberry Pi 5.

Hailo Configuration

1.3 Preparation

Please strictly follow the How to Set Up Raspberry Pi 5 and Hailo guide to fix any bugs that have already appeared or to prevent potential ones.

1.4 Identify Device Architecture

This is a MUST step to do.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
➜  ~ hailortcli fw-control identify

Executing on device: 0001:03:00.0
Identifying board
Control Protocol Version: 2
Firmware Version: 4.22.0 (release,app,extended context switch buffer)
Logger Version: 0
Board Name: Hailo-8
Device Architecture: HAILO8L
Serial Number: HLDDLBB243201887
Part Number: HM21LB1C2LAE
Product Name: HAILO-8L AI ACC M.2 B+M KEY MODULE EXT TMP

➜ ~

Mine is a HAILO8L.

2 Models

2.1 Download .hefs

For simplicity, I directly downloaded some .hef files from HAILO8L Models

2.2 hailortcli run .hefs

hailortcli run Tests

The .hef (Hailo Executable File) format is platform-independent: a single .hef file can be executed on both x86_64 hosts and aarch64 (ARM64) hosts, as long as the system has the appropriate Hailo runtime (HailoRT) and driver installed.

This is possible because the .hef file does not contain host-specific binaries or compiled CPU code. Instead, it encapsulates the compiled Hailo neural network graph targeted for the Hailo hardware accelerator itself. The host platform - whether x86_64 or aarch64 - acts mainly as a controller that loads the .hef into the Hailo device, configures it, and orchestrates inference.

In other words, the .hef file is tied to the Hailo hardware (e.g., Hailo-8, Hailo-8L, Hailo-10) but is independent of the host CPU architecture. This allows the same .hef model file to be deployed seamlessly across development environments (for example, a workstation with an x86_64 CPU and PCIe card) and edge devices (for example, a Raspberry Pi 5 or Jetson board with an ARM64 CPU and M.2 card).

3. Demonstration

3.1 Single Image - Object Detection and Image Segmentation

In this demonstration, 2 famous images from Ultralytics are respectively adopted for object detection and image segmentation:

Hailo Object Detection using yolov11s.hef Hailo Image Segmentation using yolov8s_seg.hef
Hailo Object Detection using yolov11s.hef Hailo Image Segmentation using yolov8s_seg.hef

3.2 Video - Detection and Tracking

3.3 Detection and Tracking - Live Camera RTSP

3.3.1 On Server Raspberry Pi 5

1
2
3
4
5
6
7
8
9
10
11
✗ python3 camera_ai_rtsp.py

[1:50:26.068253200] [7893] INFO Camera camera_manager.cpp:326 libcamera v0.5.1+100-e53bdf1f
[1:50:26.075415015] [7907] INFO RPI pisp.cpp:720 libpisp version v1.2.1 981977ff21f3 29-04-2025 (14:13:50)
[1:50:26.076215774] [7907] WARN CameraSensorProperties camera_sensor_properties.cpp:473 No static properties available for 'imx708_noir'
[1:50:26.076235959] [7907] WARN CameraSensorProperties camera_sensor_properties.cpp:475 Please consider updating the camera sensor properties database
[1:50:26.085411941] [7907] WARN CameraSensor camera_sensor_legacy.cpp:501 'imx708_noir': No sensor delays found in static properties. Assuming unverified defaults.
[1:50:26.085847404] [7907] INFO RPI pisp.cpp:1179 Registered camera /base/axi/pcie@1000120000/rp1/i2c@88000/imx708@1a to CFE device /dev/media0 and ISP device /dev/media2 using PiSP variant BCM2712_C0
[1:50:26.088843719] [7893] INFO Camera camera.cpp:1205 configuring streams: (0) 1280x720-RGB888/Rec709/Rec709/None/Full (1) 1536x864-BGGR_PISP_COMP1/RAW
[1:50:26.088947294] [7907] INFO RPI pisp.cpp:1483 Sensor: /base/axi/pcie@1000120000/rp1/i2c@88000/imx708@1a - Selected sensor format: 1536x864-SBGGR10_1X10 - Selected CFE format: 1536x864-PC1B
✅ RTSP server running at rtsp://<RPi5-IP>:8554/ai

3.3.2 On Any Client

1
ffplay -rtsp_transport tcp rtsp://192.168.1.90:8554/ai
Live Stream RTSP Broadcasted After Processed by Hailo on Raspberry Pi 5 ffplay the Processed Live Stream on Server
Hailo Object Detection using yolov11s.hef Hailo Image Segmentation using yolov8s_seg.hef

4. Compilation

Like other dedicated AI hardware platforms, Hailo‘s software stack involves compiling a trained model, converting it from the standard ONNX format into its proprietary HEF (Hailo Executable Format) file optimized for its own architecture.

1. Reference - About ESP32

All well documented by Espressif.

Cited from I2S,

1
2
3
I2S (Inter-IC Sound) is a synchronous serial communication protocol usually used for transmitting audio data between two digital audio devices.

ESP32-C3 contains one I2S peripheral(s). These peripherals can be configured to input and output sample data via the I2S driver.

In sum:

Although a single I2S controller is nominally full-duplex – supporting both input (recording) and output (playback), in practice, operations must be time-multiplexed. In other words, it is not truly capable of simultaneous input and output. To achieve real-time interaction – such as detecting user input and instantly interrupting playback – two independent I2S controllers are required: one dedicated to continuously handling microphone input, and the other to audio output to the speaker.

So, today, let’s make a bluetooth speaker based on ESP32-C3, which ONLY requires I2S to serve as output (playback).

2. Hardware Components

Any ESP32-C3 board MAX98357A I2S amplifier Any speaker
ESP32C3-Pro MAX98357A Any Speaker

3. Curcuit Connection

3.1 KiCad Schematic

KiCad Schematic

3.2 Real Connection

Real Connection

4. ESP32 Code

Please refer to Github LongerVisionRobot ESP32-C3-MAX98357A-WiFi-speaker.

5. Demonstration

ESP32-C3 Playing a Tone ESP32-C3 Playing an Audio File

Happy Friday… And, how I miss my beloved son… God bless… Today, I’ll talk about Maix Bit board.

1. Introduction

1.1 lsusb

1
2
3
......
Bus 009 Device 112: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC
......

1.2 Hardware Wiki

Detailed specification about Maix Bit board can be found on MaixBit Wiki.

1.3 Software

And, I am using MaixPy-v1 (Please refer to Introduction of MaixPy-v1).

2. Kendryte Toolchain Preparatio

You first need to build the executable toolchains out from the provided Kendryte RISC-V GNU Compiler Toolchain.

Kendryte RISC-V GNU Toolchain Built

In order to successfully build out the Kendryte toolchain, please handle the same ERROR in the following four files under riscv-binutils-gdb:

  • ./riscv-binutils-gdb/readline/complete.c
  • ./riscv-binutils-gdb/readline/display.c
  • ./riscv-binutils-gdb/readline/histfile.c
  • ./riscv-binutils-gdb/readline/mbutil.c

And modify the above 4 files as follows:

  • Add
1
2
3
4
5
6
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 600
#endif
#ifndef _POSIX_SOURCE
#define _POSIX_SOURCE
#endif

at the very top for each file.

  • Add #include <wchar.h> before line #include <sys/types.h> for each file.

3. Build and Flash maixpy_k210

3.1 To Build - 3 Commands

  • python3 project.py --toolchain /opt/toolchains/kendryte/kendryte-toolchain/bin --toolchain-prefix riscv64-unknown-elf- config
  • python3 project.py menuconfig
  • python3 project.py build

3.2 To Flash - Key Points

  • Find a good USB Type-C cable
  • You may need to flash at a lower baud rate.
  • Two commands:
    • python3 project.py flash -B dan -b 1500000 -p /dev/ttyUSB0 -t
    • In my case: kflash -p /dev/ttyUSB0 -b 9600 -t ./build/maixpy.bin

maixpy_k210 flashed

4. Camera and LCD

OV2640 Camera Live Stream with LCD Display FPS at The End
OV2640 Camera Live Streaming with LCD Display FPS at The End

5. SPI Test

My Logic Analyzer Driver sigrok-firmware-fx2lafw
My Logic Analyzer PulseView fx2lafw Driver

SPI Signal Analysis GUI - PulseView Adding SPI Decoder

SPI Signal Analysis GUI - PulseView Adding SPI Decoder

PulseView SPI Signal Analysis GUI Logic Analyzer

SPI Signal Analysis GUI - PulseView Logic Analyzer