雪山飛狐
級(jí)別: 網(wǎng)絡(luò)英雄
![]() |
這個(gè)要采用中斷的方式去做。 |
---|---|
本帖最近評(píng)分記錄: |
xy8896
級(jí)別: 正式會(huì)員
![]() |
看是何時(shí)檢查開(kāi)關(guān)信號(hào),如起點(diǎn)檢查就簡(jiǎn)單,運(yùn)行中檢查后一個(gè)肯定會(huì)有加減速的,感應(yīng)器用變址寫(xiě)法,程序比較簡(jiǎn)短 |
---|---|
|
夢(mèng)雨天涯
微信hui530527 &
級(jí)別: 網(wǎng)絡(luò)英雄
![]() |
圖片:
![]() 大概這個(gè)樣子,你覺(jué)得呢?? |
|
---|---|---|
本帖最近評(píng)分記錄:
|
工控小c
級(jí)別: 工控俠客
![]() |
圖片:
![]()
圖片:
![]()
圖片:
![]()
圖片:
![]()
圖片:
![]() 我也來(lái)湊湊熱鬧,偷個(gè)懶就不寫(xiě)自動(dòng)程序了,問(wèn)題的關(guān)鍵就在于計(jì)算下一個(gè)首先為ON的開(kāi)關(guān)距離本次停留的位置間距而已。如上圖1234,開(kāi)關(guān)號(hào)和位置號(hào)從0開(kāi)始。開(kāi)關(guān)1.4.10為ON,在1號(hào)開(kāi)始時(shí)2.3.不停留下次定位到4、增量為3份間距,4號(hào)開(kāi)始時(shí)5.6.7.8.9.不停留下次定位到10、增量為6份間距,10號(hào)開(kāi)始時(shí)11.0.不停留下次定位到1,增量為3份間距。如上圖5,僅有1號(hào)開(kāi)關(guān)ON,則下次定位12份間距既一整圈重新定位到1號(hào)開(kāi)關(guān)處。 |
---|---|
本帖最近評(píng)分記錄: |
紅云123
級(jí)別: 略有小成
![]() |
這個(gè)能不能實(shí)現(xiàn) |
---|---|
本帖最近評(píng)分記錄: |
jony7788
級(jí)別: 工控俠客
![]() |
有點(diǎn)這個(gè)意思。 |
---|---|
|
jony7788
級(jí)別: 工控俠客
![]() |
我目前的方法同你的方法有點(diǎn)類似,用電機(jī)的脈沖數(shù)來(lái)判斷區(qū)間,效果不是很好,如果前面全部是開(kāi),后面全部是斷,還可以,間隔開(kāi)斷的反應(yīng)不過(guò)來(lái)。 |
---|---|
|
工控小c
級(jí)別: 工控俠客
![]() |
可以試試我的那個(gè),當(dāng)前點(diǎn)位停留0.5秒的時(shí)候直接判斷下個(gè)點(diǎn)去哪里 |
---|---|
|
nightblueblu
道阻且長(zhǎng),窮且益堅(jiān)。
級(jí)別: 論壇先鋒
![]() |
寫(xiě)了一個(gè),沒(méi)有測(cè)試,實(shí)現(xiàn)方式和15樓基本一致,上代碼 ----------------------------------------------------------------------------分割線------------------------------------------------------------- FUNCTION_BLOCK FB_啟動(dòng)定位 (*一圈360度,分為12個(gè)段點(diǎn),每個(gè)段點(diǎn)30度,每個(gè)段點(diǎn)都有一個(gè)開(kāi)關(guān),每個(gè)開(kāi)關(guān)可以任意設(shè)置ON和OFF狀態(tài)。 當(dāng)開(kāi)關(guān)打開(kāi)的區(qū)間,步進(jìn)電機(jī)以正常速度旋轉(zhuǎn),并在段點(diǎn)停留0.5秒, 沒(méi)有打開(kāi)段點(diǎn)的區(qū)間,以快于正常速度進(jìn)行旋轉(zhuǎn),且不做停留*) VAR_INPUT Sen1 :BOOL;//位置狀態(tài)設(shè)置1 Sen2 :BOOL; Sen3 :BOOL; Sen4 :BOOL; Sen5 :BOOL; Sen6 :BOOL; Sen7 :BOOL; Sen8 :BOOL; Sen9 :BOOL; Sen10:BOOL; Sen11:BOOL; Sen12:BOOL;//位置狀態(tài)設(shè)置12 Start :BOOL;//啟動(dòng) Stop :BOOL;//停止 Auto :BOOL;//手自,TRUE:自動(dòng);FALSE:手動(dòng) Done :BOOL;//定位完成信號(hào) Now_Ang :REAL;//當(dāng)前角度 Tim :REAL;//TRUE位停頓時(shí)間,單位:s END_VAR VAR_OUTPUT rRun_F :REAL;//快速運(yùn)行距離(FALSE段角度) bRun_F :BOOL;//快速定位啟動(dòng)(FALSE段) rRun_T :REAL;//正常速度運(yùn)行距離(TRUE段角度) bRun_T :BOOL;//正常速定位啟動(dòng)(TRUE段) END_VAR VAR Pto :BOOL;//定位啟動(dòng)信號(hào) nums:INT :=12;//位置個(gè)數(shù) Now_posi :INT;//轉(zhuǎn)盤(pán)當(dāng)前位置 StatsAry :ARRAY[1..12]OF BOOL;//各位置檢測(cè)傳感器狀態(tài)存儲(chǔ)數(shù)組 rtri :BOOL;//位置計(jì)算觸發(fā) i,j :INT;//循環(huán)變量 False_Gap :INT;//距離下一個(gè)FALSE信號(hào)需要轉(zhuǎn)動(dòng)的位置個(gè)數(shù) num :INT;//定位中的段記錄 rstr,rsto,rdon :R_TRIG;//啟動(dòng),停止,轉(zhuǎn)動(dòng)一個(gè)角度的觸發(fā)沿 rton :TON;//間隔定時(shí) END_VAR ----------------------------------------------------------------------------分割線------------------------------------------------------------- (*==============================參數(shù)初始化==============================*) StatsAry[1]:=Sen1;StatsAry[2]:=Sen2;StatsAry[3]:=Sen3;StatsAry[4]:=Sen4;StatsAry[5]:=Sen5;StatsAry[6]:=Sen6; StatsAry[7]:=Sen7;StatsAry[8]:=Sen8;StatsAry[9]:=Sen9;StatsAry[10]:=Sen10;StatsAry[11]:=Sen11;StatsAry[12]:=Sen12; rRun_T:=(2*3.14159265)/nums; Now_posi:=REAL_TO_INT((Now_Ang*nums)/(2*3.14159265))+1; (*==============================觸發(fā)沿==============================*) rstr(CLK:=Start);//啟動(dòng)沿 rsto(CLK:=Stop);//停止沿 rdon(CLK:=Done);//定位完成沿 rton(IN:=num=2,PT:=REAL_TO_TIME(Tim*1000.0));//間隔定時(shí) IF rsto.Q OR (rton.Q AND NOT Auto) THEN//停止或者在手動(dòng)狀態(tài)下單次定位結(jié)束 bRun_F:=FALSE; bRun_T:=FALSE; num:=0; END_IF IF rdon.Q THEN//對(duì)定位次數(shù)進(jìn)行計(jì)數(shù) num:=num+1; END_IF (*==============================尋找下一次轉(zhuǎn)動(dòng)的TRUE信號(hào)的位置==============================*) IF rstr.Q OR (rton.Q AND Auto)THEN//啟動(dòng)計(jì)算 num:=0; rtri:=TRUE; END_IF IF rtri THEN IF Now_posi<>nums THEN//TRUE位置在當(dāng)前位置前方 FOR i:=Now_posi+1 TO nums BY 1 DO IF StatsAry THEN False_Gap:=i-Now_posi-1;//TRUE位置在當(dāng)前位置前方 rRun_F:=rRun_T*False_Gap; Pto:=TRUE; rtri:=FALSE; EXIT; END_IF END_FOR END_IF IF Now_posi<>1 THEN//TRUE位置在當(dāng)前位置后方 FOR j:=1 TO Now_posi BY 1 DO IF StatsAry[j] THEN False_Gap:=nums-j+Now_posi-1;//TRUE位置在當(dāng)前位置后方 rRun_F:=rRun_T*False_Gap; Pto:=TRUE; rtri:=FALSE; EXIT; END_IF END_FOR END_IF END_IF (*==============================執(zhí)行邏輯==============================*) IF Pto THEN//啟動(dòng)定位,或自動(dòng)狀態(tài)下定時(shí)器達(dá)到計(jì)時(shí) bRun_T:=FALSE; bRun_F:=TRUE; END_IF IF num=1 THEN//完成FALSE段的定位,進(jìn)行TRUE段定位 bRun_F:=FALSE; bRun_T:=TRUE; END_IF |
|
---|---|---|
本帖最近評(píng)分記錄:
|
jony7788
級(jí)別: 工控俠客
![]() |
請(qǐng)豆包幫忙寫(xiě)的,調(diào)整幾次之后,可以正常運(yùn)行,用的是Arduino板子,豆包寫(xiě)梯形圖的能力還不強(qiáng),寫(xiě)這種編程語(yǔ)言厲害些。 // 定義步進(jìn)電機(jī)控制引腳 const int stepPin = 2; const int dirPin = 3; // 定義啟動(dòng)按鍵引腳 const int startButtonPin = 4; // 定義 12 個(gè)開(kāi)關(guān)引腳 const int switchPins[12] = {5, 6, 7, 8, 9, 10, 11, 12, 13, A0, A1, A2}; // 定義原點(diǎn)感應(yīng)點(diǎn)位引腳 const int originPin = A3; // 定義料件感應(yīng)點(diǎn)位引腳 const int materialSensorPin = A4; // 定義振動(dòng)盤(pán)點(diǎn)位引腳 const int vibrationDiskPin = A5; // 定義步進(jìn)電機(jī)參數(shù) const int stepsPerRevolution = 1000; // 步進(jìn)電機(jī)每轉(zhuǎn)脈沖數(shù) // 定義速度參數(shù)(毫秒) const unsigned long normalSpeedDelay = 1; // 正常速度延遲 const unsigned long fastSpeedDelay = 0.2; // 快速速度延遲 const unsigned long returnSpeedDelay = 0.5; // 返回原點(diǎn)速度延遲 // 定義停留時(shí)間(毫秒) const unsigned long pauseTime = 500; // 定義變量 bool startButtonState = false; bool lastStartButtonState = false; bool isRunning = false; bool isReturning = false; int currentSegment = 0; int remainingSteps = stepsPerRevolution; unsigned long lastStepTime = 0; unsigned long lastPauseTime = 0; bool isPausing = false; void setup() { // 初始化步進(jìn)電機(jī)控制引腳為輸出模式 pinMode(stepPin, OUTPUT); pinMode(dirPin, OUTPUT); // 初始化啟動(dòng)按鍵引腳為輸入模式,并啟用上拉電阻 pinMode(startButtonPin, INPUT_PULLUP); // 初始化 12 個(gè)開(kāi)關(guān)引腳為輸入模式,并啟用上拉電阻 for (int i = 0; i < 12; i++) { pinMode(switchPins, INPUT_PULLUP); } // 初始化原點(diǎn)感應(yīng)點(diǎn)位引腳為輸入模式,并啟用上拉電阻 pinMode(originPin, INPUT_PULLUP); // 初始化料件感應(yīng)點(diǎn)位引腳為輸入模式,并啟用上拉電阻 pinMode(materialSensorPin, INPUT_PULLUP); // 初始化振動(dòng)盤(pán)點(diǎn)位引腳為輸出模式 pinMode(vibrationDiskPin, OUTPUT); // 設(shè)置初始方向 digitalWrite(dirPin, HIGH); } void loop() { // 讀取啟動(dòng)按鍵狀態(tài) startButtonState = digitalRead(startButtonPin); // 檢測(cè)啟動(dòng)按鍵按下事件 if (startButtonState == LOW && lastStartButtonState == HIGH) { isRunning = true; currentSegment = 0; remainingSteps = stepsPerRevolution; isReturning = false; } // 保存上一次啟動(dòng)按鍵狀態(tài) lastStartButtonState = startButtonState; // 控制振動(dòng)盤(pán) bool materialDetected = digitalRead(materialSensorPin) == LOW; digitalWrite(vibrationDiskPin, !materialDetected); // 如果電機(jī)正在運(yùn)行 if (isRunning) { if (isReturning) { unsigned long currentTime = millis(); if (currentTime - lastStepTime >= returnSpeedDelay) { digitalWrite(dirPin, LOW); // 設(shè)置返回方向 digitalWrite(stepPin, HIGH); delayMicroseconds(10); // 確保脈沖寬度 digitalWrite(stepPin, LOW); lastStepTime = currentTime; if (digitalRead(originPin) == LOW) { isRunning = false; isReturning = false; digitalWrite(dirPin, HIGH); // 恢復(fù)正向 } } } else { if (isPausing) { if (millis() - lastPauseTime >= pauseTime) { isPausing = false; } } else { unsigned long currentTime = millis(); bool switchState = digitalRead(switchPins[currentSegment]); unsigned long speedDelay = switchState ? normalSpeedDelay : fastSpeedDelay; if (currentTime - lastStepTime >= speedDelay) { if (remainingSteps > 0) { digitalWrite(stepPin, HIGH); delayMicroseconds(10); // 確保脈沖寬度 digitalWrite(stepPin, LOW); remainingSteps--; lastStepTime = currentTime; } if (remainingSteps * 12 <= (11 - currentSegment) * stepsPerRevolution) { if (switchState) { isPausing = true; lastPauseTime = currentTime; } currentSegment++; } if (currentSegment >= 12) { isReturning = true; } } } } } // 短暫延遲以減少 CPU 負(fù)載 delay(1); } |
---|---|
|