chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何在Arduino上實(shí)現(xiàn)有限狀態(tài)機(jī)

454398 ? 來源:wv ? 2019-09-23 11:17 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

步驟1:什么是有限狀態(tài)機(jī)?

如何在Arduino上實(shí)現(xiàn)有限狀態(tài)機(jī)

一個有限狀態(tài)機(jī)(簡稱FSM)是一臺機(jī)器(以抽象的方式)具有定義的有限數(shù)量的可能狀態(tài),一次只能激活一個狀態(tài)。狀態(tài)通過轉(zhuǎn)換連接。這些過渡有一個確定的方向,只能朝這個方向通過-可以將其視為一條單向街道。此外,過渡具有某些輸入和輸出。您可以將其視為要使用單向街道之前必須滿足的條件,并且在使用單向街道時會向外界發(fā)出信號–例如,您必須先付費(fèi)才能使用使用街道,然后計(jì)算您的汽車。

在許多房屋中都發(fā)現(xiàn)了一個非?;镜腇SM示例:按一下按鈕即可激活樓梯間的燈。一定時間后,指示燈會自動關(guān)閉。您可以將此模型建模為具有兩種狀態(tài)的FSM:“亮”和“滅”。從一種狀態(tài)過渡到另一種狀態(tài),反之亦然,條件是在一個方向上按下按鈕,而在另一方向上經(jīng)過了一定的時間。我們可以在圖表(即狀態(tài)圖)中對此行為進(jìn)行建模??匆幌聢D片1。

黑色實(shí)心圓圈標(biāo)記著狀態(tài)機(jī)的入口點(diǎn)(一切都必須從某處開始)。因此,如果我們的機(jī)器開始運(yùn)行,則指示燈熄滅。一直這樣,直到我們使用電燈開關(guān)–燈才亮起,并在30秒后熄滅。當(dāng)指示燈已亮起時按按鈕不起作用,并且30秒鐘后指示燈熄滅。該FSM沒有任何輸出。從傳統(tǒng)的數(shù)學(xué)角度來看,“點(diǎn)亮”狀態(tài)與“打開”狀態(tài)等效,但是當(dāng)我們真正開始對系統(tǒng)進(jìn)行編程時,我們當(dāng)然需要添加某種實(shí)際上可以完成某些工作的輸出,例如打開

此狀態(tài)機(jī)有效,但這是一個好的系統(tǒng)嗎? 30秒足夠長嗎?對于大多數(shù)人來說,可能是的,但是位于10樓的人們可能不喜歡我們的系統(tǒng)。他們可能需要30秒以上的時間,比方說他們需要40秒。但是他們需要等待30秒鐘過去,然后關(guān)閉燈以再次激活燈,然后他們可能在樓梯中間。因此,我們需要做的是允許在燈亮并且再次按下按鈕時重置計(jì)時器。為此,我們將需要對系統(tǒng)進(jìn)行重新建模,將計(jì)時器的開始建模為轉(zhuǎn)換的輸出,并添加另一個轉(zhuǎn)換,如圖2所示。

在這里,您可以看到兩件事:

過渡完全可以進(jìn)入到它來自的狀態(tài)

過渡可以有一個事件作為發(fā)生過渡的條件,例如以及分配的輸出。斜線左邊的信息是事件,右邊的信息是輸出。事件也被視為機(jī)器的輸入,這被稱為輸入-輸出-自動機(jī)。

步驟2:在Arduino上手動實(shí)現(xiàn)FSM

當(dāng)我們想在Arduino上實(shí)現(xiàn)此行為時,代碼可能類似于以下要點(diǎn)。代碼沒有什么特別的,switch-case語句僅針對每種可能的狀態(tài)包含一個case,并在其中檢查是否滿足轉(zhuǎn)換條件。如果是這樣,狀態(tài)就會更改。

如您所見,代碼非常簡單。但是您能想象如果沒有2個州,而是10個或100個州,會發(fā)生什么情況?對于現(xiàn)實(shí)世界的FSM來說,這并不罕見。該代碼變得不可讀,并且可以達(dá)到數(shù)千行的長度。同樣,通常,我們希望以圖形方式計(jì)劃FSM,因?yàn)槲覀冃枰軌虮M快查看其實(shí)際功能。然后,我們?nèi)匀恍枰獙?shí)際的狀態(tài)機(jī)進(jìn)行編碼,并且需要確保圖形設(shè)計(jì)和手寫代碼實(shí)際上可以完成相同的工作。這可能是一個巨大的問題。

