2025年4月10日 星期四

Orange Pi One / Zero3 接 ILI9488 / ST7796 LCD

Linux 的 fb-tft 對 ILI9341 有完整的支援,但是解析度只有 320x240。KlipperScreen 要求的最低解析度是 480x320,若解析度低於這要求,雖然還是可以執行,但字跡會變模糊不清。

在淘寶可以找到較多人使用,480x320 的 SPI 界面 LCD,其控制晶片為 ILI9488/9486,另外則是 ST7796。因為搜尋 SPI LCD 的方案,大多會找到 ILI9488 相關的,因此先買 ILI9488 / ILI9486 來測試。很辛苦的改驅動,編譯 kernel module,最後是成功了。但是系統一更新,又變得改的程式都不能用了。

經過交叉測試,發現 Fly PI 的 LCD,使用 ST7796 控制器,用 fb_ili9341 的 driver,竟然能夠點亮,雖然顯示不正常,但可以看到在 320x240 的範圍內,正常顯示。

這表示 ST7796 可以使用 RGB565 的格式,經測試,只要把 fb_ili9341 的驅動程式的解析度改成 480x320 即可使用,幾乎完全不用改到程式的其他部分。

淘寶買 ili9488 的 LCD,用 fb_ili9341 的驅動程式來改,只會一片白屏。使用 fb_ili9486.c 來改,若 PIXEL_FORMAT 是 0x55,顯示一片白屏。將 PIXEL_FORMAT 是 0x66,會輸出雜亂的顯示。再加上轉換的 function,則可以成功驅動。

這類控制晶片透過 SPI 界面串列的傳送視訊資料,為了減少資料量,一個畫素 (pixel) 通常用 RGB565 或 RGB666 的格式。RGB565 為 R: 5bits, G: 6bits, B:5bits,共 16bits,傳送時,一個畫素佔 2bytes。RGB666 為 R: 6bits, G: 6bits, B:6bits,共 18bits ,傳送時,一個畫素佔 3bytes。相同的頻寬,後者可傳送的資料量只剩 2/3。

ILI9488 / ILI 9486,確定只能使用 RGB666 的格式。因此,較佳的選擇是買 ST7796 控制的 LCD。但 ILI9488 的 LCD,有較小的 3.5" 螢幕的選擇,價格更低。

參考連結

能夠找到的資訊,有的有點過時,或者,更新後,OS 版本太新,舊的方式不能用。因此雜亂地收集了一堆可能用得到的參考,等確定作法,再將沒用的刪除。

  • https://www.kernel.org/doc/Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml
  • https://github.com/KungfuPancake/v0_ips_touch_display/tree/main
  • https://github.com/notro/panel-mipi-dbi/wiki
  • https://forum.armbian.com/topic/48441-st7796-display-w-opiz3/
  • https://forums.raspberrypi.com/viewtopic.php?t=380704
  • https://forum.armbian.com/topic/47971-driving-the-ili9488-lcd-40-inch-cheap-chinese-clone/
  • https://github.com/notro/panel-mipi-dbi/issues/2
  • https://forums.raspberrypi.com/viewtopic.php?t=369139
  • https://github.com/raspberrypi/linux/blob/rpi-5.15.y/arch/arm/boot/dts/overlays/mipi-dbi-spi-overlay.dts
  • https://github.com/Vasily-Kapustin/ti9488/blob/master/ili9488.c
  • https://blog.dowhile0.org/2022/06/21/how-to-troubleshoot-deferred-probe-issues-in-linux/,出現 deferred probe 錯誤的原因與處理。

升級至最近的 kernel 6.12.30 之後,可以使用 tiny drm 的 panel-mipi-dbi-spi 模組,不用自行編譯 kernel module 了,方便很多。

SDO 和 T_DO 併聯問題

LCD 的 SDO 和觸控的 T_DO 都是接到 host 的 MISO。這兩支腳都是輸出,若將這兩支腳短路,可能會使得觸控不能運作。

將這兩支腳短路,在 ILI9341 的板子上沒問題,在 ILI9486 或 ILI9488 上,卻使得觸控不能運作。經過不斷的測試,花了好久的時間,才確認問題。

要同時驅動 LCD 和觸控,照著 ILI9341 測試成功的作法,將 SCK, SDO, SDI 三支腳都短路,然後 ILI9486 和 ILI9488 的觸控一直都沒反應。

先前因為 ads7846 驅動的設定改變,花了不少時間才解決。因而一開始也懷疑是 DTS 設定問題,或是某些 MCU 的接腳不能用。把手邊各種不同的 LCD 都拿來測試,包括 Fly Pi 的螢幕。改變各種設定,還是不能動作。

