2024年7月29日 星期一

透過 Ollama 本地部署 Llama 3.1 大型語言模型服務

開源模型的好處是讓企業得以根據需求用公司內部資料來建置模型,而不受封閉模型供應商的限制。

Llama 是 Meta 釋出的開源模型,Meta 於 7/23 釋出了 Llama 3.1 其亮點 405B (4,050 億參數) 是 Meta 迄今為止最強大的模型, 趁前兩天颱風假的空檔利用 Ollama + Llama 3.1 來架設一個私有的大型語言模型服務( LLM Model )。

Ollama 是一個開源軟體,使用者可以在自己的硬體上執行大型語言模型服務。選用 Ollama 是因為其架設容易且支援的模型總類很多,官方有提供 Windows, Apple, Linux OS 的安裝程式,可用短短的幾分鐘就可以在自己的個人電腦上架設完成大型語言模型服務。

2024年7月25日 星期四

使用sprkfun的micro:bit底座測試neopixel WS2812b燈控的功能

sprkfun的micro:bit底座的資料:micro:bit Breakout Board Hookup Guide

micro:bit版本:V2

MakeCode測試:

擴展套件:Adafruit Neopixel Driver

積木程式:


修改上圖 Pin腳位,測試結果Pin 0, 1, 2, 5, 8, 9, 11, 12, 13, 14, 15, 16可以使用neopixel。

改採Python Editor:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from microbit import *
import neopixel
from random import randint

# Setup the Neopixel strip on pin0 with a length of 8 pixels
np = neopixel.NeoPixel(pin0, 16)
np.clear()

while True:
    #Iterate over each LED in the strip

    for pixel_id in range(0, len(np)):
        red = randint(0, 255)
        green = randint(0, 255)
        blue = randint(0, 255)

        # Assign the current LED a random red, green and blue value between 0 and 60
        np[pixel_id] = (red, green, blue)

        # Display the current pixel data on the Neopixel strip
        np.show()
    sleep(300)

測試結果Pin 0~16都可以使用neopixel,但Pin 3, 4,6, 7, 10會使5x5 矩陣LED,造成不正常顯示,其主要原因是這幾支腳位做為LED Col使用。




2024年7月22日 星期一

micro:bit控制雙顆16個光環環板控制程式以及王米葉編織的花

 

  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
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
def rainbow2():
    global ShiftCount
    strip.show()
    strip2.show()
    strip.shift(1)
    strip2.shift(1)
    basic.pause(100)
    ShiftCount = (ShiftCount + 1) % (Number2 + 1)
    if ShiftCount == 0:
        strip.show_rainbow(1, 360)
        strip2.show_rainbow(1, 360)
def rainbow3():
    global range3, range2, ShiftCount
    strip.clear()
    strip2.clear()
    range3 = strip.range(0, ShiftCount)
    range2 = strip2.range(0, ShiftCount)
    range3.show_rainbow(1, 360)
    range2.show_rainbow(1, 360)
    range3.show()
    range2.show()
    ShiftCount = (ShiftCount + 1) % (Number2 + 1)
    basic.pause(100)
def monochrome():
    if submode == 0:
        strip.show_color(neopixel.colors(NeoPixelColors.RED))
        strip2.show_color(neopixel.colors(NeoPixelColors.RED))
    elif submode == 1:
        strip.show_color(neopixel.colors(NeoPixelColors.ORANGE))
        strip2.show_color(neopixel.colors(NeoPixelColors.ORANGE))
    elif submode == 2:
        strip.show_color(neopixel.colors(NeoPixelColors.YELLOW))
        strip2.show_color(neopixel.colors(NeoPixelColors.YELLOW))
    elif submode == 3:
        strip.show_color(neopixel.colors(NeoPixelColors.GREEN))
        strip2.show_color(neopixel.colors(NeoPixelColors.GREEN))
    elif submode == 4:
        strip.show_color(neopixel.colors(NeoPixelColors.BLUE))
        strip2.show_color(neopixel.colors(NeoPixelColors.BLUE))
    elif submode == 5:
        strip.show_color(neopixel.colors(NeoPixelColors.INDIGO))
        strip2.show_color(neopixel.colors(NeoPixelColors.INDIGO))
    elif submode == 6:
        strip.show_color(neopixel.colors(NeoPixelColors.VIOLET))
        strip2.show_color(neopixel.colors(NeoPixelColors.VIOLET))
    elif submode == 7:
        strip.show_color(neopixel.colors(NeoPixelColors.PURPLE))
        strip2.show_color(neopixel.colors(NeoPixelColors.PURPLE))
    elif submode == 8:
        strip.show_color(neopixel.colors(NeoPixelColors.WHITE))
        strip2.show_color(neopixel.colors(NeoPixelColors.WHITE))
    elif submode == 9:
        strip.show_color(neopixel.colors(NeoPixelColors.BLACK))
        strip2.show_color(neopixel.colors(NeoPixelColors.BLACK))
    strip.show()

