我們使用Pico、WIZnet W5100S 和 PicoBricks 開發(fā)板開發(fā)了MQTT RGB燈,通過ChatGPT 4.0生成和優(yōu)化代碼。
項(xiàng)目所需組件
硬件組件
PicoBricks 擴(kuò)展板 x 1
WIZnet W5100S-EVB-Pico x 1
WIZnet W5500-EVB-Pico
WIZnet以太網(wǎng)HAT x 1
樹莓派Pico x 1
軟件應(yīng)用和在線服務(wù)
MicroPython
項(xiàng)目背景
有很多關(guān)于如何用ChatGPT編碼的介紹,我還嘗試過用它來創(chuàng)建簡單的例子或生成一些邏輯代碼。但是有沒有可能只用ChatGPT就可以開發(fā)一個項(xiàng)目呢?
ChatGPT4最近開放了代碼解釋器功能,讓我們嘗試使用這個新功能。我進(jìn)行了即時書寫,沒有使用任何命令或擴(kuò)展應(yīng)用程序。結(jié)果如何?獲得了巨大成功。
除了對一些非常簡單的代碼進(jìn)行修改之外,大部分代碼都是借助 ChatGPT 完成的。
Pico 遙控?zé)?/strong>

這是一份總結(jié)。請牢記這一點(diǎn),并查看以下文本,看看它是如何被運(yùn)用的。
這項(xiàng)工作是通過編寫并驗(yàn)證基礎(chǔ)庫和示例代碼,然后將必要的部分進(jìn)行整合來完成的。
1.如果你正在使用特定的模塊/庫,請明確指出。
2.執(zhí)行代碼后,如果出現(xiàn)錯誤,請將錯誤信息以及疑似出錯的代碼部分告知GPT,并請求其進(jìn)行修正。即使你應(yīng)用了修改后的代碼后錯誤仍然存在,也要堅(jiān)持不懈地尋求解答。之后,會為你提出一個新的方向。
3.你必須清晰明確地寫出你期望實(shí)現(xiàn)的功能、觸發(fā)操作的條件、執(zhí)行時機(jī)等信息,這樣才能更接近你想要的執(zhí)行效果。
4.在創(chuàng)建新類時,如果你能提供一個功能與結(jié)構(gòu)相似的類作為示例,那么將會為你創(chuàng)建一個類似的類。
5.當(dāng)組合使用各種類時,分別請求每個單獨(dú)功能的示例并將它們組合起來,往往比直接輸入類信息并要求得到一個完整功能的效果更好。
6.如果你想為達(dá)到同一結(jié)果而采用不同的邏輯,請?zhí)峁┮粋€邏輯示例,并請求將其應(yīng)用。
與其絞盡腦汁地過度思考,不如就把它讀作:“啊,他們這樣用提示來解決這樣的問題?”
如果你覺得:“這部分不錯!”那就把它記下來,并試著在自己的項(xiàng)目中運(yùn)用。
設(shè)置代碼解釋器



功能定義
為了創(chuàng)建一個恰當(dāng)?shù)奶崾?,需清晰勾勒出功能特性?/span>
這部分對于開發(fā)以及編寫提示都至關(guān)重要。當(dāng)你對功能特性有清晰的理解時,提出的問題就會更加精確,也就能明確劃分并著手處理哪些部分。
由于很多時候需要分部分開展工作然后再進(jìn)行整合,因此理解整體結(jié)構(gòu)就顯得更為關(guān)鍵。

