• «
  • 1
  • 2
  • »
  • Pages: 2/2     Go
雪山飞狐
级别: 网络英雄
精华主题: 0
发帖数量: 12881 个
工控威望: 15573 点
下载积分: 42382 分
在线时间: 985(小时)
注册时间: 2019-06-05
最后登录: 2025-03-03
查看雪山飞狐的 主题 / 回贴
12楼  发表于: 70天前
这个要采用中断的方式去做。
本帖最近评分记录:
  • 下载积分:+5(jony7788) 感谢分享!
    xy8896
    级别: 正式会员
    精华主题: 0
    发帖数量: 41 个
    工控威望: 91 点
    下载积分: 5299 分
    在线时间: 42(小时)
    注册时间: 2023-06-23
    最后登录: 2025-03-03
    查看xy8896的 主题 / 回贴
    13楼  发表于: 70天前
    看是何时检查开关信号,如起点检查就简单,运行中检查后一个肯定会有加减速的,感应器用变址写法,程序比较简短
    梦雨天涯
    微信hui530527   &
    级别: 网络英雄
    精华主题: 0
    发帖数量: 4511 个
    工控威望: 7899 点
    下载积分: 16508 分
    在线时间: 3122(小时)
    注册时间: 2016-10-31
    最后登录: 2025-03-03
    查看梦雨天涯的 主题 / 回贴
    14楼  发表于: 70天前
    图片:
    大概这个样子,你觉得呢??
    本帖最近评分记录:
  • 下载积分:+5(jony7788) 感谢分享!
  • 微信hui530527      b站账号,非标自动化谭工
    请不要随意加我,不会随便通过。QQ群942493953
    工控小c
    级别: 工控侠客
    精华主题: 0
    发帖数量: 384 个
    工控威望: 2192 点
    下载积分: 3477 分
    在线时间: 384(小时)
    注册时间: 2022-10-14
    最后登录: 2025-03-03
    查看工控小c的 主题 / 回贴
    15楼  发表于: 70天前
    图片:
    图片:
    图片:
    图片:
    图片:
    我也来凑凑热闹,偷个懒就不写自动程序了,问题的关键就在于计算下一个首先为ON的开关距离本次停留的位置间距而已。如上图1234,开关号和位置号从0开始。开关1.4.10为ON,在1号开始时2.3.不停留下次定位到4、增量为3份间距,4号开始时5.6.7.8.9.不停留下次定位到10、增量为6份间距,10号开始时11.0.不停留下次定位到1,增量为3份间距。如上图5,仅有1号开关ON,则下次定位12份间距既一整圈重新定位到1号开关处。
    本帖最近评分记录:
  • 下载积分:+2(nightblueblu) 好贴好贴!
  • 下载积分:+5(jony7788) 热心助人!
    红云123
    级别: 略有小成
    精华主题: 0
    发帖数量: 311 个
    工控威望: 381 点
    下载积分: 2894 分
    在线时间: 162(小时)
    注册时间: 2020-09-22
    最后登录: 2025-02-28
    查看红云123的 主题 / 回贴
    16楼  发表于: 70天前
    这个能不能实现
    附件: 0000.zip (182 K) 下载次数:23
    网站提示: 请不要用迅雷下载附件,容易出错
    本帖最近评分记录:
  • 下载积分:+5(jony7788) 热心助人!
    jony7788
    级别: 工控侠客
    精华主题: 0
    发帖数量: 50 个
    工控威望: 2003 点
    下载积分: 533 分
    在线时间: 236(小时)
    注册时间: 2023-02-25
    最后登录: 2025-03-03
    查看jony7788的 主题 / 回贴
    17楼  发表于: 70天前
    引用
    引用第14楼梦雨天涯于2024-12-24 15:07发表的  :
    大概这个样子,你觉得呢??


    有点这个意思。
    jony7788
    级别: 工控侠客
    精华主题: 0
    发帖数量: 50 个
    工控威望: 2003 点
    下载积分: 533 分
    在线时间: 236(小时)
    注册时间: 2023-02-25
    最后登录: 2025-03-03
    查看jony7788的 主题 / 回贴
    18楼  发表于: 70天前
    引用
    引用第16楼红云123于2024-12-24 17:05发表的  :
    这个能不能实现


    我目前的方法同你的方法有点类似,用电机的脉冲数来判断区间,效果不是很好,如果前面全部是开,后面全部是断,还可以,间隔开断的反应不过来。
    工控小c
    级别: 工控侠客
    精华主题: 0
    发帖数量: 384 个
    工控威望: 2192 点
    下载积分: 3477 分
    在线时间: 384(小时)
    注册时间: 2022-10-14
    最后登录: 2025-03-03
    查看工控小c的 主题 / 回贴
    19楼  发表于: 70天前
    引用
    引用第18楼jony7788于2024-12-24 21:15发表的  :


    我目前的方法同你的方法有点类似,用电机的脉冲数来判断区间,效果不是很好,如果前面全部是开,后面全部是断,还可以,间隔开断的反应不过来。

    可以试试我的那个,当前点位停留0.5秒的时候直接判断下个点去哪里
    nightblueblu
    道阻且长,穷且益坚。
    级别: 论坛先锋
    精华主题: 0
    发帖数量: 1031 个
    工控威望: 1854 点
    下载积分: 275 分
    在线时间: 1139(小时)
    注册时间: 2017-02-09
    最后登录: 2025-02-24
    查看nightblueblu的 主题 / 回贴
    20楼  发表于: 68天前
    写了一个,没有测试,实现方式和15楼基本一致,上代码
    ----------------------------------------------------------------------------分割线-------------------------------------------------------------
    FUNCTION_BLOCK FB_启动定位
    (*一圈360度,分为12个段点,每个段点30度,每个段点都有一个开关,每个开关可以任意设置ON和OFF状态。
      当开关打开的区间,步进电机以正常速度旋转,并在段点停留0.5秒,
      没有打开段点的区间,以快于正常速度进行旋转,且不做停留*)
    VAR_INPUT      
        Sen1  :BOOL;//位置状态设置1
        Sen2  :BOOL;
        Sen3  :BOOL;
        Sen4  :BOOL;
        Sen5  :BOOL;
        Sen6  :BOOL;
        Sen7  :BOOL;
        Sen8  :BOOL;
        Sen9  :BOOL;
        Sen10:BOOL;
        Sen11:BOOL;
        Sen12:BOOL;//位置状态设置12

        Start          :BOOL;//启动
            Stop          :BOOL;//停止
        Auto          :BOOL;//手自,TRUE:自动;FALSE:手动
        Done         :BOOL;//定位完成信号
        Now_Ang  :REAL;//当前角度
        Tim            :REAL;//TRUE位停顿时间,单位:s
    END_VAR
    VAR_OUTPUT
        rRun_F    :REAL;//快速运行距离(FALSE段角度)
        bRun_F   :BOOL;//快速定位启动(FALSE段)
        rRun_T    :REAL;//正常速度运行距离(TRUE段角度)
        bRun_T   :BOOL;//正常速定位启动(TRUE段)        
    END_VAR
    VAR    
            Pto                  :BOOL;//定位启动信号
        nums:INT        :=12;//位置个数
        Now_posi        :INT;//转盘当前位置
        StatsAry          :ARRAY[1..12]OF BOOL;//各位置检测传感器状态存储数组
        rtri                   :BOOL;//位置计算触发
        i,j                     :INT;//循环变量
        False_Gap      :INT;//距离下一个FALSE信号需要转动的位置个数
        num                     :INT;//定位中的段记录
        rstr,rsto,rdon    :R_TRIG;//启动,停止,转动一个角度的触发沿
        rton                  :TON;//间隔定时
    END_VAR
    ----------------------------------------------------------------------------分割线-------------------------------------------------------------
    (*==============================参数初始化==============================*)
    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;
    (*==============================触发沿==============================*)
    rstr(CLK:=Start);//启动沿
    rsto(CLK:=Stop);//停止沿
    rdon(CLK:=Done);//定位完成沿
    rton(IN:=num=2,PT:=REAL_TO_TIME(Tim*1000.0));//间隔定时

    IF rsto.Q OR (rton.Q AND NOT Auto) THEN//停止或者在手动状态下单次定位结束
        bRun_F:=FALSE;
        bRun_T:=FALSE;
        num:=0;
    END_IF
    IF rdon.Q THEN//对定位次数进行计数
        num:=num+1;
    END_IF
    (*==============================寻找下一次转动的TRUE信号的位置==============================*)
    IF rstr.Q OR (rton.Q AND Auto)THEN//启动计算
        num:=0;
        rtri:=TRUE;
    END_IF
    IF rtri THEN
        IF Now_posi<>nums THEN//TRUE位置在当前位置前方
            FOR i:=Now_posi+1 TO nums BY 1 DO
                IF StatsAry THEN
                    False_Gap:=i-Now_posi-1;//TRUE位置在当前位置前方
                    rRun_F:=rRun_T*False_Gap;    
                    Pto:=TRUE;
                    rtri:=FALSE;
                    EXIT;
                END_IF
            END_FOR
        END_IF
        IF Now_posi<>1 THEN//TRUE位置在当前位置后方
            FOR j:=1 TO Now_posi BY 1 DO
                IF StatsAry[j] THEN
                    False_Gap:=nums-j+Now_posi-1;//TRUE位置在当前位置后方
                    rRun_F:=rRun_T*False_Gap;
                    Pto:=TRUE;
                    rtri:=FALSE;
                    EXIT;
                END_IF
            END_FOR
        END_IF
    END_IF

    (*==============================执行逻辑==============================*)
    IF Pto THEN//启动定位,或自动状态下定时器达到计时
        bRun_T:=FALSE;
        bRun_F:=TRUE;
    END_IF
    IF num=1 THEN//完成FALSE段的定位,进行TRUE段定位
        bRun_F:=FALSE;
        bRun_T:=TRUE;
    END_IF
    本帖最近评分记录:
  • 下载积分:+5(jony7788) 热心助人!
  • Your happiness is everything.
    jony7788
    级别: 工控侠客
    精华主题: 0
    发帖数量: 50 个
    工控威望: 2003 点
    下载积分: 533 分
    在线时间: 236(小时)
    注册时间: 2023-02-25
    最后登录: 2025-03-03
    查看jony7788的 主题 / 回贴
    21楼  发表于: 9天前
    请豆包帮忙写的,调整几次之后,可以正常运行,用的是Arduino板子,豆包写梯形图的能力还不强,写这种编程语言厉害些。
    // 定义步进电机控制引脚
    const int stepPin = 2;
    const int dirPin = 3;

    // 定义启动按键引脚
    const int startButtonPin = 4;

    // 定义 12 个开关引脚
    const int switchPins[12] = {5, 6, 7, 8, 9, 10, 11, 12, 13, A0, A1, A2};

    // 定义原点感应点位引脚
    const int originPin = A3;

    // 定义料件感应点位引脚
    const int materialSensorPin = A4;

    // 定义振动盘点位引脚
    const int vibrationDiskPin = A5;

    // 定义步进电机参数
    const int stepsPerRevolution = 1000;  // 步进电机每转脉冲数

    // 定义速度参数(毫秒)
    const unsigned long normalSpeedDelay = 1;  // 正常速度延迟
    const unsigned long fastSpeedDelay = 0.2;  // 快速速度延迟
    const unsigned long returnSpeedDelay = 0.5; // 返回原点速度延迟

    // 定义停留时间(毫秒)
    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() {
      // 初始化步进电机控制引脚为输出模式
      pinMode(stepPin, OUTPUT);
      pinMode(dirPin, OUTPUT);

      // 初始化启动按键引脚为输入模式,并启用上拉电阻
      pinMode(startButtonPin, INPUT_PULLUP);

      // 初始化 12 个开关引脚为输入模式,并启用上拉电阻
      for (int i = 0; i < 12; i++) {
        pinMode(switchPins, INPUT_PULLUP);
      }

      // 初始化原点感应点位引脚为输入模式,并启用上拉电阻
      pinMode(originPin, INPUT_PULLUP);

      // 初始化料件感应点位引脚为输入模式,并启用上拉电阻
      pinMode(materialSensorPin, INPUT_PULLUP);

      // 初始化振动盘点位引脚为输出模式
      pinMode(vibrationDiskPin, OUTPUT);

      // 设置初始方向
      digitalWrite(dirPin, HIGH);
    }

    void loop() {
      // 读取启动按键状态
      startButtonState = digitalRead(startButtonPin);

      // 检测启动按键按下事件
      if (startButtonState == LOW && lastStartButtonState == HIGH) {
        isRunning = true;
        currentSegment = 0;
        remainingSteps = stepsPerRevolution;
        isReturning = false;
      }

      // 保存上一次启动按键状态
      lastStartButtonState = startButtonState;

      // 控制振动盘
      bool materialDetected = digitalRead(materialSensorPin) == LOW;
      digitalWrite(vibrationDiskPin, !materialDetected);

      // 如果电机正在运行
      if (isRunning) {
        if (isReturning) {
          unsigned long currentTime = millis();
          if (currentTime - lastStepTime >= returnSpeedDelay) {
            digitalWrite(dirPin, LOW); // 设置返回方向
            digitalWrite(stepPin, HIGH);
            delayMicroseconds(10);  // 确保脉冲宽度
            digitalWrite(stepPin, LOW);
            lastStepTime = currentTime;

            if (digitalRead(originPin) == LOW) {
              isRunning = false;
              isReturning = false;
              digitalWrite(dirPin, HIGH); // 恢复正向
            }
          }
        } 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 负载
      delay(1);
    }
    wujie2163
    级别: 探索解密
    精华主题: 0
    发帖数量: 89 个
    工控威望: 121 点
    下载积分: 613 分
    在线时间: 26(小时)
    注册时间: 2020-11-10
    最后登录: 2025-03-03
    查看wujie2163的 主题 / 回贴
    22楼  发表于: 12小时前
    速度快了步进电机停有办法这么精准的停下来么??不需要用刹车么??
    • «
    • 1
    • 2
    • »
    • Pages: 2/2     Go