def on_button_pressed_a():
    global mode, strip, strip2
    mode = (mode + 1) % maxMode
    basic.show_string("" + str(mode))
    if mode == 3 and mode <= 4:
        strip = neopixel.create(DigitalPin.P0, Number2, NeoPixelMode.RGB)
        strip2 = neopixel.create(DigitalPin.P1, Number2, NeoPixelMode.RGB)
        strip.show_rainbow(1, 360)
        strip2.show_rainbow(1, 360)
    elif mode >= 5:
        strip.clear()
        strip2.clear()
        strip.show()
        strip2.show()
input.on_button_pressed(Button.A, on_button_pressed_a)

def loudness():
    strip.clear()
    strip2.clear()
    strip.show_bar_graph(Math.map(input.sound_level(), 0, 255, 0, 16), 16)
    strip2.show_bar_graph(Math.map(input.sound_level(), 0, 255, 0, 16), 16)
    strip.show()
    strip2.show()
def rainbow5():
    global range3, range2, ShiftCount
    strip.clear()
    strip2.clear()
    range3 = strip.range(randint(0, Number2 - 1), 1)
    range2 = strip2.range(randint(0, Number2 - 1), 1)
    range3.show_color(randint(0, 65535))
    range2.show_color(randint(0, 65535))
    range3.show()
    range2.show()
    ShiftCount = (ShiftCount + 1) % (Number2 + 1)
    basic.pause(200)
def rainbow():
    strip.rotate(3)
    strip2.rotate(3)
    strip.show()
    strip2.show()
    basic.pause(100)
def rainbow4():
    global range3, range2, ShiftCount
    strip.clear()
    strip2.clear()
    range3 = strip.range(ShiftCount, 1)
    range2 = strip2.range(ShiftCount, 1)
    range3.show_rainbow(1, 360)
    range2.show_rainbow(1, 360)
    range3.show()
    range2.show()
    ShiftCount = (ShiftCount + 1) % (Number2 + 1)
    basic.pause(100)

def on_button_pressed_b():
    global submode
    submode = (submode + 1) % 10
input.on_button_pressed(Button.B, on_button_pressed_b)

def brightness():
    strip.clear()
    strip2.clear()
    strip.show_bar_graph(Math.map(input.light_level(), 0, 255, 0, 16), 16)
    strip2.show_bar_graph(Math.map(input.light_level(), 0, 255, 0, 16), 16)
    strip.show()
    strip2.show()
range2: neopixel.Strip = None
range3: neopixel.Strip = None
strip2: neopixel.Strip = None
strip: neopixel.Strip = None
ShiftCount = 0
Number2 = 0
submode = 0
maxMode = 0
mode = 0
mode = 2
maxMode = 10
submode = 0
Number2 = 16
ShiftCount = 0
strip = neopixel.create(DigitalPin.P0, Number2, NeoPixelMode.RGB)
strip2 = neopixel.create(DigitalPin.P1, Number2, NeoPixelMode.RGB)
basic.show_string("" + str(mode))