- 控制設(shè)備
1.控制設(shè)備將使用MQTT協(xié)議向RGB燈傳輸JSON格式的數(shù)據(jù)。這些數(shù)據(jù)將包含調(diào)整燈具RGB顏色和亮度的信息。
2.控制設(shè)備將配備一個按鈕,用于控制RGB燈的顏色。
當(dāng)按鈕按下時間少于0.5秒時,將選擇RGB顏色。
3.控制設(shè)備將使用可變電阻來調(diào)節(jié)燈具的亮度。
電阻值將被映射到1~100的亮度級別。
4.在OLED顯示屏上顯示RGB燈的顏色和亮度信息。
- RGB燈設(shè)備
1.RGB燈設(shè)備將通過MQTT協(xié)議從控制設(shè)備接收J(rèn)SON格式的數(shù)據(jù)。
這些數(shù)據(jù)將包含調(diào)整燈具RGB顏色和亮度的信息。
2.RGB燈設(shè)備將根據(jù)接收到的JSON數(shù)據(jù)調(diào)整其RGB值和亮度。
3.在OLED顯示屏上顯示RGB燈的顏色和亮度信息。
- 網(wǎng)絡(luò):MQTT
1.初始化
如果你正在使用特定的模塊/庫,請明確指出。
請求網(wǎng)絡(luò)和MQTT的基礎(chǔ)示例。網(wǎng)絡(luò)和MQTT的相關(guān)信息通過define進(jìn)行聲明。
MQTT默認(rèn)設(shè)置
提示1:當(dāng)然,這里有一個使用MicroPython和WIZNET5K驅(qū)動器進(jìn)行MQTT通信的基礎(chǔ)函數(shù)示例。在這個函數(shù)中,設(shè)備被設(shè)置為靜態(tài)IP地址192.168.11.101,網(wǎng)關(guān)為192.168.11.1,子網(wǎng)掩碼為255.255.255.0,DNS服務(wù)器為8.8.8.8。MQTT代理位于IP地址192.168.11.100,主題為ctrl_state。未使用用戶名和密碼。保持連接時間為60秒。SPI配置:波特率:2,000,000,MOSI:19,MISO:16,SCK:18,CS:17,RESET:20。添加默認(rèn)訂閱和發(fā)布功能。
提示2:請?jiān)谀憔帉懙拇a中定義與用戶名、IP、網(wǎng)關(guān)、子網(wǎng)掩碼、DNS和主題相關(guān)的內(nèi)容。
ChatGPT一次性完成了這個任務(wù)。我使用Mosquitto測試了訂閱和發(fā)布功能。

由于MQTT經(jīng)常在其他項(xiàng)目中使用,我們將其創(chuàng)建為一個庫。
提示1:我打算將下面的代碼封裝成一個庫,命名為WIZnetMQTT.py。請將其修改為類格式,以便于作為API使用。
提示2:在你編寫的類中,我們打算將初始化函數(shù)中的網(wǎng)絡(luò)初始化部分放到另一個函數(shù)中使用。請將其拆分,不包括網(wǎng)絡(luò)初始化部分,僅保留MQTT初始化部分。
在收到庫的更新代碼以及主程序的測試示例后,我再次檢查了其運(yùn)行情況,它工作得很好。
2.訂閱回調(diào)
為了更靈活地使用MQTT庫,我們允許注冊回調(diào)函數(shù)來處理訂閱的消息。
如果沒有提供回調(diào)函數(shù),則設(shè)計為直接返回主題和消息。
提示1:請修改def sub_cb(self, topic, msg)函數(shù),使其更具通用性。如果提供了回調(diào)函數(shù),則使用該回調(diào)函數(shù);如果沒有提供,則返回主題和消息。
classWIZnetMQTT: def__init__(self, username, broker_ip, topic, keep_alive, callback=None):…self.callback = callback…defsub_cb(self, topic, msg): ifself.callback: returnself.callback(topic, msg) else: returntopic, msg
出于測試目的,我將創(chuàng)建一個訂閱回調(diào)函數(shù)。
由于我們計劃接收J(rèn)SON格式的數(shù)據(jù),我將添加一個解析函數(shù)。
提示2:另外,你能提供一個使用回調(diào)函數(shù)的示例嗎?接收到的消息是JSON格式的,比如{"color":"R", "brightness": 0}。顏色值可以是'R'、'G'或'B',亮度值的范圍是從0.01到1。在WIZnetMQTT類中,請包含一個能夠解析這種JSON消息的回調(diào)函數(shù)。
defexample_callback(topic, msg): try: data = json.loads(msg) color = data.get("color",None) brightness = data.get("brightness",None) … print(f"Received color:{color}, brightness:{brightness}") exceptjson.JSONDecodeError: print("Error decoding JSON!")
如果直接這樣運(yùn)行,將會出現(xiàn)錯誤。
執(zhí)行后,如果發(fā)生錯誤,請將錯誤信息以及疑似存在錯誤的代碼告知GPT,并請求修正。
即使你應(yīng)用了修改后的代碼但錯誤仍然存在,也要堅(jiān)持不懈地尋求答案。隨后,會提出一個新的解決方向。
提示:我在下面的example_callback函數(shù)中遇到了“AttributeError: 'module' object has no attribute 'JSONDecodeError'”錯誤??赡苁悄睦锍隽藛栴}?
…To handlethis, you cancatcha more general exception, like Exception, to capture any kind of error that arises during the JSON decoding process:…except Exception: # Catch any exception,notjust JSONDecodeError…
你需要檢查其是否正常運(yùn)行。
模塊
對于模塊而言,我擁有一個之前已經(jīng)創(chuàng)建好的庫。
對于現(xiàn)有的類,我直接使用它們或者在其基礎(chǔ)上進(jìn)行擴(kuò)展;對于不存在的類,我會創(chuàng)建它們以匹配相似的格式。
(這個庫的大部分內(nèi)容也是使用ChatGPT創(chuàng)建的)
1.電位器
電位器的邏輯相對簡單。我將把Pico bricks提供的電位器示例,以及從picobricks_utils.py的類(picobricks_hum_temp)中引用的結(jié)構(gòu)添加到提示中。
你必須清楚地寫出你想要實(shí)現(xiàn)的功能、觸發(fā)操作的條件、時間安排等,以便更接近期望的動作。
在創(chuàng)建一個新類時,如果你能提供一個功能與結(jié)構(gòu)相似的類作為示例,那么將為你創(chuàng)建一個類似的類。
提示:這是電位器的基本功能代碼。“pot=ADC(Pin(26)) pot_val=((pot.read_u16()/65535.0)*20) +1”。請按照下面類的格式來編寫。class picobricks_hum_temp: ...
importmachinefrom machineimportADC, PinclassPotentiometer:...

修改雖然成功了,但輸出值是一個介于1到21之間的小數(shù)
請將其更改為一個函數(shù),使其能夠?qū)⒃撝涤成涞?到100之間的整數(shù)(默認(rèn)范圍是0~100)。
如果你想修改輸出的某一部分,無需創(chuàng)建新的提示,只需從已寫好的輸出中請求修正你希望更改的部分即可。
提示:這個函數(shù)的結(jié)果是最小值和最大值分別為1.0和21.0之間的小數(shù)。請?zhí)砑右粋€函數(shù),根據(jù)輸入的最小值和最大值進(jìn)行映射。默認(rèn)值應(yīng)設(shè)為1和100,并且應(yīng)能夠通過init方法中的參數(shù)進(jìn)行配置。
def__init__(self, pot_pin=26, read_timer=2, min_val=0, max_val=100): self.min_val = min_val self.max_val = max_val def_map_value(self, value): # Map the value from [1, 21] range to [self.min_val, self.max_val] range return((value -1) / (21-1)) * (self.max_val -self.min_val) +self.min_val

2.按鈕
已經(jīng)為按鈕創(chuàng)建了一個類。
然而,由于目前只有一個切換按鈕模式,我將添加一個按壓按鈕模式以及一個按壓回調(diào)函數(shù)。
此外,我還將添加模式選擇功能,以便根據(jù)所選模式進(jìn)行操作。
(由于默認(rèn)模式是“開/關(guān)”,因此與之前編寫的示例不會產(chǎn)生沖突)。
提示1:以下是與按鈕相關(guān)的類。請?jiān)诖颂幪砑右粋€新函數(shù),用于識別和控制按壓按鈕。同時,確保將按壓按鈕作為回調(diào)函數(shù)參數(shù)接收,并相應(yīng)地調(diào)用它。class picobricks_button:~Omitted~
提示2:請將set_toggle_button_state函數(shù)拆分為兩種模式:“開/關(guān)”(on/off)和“按壓”(push)。當(dāng)處于“按壓”模式時,執(zhí)行按壓回調(diào)函數(shù)。
classpicobricks_button: def__init__(self, btn_pin=10, detect_time_ms=500, mode="on/off"): self.push_callback =None self.mode = mode