考慮一下:對于我們的FSM所具有的每個狀態(tài),我們的代碼都需要一個“ case”語句,對于向其他狀態(tài)的每個轉(zhuǎn)換,我們都需要在其中包含一個if或case語句。如果我們有一個狀態(tài)機(jī),每個狀態(tài)都可以到達(dá)其他每個狀態(tài)(最極端的情況),我們的代碼將以 n平方增長,其中 n 是狀態(tài)。因此,對于3個狀態(tài),我們將有3種情況,內(nèi)部有3個ifs,因此代碼長度將與9成正比。當(dāng)我們有10個狀態(tài)(不是很多)時,代碼長度將與100成正比,并且在20個州中,代碼已長四倍。該FSM的圖形表示將更容易掌握,并且如果我們不必處理所有這些switch case語句,那將很好。如果您熟悉描述模擬器原理圖的網(wǎng)表–我們也不想使用網(wǎng)表設(shè)計(jì)原理圖。那么,我們該怎么做呢?

步驟3:獲取YAKINDU Statechart工具

Yakindu SCT正是為此而設(shè)計(jì)的:對系統(tǒng)建模并從中生成代碼。建模工具比簡單的有限狀態(tài)機(jī)先進(jìn)得多,因?yàn)樗鼈兓贖arel的狀態(tài)圖理論。它們通過一些其他概念擴(kuò)展了常規(guī)自動機(jī)理論-例如,歷史狀態(tài),其中離開狀態(tài)圖可保存活動狀態(tài),因此您可以稍后再返回等等。對于‘Ible,我們將不需要這些額外的功能。

Yakindu SCT基于Eclipse(最常用的IDE之一)。因此,我們可以使用市場上所有的Eclipse插件,并擁有一個已知的環(huán)境。它是開源的,這意味著它是免費(fèi)的!首先,請?jiān)L問statecharts.org,然后選擇“下載SCT”。您將需要輸入姓名,電子郵件地址和職業(yè)。下載該工具后,只需解壓縮它(右鍵單擊-》全部提取,或類似操作)。在里面,您會發(fā)現(xiàn)“ SCT”。啟動它。 (不,不需要真正的安裝。)

在安裝Yakindu SCT之后,您將具有對FSM進(jìn)行建模的工具,但是我們將希望獲得在Arduino上運(yùn)行的代碼。有一個出色的Eclipse插件可以做到這一點(diǎn),您可以在http://www.baeyens.it/eclipse/上找到有關(guān)它的更多信息。它為您提供了Eclipse內(nèi)部的完整Arduino工具鏈,因此您可以輕松使用Arduino IDE以及Eclipse的智能代碼管理和編碼助手。在SCT中,轉(zhuǎn)到幫助-》安裝新軟件。安裝向?qū)Т蜷_。單擊向?qū)в疑辖歉浇奶砑印?. 按鈕。將打開一個對話框,要求您指定要從中安裝新軟件的更新存儲庫。在“名稱”字段中輸入一些文本。該文本原則上是任意的,但是您應(yīng)該選擇一些使其更容易在其他更新存儲庫中標(biāo)識此特定更新存儲庫的內(nèi)容。輸入更新存儲庫的名稱和位置(http://eclipse.baeyens.it/update/V4/stable)之后,單擊“確定”。 Eclipse建立與更新存儲庫的網(wǎng)絡(luò)連接,向其詢問可用的軟件項(xiàng),并在安裝向?qū)е酗@示它們。在這里,您只需接受“ Arduino”選項(xiàng)。再單擊幾次“下一步”并在以后接受許可協(xié)議,它將要求您重新啟動該工具。完成此操作后,插件將下載所有需要的庫,因此您無需從現(xiàn)有的Arduino項(xiàng)目復(fù)制它們。接下來,在Yakindu SCT安裝中安裝了Arduino工具?,F(xiàn)在是時候結(jié)合兩者的可能性了。

注意:如果您尚未安裝Windows,請同時安裝官方的Arduino IDE。它帶有必需的驅(qū)動程序。我不確定Mac上的情況。 Linux已經(jīng)包含驅(qū)動程序,因此不需要安裝Arduino IDE。

步驟4:開始創(chuàng)建狀態(tài)圖

我們現(xiàn)在將開始一起對狀態(tài)圖進(jìn)行建模。首先,我們將創(chuàng)建一個新項(xiàng)目。您應(yīng)該在SCT/Eclipse的歡迎頁面上。 轉(zhuǎn)到文件-》新建-》項(xiàng)目。.. ,然后在主菜單中選擇 Arduino-》新建Arduino Sketch 。將出現(xiàn)新Eclipse項(xiàng)目的常規(guī)向?qū)?。您必須給您的項(xiàng)目起一個名字。我們將其命名為ArduinoFSM。在下一個窗口中,您可以指定arduino連接到的端口。如果您不知道并且不知道如何查找,請忽略此?,F(xiàn)在,您可以單擊完成。