def on_forever():
    global submode
    if mode == 0:
        strip.clear()
        strip2.show()
    elif mode == 1:
        monochrome()
    elif mode == 2:
        monochrome()
        basic.pause(500)
        submode = (submode + 1) % 10
    elif mode == 3:
        rainbow()
    elif mode == 4:
        rainbow2()
    elif mode == 5:
        rainbow3()
    elif mode == 6:
        rainbow4()
    elif mode == 7:
        rainbow5()
    elif mode == 8:
        loudness()
    else:
        brightness()
basic.forever(on_forever)

micro:bit 十種模式的燈條控制

這個程式控制一個 NeoPixel 燈條,實現了 10 種不同的顯示模式。以下是每個模式的解釋:

  • 模式 0: 清除顯示

清除燈條上的顏色,將所有燈熄滅。

  • 模式 1: 單色顯示

根據 submode 的值顯示不同的顏色。顏色從紅色開始,依次是橙色、黃色、綠色、藍色、靛藍色、紫色、紫羅蘭色、白色和黑色。

  • 模式 2: 單色顯示(自動變換顏色)

與模式 1 相同,但每 500 毫秒 submode 自動增加,改變顏色。

  • 模式 3: 彩虹旋轉

燈條上的顏色進行旋轉。

  • 模式 4: 移動彩虹

彩虹顏色向左移動,並在特定條件下重置顯示。

  • 模式 5: 部分顯示彩虹

在燈條的前部分顯示彩虹,範圍根據 ShiftCount 增加。

  • 模式 6: 單個 LED 顯示彩虹

每次僅在一個 LED 上顯示彩虹顏色,位置根據 ShiftCount 變化。

  • 模式 7: 隨機顏色顯示

隨機選擇一個 LED 顯示隨機顏色。

  • 模式 8: 聲音圖表

根據環境聲音的強度顯示條形圖。

  • 模式 9: 亮度圖表

根據環境光亮度顯示條形圖。


按鈕控制:

  • 按鈕 A:

切換模式,每次按下時 mode 增加 1,顯示當前模式。

  • 按鈕 B:

切換 submode,每次按下時 submode 增加 1,影響單色顯示的顏色。


主循環:

根據當前的 mode 執行對應的顯示模式。


積木程式:


JavaScript程式:

  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
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
function rainbow2 () {
    strip.show()
    strip.shift(1)
    basic.pause(100)
    ShiftCount = (ShiftCount + 1) % (Number2 + 1)
    if (ShiftCount == 0) {
        strip.showRainbow(1, 360)
    }
}
function rainbow3 () {
    strip.clear()
    range = strip.range(0, ShiftCount)
    range.showRainbow(1, 360)
    range.show()
    ShiftCount = (ShiftCount + 1) % (Number2 + 1)
    basic.pause(100)
}
function monochrome () {
    if (submode == 0) {
        strip.showColor(neopixel.colors(NeoPixelColors.Red))
    } else if (submode == 1) {
        strip.showColor(neopixel.colors(NeoPixelColors.Orange))
    } else if (submode == 2) {
        strip.showColor(neopixel.colors(NeoPixelColors.Yellow))
    } else if (submode == 3) {
        strip.showColor(neopixel.colors(NeoPixelColors.Green))
    } else if (submode == 4) {
        strip.showColor(neopixel.colors(NeoPixelColors.Blue))
    } else if (submode == 5) {
        strip.showColor(neopixel.colors(NeoPixelColors.Indigo))
    } else if (submode == 6) {
        strip.showColor(neopixel.colors(NeoPixelColors.Violet))
    } else if (submode == 7) {
        strip.showColor(neopixel.colors(NeoPixelColors.Purple))
    } else if (submode == 8) {
        strip.showColor(neopixel.colors(NeoPixelColors.White))
    } else if (submode == 9) {
        strip.showColor(neopixel.colors(NeoPixelColors.Black))
    }
    strip.show()
}
input.onButtonPressed(Button.A, function () {
    mode = (mode + 1) % maxMode
    basic.showString("" + (mode))
    if (mode == 3 && mode <= 4) {
        strip = neopixel.create(DigitalPin.P0, Number2, NeoPixelMode.RGB)
        strip.showRainbow(1, 360)
    } else if (mode >= 5) {
        strip.clear()
        strip.show()
    }
})
function loudness () {
    strip.clear()
    strip.showBarGraph(Math.map(input.soundLevel(), 0, 255, 0, 16), 16)
    strip.show()
}
function rainbow5 () {
    strip.clear()
    range = strip.range(randint(0, Number2 - 1), 1)
    range.showColor(randint(0, 65535))
    range.show()
    ShiftCount = (ShiftCount + 1) % (Number2 + 1)
    basic.pause(200)
}
function rainbow () {
    strip.rotate(3)
    strip.show()
    basic.pause(100)
}
function rainbow4 () {
    strip.clear()
    range = strip.range(ShiftCount, 1)
    range.showRainbow(1, 360)
    range.show()
    ShiftCount = (ShiftCount + 1) % (Number2 + 1)
    basic.pause(100)
}
input.onButtonPressed(Button.B, function () {
    submode = (submode + 1) % 10
})
function brightness () {
    strip.clear()
    strip.showBarGraph(Math.map(input.lightLevel(), 0, 255, 0, 16), 16)
    strip.show()
}
let range: neopixel.Strip = null
let strip: neopixel.Strip = null
let ShiftCount = 0
let Number2 = 0
let submode = 0
let maxMode = 0
let mode = 0
mode = 0
maxMode = 10
submode = 0
Number2 = 16
ShiftCount = 0
strip = neopixel.create(DigitalPin.P0, Number2, NeoPixelMode.RGB)
basic.showString("" + (mode))
basic.forever(function () {
    if (mode == 0) {
        strip.clear()
        strip.show()
    } else if (mode == 1) {
        monochrome()
    } else if (mode == 2) {
        monochrome()
        basic.pause(500)
        submode = (submode + 1) % 10
    } else if (mode == 3) {
        rainbow()
    } else if (mode == 4) {
        rainbow2()
    } else if (mode == 5) {
        rainbow3()
    } else if (mode == 6) {
        rainbow4()
    } else if (mode == 7) {
        rainbow5()
    } else if (mode == 8) {
        loudness()
    } else {
        brightness()
    }
})

Python程式:

  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
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
def rainbow2():
    global ShiftCount
    strip.show()
    strip.shift(1)
    basic.pause(100)
    ShiftCount = (ShiftCount + 1) % (Number2 + 1)
    if ShiftCount == 0:
        strip.show_rainbow(1, 360)
def rainbow3():
    global range2, ShiftCount
    strip.clear()
    range2 = strip.range(0, ShiftCount)
    range2.show_rainbow(1, 360)
    range2.show()
    ShiftCount = (ShiftCount + 1) % (Number2 + 1)
    basic.pause(100)
def monochrome():
    if submode == 0:
        strip.show_color(neopixel.colors(NeoPixelColors.RED))
    elif submode == 1:
        strip.show_color(neopixel.colors(NeoPixelColors.ORANGE))
    elif submode == 2:
        strip.show_color(neopixel.colors(NeoPixelColors.YELLOW))
    elif submode == 3:
        strip.show_color(neopixel.colors(NeoPixelColors.GREEN))
    elif submode == 4:
        strip.show_color(neopixel.colors(NeoPixelColors.BLUE))
    elif submode == 5:
        strip.show_color(neopixel.colors(NeoPixelColors.INDIGO))
    elif submode == 6:
        strip.show_color(neopixel.colors(NeoPixelColors.VIOLET))
    elif submode == 7:
        strip.show_color(neopixel.colors(NeoPixelColors.PURPLE))
    elif submode == 8:
        strip.show_color(neopixel.colors(NeoPixelColors.WHITE))
    elif submode == 9:
        strip.show_color(neopixel.colors(NeoPixelColors.BLACK))
    strip.show()