它工作得很好。讓我們?yōu)檫@個功能創(chuàng)建一個回調(diào)函數(shù)。
基于按壓動作,讓我們將狀態(tài)從紅色(R)變?yōu)榫G色(G),再變?yōu)樗{(lán)色(B)...并創(chuàng)建一個函數(shù)來讀取已設(shè)置的RGB值。
提示1:創(chuàng)建一個函數(shù)以注冊到按壓回調(diào)中。實(shí)現(xiàn)一個邏輯,即當(dāng)按下按壓按鈕時,RGB狀態(tài)按照“紅(R)”、“綠(G)”、“藍(lán)(B)”的順序循環(huán)變化。
提示2:使用這個函數(shù)時,初始值被設(shè)置為“藍(lán)(B)”,請修改為從“紅(R)”開始。此外,添加一個“獲取(get)”函數(shù),以便能夠讀取當(dāng)前設(shè)置的RGB值。
classRGBController: def__init__(self): defcycle_rgb_state(self):defmain(): btn =picobricks_button(mode="push") btn.set_button_callback(push_callback=rgb_controller.cycle_rgb_state) whileTrue: btn.set_toggle_button_state() time.sleep_ms(50)
我原本請求的是一個函數(shù),但收到的是一個類。不過,由于RGB循環(huán)似乎會以多種形式被使用,因此我會將其以類的格式直接添加到picobricks_utils.py文件中。

3.斜坡控制
在組合使用各種類時,相較于直接輸入類信息并要求一個完整的功能,為每個單獨(dú)的功能請求示例并將它們組合起來,往往能獲得更好的效果。
基于上述內(nèi)容,我們將兩個功能(按鈕控制和斜坡控制)組合起來。
同時,我會在過程中修改錯誤信息。
提示1:我需要按鈕按壓和電位器的示例。我需要在主程序中使用的函數(shù)。創(chuàng)建一個函數(shù),每當(dāng)按鈕被按下或電位器值發(fā)生變化時,就打印當(dāng)前的RGB值和電位器值/100的結(jié)果。~示例按鈕/電位器~
提示2:當(dāng)我進(jìn)行這些修改時,變化并沒有實(shí)時更新。可能是什么問題?
提示3:每1秒讀取一次值,并在按鈕和電位器值與前一次不同時打印變化的值。
提示4:存在一個漏洞,即在沒有任何按鈕操作的情況下,當(dāng)電位器值變化時,RGB值會自動改變。請修復(fù)這個問題。
并且使用[time.sleep(1)]來實(shí)現(xiàn)時間延遲。但這并不是最好的方法。
如果你想為相同的結(jié)果應(yīng)用不同的邏輯,請?zhí)峁┮粋€邏輯示例并請求其應(yīng)用。
提示5:設(shè)置定時器,每1秒讀取一次值。使用'get_time'格式而不是'sleep'。current_pot_value = pot_value_scaled() 如果 current_pot_value != prev_pot_value:打印 f"亮度值已更改為: {current_pot_value:.2f}" prev_pot_value = current_pot_value
提示6:將定時器減少到500毫秒。
4. OLED
我已經(jīng)為OLED創(chuàng)建了一個類,現(xiàn)在我將添加一個新函數(shù),該函數(shù)可以在每一行上顯示不同的內(nèi)容。
由于有多個打印函數(shù),函數(shù)名變得不太易讀。我請求進(jìn)行修改。
提示1:請?jiān)谙旅娴念愔刑砑右粋€名為'oled'的函數(shù),該函數(shù)允許在5行的每一行中輸入不同的內(nèi)容。
提示2:如果某一行沒有輸入內(nèi)容,請確保不調(diào)用self.oled.text(line5, 5, 48)(或類似針對該行的文本顯示調(diào)用)。
提示3:請重命名該函數(shù)
使用在按鈕和電位器中創(chuàng)建的變量,在OLED上顯示當(dāng)前的顏色和亮度值。
由于之前有提示編寫歷史,因此無需輸入額外的變量信息。
提示1:參考下面的函數(shù),請創(chuàng)建一個函數(shù),該函數(shù)在OLED的第一行上打印'Color: {rgb}',在第二行上打印'Brightness: {current_pot_value}%',使用提供的cur_rgb和current_pot_value值。
提示2:當(dāng)值發(fā)生變化時,我希望在更改“亮度”時同時更新“顏色”顯示,在更改“顏色”時也同時更新“亮度”顯示。我希望兩者能同時顯示,并且只更新發(fā)生變化的值。
我們還將使用生成的值創(chuàng)建一個JSON編碼函數(shù)。
5.燈具控制
創(chuàng)建一個燈具控制設(shè)備
首先,我們將使用虛擬數(shù)據(jù)來生成JSON消息。
利用之前創(chuàng)建的類和函數(shù),根據(jù)JSON消息在OLED上顯示數(shù)據(jù),并控制RGB LED燈。
提示1:這是一個用于解析JSON消息的函數(shù)。當(dāng)“顏色(color)”和“亮度(brightness)”與它們之前的值不同時,創(chuàng)建一個函數(shù)來控制Neopixel燈帶。請參考Neopixel類。
我已經(jīng)進(jìn)行了測試,效果良好。
現(xiàn)在,各個設(shè)備的單獨(dú)功能已經(jīng)完成,讓我們來完善MQTT控制部分。
我將輸入兩個已完成的代碼,并請求將它們合并。
如前所述,與其一開始就要求完整的代碼,不如為每個功能編寫代碼,然后再請求合并,這樣更有效率。這種方法可以確保詳細(xì)功能得到良好實(shí)現(xiàn),并減少嘗試次數(shù)。
我們還將更改函數(shù)名以匹配其功能。
運(yùn)行代碼后,如果出現(xiàn)錯誤,只需請求修改即可。
提示1:將兩個代碼合并。
提示2:在調(diào)用'update_oled_display'函數(shù)時,也使用與'update_oled_display'相同的參數(shù)調(diào)用'generate_json_message'函數(shù)。此外,使用'generate_json_message'返回的消息來執(zhí)行'publish()'函數(shù)。
提示3:修改'update_oled_display'的函數(shù)名,以反映其更新后的功能。
提示4:NameError: name 'mqtt' isn't defined(名稱錯誤:未定義名稱'mqtt')
對于控制設(shè)備,我們將功能分類為MQTT發(fā)布、按鈕、電位器和OLED。對于燈具設(shè)備,我們將功能分類為MQTT訂閱、OLED和受控的RGB LED。
由于這是一個簡單的任務(wù),我直接編寫了代碼。
我將與你分享我在項(xiàng)目開發(fā)過程中使用的編寫提示的過程。
我所有工作的歷史記錄,請參考這里的chatgpt日志。其中記錄了許多嘗試和失敗。
項(xiàng)目現(xiàn)已完成。這是一個簡單的項(xiàng)目,不是嗎?
盡管這是一個小項(xiàng)目,但我們完全使用chatGPT進(jìn)行了開發(fā)。
就像編碼一樣,練習(xí)得越多,水平就越高,使用提示似乎也是如此。
雖然體驗(yàn)大型項(xiàng)目的部分開發(fā)過程至關(guān)重要,但完成小型項(xiàng)目的從始至終也同樣重要。
我經(jīng)常使用chatGPT,但這是我第一次完全使用提示從開始到結(jié)束進(jìn)行開發(fā),我感覺自己比以前更得心應(yīng)手了。
雖然這是我第一次嘗試,還有些生疏,但我會繼續(xù)更多地使用它。如果將來有更好的項(xiàng)目,我會帶著另一個項(xiàng)目回來。
代碼
https://github.com/wiznetmaker/RP2040-PicoBricks-HAT-Micropython/tree/main/example/AI_Lamp
原文地址:
https://www.hackster.io/wizscarlet5986/mqtt-project-with-pico-and-ethernethat-using-chatgpt-prompts-0c44eb
-
智能家居
+關(guān)注
關(guān)注
1943文章
9995瀏覽量
197435 -
樹莓派
+關(guān)注
關(guān)注
122文章
2078瀏覽量
110474 -
MQTT
+關(guān)注
關(guān)注
5文章
733瀏覽量
25087 -
ChatGPT
+關(guān)注
關(guān)注
31文章
1598瀏覽量
10269
發(fā)布評論請先 登錄
《電子發(fā)燒友電子設(shè)計周報》聚焦硬科技領(lǐng)域核心價值 第14期:2025.06.2--2025.06.6
《電子發(fā)燒友電子設(shè)計周報》聚焦硬科技領(lǐng)域核心價值 第16期:2025.06.16--2025.06.20
樹莓派與Z-wave模塊制作一個智能家居的網(wǎng)關(guān)
【NanoPi2申請】智能家居主控中心
【NanoPi2申請】智能家居控制系統(tǒng)
【品勝云路由申請】智能家居
【SNIOT506申請】智能家居控制框架
【orangepi zero申請】智能家居中繼器
【下載】《Linux+樹莓派玩轉(zhuǎn)智能家居》——親手進(jìn)行樹莓派應(yīng)用制作
如何利用樹莓派讓家庭nas和智能家居中控系統(tǒng)進(jìn)行組合呢
樹莓派 Zero 2 W 是開啟智能家居生活的理想之選!
樹莓派與EthernetHat:用ChatGPT實(shí)現(xiàn)的MQTT智能家居項(xiàng)目!
評論