原文:
Control Devices (GPIOs and more) - Blynk Documentation
虛擬引腳 控制設備(GPIO 等)
Blynk 可以直接控制硬件上的數字和模擬 I/O 引腳(GPIO)。您甚至不需要為它編寫代碼。但是當它不夠用時,您可以使用 Virtual Pins。
我們設計了虛擬引腳來在您的硬件和 Blynk 之間交換任何數據。你連接到硬件的任何東西都可以與 Blynk 交談。使用 Virtual Pins,您可以從應用程序發送一些內容,在微控制器上進行處理,然後將其發送回智能手機。您可以觸發函數、讀取 I2C 設備、轉換值、控制伺服和直流電機等。
虛擬引腳可用於與外部庫(伺服、LCD 等)交互並實現自定義功能。
硬件可以像這樣通過 Virtual Pin 向 Widget 發送數據:
Blynk.virtualWrite(pin, "abc");Blynk.virtualWrite(pin, 123); Blynk.virtualWrite(pin, 12.34);Blynk.virtualWrite(pin, "hello", 123, 12.34);
為什麼要使用虛擬引腳?
虛擬引腳與硬件無關。這意味著將來將您的代碼從一個硬件平台移植到另一個硬件平台要容易得多(例如,當您意識到 NodeMCU 比您開始使用的 Arduino Uno + ESP-01 好得多時)。
使用虛擬引腳時,您可以更好地控制小部件的功能。例如,如果您希望單個應用程序按鈕同時打開或關閉多個繼電器,那麼使用虛擬引腳很簡單,但使用數字引腳幾乎不可能。
虛擬引腳比操縱數字引腳更可預測(如果你願意,可以穩定)。
虛擬引腳如何與硬件上的 GPIO引腳相關聯?
虛擬引腳實際上只是一種(通過 Blynk 服務器)將消息從應用程序發送到在您的板上運行的代碼的方式。
虛擬引腳與硬件上的任何物理 GPIO 引腳之間沒有關聯。如果您希望 Virtual Pin 改變您的一個物理 pin 的狀態,那麼您必須編寫代碼來實現這一點。
使用虛擬引腳的基本原則
我們將使用電源開關的示例,設置為整數數據類型,連接到虛擬引腳Virtual Pin 0 (V0)。在 Blynk.Console 中,我們將值設置為 0 和 1,因此小部件在關閉時發送 0,在打開時發送 1 - 像這樣:
BLYNK_WRITE(vPin) 函數
在你的 C++ 草圖中,你可以添加一個特殊的函數,讓BLYNK服務器告訴你.只要你的設備的虛擬引腳的值已經改變,它就會自動觸發。
當按下應用程序中的小部件按鈕時,通常會發生這種變化。
這個特殊的函數被稱為 BLYNK_WRITE
。可以將其視為 Blynk.Cloud 告訴您的硬件“有一個新值寫入您的虛擬引腳”。
因此,對於 Virtual Pin 0,您的草圖需要添加這些代碼……
BLYNK_WRITE(V0){// any code you place here will execute when the virtual pin value changes// 當虛擬引腳值更改時,自動觸發。您放置在此處的任何代碼都將執行}
如果您希望無論按鈕小部件是打開還是關閉都執行相同的代碼,那沒關係,但這在現實生活中並沒有多大用處,
因此我們需要找出虛擬引腳的新值是什麼。
不要忘記,如果按鈕小部件off 這將是0,而他的1是on.
從虛擬引腳獲取值
服務器將當前的 Virtual Pin value作為參數發送到硬件,這可以從BLYNK_WRITE(vPin)函數內部通過這樣的一段代碼獲得......
int virtual_pin_value = param.asInt();
這告訴代碼從虛擬引腳獲取 virtual_pin_value.並將其value 參數存儲在名為param的本地Int整數變量中。
然後,如果按鈕小部件現在打開,與現在關閉時相比,我們可以使用此值執行不同的操作。
以下是為何使用param.asInt的說明
一些數據流以文本或雙/浮點數發送它們的值(整數是整數,雙點變量是小數點右側的數字)。
為了允許您使用這些值,Blynk 庫還允許以下內容:
param.asStrng()param.asFloat()
但是,由於我們只處理零和一,它們是整數,我們將使用該方法。param.asInt
如何控制我板上的物理 GPIO 引腳?
如果您熟悉 C++/Arduino 編程,您可能已經了解pinMode和digitalWrite命令。這些是我們用來從BLYNK_WRITE(vPin)函數中控制設備物理引腳的東西。
對於那些不熟悉這些命令的人,我將在此處給出一個簡短的總結 - 但可以通過搜索互聯網來了解更多信息。
pinMode 命令告訴您的電路板將如何使用特定的引腳。三個最常用的命令是:
pinMode(pin,OUTPUT);
pinMode(pin, INPUT);
pinMode(pin, INPUT_PULLUP);
由於我們將在此示例中控制諸如繼電器或 LED 之類的東西,因此我們希望引腳為 OUTPUTS——我們將向繼電器/LED 輸出高電平或低電平信號。
當您的設備啟動時,您只需要發出一次 pinMode 命令,因此此命令會進入您的
void setup()
這個digitalWrite(pin, value) 命令將指定的引腳設置為低(零伏)或高(3.3v 或 5v,具體取決於您的電路板類型)。這就是您為繼電器、LED 等供電的方式。
Bringing it all together…把這一切放在一起……
此示例代碼假設我們要控制板上的數字引腳 2……
void setup(){pinMode(2, OUTPUT); // Initialise digital pin 2 as an output pin// 將數字引腳 2 初始化為輸出引腳}}BLYNK_WRITE(V0) // Executes when the value of virtual pin 0 changes//當虛擬引腳 0 的值改變時執行{if(param.asInt() == 1){// execute this code if the switch widget is now ON// 如果開關小部件現在打開,則執行此代碼digitalWrite(2,HIGH); // Set digital pin 2 HIGH//將數字引腳 2 設置為高電平{else{// execute this code if the switch widget is now OFF// 如果開關小部件現在關閉,則執行此代碼digitalWrite(2,LOW); // Set digital pin 2 LOW// 將數字引腳 2 設置為低電平}}
請注意,您的草圖中只能有一個void setup,因此需要將 pinMode 語句複製到您現有的void setup中
就是這樣,您現在可以從虛擬 PIN virtual pin獲得與使用數字 PIN digital pins相同的功能。
我現在將介紹一些額外的東西——其中一些是特定於使用虛擬引腳的,但如果你使用數字引腳digital pins,一些也適用......
使用虛擬 Pin 時的有用提示
處理低電平有效解決方法
許多設備,例如連接到 NodeMCU GPIO2 的板載 LED 和許多繼電器板,都是由低信號而不是高信號供電。這意味著,如果您使用上面的代碼示例,當開關小部件顯示打開時,LED/繼電器將關閉,反之亦然。
有幾種方法可以解決這個問題。您可以將開關小部件輸出設置更改為 1/0 而不是 0/1 - 以便 On 狀態向應用程序發送“0”值,如下所示……
在啟動時將輸出狀態與應用程序同步
當設備啟動(重新啟動)時,它不會知道應用程序中按鈕小部件的狀態,因此可能處於與應用程序中按鈕小部件顯示不同的狀態。當您在應用程序中切換按鈕小部件時,這將得到糾正,但這不是一個非常令人滿意的解決方案。
我們可以使用Blynk.syncVirtual(vPin)命令強制 Blynk 服務器發送虛擬引腳的最新值。這會導致相應的BLYNK_WRITE(vPin)
命令執行。
要在設備連接到 Blynk 服務器時自動運行BlynkSyncVirtual(vPin)
命令(通常在重啟後,但也可能在斷開連接後),我們可以使用另一個名為“BLYNK_CONNECTED”的特殊函數,像這樣……
BLYNK_CONNECTED(){Blynk.syncVirtual(V0); // will cause BLYNK_WRITE(V0) to be executed // 將導致執行 BLYNK_WRITE(V0)}
Pin numbering引腳編號
如果您正在使用 Arduino,那麼這一切都非常簡單。通用輸入/輸出 (GPIO) 引腳 2 標記為“2”或“D2”。
但是,如果您使用的是 NodeMCU 類型的設備,那麼製造商決定讓事情變得更複雜一些。印刷在板上的數字不是 GPIO 數字。您必須將這些 NodeMCU“D”數字轉換為實際的 GPIO,如下所示……
Lablel GPIO
D1 5
D2 4
D3 0
D4 2
D5 14
D6 12
D7 13
D8 15
因此,在上面我們使用digitalWrite(2,HIGH)命令控制 GPIO2 的示例中,實際上是我們打開和關閉 NodeMCU 上標記為“D4”的引腳。
Arduino IDE 確實允許您直接使用 NodeMCU 的“D”引腳編號而不是 GPIO,如下所示:
like this:
digitalWrite(D4,HIGH);
但就個人而言。我不喜歡這種方法,因為如果需要,它會使在不同類型的設備上使用代碼變得更加困難。
需要避免一些 NodeMCU 物理引腳
NodeMCU 上的某些引腳並不真正適合連接某些類型的設備。特別是,如果 GPIO0(標記為 D3 的引腳)在啟動時被拉低,那麼設備將不會執行草圖,而是進入編程模式,等待上傳新的草圖。有一個關於此主題的更多信息:
ESP8266 GPIO pins info, restrictions and featuresFAQ
如何使用應用程序中的單個按鈕觸發多個操作(例如打開/關閉 4 個繼電器)?
你說“如果你想要一個應用程序按鈕同時打開或關閉多個繼電器,那麼使用虛擬引腳就很簡單”,但我們如何做到這一點?- 使用 Virtual Pins 真的非常簡單。
假設您有四個繼電器,它們都由連接到虛擬引腳(V1 到 V4)的四個不同按鈕小部件控制。這些允許獨立控制每個繼電器,但是您需要另一個按鈕小部件,我們將附加到虛擬引腳 5,只需單擊一下即可打開或關閉所有繼電器。
當此按鈕打開/關閉所有繼電器時,它還需要更新 4 個按鈕小部件(連接到 V1 到 V4),以便它們也全部打開或關閉。
這是執行此BLYNK_WRITE(V5)操作的function函數的樣子……
BLYNK_WRITE(V5) // Executes when the value of virtual pin 5 changes// 當虛擬引腳 5 的值改變時執行{if(param.asInt() == 1){// execute this code if the switch widget is now ON// 如果開關小部件現在打開,則執行此代碼digitalWrite(2,HIGH); // Set digital pin 2 HIGH// 將數字引腳 2 設置為高電平digitalWrite(4,HIGH); // Set digital pin 4 HIGHdigitalWrite(5,HIGH); // Set digital pin 5 HIGHdigitalWrite(12,HIGH); // Set digital pin 12 HIGHBlynk.virtualWrite(V1,1); // Turn the widget attached to V1 On// 打開附加到 V1 的小部件Blynk.virtualWrite(V2,1); // Turn the widget attached to V2 OnBlynk.virtualWrite(V3,1); // Turn the widget attached to V3 OnBlynk.virtualWrite(V4,1); // Turn the widget attached to V4 On{else{// execute this code if the switch widget is now OFFdigitalWrite(2,LOW); // Set digital pin 2 LOWdigitalWrite(4,LOW); // Set digital pin 4 LOWdigitalWrite(5,LOW); // Set digital pin 5 LOWdigitalWrite(12,LOW); // Set digital pin 12 LOWBlynk.virtualWrite(V1,0); // Turn the widget attached to V1 OffBlynk.virtualWrite(V2,0); // Turn the widget attached to V2 OffBlynk.virtualWrite(V3,0); // Turn the widget attached to V3 OffBlynk.virtualWrite(V4,0); // Turn the widget attached to V4 Off}}
如您所見,我們不僅對一個 GPIO 引腳進行數字寫入,而是一個接一個地進行 4 個引腳。然後發出Blynk.virtualWrite命令,這將更新按鈕小部件以匹配數字引腳。
完成!
更進一步參考