如果您改為選擇 New-》 Arduino Sketch ,則不會詢問您arduino的連接位置。然后,使用 Project-》 Properties 進(jìn)行操作。如果您不知道如何確定Arduino的端口,此說明的最后一步將為您提供幫助。

如果在創(chuàng)建項(xiàng)目后未關(guān)閉歡迎屏幕,請關(guān)閉它您自己的,使用標(biāo)簽中的X?,F(xiàn)在,您應(yīng)該具有與左側(cè)“項(xiàng)目資源管理器”中的第一張圖片相似的圖片。

我們現(xiàn)在要創(chuàng)建一個名為“ model”的新文件夾。右鍵單擊您的項(xiàng)目,然后選擇新建-》文件夾。鍵入名稱,然后單擊“完成”。

右鍵單擊該新文件夾,再次轉(zhuǎn)到“新建”。根據(jù)您的安裝,您可能可以直接添加新的Statechart模型,或者可能必須使用Other,選擇Yakindu,然后選擇Statechart模型?,F(xiàn)在,您應(yīng)該看到的是第二張圖片:一個進(jìn)入狀態(tài)和一個名為 StateA 的通用第一狀態(tài)。

左側(cè)的文本框允許您聲明相關(guān)的事件和變量狀態(tài)圖,右邊的區(qū)域是圖形狀態(tài)圖編輯器。

我們將需要一個事件:按鈕。雙擊左側(cè)的文本框,然后在界面下插入文本

in event button

,然后聲明有一個名為“ button”的傳入事件。另外,在該文本框中雙擊單詞“ default”,并給狀態(tài)圖取一個更好的名稱-“ LightCtrl”怎么樣?現(xiàn)在,添加另一個狀態(tài):只需在右側(cè)面板中單擊 State ,然后在圖形狀態(tài)圖編輯器中的某個位置。雙擊這兩個州的名稱,并為其命名一個帶有黑色輸入狀態(tài)的名稱,熄滅,然后將新狀態(tài)點(diǎn)亮?,F(xiàn)在,我們需要過渡:從面板中選擇過渡,單擊一個狀態(tài),保持并拖動到另一狀態(tài)。這應(yīng)該構(gòu)成過渡。它從您第一次單擊的狀態(tài)變?yōu)榈诙€狀態(tài)。通過單擊您現(xiàn)在拖動到第一個的狀態(tài)并拖動到另一個狀態(tài)來添加第二個過渡,這樣您就可以在兩個方向上進(jìn)行過渡?,F(xiàn)在,單擊過渡。將出現(xiàn)一個文本字段。在這里,您可以輸入要進(jìn)行過渡的事件和輸出。在從關(guān)閉燈光到打開燈光的過渡上,鍵入按鈕,在另一個按鈕上,在5秒后鍵入 (比測試的30秒要快)。現(xiàn)在,您應(yīng)該擁有看起來像第三張圖片的東西!

現(xiàn)在就這些了。您有一個樓梯燈的工作模型!

步驟5:模擬狀態(tài)圖

Yakindu SCT的另一個不錯的功能是您可以模擬狀態(tài)圖而無需事先編寫任何代碼。您可以嘗試使用狀態(tài)機(jī)來實(shí)現(xiàn)您想要的狀態(tài)。

模擬狀態(tài)圖非常簡單。右鍵單擊Eclipse/SCT中的.sct文件,選擇運(yùn)行方式,然后選擇狀態(tài)圖模擬。

將打開一個新透視圖。您應(yīng)該能夠看到第一個狀態(tài)是紅色,這是活動狀態(tài)。 (看圖片)在右邊,應(yīng)該打開了Simulation View。您可以通過在右下方的模擬視圖中單擊單詞 button 來模擬按鈕按下事件?;顒訝顟B(tài)應(yīng)從“熄滅”更改為“點(diǎn)亮”。五秒鐘后,或單擊時間事件 Light_On_timer_event_0 后,活動狀態(tài)將更改回 Light Off 。太棒了!現(xiàn)在,讓我們檢查一下如何在Arduino上使用它。

步驟6:將系統(tǒng)帶入現(xiàn)實(shí)世界

好吧,我們點(diǎn)擊了一下,使用了圖形編輯器(通常與低級語言相關(guān)聯(lián)),讓這件事栩栩如生。首先,我們需要一個代碼生成器,將狀態(tài)圖轉(zhuǎn)換為C代碼。

右鍵單擊您的模型文件夾,然后選擇 New-》 Code Generator Model ,這非常簡單,盡管看起來一開始就像是黑魔法。在向?qū)е袉螕糇约海缓髮⒋a生成器附加到之前創(chuàng)建的狀態(tài)圖。注意:在同一窗口中,頂部有一個選擇器,可以輕松查看。使用它選擇C代碼生成器而不是Java代碼生成器,然后選中狀態(tài)圖旁邊的復(fù)選框,然后單擊完成。正常情況下,生成器現(xiàn)在應(yīng)該一直一直直接自動運(yùn)行。檢查是否創(chuàng)建了兩個文件夾src和src-gen。如果不是這種情況,請轉(zhuǎn)到主菜單中的“項(xiàng)目”,然后檢查是否激活了“自動生成”。如果不是,請這樣做,然后右鍵單擊您的項(xiàng)目,然后選擇“生成項(xiàng)目”。進(jìn)度條以及兩個提到的文件夾都應(yīng)出現(xiàn)。進(jìn)行任何更改后,還可以右鍵單擊生成器文件,然后選擇 Generate Code Artifacts 。

src-gen文件夾的內(nèi)容非常有趣。文件 LightCtrl.c 包含狀態(tài)圖的實(shí)現(xiàn)。檢查時,您會發(fā)現(xiàn)一個函數(shù) LightCtrlIface_raise_button(LightCtrl *句柄)。您可以調(diào)用此函數(shù)來引發(fā)我們先前聲明的按鈕事件,例如,當(dāng)您檢查硬件按鈕的引腳并看到其具有高電平時。然后是文件 LightCtrlRequired.h ,您需要在其中查看。它聲明您需要實(shí)現(xiàn)的功能。對于此狀態(tài)圖,只有兩個功能: lightCtrl_setTimer 和 lightCtrl_unsetTimer 。我們需要這些功能,因?yàn)闋顟B(tài)圖在5s之后使用了構(gòu)造。這是一個非常方便的功能,但是我們的狀態(tài)圖代碼生成器不提供計(jì)時服務(wù),因?yàn)樗叨纫蕾囉谄脚_–您的計(jì)算機(jī)與微型Arduino的計(jì)時器處理方式不同,而Mac和Linux上的計(jì)時器處理方式與Windows上的處理方式不同。

幸運(yùn)的是,我將為您提供計(jì)時服務(wù),因此您無需自己實(shí)現(xiàn)。在您的項(xiàng)目中,創(chuàng)建一個新文件夾,將其命名為 scutils ,用于 s tate c hart 實(shí)用程序功能。您可以隨意命名,也可以選擇不創(chuàng)建該文件夾,這只是組織問題。我們將在其中創(chuàng)建兩個文件,分別是 sc_timer_service.c 和 sc_timer_service.h 。從GitHub中復(fù)制

代碼:

sc_timer_service.h

sc_timer_service.c

使用YAKINDU SCT 2.7.0,在那里是一個新選項(xiàng),可用于獲得此可指導(dǎo)的項(xiàng)目:

在SCT中,轉(zhuǎn)到“文件”-》“新建”-》“示例。..”,選擇“ YAKINDU Statechart示例”,然后單擊“下一步”。在新的示例向?qū)е?,單擊“下載”以獲取最新的示例集。從arduino類別中選擇“ Arduino的有限狀態(tài)機(jī)”,然后單擊“完成”。該項(xiàng)目將被復(fù)制到您的工作區(qū)中。右鍵單擊它,然后單擊“刷新”-可以肯定。

現(xiàn)在,我們可以開始在向?qū)傻? .ino文件中的Arduino代碼上工作。

除了 Arduino.h ,還包括 avr/sleep.h ,當(dāng)然還有我們的狀態(tài)機(jī)和計(jì)時器服務(wù): LightCtrl.h , LightCtrlRequired.h 和 sc_timer_service.h ?,F(xiàn)在,需要常規(guī)的Arduino東西:我們定義按鈕和LED的引腳,并將它們設(shè)置在設(shè)置功能內(nèi)(這就是它的用途)。然后,我們需要定義狀態(tài)圖期望我們定義的函數(shù)-如前所述,- lightCtrl_setTimer 和 lightCtrl_unsetTimer 。在這里,我們只使用計(jì)時器服務(wù),就完成了?,F(xiàn)在,我們應(yīng)該思考一下當(dāng)達(dá)到 Light On 狀態(tài)時實(shí)際上如何激活LED。基本上,我們有三個選項(xiàng):

我們可以檢查狀態(tài)機(jī)是否處于Light On狀態(tài),并根據(jù)該信息激活/禁用LED

我們可以進(jìn)入狀態(tài)圖,并在到達(dá)狀態(tài)時設(shè)置一個變量,以便我們可以輪詢

我們可以添加一個操作來管理狀態(tài)圖在過渡時調(diào)用的光。

第一個解決方案確實(shí)很糟糕。我們將有關(guān)于狀態(tài)圖外部的邏輯。如果我們重命名我們的州,它將停止正常工作;但是這些名稱是平淡無奇的,與邏輯無關(guān)??梢允褂米兞?,特別是在使用桌面應(yīng)用程序時。我們可以每x毫秒左右與他們同步一次。在這里,我們要使用一個操作。在狀態(tài)圖的接口聲明中添加以下內(nèi)容:

operation setLight(LightOn: boolean): void

這聲明了一個函數(shù),該函數(shù)接受布爾值作為參數(shù),但不返回任何值(無效)。這對您來說不是新手,只是這里的語法不同。請記住–狀態(tài)圖未綁定到特定語言,因此語法是通用的。此功能自動顯示在 LightCtrlRequired.h 中。如果沒有,請保存狀態(tài)圖,右鍵單擊您的項(xiàng)目并進(jìn)行構(gòu)建。

此處聲明的函數(shù)如下所示:

extern void lightCtrlIface_setLight(const LightCtrl* handle, const sc_boolean lightOn);

輸入?yún)?shù)句柄為類型的LightCtrl,它是狀態(tài)圖的引用者。如果您不熟悉C:星號表示所謂的指針,那么該變量包含statechart變量的地址。這對我們有幫助,因?yàn)槲覀兛梢詫υ紝ο筮M(jìn)行操作,而不必創(chuàng)建其副本。因此,讓我們實(shí)現(xiàn)此功能:

void lightCtrlIface_setLight(const LightCtrl* handle, const sc_boolean lightOn) {

if(lightOn)

digitalWrite(LED_PIN, HIGH);

else

digitalWrite(LED_PIN, LOW);

}

如您所見,此功能非常簡單-我們甚至不使用狀態(tài)圖的句柄,我們只在LED上寫HIGH如果操作的參數(shù)為true,則為pin;否則為LOW。

我們更改狀態(tài)圖本身,使其看起來像第一張圖片。

還記得第1步嗎?斜線左邊是過渡所需要的輸入,右邊是狀態(tài)機(jī)的輸出(如果進(jìn)行了過渡)。此處的輸出是使用這些參數(shù)調(diào)用指定的操作。

#include “Arduino.h”

#include “avr/sleep.h”

#include “src-gen/LightCtrl.h”

#include “src-gen/LightCtrlRequired.h”

#include “scutil/sc_timer_service.h”

#define BUTTON_PIN 3

#define LED_PIN 6

#define MAX_TIMERS 20 //number of timers our timer service can use

#define CYCLE_PERIOD 10 //number of milliseconds that pass between each statechart cycle

static unsigned long cycle_count = 0L; //number of passed cycles

static unsigned long last_cycle_time = 0L; //timestamp of last cycle

static LightCtrl lightctrl;

static sc_timer_service_t timer_service;

static sc_timer_t timers[MAX_TIMERS];

//! callback implementation for the setting up time events

void lightCtrl_setTimer(LightCtrl* handle, const sc_eventid evid, const sc_integer time_ms, const sc_boolean periodic){

sc_timer_start(&timer_service, (void*) handle, evid, time_ms, periodic);

}

//! callback implementation for canceling time events.

void lightCtrl_unsetTimer(LightCtrl* handle, const sc_eventid evid) {

sc_timer_cancel(&timer_service, evid);

}

void lightCtrlIface_setLight(const LightCtrl* handle, const sc_boolean lightOn) {

if(lightOn)

digitalWrite(LED_PIN, HIGH);

else

digitalWrite(LED_PIN, LOW);

}

//The setup function is called once at startup of the sketch

void setup()

{

pinMode(BUTTON_PIN, INPUT);

pinMode(LED_PIN, OUTPUT);

sc_timer_service_init(

&timer_service,

timers,

MAX_TIMERS,

(sc_raise_time_event_fp) &lightCtrl_raiseTimeEvent

);

lightCtrl_init(&lightctrl); //initialize statechart

lightCtrl_enter(&lightctrl); //enter the statechart

}

// The loop function is called in an endless loop

void loop()

{

unsigned long current_millies = millis();

if(digitalRead(BUTTON_PIN))

lightCtrlIface_raise_button(&lightctrl);

if ( cycle_count == 0L || (current_millies 》= last_cycle_time + CYCLE_PERIOD) ) {

sc_timer_service_proceed(&timer_service, current_millies - last_cycle_time);

lightCtrl_runCycle(&lightctrl);

last_cycle_time = current_millies;

cycle_count++;

}

}

此外,請按行號在本要點(diǎn)中檢查代碼。

第1-6行包含如前所述的包含。

第8行和第9行定義了我們將要用于arduino的硬件引腳。

第11行和第12行定義了狀態(tài)圖可以使用多少個計(jì)時器,以及狀態(tài)圖的每個計(jì)算周期之間應(yīng)經(jīng)過多少毫秒。

第15和16行聲明了一些變量,我們可以用它們來計(jì)數(shù)周期并管理最后一個周期的時間。

第17、19和21行聲明了使用狀態(tài)圖的重要變量:狀態(tài)圖本身,計(jì)時器服務(wù)和計(jì)時器數(shù)組。

第24行和第33行定義了狀態(tài)圖需要計(jì)時器使用的功能,第33行是設(shè)置前面討論過的LED的功能。

在第41行中,void setup()是Arduino的標(biāo)準(zhǔn)功能。它在啟動時被調(diào)用一次。我們用它來初始化東西–我們的LED和按鈕引腳配置了它們的方向(INPUT是標(biāo)準(zhǔn)的,為清楚起見,我們這樣做了),計(jì)時器服務(wù)被初始化,狀態(tài)圖被初始化并輸入。輸入意味著啟動狀態(tài)機(jī),因此第一個狀態(tài)被激活-這是輸入狀態(tài)所指向的狀態(tài)。因此,在啟動時,指示燈熄滅。

在第59行中,跟隨著循環(huán)功能,Arduino一直在調(diào)用它。

在第61行中,我們使用millis()函數(shù)捕獲當(dāng)前時間,該函數(shù)由Arduino庫定義。

在第63行中,我們檢查按鈕是否被按下,如果按下,則引發(fā)按鈕事件。

在第66行中,我們檢查自上次循環(huán)狀態(tài)圖以來是否已超過CYCLE_PERIOD毫秒。

這會給我們的arduino帶來一些負(fù)擔(dān),這意味著我們可以可靠地將長達(dá)10毫秒的時間用于自己的功能。

在第68行中,我們告訴計(jì)時器服務(wù)自上次調(diào)用以來已經(jīng)過去了多少時間,在第70行中告訴statechart運(yùn)行一個周期,在第72行中保存當(dāng)前時間,并增加周期計(jì)數(shù)在第73行。

使用arduino插件,您現(xiàn)在可以將arduino與LED和連接到計(jì)算機(jī)的按鈕連接起來,并使用頂部工具欄中的按鈕將程序上傳到

電路如圖2和圖3所示。

LED通過大約200歐姆的電阻連接到數(shù)字引腳(6)。陰極連接到GND。

按鈕有四個引腳,請?jiān)诎聪掳粹o時檢查其中哪些始終連接以及哪些連接。然后,將數(shù)字引腳(此處使用3)連接到一側(cè),將下拉電阻連接到GND。這將使引腳停止處于“浮動”狀態(tài)(不確定狀態(tài)),并將其保持在0 V電壓。當(dāng)按下按鈕并將另一側(cè)連接到VCC時,該側(cè)“更強(qiáng)”,因?yàn)樗鼪]有電阻,并且電壓高達(dá)5伏–基本上是一個分壓器,其中一個電阻為0歐姆。請?jiān)诖耸褂靡粋€較高的電阻,因?yàn)樗鼤拗仆ㄟ^按鈕的電流。最小值為1 kR。

如您所見,該程序的邏輯完全獨(dú)立于我們狀態(tài)圖的實(shí)際大小。狀態(tài)圖具有2個或20個狀態(tài)都沒有關(guān)系-當(dāng)然,如果我們想做點(diǎn)什么,我們需要在這里和那里實(shí)現(xiàn)一個功能。但是void loop()內(nèi)部的主要代碼總是很小,并且允許模塊化程序體系結(jié)構(gòu)。我們只需要在代碼中處理從狀態(tài)圖到Arduino硬件的接口,自動生成的狀態(tài)圖將處理其內(nèi)部邏輯。還記得我們討論過如何在再次按下按鈕時重置計(jì)時器嗎?現(xiàn)在,您可以使用“按鈕”作為保護(hù)事件,從“點(diǎn)亮”狀態(tài)添加到其自身的過渡,而無需在代碼中更改或添加一行。嘗試一下,然后開始對軟件進(jìn)行建模,而不是編寫它!

步驟7:此外:查找您的Arduino端口

因此,您陷入困境,因?yàn)槟鸁o法弄清Arduino連接到哪個串行/USB端口。好的,您會在下面找到有關(guān)Windows和Linux的說明。

Windows

將arduino插入計(jì)算機(jī),然后轉(zhuǎn)到“設(shè)備和打印機(jī)”(從開始菜單或系統(tǒng)控制面板)。如圖所示,您的arduino應(yīng)該出現(xiàn)在這里-對我來說,端口為COM12。這可能會改變,例如,當(dāng)您使用另一個USB端口時,重新啟動系統(tǒng)。..如果仍然無法解決問題,請檢查是否仍然正確。

Linux

使用您的arduino未連接,啟動終端。輸入 dmesg 并返回,這將為您提供冗長的文本輸出。插入您的arduino,然后再次輸入 dmesg 。最后應(yīng)該是一些有關(guān)arduino的消息,包括一個端口-例如,/dev/USB0,/dev/ttyAMC3-可以理解。如果您插入arduino且LED不亮,并且 dmesg 在插入之前和之后都顯示完全相同的內(nèi)容,則很可能是您的Arduino吐司了。

如果此方法不適合您,也可以在插入Arduino之前和之后嘗試 ls/dev/。這列出了所有可用的設(shè)備,并且在連接Arduino之后應(yīng)該能夠看到一個新設(shè)備。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • fsm
    fsm
    +關(guān)注

    關(guān)注

    0

    文章

    36

    瀏覽量

    13108
  • Arduino
    +關(guān)注

    關(guān)注

    190

    文章

    6526

    瀏覽量

    196770
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    為什么在FPGA設(shè)計(jì)中使用MicroBlaze V處理器

    在各類行業(yè)與應(yīng)用中,經(jīng)常能看到許多 FPGA 設(shè)計(jì)。一個非常常見的現(xiàn)象是:設(shè)計(jì)者常常用復(fù)雜的有限狀態(tài)機(jī)(FSM)來實(shí)現(xiàn) I2C、SPI、GPIO 時序控制等功能。
    的頭像 發(fā)表于 12-19 15:29 ?8183次閱讀
    為什么在FPGA設(shè)計(jì)中使用MicroBlaze V處理器

    條件判斷法來實(shí)現(xiàn)狀態(tài)機(jī)

    狀態(tài)用 switch—case 組織起來, 將事件也用switch—case 組織起來, 然后讓其中一個 switch—case 整體插入到另一個 switch—case 的每一個 case 項(xiàng)中
    發(fā)表于 12-09 08:18

    睿遠(yuǎn)研究院丨IO-Link規(guī)范解讀(十一):ISDU狀態(tài)機(jī)與EVENT事件

    上篇我們介紹了ISDU的典型編碼格式和應(yīng)用案例,本篇我們就來詳細(xì)介紹下,ISDU的狀態(tài)機(jī),并把EVENT事件的邏輯,給大家好好解析下。 1主站ISDU狀態(tài)機(jī) 如上圖所示,ISDU的狀態(tài)機(jī)的核心
    的頭像 發(fā)表于 11-29 18:28 ?4692次閱讀
    睿遠(yuǎn)研究院丨IO-Link規(guī)范解讀(十一):ISDU<b class='flag-5'>狀態(tài)機(jī)</b>與EVENT事件

    什么是狀態(tài)機(jī)

    另一個狀態(tài)的過程稱作遷移,遷移不是自動發(fā)生的,需要外界對系統(tǒng)施加影響。停轉(zhuǎn)的電動機(jī)自己不會轉(zhuǎn)起來,讓它轉(zhuǎn)起來必須電。 事件:某一時刻發(fā)生的對系統(tǒng)有意義的事情,狀態(tài)機(jī)之所以發(fā)生狀態(tài)遷移
    發(fā)表于 11-27 08:15

    嵌入式開發(fā)為何經(jīng)常用到狀態(tài)機(jī)架構(gòu)

    一個管腳電平跳變或者一個串口數(shù)據(jù),讓整個程序都不動的情況也讓我非常糾結(jié),如果事件一直不發(fā)生電平跳變,你要等到世界末日么? 如果應(yīng)用狀態(tài)機(jī)編程思想,程序只需要用全局變量記錄下工作狀態(tài),就可以轉(zhuǎn)頭去干別的
    發(fā)表于 11-25 07:08

    睿遠(yuǎn)研究院丨IO-Link規(guī)范解讀(八):M-Sequence Type 與消息處理狀態(tài)機(jī)

    丟棄,減少后端工作量。 那么今天我們就來深入研究下,消息處理模塊中提到的各類M-Sequence,以及主從站的消息處理狀態(tài)機(jī)! ? 1 M-Sequence Type 上回講到主站發(fā)出來的MC和CKT
    的頭像 發(fā)表于 11-07 16:18 ?6228次閱讀
    睿遠(yuǎn)研究院丨IO-Link規(guī)范解讀(八):M-Sequence Type 與消息處理<b class='flag-5'>狀態(tài)機(jī)</b>

    復(fù)雜的軟件算法硬件IP核的實(shí)現(xiàn)

    中的運(yùn)算符有對應(yīng)關(guān)系。 結(jié)構(gòu)域負(fù)責(zé)將功能域中的各個基本功能單元按特定的順序和方式連接起來,通常被實(shí)現(xiàn)為一個由有限狀態(tài)機(jī)控制的數(shù)據(jù)通路,該結(jié)構(gòu)與C 語言的流程控制語句相對應(yīng)。 以一個簡單的加法組合邏輯為例
    發(fā)表于 10-30 07:02

    睿遠(yuǎn)研究院丨IO-Link規(guī)范解讀(六):主從站狀態(tài)機(jī)解析

    前言 書接上文,今天我們就來好好聊聊主從站的DL-Mode狀態(tài)機(jī),還請各位童鞋前排坐好! 1主站狀態(tài)機(jī)解析 主站的DL-Mode狀態(tài)機(jī)有5個大狀態(tài),也是我們很熟悉的 建立通信、開始、預(yù)
    的頭像 發(fā)表于 10-28 17:34 ?6178次閱讀
    睿遠(yuǎn)研究院丨IO-Link規(guī)范解讀(六):主從站<b class='flag-5'>狀態(tài)機(jī)</b>解析

    掌握數(shù)字設(shè)計(jì)基礎(chǔ):邁向芯片設(shè)計(jì)的第一步

    寄存器、計(jì)數(shù)器。 兩者結(jié)合,就能實(shí)現(xiàn)強(qiáng)大的數(shù)據(jù)處理與控制能力。 4、有限狀態(tài)機(jī)(FSM):數(shù)字系統(tǒng)的大腦 在更復(fù)雜的設(shè)計(jì)中,有限狀態(tài)機(jī)(FSM) 就像系統(tǒng)的“大腦”,通過狀態(tài)與轉(zhuǎn)移邏輯
    發(fā)表于 10-09 21:11

    JTAG標(biāo)準(zhǔn)的狀態(tài)機(jī)實(shí)現(xiàn)

    JTAG作為一項(xiàng)國際標(biāo)準(zhǔn)測試協(xié)議(IEEE1149.1兼容),主要用于芯片內(nèi)部測試和調(diào)試。目前的主流芯片均支持JTAG協(xié)議,如DSP、FPGA、ARM、部分單片機(jī)等。標(biāo)準(zhǔn)的JTAG接口是20Pin,但JTAG實(shí)際使用的只有4根信號線,再配合電源、地。
    的頭像 發(fā)表于 08-21 15:12 ?2670次閱讀
    JTAG標(biāo)準(zhǔn)的<b class='flag-5'>狀態(tài)機(jī)</b><b class='flag-5'>實(shí)現(xiàn)</b>

    請問如何在FX10使用GPIF III狀態(tài)機(jī) *.h 文件?

    LVCMOS 2 位 SlaveFIFO GPIF III 狀態(tài)機(jī)的演示中有一個 cy_gpif_header_lvcmos.h 文件。 我想知道如何使用.h文件,只需放入.h文件放入 FX10 項(xiàng)目? 您有它的用戶指南文檔嗎?
    發(fā)表于 07-16 08:17

    NVMe高速傳輸之?dāng)[脫XDMA設(shè)計(jì)之八:PCIe初始化狀態(tài)機(jī)設(shè)計(jì)

    PCIe配置初始化狀態(tài)機(jī)實(shí)現(xiàn)PCIe設(shè)備枚舉和配置空間初始化過程,在完成鏈路訓(xùn)練后,使用DFS(深度優(yōu)先搜索)算法枚舉PCIe總線上的設(shè)備,完成PCIe總線域的地址分配和設(shè)備的初始化。PCIe配置
    發(fā)表于 07-05 22:00

    有可能在 FX3 GPIF2 中創(chuàng)建兩個獨(dú)立的狀態(tài)機(jī)嗎?

    我想,如果我想通過 FX3 GPIF2 創(chuàng)建兩個獨(dú)立的傳輸流接口,我需要在 GPIF2 設(shè)計(jì)器中創(chuàng)建兩個獨(dú)立的狀態(tài)機(jī),我是否有可能在 GPIF2 設(shè)計(jì)器中創(chuàng)建兩個獨(dú)立的狀態(tài)機(jī)?
    發(fā)表于 05-20 06:14

    cypress3014視頻格式改變的話,GPIF狀態(tài)機(jī)需不需要重新配置?

    你好,請問視頻格式改變的話,GPIF狀態(tài)機(jī)需不需要重新配置
    發(fā)表于 05-14 07:28

    求助,關(guān)于srammaster.cydsn中狀態(tài)機(jī)的問題求解

    晚上好。 我目前正在學(xué)習(xí) GPIF II。 查看..EZ-USB FX3 SDK1.3firmwaregpif_examplescyfxsrammastersrammaster.cydsn中的狀態(tài)機(jī),有狀態(tài)START和START1。 這意味著什么?
    發(fā)表于 05-12 06:20