只能懷疑是 IC 壞掉,或是電阻膜被我弄壞。拿一塊新的 ILI9488,還沒把接腳短路,單獨測觸控功能,正常。但將接腳一短路,就掛了。

準備去買幾顆 IC 來換,發現 ILI9341 板子上的觸控 IC 是 XPT2046,ILI9488 板子上的觸控 IC 是 HR2046,是相容的 IC,才懷疑可能是 IC 的輸出短路造成問題。將 SDO 的短路線剪掉,測試觸控功能,OK。

LCD 沒用到 SDO,那就不要將這支腳短路吧,這樣 LCD 和觸控都正常了。

不能用的 pin

在 Orange PI Zero3,6.6.75-current-sunxi64,PC9 接腳不能用。

overlay 的改變

開始測試時,kernel 版本是 6.6.75,測試成功後。升級後,kernel 版本變 6.12.30,又變成不能驅動 LCD 了,會出現  "cannot register SPI host" 的錯誤。

---------
[    1.551842] ili9341@0 enforce active low on GPIO handle
[    1.551871] sun6i-spi 5011000.spi: cannot register SPI host
------------

經過好久,終於撈到解答。

/dts-v1/;
/plugin/;

/ {
    compatible = "xunlong,orangepi-zero3", "allwinner,sun50i-h616";

    fragment@0 {
        target = <&spi1>;
        __overlay__ {
            status = "okay";
            pinctrl-names = "default"; // new for linux 6.12
            pinctrl-0 = <&spi1_pins>;  // new for linux 6.12
            cs-gpios = <&pio 2 7 0>;  /* PC7 */

            st7796s: st7796s@0 {
                compatible = "sitronix,st7796s";
                reg = <0>;  /* Chip Select 0 */
		#spi-cs-high;
                spi-max-frequency = <40000000>;
                rotate = <180>;
                bgr = <0>;
                fps = <30>;
		width = <480>;
		height = <320>;
                buswidth = <8>;
                reset-gpios = <&pio 2 6 1>; /*RESET=PC6*/
                dc-gpios = <&pio 2 5 0>; /*DC_RS=PC5*/
                led-gpios = <&pio 2 8 0>; /*LED=PC8*/
                debug = <4>;
            };

        };
    };
};

要加上 pinctrl-names = "default"; 和 pinctrl-0 = <&spi1_pins>; 。





2025年4月8日 星期二

Rapide Lite 200 改 Klipper

 在網路上收的二手機。



建立及燒錄 Firmware

$ cd klipper
$ make menuconfig

[*] Enable extra low-level configuration options
    Micro-controller Architecture (Atmega AVR)
    Processor model (atmega2560)

$ make
  Creating symbolic link out/board
  Building out/autoconf.h
  Compiling out/src/sched.o
  .................
  Compiling out/src/generic/serial_irq.o
  Building out/compile_time_request.o
Version: v0.12.0-458-gd886c1761
  Linking out/klipper.elf
  Creating hex file out/klipper.elf.hex
$ make
$ make flash FLASH_DEVICE=/dev/serial/by-id/usb-RRD__www.ru_RUMBA_-_ATmega_2560_co_55437333437351B0A120-if00 

重新啟動系統。

2025年2月26日 星期三

requireJs 中使用 Vue3 框架


 參考 requireJs中使用Vue3及Vue3框架(viewUIPlus、elementPlus)。

目录结构


HTML页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hello</title>
    <script src="js/lib/require.js" data-main="js/script/main"></script>
</head>
<body>

main 配置文件

require.config({
    // 加載 js 的目錄,paths 中以此目錄為標準讀取
    baseUrl: 'js',

    // 類庫别名和路徑配置
    paths: {
        jquery: 'lib/jquery-3.7.1',
        // vue 别名必须為 vue,由於其他框架或模块寻找 vue 时查询的是 vue 的别名
        vue: 'lib/vue3/vue.global.prod',
        // viewUIPlus框架
        viewUIPlus: 'lib/viewUiPlus/viewuiplus.min',
        // elementPlus 框架
        elementPlus: 'lib/elementPlus/index.full.min',
        // elementPlus 字体库
        elementPlusIconsVue: 'lib/elementPlus/icons-vue/dist/index.iife.min',
    },

    // 依赖以及导出设置,key值需对应paths中的别名,用于非AMD标准的类库进行导出
    shim: {
        // 由于vue3不是标准的AMD模块,需要手动抛出Vue变量,供其他框架使用
        'vue': {
            exports: 'Vue'
        },
        // viewUIPlus css
        'viewUIPlus': ['vue', 'css!lib/viewUiPlus/styles/viewuiplus.css'],
        // elementPlus 字体库依赖vue 没有这个配置,加载字体库时可能因为vue还未加载而报错
        'elementPlusIconsVue': {
            // 依赖
            deps: ['vue'],
            // 导出变量
            exports: 'ElementPlusIconsVue',
        },
        // elementPlus css 字體庫
        'elementPlus': ['vue', 'css!lib/elementPlus/index.css', 'elementPlusIconsVue',],
    },

    // 插件以及其他模塊配置
    map: {
        '*': {
            // 加載 css 插件
            'css': 'lib/require-css'
        },
    },
});

// 單獨使用 vue
require(['vue'], function (Vue) {
    const {createApp} = Vue
    const app = createApp({
        data() {
            return {
                message: 'Hello Vue!',
            }
        },
        methods: {}
    })
    app.mount("#app");
})

// viewUIPlus vue依赖已在shim中配置,无需再次引入
require(['viewUIPlus'], function (ViewUIPlus) {
    const {createApp} = Vue
    const app = createApp({
        data() {
            return {
                message: 'Hello viewUiPlus!',
            }
        },
        methods: {}
    })
    app.use(ViewUIPlus);
    app.mount("#viewUi");
})

// elementPlus 字体库和vue依赖已在shim中配置,无需再次引入
require(['elementPlus'], function (ElementPlus) {
    const {createApp} = Vue
    const app = createApp({
        data() {
            return {
                message: 'Hello elementPlus'
            }
        },
        methods: {}
    })
    // 字体库组件
    for ([name, comp] of Object.entries(ElementPlusIconsVue)) {
        app.component(name, comp);
    }
    app.use(ElementPlus);
    app.mount("#ele");
})

效果

Vue2 及 Vue3 同時存在

require.config({
  baseUrl: ntuweb.baseUrl+'/assets',
  paths: {
    "jquery": "jquery-1.12.4.min",
    "jqueryform": "jquery.form.4.2.2.min",
    "jqueryui": "jquery-ui/jquery-ui-1.10.4.custom.min",
    "vue": "vue_2.6.14",  
    'vue3': "vue.global-3.5.12.min",
    "showModalDialog": "showModalDialog",
    'corejs': 'corejs-2.6.12_shim.min'
    , 'swal': 'sweetalert2-10.min'
  },
  // 以下為非 AMD 程式,有固定的載入順序
  shim : {
    // 由於 vue3 不是準的 AMD 模塊,需要手動拋出 Vue 變量,用於非AMD標準類庫進行導出
    'vue3': {
      exports: 'Vue'
    },
    "jqueryui": ["jquery"],
    "jqueryform": ["jquery"]
    , 'swal': ['corejs']
    , "showModalDialog": ["jqueryui"]
    , 'wbSingle': ['swal']
  }
});

使用 Vue2

require(['jquery', 'vue', 'showModalDialog', 'jqueryform'], function($, Vue)
{
    vm = new Vue({
        el: '#main-div',
        data: {
            dat: <?= json_encode($gdat) ?>,
            frm_label: '',
            LbState: 0, 
        },
        computed: {
            .....
        },
        methods: {
            .....
        }
    });
});

使用 Vue3

rrequire(['jquery', 'vue3', 'showModalDialog', 'jqueryform'], function($, Vue)
{
    const { createApp, ref ,reactive, computed} = Vue;

    vm = createApp({
        setup() {
            const dat = reactive({
                cou_code: ref(''),
                cou_cname: ref(''),
                credit: ref(0),
		..........
            });

            const frm_label = ref('');
            const LbState = ref(0); 

            return {
                dat, frm_label, LbState,
            }
        },
        computed: {
            ..........
        },
        methods: {
            ...........
        }
    }).mount('#main-div');
});

更新物件 dat 的屬性的值

Object.keys(vm.dat).forEach(function (kk) {
    vm.dat[kk] = ret[kk];
});











2025年2月21日 星期五

LCD debug

9341 正常的訊息 

-----------
[    1.664021] ili9341@0 enforce active low on GPIO handle
[    6.580043] fb_ili9341: module is from the staging directory, the quality is 
unknown, you have been warned.
[    6.580648] fb_ili9341 spi0.0: fbtft_property_value: width = 240
[    6.580674] fb_ili9341 spi0.0: fbtft_property_value: height = 320
[    6.580685] fb_ili9341 spi0.0: fbtft_property_value: buswidth = 8
[    6.580697] fb_ili9341 spi0.0: fbtft_property_value: debug = 4
[    6.580706] fb_ili9341 spi0.0: fbtft_property_value: rotate = 90
[    6.580716] fb_ili9341 spi0.0: fbtft_property_value: fps = 30
[    6.580973] fb_ili9341 spi0.0: fbtft_request_one_gpio: 'reset' GPIO
[    6.581032] fb_ili9341 spi0.0: fbtft_request_one_gpio: 'dc' GPIO
[    6.581067] fb_ili9341 spi0.0: fbtft_request_one_gpio: 'rd' GPIO
 ........... 一直重複 -----------
[    6.581590] fb_ili9341 spi0.0: fbtft_request_one_gpio: 'db' GPIO
...
[    6.887247] fb_ili9341 spi0.0: Display update: 3837 kB/s, fps=0
[    6.888155] Console: switching to colour frame buffer device 40x30
[    6.888772] graphics fb0: fb_ili9341 frame buffer, 320x240, 150 KiB video memory, 16 KiB buffer memory, fps=31, spi0.0 at 40 MHz
[    6.999727] systemd[1]: Starting systemd-backlight@backlight:fb_ili9341.service - Load/Save Screen Backlight Brightness of backlight:fb_ili9341...
[    7.003913] systemd[1]: Finished systemd-binfmt.service - Set Up Additional Binary Formats.
[    7.023356] usb 2-1: Firmware revision 11.1 (signature 0x88e1)
[    7.080231] systemd[1]: Finished systemd-backlight@backlight:fb_ili9341.service - Load/Save Screen Backlight Brightness of backlight:fb_ili9341.

--------------

使用 lsmod 

-------------
Module                  Size  Used by
fb_ili9341             12288  1
fbtft                  36864  1 fb_ili9341
-------------


https://mjmwired.net/kernel/Documentation/devicetree/bindings/display/ilitek,ili9486.yaml

參考 Using GPIO from a Linux Shell

--------------
$ dmesg | grep -i ads
[    7.067079] ads7846 spi0.1: supply vcc not found, using dummy regulator
[    7.072789] ads7846 spi0.1: touchscreen, irq 47
[    7.073534] input: ADS7846 Touchscreen as /devices/platform/soc/1c68000.spi/spi_master/spi0/spi0.1/input/input1

$ cat /proc/interrupts | grep ads
 47:         22          0          0          0  sunxi_pio_edge   6 Edge      ads7846

$ sudo gpiodetect
gpiochip0 [1c20800.pinctrl] (224 lines)
gpiochip1 [1f02c00.pinctrl] (32 lines)

$ sudo gpioinfo
gpiochip0 - 224 lines:
line   0:      unnamed       unused   input  active-high 
.....
line   5:      unnamed       unused   input  active-high 
line   6:      unnamed    "pendown"   input   active-low [used]
line   7:      unnamed        "led"  output  active-high [used]
line   8:      unnamed         "dc"  output  active-high [used]
line   9:      unnamed      "reset"  output   active-low [used]
line  10:      unnamed   "spi0 CS0"  output   active-low [used]
line  11:      unnamed       unused   input  active-high 
line  12:      unnamed       unused   input  active-high 
line  13:      unnamed       unused   input  active-high 
line  14:      unnamed       unused   input  active-high 
line  15:      unnamed "orangepi:red:status" output active-high [used]
line  16:      unnamed       unused   input  active-high 
.....
line  20:      unnamed   "spi0 CS1"  output  active-high [used]
.....
line 165:      unnamed       unused   input  active-high 
line 166:      unnamed         "cd"   input   active-low [used]
        ..... 
line 204:      unnamed "usb0_id_det" input active-high [used]
line 205:      unnamed       unused   input  active-high 

--------------

https://www.kernel.org/doc/Documentation/devicetree/bindings/input/touchscreen/ads7846.txt

https://github.com/raspberrypi/linux/pull/6029 (Mar 13, 2024)

The driver has been converted to use gpiod, which will normalise polarity based on DT.

The piscreen overlay (and others) incorrectly defines the pendown GPIO as being ACTIVE_HIGH (0), althought triggering on the high-low edge for pen down. It therefore tries reading the pen position when not being touched, and stops when it is touched.

Tested with piscreen and ads7846 overlays. Also fixed on others where the interrupt says high->low but the polarity was ACTIVE_HIGH.


ADS7846 Touch controller does not work anymore after upgrade to the latest kernel 6.6.20 on 64-bit Raspberry Pi OS Bookworm. It works well with the older kernel 6.1.0.

https://github.com/raspberrypi/linux/blob/rpi-6.6.y/arch/arm/boot/dts/overlays/ads7846-overlay.dts

-----------
pendown-gpio = <&pio 0 19 0>;
line  19:      unnamed    "pendown"   input  active-high [used]

pendown-gpio = <&pio 0 19 1>;
line  19:      unnamed    "pendown"   input   active-low [used]
---------------






2025年2月16日 星期日

在 Klipper 中使用 Fly 3D 的 D5