def on_button_pressed_a():
    global mode, strip
    mode = (mode + 1) % maxMode
    basic.show_string("" + str((mode)))
    if mode == 3 and mode <= 4:
        strip = neopixel.create(DigitalPin.P0, Number2, NeoPixelMode.RGB)
        strip.show_rainbow(1, 360)
    elif mode >= 5:
        strip.clear()
        strip.show()
input.on_button_pressed(Button.A, on_button_pressed_a)

def loudness():
    strip.clear()
    strip.show_bar_graph(Math.map(input.sound_level(), 0, 255, 0, 16), 16)
    strip.show()
def rainbow5():
    global range2, ShiftCount
    strip.clear()
    range2 = strip.range(randint(0, Number2 - 1), 1)
    range2.show_color(randint(0, 65535))
    range2.show()
    ShiftCount = (ShiftCount + 1) % (Number2 + 1)
    basic.pause(200)
def rainbow():
    strip.rotate(3)
    strip.show()
    basic.pause(100)
def rainbow4():
    global range2, ShiftCount
    strip.clear()
    range2 = strip.range(ShiftCount, 1)
    range2.show_rainbow(1, 360)
    range2.show()
    ShiftCount = (ShiftCount + 1) % (Number2 + 1)
    basic.pause(100)

def on_button_pressed_b():
    global submode
    submode = (submode + 1) % 10
input.on_button_pressed(Button.B, on_button_pressed_b)

def brightness():
    strip.clear()
    strip.show_bar_graph(Math.map(input.light_level(), 0, 255, 0, 16), 16)
    strip.show()
range2: neopixel.Strip = None
strip: neopixel.Strip = None
ShiftCount = 0
Number2 = 0
submode = 0
maxMode = 0
mode = 0
mode = 0
maxMode = 10
submode = 0
Number2 = 16
ShiftCount = 0
strip = neopixel.create(DigitalPin.P0, Number2, NeoPixelMode.RGB)
basic.show_string("" + str((mode)))

def on_forever():
    global submode
    if mode == 0:
        strip.clear()
        strip.show()
    elif mode == 1:
        monochrome()
    elif mode == 2:
        monochrome()
        basic.pause(500)
        submode = (submode + 1) % 10
    elif mode == 3:
        rainbow()
    elif mode == 4:
        rainbow2()
    elif mode == 5:
        rainbow3()
    elif mode == 6:
        rainbow4()
    elif mode == 7:
        rainbow5()
    elif mode == 8:
        loudness()
    else:
        brightness()
basic.forever(on_forever)

2024年7月11日 星期四

用Python實作HEIC 轉JPG 轉換器

套件:https://pypi.org/project/pillow-heif/

安裝套件:

pip install pillow-heif


程式碼是用ChatGPT產生,提示語如下:

Python程式,針對一個目錄,底下有子目錄也有HEIC檔案和其他檔案,請把HEIC 轉JPG 轉換

但產生出來的程式不能用,後改用第二提示語:

請用pillow_heif

以下程式經測試是可以的。

程式碼:

 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
import os
from PIL import Image
import pillow_heif

def convert_heic_to_jpg(input_path, output_path):
    heif_file = pillow_heif.open_heif(input_path)
    image = Image.frombytes(
        heif_file.mode,
        heif_file.size,
        heif_file.data,
        "raw",
        heif_file.mode,
        heif_file.stride,
    )
    image.save(output_path, "JPEG")

def process_directory(directory):
    for root, _, files in os.walk(directory):
        for file in files:
            if file.lower().endswith('.heic'):
                input_file = os.path.join(root, file)
                output_file = os.path.splitext(input_file)[0] + '.jpg'
                try:
                    convert_heic_to_jpg(input_file, output_file)
                    print(f"Converted: {input_file} -> {output_file}")
                except Exception as e:
                    print(f"Failed to convert {input_file}: {e}")

if __name__ == "__main__":
    directory = input("Enter the directory path: ")
    process_directory(directory)

執行結果:
Enter the directory path: Apple
Converted: Apple\sample1.heic -> Apple\sample1.jpg
Converted: Apple\APPLE01\sample1.heic -> Apple\APPLE01\sample1.jpg

查看目錄: