PLC中的常量,同樣是我所不喜歡用的。
因?yàn)榕c我抨擊過多次的全局變量和UDT一樣,它們都是一種全局資源。
然而, 因?yàn)檫@個觀點(diǎn)又是在整個PLC行業(yè)中獨(dú)一無二的首發(fā),以前未見到其他人發(fā)表過,所以勢必又會驚掉一大堆人的下巴,所以需要先把這其中的道理掰扯清楚。
以往我發(fā)表的很多類似技術(shù)觀點(diǎn)的文章發(fā)表后, 總會出現(xiàn)各種不同的聲音。
其中一種是指責(zé)我故意制造爭論,嘩眾取寵。
嘩眾取寵這種罪責(zé)從來都是完全沒有邏輯的。技術(shù)的問題, 要么對, 要么錯。如果你不能證明錯誤,而只是因?yàn)樽约簺]有相關(guān)的認(rèn)知那么至少暫時你也應(yīng)該暫時擱置,給自己留個學(xué)習(xí)認(rèn)證的時間,而不是第一時間就加以否定, 甚至還什么我的目的是要取寵你。
讀者有什么好取寵的呢?除非我能帶給讀者真正的知識,讓他有思考有收獲,他會感激我。初次之外,我僅僅驚嚇了他們一跳,他憑啥就要寵我,我還取寵呢!
還有一種觀點(diǎn)是倒過來質(zhì)疑我不會用我文章提到的這個技術(shù)點(diǎn)。我講不用UDT的時候懷疑我不會用UDT,我講不用循環(huán)的時候懷疑我不會用循環(huán),我講不用IO映射的時候懷疑我不會用IO映射,我講不用全局變量的時候懷疑我不會用全局變量??傊?,我不用啥都不是因?yàn)檫@個方法有啥缺點(diǎn),而是因?yàn)槲也粫谩H缓笪覍懗鑫恼聛碚米驳搅藭玫乃?/p>
就不想想,我不會的東西可多了去了。天文地理軍事體育,天底下的知識技能包羅萬象,其中的大部分都是我不懂的。那么多我不懂的內(nèi)容我為啥不去寫挨著寫文章發(fā)表觀點(diǎn), 憑啥就撞到了你特長的槍口上發(fā)表觀點(diǎn)呢?
真實(shí)的情況應(yīng)該是, 那些我不懂的東西我應(yīng)該是它們的名字都叫不上來,甚至都不了解它們的存在。我既然能拿這些作為題目寫出一篇小作文來,而且能準(zhǔn)確地踩到一大批人的脈搏,大概率當(dāng)然應(yīng)該是我會的。就因?yàn)槲視?,我才有能力拿它們開刀開涮。而且所理解的深度比剛剛讀到這個觀點(diǎn)的你更深刻。 ? ?
亦或是, 如果你覺得你也可以憑自己不懂,就可以寫文章, 那不妨寫一兩篇出來試試。我相信你如果愿意寫,很快就能寫上幾萬篇文章,積累成專輯出版?zhèn)魇篮笕恕?/p>
而且,咱說的這些問題,普遍都是需要掌握的非常低的技能,斷然連門檻都算不上。比如全局變量, 你說會用全局變量還需要什么技能?相反,會不用, 能不用才是技能!
當(dāng)然,還有一些人,在用上述觀點(diǎn)跟我周旋良久占不到便宜后,還會使出最后的絕技:人家西門子, CODESYS ,? 三菱等系統(tǒng)平臺,既然設(shè)計了此功能, 你為啥不讓我用呢?
這種通常就是屬于沒有邏輯的人群中的下下限,通常到此為止我就沒必要再與這樣的人進(jìn)行技術(shù)話題的探討了。
就好比,我在分享工程師如何做到出差不帶編程電纜萬用表的經(jīng)驗(yàn)知識,他來抬杠我家里有,憑什么就不能帶?我講可以出差不帶電腦,他來杠不帶電腦拿什么干活?講如何做到乘坐商務(wù)倉而不去擠經(jīng)濟(jì)艙,他來杠飛機(jī)上有經(jīng)濟(jì)艙你憑啥不讓人坐?要不要你去建議飛機(jī)制造商把經(jīng)濟(jì)艙座位全部取消了!
所以一定要注意,我在講到不使用這個不使用那個的時候,我說的是我自己做到了不用,我從來沒有卡住別人的脖子不許別人使用。甚至連對煙臺方法的學(xué)員,我都沒有這個權(quán)力。其次,我在講這些觀點(diǎn)的時候,都是有前提條件的,就是在做標(biāo)準(zhǔn)化架構(gòu)的模塊的時候的最優(yōu)解。如果不求最優(yōu),或者根本不在模塊化范圍內(nèi),那也是無關(guān)的。?
要說卡脖子,我也只是卡住了我自己的脖子,并且還秀給別人看:我不用這個材料,也不用那個材料,卻仍然做出了標(biāo)準(zhǔn)化架構(gòu)煙臺方法(6年前)。圍觀群眾縱然沒有機(jī)會親自領(lǐng)略其神奇,但可以通過排除法逐漸逼近真相。因?yàn)槭紫纫粋€前提是可以保證的:真實(shí)。 ? ?
因?yàn)榈参矣卸↑c(diǎn)撒謊, 比如如果我明明在自己的項(xiàng)目程序中使用了全局變量或者常量,卻還寫文章來探討這個不用那個不用,那就等于把命門暴露給了別人,分分鐘等待被學(xué)員給揭發(fā),扒掉了底褲。
而從利益的角度,如果我在用的東西,我也完全沒必要編瞎話再給自己無端增加事端,我就保持我既有的技術(shù)架構(gòu),繼續(xù)出售我的技能知識,都足夠。所以我寫這些文章更多的意義在于啟發(fā)已有的煙臺方法的學(xué)員,從我交付的資料中發(fā)現(xiàn)這些細(xì)節(jié)的閃光點(diǎn)。我只是在對自己已經(jīng)做到的技術(shù)方法持續(xù)做出總結(jié)而已。比如在我寫本文發(fā)表本文的觀點(diǎn)之前, 那些學(xué)習(xí)了3-5年的煙臺方法學(xué)員,恐怕未必自己能從煙臺方法的案例中總結(jié)歸納到。
當(dāng)然,未來的學(xué)員提前有了這方面的準(zhǔn)備預(yù)期,真正入手之后方向也會更明確。
回到文章的開始我把常量和全局變量都比作全局資源,一定有人不能理解。全局變量M是有地址范圍的,有可能會用光,不同的CPU,其M空間不一樣多。而常量是不需要地址的,怎么也算全局資源呢?
其實(shí),我在最早的講不用全局變量的文章中,就已經(jīng)提到過了,比方AB PLC,它是沒有M的概念的。所有的全局變量沒有地址,你聲明一批BOOL或者INT等數(shù)據(jù)類型的變量名,然后就全局使用了。我們指的是它們,符號化的全局變量。而平常用M來泛指,只是為了表達(dá)方便。
所以,即便是符號命名的變量或者常量,或者UDT,它們的名字也是全局資源,也是可能發(fā)生沖突,而只要有發(fā)生沖突的可能, 那么不管這個可能性的概率有多低,在制作標(biāo)準(zhǔn)的模塊庫時都應(yīng)該盡量避免。比如我自己,就從來不用。當(dāng)然讀者可以質(zhì)疑我經(jīng)歷過的項(xiàng)目都還不夠復(fù)雜, 也確實(shí)我目前也遇到的一些功能使用了常量,而我還沒找到更好的避免的方法,也仍然在探索中。文章的最后會提及。 ? ?
有的人搞不懂我為啥要對沖突如此敏感,尤其是這種可能性極小的沖突。做一個約定,事先規(guī)定一個規(guī)則,把所有的功能模塊都約定在規(guī)則之下,不就好了嘛!
比如我在講不用M的時候,就有博主表示不以為然,并大秀智商給了一個高級解決方案:提前規(guī)劃。即針對不同的應(yīng)用和功能,預(yù)先分配好不同的M地址區(qū)域, 不就好了嘛!
然而,有沒有想過,如果你通過規(guī)劃的約束,不管是一個工程項(xiàng)目,還是一套架構(gòu)方案,那么在規(guī)劃誕生之前所做的技術(shù)儲備就全部不能直接拿來使用了。即便不會被作廢,也需要在使用之前做沖突檢查。那所謂的封裝和復(fù)用的模塊化的效果就大打了折扣。
而且,這種規(guī)劃并沒有一個天然的核心,并不是你或者我提出了這種規(guī)劃大法,我或者你就擁有了天然的主持規(guī)劃的話語權(quán), 而是所有人都可以主持規(guī)劃, 那么導(dǎo)致的結(jié)果是人人都可以做規(guī)劃主任, 每個人的規(guī)劃方案當(dāng)然會有差異, 那么即便假設(shè)有人甘心做小弟,不謀求做規(guī)劃主任,而只是被動執(zhí)行規(guī)劃,也會因?yàn)橛卸鄠€不同的主心骨而無所適從。比如A主導(dǎo)了一個平臺架構(gòu), B主導(dǎo)了另一個平臺架構(gòu),而C作為小弟,想貢獻(xiàn)一套自己做的算法模塊的時候,還需要分別調(diào)整,根據(jù)AB各自的規(guī)則調(diào)整之后,才可以投稿。除非他在做這套算法模塊的時候沒有使用到任何全局資源,模塊是完全內(nèi)聚的,對資源沒有任何要求和約定。如我一直在號召并踐行的。這就是為什么在GITHUB上面關(guān)于PLC的庫分享還完全不成氣候的原因。連規(guī)則方法都還沒達(dá)成一致的行業(yè),怎么可能有共享的生態(tài)環(huán)境呢? ? ?
下面我們在TIA PORTAL中演示下使用CONST常量會帶來的危害。當(dāng)然順便也演示使用了UDT, 用戶數(shù)據(jù)類型。
新建一個S7-1200的項(xiàng)目, 在其中建立用戶數(shù)據(jù)類型,就缺省的名字“用戶數(shù)據(jù)類型_1”好了。建立了2條數(shù)據(jù)DATA1和DATA2,分別為BOOL,假設(shè)算法需要。

然后PLC變量表中的用戶常量的頁,建立一個INT類型的常量,名字為MAX, 數(shù)值等于99。通常使用常量的目的就是為了數(shù)值可以統(tǒng)一修改。將來需要的時候可以從99改為別的數(shù)值。

然后建立FB塊, 在其靜態(tài)變量中建立變量,一個數(shù)組,數(shù)組的上限是MAX, 數(shù)據(jù)類型即為建立的UDT。 ? ?

這不就是你們使用常數(shù)的最大目的嘛!需要建立數(shù)組做循環(huán),然而循環(huán)的上限提前不能確定,導(dǎo)致數(shù)組的上限也不能確定,然而幾乎所有的編程語言都不允許數(shù)組的上限值不確定,不允許變化的變量, 只接受常量。所以就只好用常量來實(shí)現(xiàn)了。
后面的程序邏輯就不具體做了。反正就是有了這樣的數(shù)據(jù)接口和結(jié)構(gòu),最終在FB內(nèi)實(shí)現(xiàn)了特定的算法功能,然后以為可以封裝成一個固化的FB了,可以無限重復(fù)使用了。
然后把整個PLC復(fù)制一份,并修改自定義數(shù)據(jù)的結(jié)構(gòu),比如數(shù)據(jù)類型改為2個INT,而UDT的名稱不變。

同樣也建立FB, 定義數(shù)據(jù),為了實(shí)現(xiàn)另外其它的算法功能。其中MAX常量的數(shù)值做了修改,比如10 ? ?
好啦!我們現(xiàn)在假設(shè)手里有2套完全不同的庫函數(shù),分別實(shí)現(xiàn)了不同的控制算法功能。唯獨(dú)它們之間好巧不巧使用了相同的名稱,F(xiàn)B的名稱、自定義數(shù)據(jù)名稱以及常量名稱。當(dāng)然這個巧合是我人為造出來的, 但你不可否認(rèn)這種巧合當(dāng)然存在。
現(xiàn)在,我們假設(shè)有第三個項(xiàng)目,需要用到上述的2個功能庫, 所以需要把它們復(fù)制到同一個PLC中。
FB名稱的重復(fù)很容易發(fā)現(xiàn),也很容易處理。復(fù)制的時候另外取個名字,也另外分配個FB編號即可。當(dāng)然CODESYS等環(huán)境下的FB沒有編號,不需要。
然而如果重復(fù)使用這2個FB的不是原作者本人, 必然對數(shù)據(jù)結(jié)構(gòu)和邏輯不夠熟悉。復(fù)制之后再編譯的時候,發(fā)現(xiàn)提示UDT和常數(shù)缺失,然后按照提示去源程序中復(fù)制。對于FB1,沒有問題,而對FB2,則會發(fā)現(xiàn)出了問題。UDT結(jié)構(gòu)定義變化了, 編譯沖突,通不過了。
解決辦法是,可以在復(fù)制之前,先將UDT的名稱改掉,改為不重復(fù),然后再復(fù)制,就可以不沖突了。
而常量,則并不會有提示,所以,如果你不曉得代碼邏輯中有沖突使用的常量,就不會發(fā)現(xiàn)其中的數(shù)值被偷偷的改掉了,而你一無所知。----------這樣,必然就留下了BUG隱患。
這就是我反對我自己使用全局常量的原因所在。因?yàn)樗茐牧朔庋b的獨(dú)立性和完整性,給原本調(diào)試完成的代碼留下了一個缺口,有可能隨時被干擾,而產(chǎn)生功能的不完整。
假設(shè)我是有償庫函數(shù)的提供者, 那么我自然要對庫的功能完整負(fù)有服務(wù)義務(wù),而這種因?yàn)槌A繑?shù)值變化導(dǎo)致的功能失效,我是沒有臉面來指責(zé)用戶使用不當(dāng)?shù)?。比如我咋樣給自己找理由擺脫責(zé)任呢?你們對我的庫不熟悉, 你們系統(tǒng)里使用了不該用的常量?對方會回答:我們當(dāng)然不熟悉,我們從頭就不打算熟悉,而只想簡單使用。我們?nèi)绻煜ち司妥约鹤隽?,誰稀罕用你的庫! ? ?
這還是在庫函數(shù)并沒有被加密的情況下。如果指望把庫函數(shù)加密,然后不給用戶看到源代碼,用戶只能使用而不能盜用專利技術(shù),那么使用了上述UDT和常量的庫函數(shù)都是幾乎不可能的。因?yàn)橛脩綦S時需要編譯,需要使用密碼打開程序塊。
所以總結(jié):如果這個行業(yè)普遍習(xí)慣于大量使用全局常量數(shù)據(jù)來做所謂的標(biāo)準(zhǔn)化封裝模塊, 那就永遠(yuǎn)不會有成熟穩(wěn)定的庫函數(shù)交易市場。那么所有人,都只能永遠(yuǎn)自己閉門造車,自己做庫自己用。分工與專業(yè)化提高效率就永遠(yuǎn)沒有可能。
有沒有人注意到我在建立FB的時候,圖中,在FB的常量區(qū)還順手建立了一個MAXX的常量?
如果你要使用的常量在這里,我們稱之為局部常量數(shù)據(jù)的話,那是沒有問題的。因?yàn)镕B和FB之間不會發(fā)生沖突,隨便使用都可以。我本文針對的內(nèi)容是全局常量, 而非局部。
然而,恐怕這又是那些習(xí)慣于使用全局常量的同行們所不能接受的。因?yàn)槟愦蟾怕实氖菚诙鄠€FB中公用這一個常量。即,你本來使用常量的目的也是為了在不同模塊之間分享信息。而這恰恰是我著本文提醒你需要更改提升方法的所在。
我當(dāng)然清楚你們的習(xí)慣,以及技能方法。并不是我不知道這種用法,而恰恰是我更清楚這種用法,并非常知曉這種用法的弊端,所以才會提出來主張。
這里也引申出來另一個道理,即一個人, 遇到對自己固有觀念和習(xí)慣有沖擊力的理論和方法的時候,應(yīng)該持有怎樣的態(tài)度。 ? ?
是承認(rèn)自己的未知狀態(tài),遇到的理論方法,哪怕暫時自己還不能接受不能實(shí)現(xiàn),暫時做下記號,留待自己以后有機(jī)會時再圖謀深入了解, 還是第一時間先否定,先找各種理由為自己做法的合理性做辯解,不管是發(fā)出聲來還是自己默默內(nèi)心給自己辯護(hù)?這都體現(xiàn)了一個人的學(xué)習(xí)能力和創(chuàng)新思維能力。對未知事物的拒絕保守態(tài)度,本質(zhì)上是井底之蛙的邏輯。
我曾經(jīng)研究實(shí)現(xiàn)了將LBP庫函數(shù)從S7-1500移植到S7-1200,對其中大量使用的UDT頭痛不已。其整個系統(tǒng)中用到了UDT 共有130多個,而且是互相耦合的,即要使用哪怕只有1個FB, 所有的其它的UDT也必須復(fù)制過來,少一個都不行。所以為了解耦它們,花費(fèi)了許多的精力。
而在LBP中,常量的使用則比較少,只有一個:PANELS_NO=2 。
代表的是這臺PLC通訊的觸摸屏的數(shù)量等于2 。如果下一個項(xiàng)目,觸摸屏數(shù)量為3,則需要把這里的數(shù)值改為3。而在整套庫函數(shù)中, 這個常量到處用到,不管是循環(huán)語句還是數(shù)組定義的上限值,因?yàn)槊恳粋€對象的FB都需要處理觸摸屏通訊數(shù)據(jù),并對觸摸屏之間的操作指令做出互鎖保護(hù)。所以是幾乎沒辦法避免。

我能想到的是,如果真的需要封裝這批函數(shù),就為每一個數(shù)量值分別打包,比如2的時候一個包, 3的時候另一個包。哪怕觸摸屏數(shù)量最多到10, 那也頂多10套。 ? ?
但畢竟,在真實(shí)的行業(yè)應(yīng)用中,觸摸屏的數(shù)量并不會如此多變, 所以暫時,也還只沿用其原有的使用常數(shù)的方法了。
最后再補(bǔ)充一點(diǎn), 在PLC變量表中還有一頁“系統(tǒng)常量”,通常系統(tǒng)會自動生成一大批,程序中可以使用

有可能會有人誤解到我反對用系統(tǒng)常量。關(guān)于系統(tǒng)常量的使用是,你只要不在FB內(nèi)部使用即可。即,你可以使用,但只能把它們當(dāng)作實(shí)參掛到FB實(shí)例的管腳上,但不可以封裝在邏輯內(nèi)部。
其實(shí)我們?nèi)乃磳Φ?,也是把全局常量用到FB邏輯內(nèi)部。
審核編輯:黃飛
電子發(fā)燒友App


































評論