以前買來就直接使用。最近,怎麼都連不上。比較裝置的代碼,才發現不同

 /dev/serial/by-id/usb-katapult_stm32f072xb_MELLOW-if00

燒了 Klipper 的 firmware,應是

/dev/serial/by-id/usb-Klipper_stm32f072xb_3C0029000557465036383420-if00

原來,在2024年9月1号之后出厂的D5已经刷好Katapult固件。 

照著它的文件,就可以重新設定和 build 映像檔了。

https://mellow.klipper.cn/docs/ProductDoc/MainBoard/fly-d/fly-d5/flash/usb

燒入的指令

~/katapult/scripts$ python3 flashtool.py -d  /dev/serial/by-id/usb-katapult_stm32f072xb_MELLOW-if00

喇叭要關掉,要設 default 值。


2024年12月13日 星期五

Orange Pi One 安裝使用

網拍上,有人便宜拍賣汰換的 Orange Pi One 單板電腦,相對便宜很多,就買了幾個回來備用。

電源插頭的規格 (Plug tip size),4.0mm x 1.7mm。


到 Armbian - Orange Pi One 下載 image,是最新的 kernel。下載的是 xz 的壓縮檔,使用 unxz 解壓縮,unxz -k file.xz 則能保存壓縮檔。

可以使用圖形界面的燒錄程式,會檢查燒錄結果。也可以用 dd 或 dcfldd,後者較快,指令如下。

$ sudo dcfldd if=Armbian_xxx_Orangepizero3_bookworm_xxxx_minimal.img of=/dev/sde bs=10M

買的開發板,有附盒子,風扇,USB 轉圓柱頭的電源線,這些自己買,又要一百多吧。電源接頭規格 DC 4.0x1.7mm,打算買 DC-DC 的板子來將 24V 轉成 5V,給香橙派用。

WiFi使用 

------------
dmesg 的訊息
[    6.976374] systemd[1]: Listening on systemd-rfkill.socket - Load/Save RF Kil
l Switch Status /dev/rfkill Watch.
[    7.090397] usb 2-1: RTL8188EU rev D (TSMC) romver 0, 1T1R, TX queues 2, WiFi=1, BT=0, GPS=0, HI PA=0
[    7.090433] usb 2-1: RTL8188EU MAC: e0:e1:a9:93:da:11
[    7.090444] usb 2-1: rtl8xxxu: Loading firmware rtlwifi/rtl8188eufw.bin
[    7.398809] usb 2-1: Firmware revision 11.1 (signature 0x88e1)


$ lsmod 
Module                  Size  Used by
rtl8xxxu              159744  0
binfmt_misc            16384  1
mac80211              643072  1 rtl8xxxu
libarc4                12288  1 mac80211
-------------------

Orange Pi One,終究是 2016 的產品,使用上的體驗,速度遠比不上 2023 年出的  Orange Pi Zero 3。以電腦的進步來看,7年的時間,速度大約至少差 2倍。但是網拍的二手貨,很便宜,買一些來改 3D 印表機。3D 印表機改 Klipper,至少要一個上位機。只改一台,錢差一點沒差,但收集了一堆來改,改完想賣出,差幾百,就不一定有人要收,成本能省就省吧。 在成本上比較,前者,主板+WiFi+SD卡,約 400元,後者,主板+SD卡,約 600元。

安裝 armbian 的 image,版本比較新,https://www.armbian.com/orange-pi-one/ 。

即使安裝 network-manager,"apt install network-manager",執行 nmtui,顯示不正常。只好用 armbian-config 設定 WiFi。

參考 ARMBIAN OS - Networking,Armbian 預設使用 Netplan.io 來描述網路設定。使用 armbian-config 設定後,會將設定存在 /etc/netplan/armbian.yaml,直接修改設定,再執行  "netplan apply",即可讓設定生效。 

# cat armbian.yaml
network:
  version: 2
  renderer: networkd
  wifis:
    wlx40a5ef154b5f:
#      dhcp4: true
#      dhcp6: true
      addresses:
        - 10.161.86.137/20
      routes:
        - to: default
          via: 10.161.80.1
      nameservers:
        addresses:
          -  8.8.8.8
          - 8.8.8.4
      access-points:
        "Samsung-A50-cc":
          auth:
            key-management: "psk"
            password: "wifi-password"

"renderer: networkd",是指使用 systemd-networkd 的網路設定。但 Klipper 會安裝 NetworkManager。改用 NetworkManager,參考 Migrate Ubuntu server from NetPlan to NetworkManager without disconnection (possibly over SSH) 。

安裝 NetworkManager:

$ sudo apt install network-manager 

設定好 NetworkManager 後,Disable networkd and purge netplan:

$ sudo systemctl disable --now systemd-networkd.service systemd-networkd.socket networkd-dispatcher.service 
$ sudo systemctl restart NetworkManager
$ sudo apt purge netplan netplan.io -y

若沒有停掉 netplan 和 systemd-networkd,開機會要等 3分鐘才完成。

上面的作法,後來好像沒用,改用下面作法。

$ sudo systemctl disable --now systemd-networkd.service systemd-networkd.socket systemd-networkd-wait-online.service 
$ sudo systemctl restart NetworkManager
$ sudo systemctl mask systemd-networkd-wait-online.service

修改 /etc/netplan/armbian.yaml,如下。

network:
  version: 2
  renderer: NetworkManager

可以使用 systemd-analyze 產生時間圖,看看開機卡在那裡

$ systemd-analyze plot > systemd-analyze.svg 

由圖檔知道,一開始,kenerl 載入花了 5秒,systemd 程式載入用了 2秒,之後才開始啟動各種服務。

由時間圖,可以看到 systemd-networkd-wait-online.service 的時間是 2min 267ms,所以整個開機等了 3分鐘才完成。systemd-networkd-wait-online 會等有線網路啟動,一直到超過時間才跳過。

ZSWAP 設定

參考 Armbian Documentation - Fine Tuning: Swap for experts,簡要說明如下。

By default Armbian implements ZRAM (writing nothing to ‘disk’ but compressing memory pages in RAM) but in case you often run into out of memory errors and your device has some capable storage (e.g. a securely attached NVMe or SATA SSD) you might want to use ZSWAP instead.

不太懂有什麼好,但設一下吧。修改之前,系統顯示訊息如下。

$ systemctl --type swap
  UNIT           LOAD   ACTIVE SUB    DESCRIPTION
  dev-zram0.swap loaded active active /dev/zram0

$ dmesg | grep zswap
[    1.308166] zswap: loaded using pool zstd/zbud

利用 SD 上剩下的一點空間,建立和掛載 swap。修改 /etc/fstab,加上 swap 的掛載指令。

UUID=f6a5fd0a-8ce8-4e75-89b4-e230bd489a76 / ext4 defaults,noatime,commit=120,errors=remount-ro 0 1
UUID=3ce68f02-d664-4ae5-96ad-337c67fd74e4   none   swap   sw    0 0
tmpfs /tmp tmpfs defaults,nosuid 0 0

然後修改 /etc/default/armbian-zram-config,將 SWAP=false 的註解取消,然後重啟系統即可。

修改後,系統顯示訊息如下。

$ systemctl -t swap
  UNIT                                                                      LOAD   ACTIVE SUB    DESCRIPTION                                           
  dev-disk-by\x2duuid-5f0613fb\x2d295b\x2d4587\x2d80ef\x2d54f0c1302a73.swap loaded active active /dev/disk/by-uuid/5f0613fb-295b-4587-80ef-54f0c1302a73

若 SD卡容量比較大,可以使用 gparted 調整分割區的大小,空出比較大的空間建立 swap 分割區。

安裝 Klipper

依照 https://github.com/dw-0/kiauh 安裝 klipper。整個安裝過程,明顯比用 Orange Pi Zero 3 慢很多,可能要 2倍以上的時間。另外,由於記憶體較小,導致 tmpfs 的 /tmp 不足,在安裝 Moonraker 的階段,會耗盡 /tmp 的空間。因此需另建一個暫時的 tmp,步驟如下。

# Create a temp folder on a disk that has a lot of space:
sudo mkdir -p /bigtmp

# Set generous access to the temp folder:
sudo chmod 777 /bigtmp

# Change TMPDIR env to the big folder you just created:
export TMPDIR=/bigtmp

# install package

在安裝 Moonraker 時,改成用此暫時的 tmp。安裝其他的套件,則用 tmpfs,會比較快。安裝 moonraker,最多的時候,使用 /tmp 的空間約 266M。

-------
$ sudo apt install network-manager
....

Setting up network-manager (1.42.4-1) ...
Created symlink /etc/systemd/system/dbus-org.freedesktop.nm-dispatcher.service 
→ /lib/systemd/system/NetworkManager-dispatcher.service.
Created symlink /etc/systemd/system/network-online.target.wants/NetworkManager-
wait-online.service → /lib/systemd/system/NetworkManager-wait-online.service.
Created symlink /etc/systemd/system/multi-user.target.wants/NetworkManager.serv
ice → /lib/systemd/system/NetworkManager.service.
Processing triggers for dbus (1.14.10-1~deb12u1) ...
-------


安裝谐振测量所需的軟體

參考 Klipper documentation: Measuring Resonances

在執行到下列安裝指令時,很可能會掛掉,ssh 沒反應。

# 先將 TMPDIR env 變數改到實體目錄
$ sudo apt install python3-numpy python3-matplotlib libatlas-base-dev libopenblas-dev
$ export TMPDIR=/bigtmp
$ ~/klippy-env/bin/pip install -v "numpy<1.26"

儘可能把 service 停掉,擠出記憶體。

## 列出所有 active 的 service
systemctl list-units --type=service --state=active
OR
systemctl --type=service --state=active

## 把目前確定沒用的 service 都停掉
sudo systemctl stop klipper
sudo systemctl stop KlipperScreen.service
sudo systemctl stop NetworkManager.service
sudo systemctl stop moonraker.service
sudo systemctl stop nginx.service

終於安裝成功。測試如下,沒有出現錯誤訊息,即是成功。

$ ~/klippy-env/bin/python -c 'import numpy;'
$


啟用 SPI 

使用 armbian-config 啟用 sun8i-h3-spi-spidev,會在 /boot/armbianEnv.txt 中,加入一行

overlays=sun8i-h3-spi-spidev 

從 console 看到載入失敗的訊息

Failed to load '/boot/dtb/overlay/sun8i-h3-sun8i-h3-spi-spidev.dtbo'

因為已加上 overlay_prefix=sun8i-h3。修改後,並加上 param 參數,成功看到 /dev/spidev0.0 的裝置。完整的 /boot/armbianEnv.txt 如下。

verbosity=1
bootlogo=false
console=both
disp_mode=1920x1080p60
overlay_prefix=sun8i-h3
rootdev=UUID=5fda7286-2a9d-4d7c-aa26-de3614b88ae6
rootfstype=ext4
overlays=spi-spidev
param_spidev_spi_bus=0
usbstoragequirks=0x2537:0x1066:u,0x2537:0x1068:u

可以參考 /boot/dtb/overlay/README.sun8i-h3-overlays 的說明。

Gemini AI 提供的 klipper 的設定

# -----------------------------------------------------
# 1. 設置 Orange Pi One 本身為一個 MCU
# -----------------------------------------------------
[mcu rpi]
# 使用 host mcu 驅動 ADXL345
serial: /tmp/klipper_host_mcu 
# 確保您已經在 Klipper 安裝時編譯並啟動了 host mcu


# -----------------------------------------------------
# 2. 設置 ADXL345 加速度計
# -----------------------------------------------------
[adxl345]
# 這裡的 cs_pin 必須指向您在 OPi One 上連接 ADXL345 CS (片選) 的 GPIO 引腳
# 由於 Orange Pi 的引腳名稱不是標準的 Raspberry Pi 格式,您需要將 'rpi:' 替換為實際的 GPIO 名稱
# 
# **最常見的配置是讓 Klipper 使用 Host MCU 進行 SPI 溝通**
# 如果您已在 Armbian 啟用 SPI,Klipper 預設會使用 `/dev/spidevX.Y` 介面,
# 您可以將 cs_pin 設為 None,讓 Klipper 使用 SPI 驅動。
cs_pin: rpi:None 
spi_bus: spidev0.0 # 如果需要指定 SPI 總線,請參考 Klipper 文件

# -----------------------------------------------------
# 3. 設置共振測試器
# -----------------------------------------------------
[resonance_tester]
accel_chip: adxl345
probe_points: 90, 125, 20 # 設置測試點 (例如床面中心)

可用 ACCELEROMETER_QUERY 这个命令是查询加速器的参数。

接線

IO 的接腳如下。


觸控屏

--------------
OPi One wiring:
Pin 1  - 3.3V  (or Pin 4 - 5V)
Pin 6  - GND
Pin 35 - PA10 <-->  LCD CS   
Pin 33 - PA9  <-->  RESET
Pin 31 - PA8  <-->  DC
Pin 19 - PC0  <-->  SPI0 SDI<MOSI> & T_DIN
Pin 23 - PC2  <-->  SPI0 SCK       & T_CLK
Pin 29 - PA7  <-->  LED
Pin 21 - PC1  <-->  SPI0 SDO<MISO> & T_DO 
Pin 26 - PA20 <-->  T_CS
Pin 28 - PA19 <-->  T_IRQ
--------------
* LCD 的 MISO 不用接,接了可能使得觸控失效。

建立 /boot/overlay-user/ili9341_lcd.dts,內容如下。

/dts-v1/;
/plugin/;

/ {
    compatible = "xunlong,orangepi-one", "allwinner,sun8i-h3";

    fragment@0 {
        target = <&spi0>;
        __overlay__ {
            status = "okay";
            // cs-gpios = <&pio 0 10 0>; /* PA10*/
            cs-gpios = <&pio 0 10 0>, <&pio 0 20 0>; /* PA10 PA20 */

            ili9341: ili9341@0 {
                compatible = "ilitek,ili9341";
                reg = <0>;  /* Chip Select 0 */
		#spi-cs-high;
                spi-max-frequency = <40000000>;
                rotate = <90>;
                bgr = <0>;
                fps = <30>;
		width = <240>;
		height = <320>;
                buswidth = <8>;
                reset-gpios = <&pio 0 9 1>; /*RESET=PA9*/
                dc-gpios = <&pio 0 8 0>; /*DC_RS=PA8*/
                led-gpios = <&pio 0 7 0>; /*LED=PA7*/
                debug = <4>;
            };

	    ads7846: ads7846@0 {
                compatible = "ti,ads7846";
                reg = <1>;  /* Chip Select 1 */
		#spi-cs-high;
                spi-max-frequency = <1000000>;
                interrupt-parent = <&pio>;
                /* IRQ PA19 */
                interrupts = <0 19 2>; /* IRQ_TYPE_EDGE_FALLING */
                pendown-gpio = <&pio 0 19 1>; /* ACTIVE_HIGH */
		/* ti,swap-xy = <0x1>; */
		ti,x-min = /bits/ 16 <0>;
                ti,y-min = /bits/ 16 <0>;
                ti,x-max = /bits/ 16 <0x0FFF>;
                ti,y-max = /bits/ 16 <0x0FFF>;
                ti,pressure-min = /bits/ 16 <0>;
                ti,pressure-max = /bits/ 16 <0xFFFF>;
		ti,x-plate-ohms = /bits/ 16 <400>;
            };

        };
    };
};

再執行下面的指令,

------------------
armbian-add-overlay ili9341_lcd.dts
------------------



方便 PCB 佈線,接腳更改如下
--------------
OPi One wiring:
Pin 1  - 3.3V  (or Pin 4 - 5V)
Pin 6  - GND
Pin 7  - PA6  <-->  LCD CS   
Pin 8  - PA13 <-->  RESET
Pin 10 - PA14 <-->  DC
Pin 19 - PC0  <-->  SPI0 SDI<MOSI> & T_DIN
Pin 23 - PC2  <-->  SPI0 SCK       & T_CLK
Pin 3  - PA12 <-->  LED
Pin 21 - PC1  <-->  SPI0 SDO<MISO> & T_DO 
Pin 26 - PA21 <-->  T_CS
Pin 28 - PA18 <-->  T_IRQ
--------------





2024年11月26日 星期二

Docker 吃掉硬碟空間處理

docker container 的 log 會無限成長,可以有好幾個 GB,只能手動刪除。

-------------------
# du -h -d 1
7.6G ./usr
47G ./var

# du /var/ -h -d 1
6.9G /var/cache
509M /var/log
40G /var/lib

# du /var/cache/ -h -d 1
942M /var/cache/debtap
5.6G /var/cache/pacman
387M /var/cache/pkgfile
6.9G /var/cache/

# pacman -Sc
Packages to keep:
  All locally installed packages

Cache directory: /var/cache/pacman/pkg/
:: Do you want to remove all other packages from cache? [Y/n] 
removing old packages from cache...
error: missing package metadata in /var/cache/pacman/pkg/unzip-6.0-20-x86_64.pkg.tar.zst.part

Database directory: /var/lib/pacman/
:: Do you want to remove unused repositories? [Y/n] 
removing unused sync repositories...

# du /var/cache/ -h -d 1
3.2M /var/cache/samba
80K /var/cache/ldconfig
942M /var/cache/debtap
2.1G /var/cache/pacman
387M /var/cache/pkgfile
4.0K /var/cache/private
1.1M /var/cache/fontconfig
3.4G /var/cache/


# du -h -d 1
4.1M ./f61f4a601db2be573c2b6351a04fcf1e79540e3cd8e1de41c6c9ab4a0fa204e0
48K ./2136c92af607bfee2ca204d3c77843dce66d7706f753e944dbe84820cf72c5ee
40K ./dc1f8e5f1fb6be942dad52e52453e2960d3bedf788f1774ddfe4462a03c66dc3
21G ./f3c5128d570fec0021b34ff8650fe9dcc531a2bcc59feb52aa9ff1e3f87b7e39
10M ./a3aefcd51740895bb721982b2dff7bfbcea164290b626a1dfb226b3a85274e50

dc1f8e5f1fb6 ==> nginx-hls-vod-server-web


清除所有 container 的 log
# truncate -s 0 /var/lib/docker/containers/*/*-json.log
-------------------

可以設 option,限制log 的大小。

--------------------------
file: /etc/docker/daemon.json
{
  "log-opts": {
    "max-size": "20m",
    "max-file": "5"
  }
}
--------------------------



網誌存檔