ersha4877 发表于 2015-8-2 18:09:11

用变频电机带动连杆卷布匹,如何保持每次停止的长度不.....

用变频电机带动连杆卷布匹,布匹大概60厘米宽,51米长,开头定死在连杆上,然后一点一点的旋转把布匹卷起来,中间每隔60厘米长停一下,每次停止的长度固定都是60厘米,我现在使用编码器每隔10MS读取数据,判断长度,然后每隔50MS进行一次PID处理,控制电流输出去驱动变频器,用变频器驱动电机,发现跑起来转个10圈左右长度就短一点,跑完51米停止的长度会有四个梯次,每个梯次比上一个梯次要短1厘米左右,不知道那位高手遇到过这种情况,望指点,谢谢

ersha4877 发表于 2015-8-2 18:11:09

本帖最后由 ersha4877 于 2015-8-2 18:17 编辑

这是编码器部分的代码
#include <stdbool.h>
#include "EncoderProcess.h"
#include "encoder.h"
#include"mainprocess.h"
#include "startrun.h"
#include"yout.h"
#include"tlc5615.h"

//
//换向器不吸合延时寄存器
//
unsigned longg_ulCommutatorNoPullTimeDelay=20;
unsigned longg_ulTempCommutatorNoPullTimeDelay=0;

//
//换向器吸合延时寄存器 2s
//
unsigned longg_ulCommutatorPullTimeDelay=20;
unsigned longg_ulTempCommutatorPullTimeDelay=0;

//
//控制板输出雕刻机控制信号时间延时2s
//
unsigned longg_ulEngravingMachineStartRealyOutPutTimeDelay=20;
unsigned longg_ulTempEngravingMachineStartRealyOutPutTimeDelay=0;

//
//用于运行时降低运行速度的TLC5615 数组计数器
//
extern unsigned int g_uiTLC5615RunOut;

//
//系统设置总共的编码器数据,转轮周长300MM,2933是55CM
//
unsigned longg_ulAllEncoderData=2933;//3500;

//
//用于计算100毫秒时间的PID计算的编码器数据的定时器
//
unsigned long g_ulEvery100MSPIDReadEncoderDataTime=0;


//
//通用参数
//
tSaveParametersg_sParameters;

//
//保存用参数
//
tSaveParameters*g_psSaveParameters;

//
extern tRunParameters   g_bRunParameters;
//extern tEncoderTimParameters   g_sEncoderTimParameters;
extern tRunInputParameters   g_bRunInputParameters;

//
//通用参数
//
extern tSpeedBitParametersg_sSpeedParameters;

//系统采集时时数据
extern floatSystemRealData;
//------------------------------------------------
//
//对读取的基准编码器数据平移滤波处理
//
//------------------------------------------------
void DatumEncoderDataProcess(unsigned long ulDatumSpeedReadEncoderData)
{
    unsigned long ulDatumEncoderSpeed;       
       
          unsigned char ucCount;
       
          //
    //基准速度编码器数据计算后的平均数据
    //
    unsigned long ulAverageDatumSpeedEncoderData;               

                       
                //
                //滑动平移,先进先出
                //                       
//                g_sParameters.g_ulDatumSpeedReadEncoderData=g_sParameters.g_ulDatumSpeedReadEncoderData;
//                g_sParameters.g_ulDatumSpeedReadEncoderData=g_sParameters.g_ulDatumSpeedReadEncoderData;               
//                g_sParameters.g_ulDatumSpeedReadEncoderData=g_sParameters.g_ulDatumSpeedReadEncoderData;
//                g_sParameters.g_ulDatumSpeedReadEncoderData=g_sParameters.g_ulDatumSpeedReadEncoderData;
//             g_sParameters.g_ulDatumSpeedReadEncoderData=g_sParameters.g_ulDatumSpeedReadEncoderData;
//                g_sParameters.g_ulDatumSpeedReadEncoderData=g_sParameters.g_ulDatumSpeedReadEncoderData;
                g_sParameters.g_ulDatumSpeedReadEncoderData=g_sParameters.g_ulDatumSpeedReadEncoderData;
                g_sParameters.g_ulDatumSpeedReadEncoderData=g_sParameters.g_ulDatumSpeedReadEncoderData;
                g_sParameters.g_ulDatumSpeedReadEncoderData=g_sParameters.g_ulDatumSpeedReadEncoderData;
               
                //
                //将最新的数据放入数组最后一位,先进先出
                //
                g_sParameters.g_ulDatumSpeedReadEncoderData=ulDatumSpeedReadEncoderData;
       
                //
                //数据相加
                //
                ulDatumEncoderSpeed=0;
                for(ucCount=0;ucCount<4;ucCount++)
                        {
                                        //
                                        //数据垒加
                                        //                               
                                        ulDatumEncoderSpeed=ulDatumEncoderSpeed+g_sParameters.g_ulDatumSpeedReadEncoderData;
                        }       
                       
                        //
                        //取平均值
                        //
                        ulAverageDatumSpeedEncoderData=ulDatumEncoderSpeed/4;
                       
                        //
                        //编码器数据计算后得到的数据相加的总数据
                        //
                        g_sParameters.g_ulCurrentDatumSpeedEncoderData=g_sParameters.g_ulCurrentDatumSpeedEncoderData + ulAverageDatumSpeedEncoderData;               
      
                      //
                     //读取的编码器数据达到了需要的数据,停止运行
                     //
                     if(g_sParameters.g_ulCurrentDatumSpeedEncoderData>=g_ulAllEncoderData)       
                          {
                                          //
                                          //关定时器5
                                          //
                                          TIM_Cmd(TIM5, DISABLE);   //关定时器5
                                       
                                          //
                                          //
                                          //
                                       // g_sParameters.g_ulDatumQuanData++;
                                       
                                          //
                                          //本次数据采集完成,计算出这次跑多余的编码器数据
                                          //
//                                          g_sParameters.g_ulCurrentDatumSpeedEncoderData=        g_sParameters.g_ulCurrentDatumSpeedEncoderData ;//- g_ulAllEncoderData;                                       
                                          //
                                          //数据直接清除,下次从新开始
                                          //
                                          g_sParameters.g_ulCurrentDatumSpeedEncoderData=0;

                                         //
                                        //关闭电流输出,变频器停止运行
                                        //
                                        g_bRunParameters.bits.bAmpStop =1;
                                               
                                      //
                                    //电流不输出
                                    //               
                                    WriteTlc5615Data(0);       
            
                                     //
                                    //刹车输出
                                  //
                                   g_bRunParameters.bits.bBrakesOutPut=1;
                                               
                                //
                                //刹车输出
                                 //
                                 g_YOutPut.bits.YO11=1;

                              //
                              //刹车输出
                              //
                              OutputDataProcess();
                                       
                             //
                              //布匹已经到达指定位置,后面要让雕刻机正常雕刻
                              //用于开机时判断当前的雕刻机的运行情况,是停止等待布匹进入,还是在雕刻中
                              //
                             g_sParameters.g_sSaveBitParameters.bits.bEngravingMachineStatus=1;                                       
                                       
                             //
                             //换向器不在吸合,
                             //
                           g_bRunParameters.bits.bCommutatorPullOrNo=0;
                               
                          //
                          //数据清除
                          //
                          g_ulEvery100MSPIDReadEncoderDataTime=0;
                                               
                          //
                          //换向器不在吸合延时开始
                          //
                            g_bRunParameters.bits.bCommutatorNoPullTimeDelayStart=1;                                       
                           //g_ulTempCommutatorNoPullTimeDelay=0;
                          }                               
}

//----------------------------------------------
//
//PID需要的数据进行计算
//
//----------------------------------------------
void PidDataProcess(unsigned long ulPIDDatumSpeedReadEncoderData)
{
    unsigned long ulPIDDatumEncoderSpeed;       
       
   unsigned char ucCount;
       
    //
    //基准速度编码器数据计算后的平均数据
    //
//    unsigned long ulAveragePIDDatumSpeedEncoderData;               

                //
                //滑动平移,先进先出
                //                       
//                g_sParameters.g_ulDatumSpeedReadEncoderData=g_sParameters.g_ulDatumSpeedReadEncoderData;
//                g_sParameters.g_ulDatumSpeedReadEncoderData=g_sParameters.g_ulDatumSpeedReadEncoderData;               
//                g_sParameters.g_ulDatumSpeedReadEncoderData=g_sParameters.g_ulDatumSpeedReadEncoderData;
//                g_sParameters.g_ulDatumSpeedReadEncoderData=g_sParameters.g_ulDatumSpeedReadEncoderData;
//              g_sParameters.g_ulDatumSpeedReadEncoderData=g_sParameters.g_ulDatumSpeedReadEncoderData;
//                g_sParameters.g_ulDatumSpeedReadEncoderData=g_sParameters.g_ulDatumSpeedReadEncoderData;
                g_sParameters.g_ulPIDDatumSpeedReadEncoderData=g_sParameters.g_ulPIDDatumSpeedReadEncoderData;
                g_sParameters.g_ulPIDDatumSpeedReadEncoderData=g_sParameters.g_ulPIDDatumSpeedReadEncoderData;
                g_sParameters.g_ulPIDDatumSpeedReadEncoderData=g_sParameters.g_ulPIDDatumSpeedReadEncoderData;
               
                //
                //将最新的数据放入数组最后一位,先进先出
                //
                g_sParameters.g_ulPIDDatumSpeedReadEncoderData=ulPIDDatumSpeedReadEncoderData;
       
                //
                //数据相加
                //
                ulPIDDatumEncoderSpeed=0;
                for(ucCount=0;ucCount<4;ucCount++)
                        {
                                        //
                                        //数据垒加
                                        //                               
                                        ulPIDDatumEncoderSpeed=ulPIDDatumEncoderSpeed+g_sParameters.g_ulPIDDatumSpeedReadEncoderData;
                        }       
                       
                        //
                        //取平均值,将计算出的数据付值给PID计算数据
                        //
                        SystemRealData=ulPIDDatumEncoderSpeed/4;
                       
                        //
                        //将计算出的数据付值给PID计算数据
                        //
                        //SystemRealData=ulAveragePIDDatumSpeedEncoderData;
                       
                        //
                        //进行PID计算
                        //
                        g_uiTLC5615RunOut = PID_Cal();
}
                                  
//-----------------------------------------------
//
//读取编码器的值
//
//-----------------------------------------------
void EncoderReadDataProcess(void)
{
    unsigned long ulDatumSpeedReadEncoderDataTemp;
    unsigned long ulPIDDatumSpeedReadEncoderDataTemp;   
                //
                //启动
                //
                if(g_bRunInputParameters.bits.bStart ==1)                       
               {
                                        //
                                        //编码器数据获取
                                        //
                                       g_sParameters.g_ulNowDatumSpeedEncoderData +=TIM5_ENC_Get_Electrical_Angle();
          
                                        //
                                        //对采集的数据进行处理,数据不相等,还在运行中
                                        //
                                        if(g_sParameters.g_ulNowDatumSpeedEncoderData != g_sParameters.g_ulLastDatumSpeedEncoderData)
                                                {
                                                                //
                                                                //数据超出了
                                                                //
                                                                if(g_sParameters.g_ulNowDatumSpeedEncoderData>10000000)
                                                                        {
                                                                                  if(g_sParameters.g_ulNowDatumSpeedEncoderData>=g_sParameters.g_ulLastDatumSpeedEncoderData)
                                                                                          {
                                                                                                                //
                                                                                                                //计算这次采集的数据
                                                                                                                //
                                                                                                                ulDatumSpeedReadEncoderDataTemp=g_sParameters.g_ulNowDatumSpeedEncoderData-g_sParameters.g_ulLastDatumSpeedEncoderData;

                                                                                                                //数据从新开始,以这次的采集数据为开始
                                                                                                                g_sParameters.g_ulNowDatumSpeedEncoderData=ulDatumSpeedReadEncoderDataTemp;
                                                                                                                //上次的数据值初始值1000
                                                                                                                g_sParameters.g_ulLastDatumSpeedEncoderData=3000;
                                                                                                                g_sParameters.g_ulNowDatumSpeedEncoderData=g_sParameters.g_ulNowDatumSpeedEncoderData+3000;

                                                                                                                //
                                                                                                                //计算出PID用的编码器数据
                                                                                                                //
                                                                                                                g_sParameters.g_ulLastPIDDatumSpeedEncoderData =10000000 - g_sParameters.g_ulLastPIDDatumSpeedEncoderData;
                            g_sParameters.g_ulLastPIDDatumSpeedEncoderData =3000 - g_sParameters.g_ulLastPIDDatumSpeedEncoderData ;
                                                                                                       
                                                                                                                //
                                                                                                                //滤波平滑处理
                                                                                                                //
                                                                                                                DatumEncoderDataProcess(ulDatumSpeedReadEncoderDataTemp);
                                                                                       }
                                                                        }
                                                                else
                                                                        {
                                                                                  if(g_sParameters.g_ulNowDatumSpeedEncoderData>=g_sParameters.g_ulLastDatumSpeedEncoderData)
                                                                                          {
                                                                                                                //
                                                                                                                //计算这次采集的数据
                                                                                                                //
                                                                                                                ulDatumSpeedReadEncoderDataTemp=g_sParameters.g_ulNowDatumSpeedEncoderData-g_sParameters.g_ulLastDatumSpeedEncoderData;
                                       
                                                                                                                //保存这次的采集数据,作为下次使用
                                                                                                                g_sParameters.g_ulLastDatumSpeedEncoderData=g_sParameters.g_ulNowDatumSpeedEncoderData;                               
                                                                               
                                                                                                                //
                                                                                                                //滤波平滑处理
                                                                                                                //
                                                                                                                DatumEncoderDataProcess(ulDatumSpeedReadEncoderDataTemp);
                                                                                                }
                                                                        }
                                                }

                                        //
                                        //电流输出,变频器运行
                                        //
                                        if(g_bRunParameters.bits.bAmpStop ==0)
                                                {
                                                                        //
                                                                        //定时器计数每10MS进行一次计数,每50MS 进行一次PID处理
                                                                        //
                                                                        g_ulEvery100MSPIDReadEncoderDataTime++;
                                                                        if(g_ulEvery100MSPIDReadEncoderDataTime>=5) //50ms
                                                                                {                                                       
                                                                                                //
                                                                                                //数据清除
                                                                                                //
                                                                                                g_ulEvery100MSPIDReadEncoderDataTime=0;

                                                                                          //
                                                                                          //数据不相等,说明已经在转动
                                                                                          //
                                                                                          if(g_sParameters.g_ulNowDatumSpeedEncoderData>g_sParameters.g_ulLastPIDDatumSpeedEncoderData)
                                                                                                   {
                                                                                                                        //
                                                                                                                        //计算出着次PID计算用的编码器数据
                                                                                                                        //
                                                                                                                        ulPIDDatumSpeedReadEncoderDataTemp = g_sParameters.g_ulNowDatumSpeedEncoderData-g_sParameters.g_ulLastPIDDatumSpeedEncoderData;
                                       
                                                                                                                        //
                                                                                                                        //保存这次的数据
                                                                                                                        //       
                                                                                                                        g_sParameters.g_ulLastPIDDatumSpeedEncoderData = g_sParameters.g_ulNowDatumSpeedEncoderData;                               

                                                                                                                        //
                                                                                                                        //PID需要的数据进行计算
                                                                                                                        //
                                                                                                                        PidDataProcess(ulPIDDatumSpeedReadEncoderDataTemp);
                                                                                                  }
                                                                        }       
                                       }                                                                       
                        }
}


kafeiwutang 发表于 2015-8-2 18:27:22

变频器接编码器

ersha4877 发表于 2015-8-2 18:33:12

kafeiwutang 发表于 2015-8-2 18:27
变频器接编码器

外面接的编码器,编码器上有个转盘,是放在布匹上的,跑一圈是300MM,谢谢

Vmao 发表于 2015-8-2 19:02:36

先判断编码器是否丢数,然后在解决

_yuming 发表于 2015-8-2 19:19:47

本帖最后由 _yuming 于 2015-8-2 19:32 编辑

你的编码器是不是装在布匹主轴上了,这样的话那你就不会获得准确的长度,想要获取准确的长度,不但是需要编码器的计数,还要知道布匹每一层的周长,因为每增加一层,每层的周长就会增加,这个是必须要考虑的,

如果你的编码器不是装在主轴上,而是安装在主轴之外单独的一个轴上,此轴只做计数只用,这样就会准确。

给你个草图看一下。。

ersha4877 发表于 2015-8-2 19:30:11

_yuming 发表于 2015-8-2 19:19
你的编码器是不是装在布匹主轴上了,这样的话那你就不会获得准确的长度,想要获取准确的长度,不但是需要编 ...

这个编码器没有装载主轴上,主轴如你说的要考虑布匹厚度,所以没有装,我把编码器装在外面的,压在布匹上,布匹从编码器轮和一个固定的轴中间通过,转动的时候就如我上面说的那样了,会有梯次,但每个梯次中停止的又比较精确,谢谢你的回复

_yuming 发表于 2015-8-2 19:34:55

本帖最后由 _yuming 于 2015-8-2 19:36 编辑

ersha4877 发表于 2015-8-2 19:30
这个编码器没有装载主轴上,主轴如你说的要考虑布匹厚度,所以没有装,我把编码器装在外面的,压在布匹上 ...

你一定要保证计数轴与布匹没有打滑。一定要保证张力足够才可以。。。检测要用中断完成,不能用查询的方法。。还要考虑编码器的溢出计数。。。编码器上要安装一个与布匹等宽的光轴,而不是一个轮,要考虑轴的周长。。

ersha4877 发表于 2015-8-2 19:38:00

_yuming 发表于 2015-8-2 19:34
你一定要保证计数轴与布匹没有打滑。一定要保证张力足够才可以。。。检测要用中断完成,不能用查询的方法 ...

谢谢了,张力还真没有考虑,请问如何保证张力,布匹输出端和布匹输入端都用变频电机吗?

ersha4877 发表于 2015-8-2 19:40:49

编码器上要安装一个与布匹等宽的光轴,而不是一个轮,要考虑轴的周长。。这个什么意思啊,谢谢

bailao99 发表于 2015-8-2 19:45:36

跑一圈是300MM?如果是布匹在轴上连续缠若干圈,那么开头是300MM,后面应该比300MM大,多圈累计下来就产生了明显误差

_yuming 发表于 2015-8-2 19:47:40

本帖最后由 _yuming 于 2015-8-2 19:49 编辑

ersha4877 发表于 2015-8-2 19:40
编码器上要安装一个与布匹等宽的光轴,而不是一个轮,要考虑轴的周长。。这个什么意思啊,谢谢 ...


给你个草图看一下。。所谓的张力就是要保证布与轴要有足够的摩擦力。。所谓的周长就是轴转一圈对应的计数,做除法后得到每一个脉冲的长度。。。

ersha4877 发表于 2015-8-2 20:08:37

bailao99 发表于 2015-8-2 19:45
跑一圈是300MM?如果是布匹在轴上连续缠若干圈,那么开头是300MM,后面应该比300MM大,多圈累计下来就产生 ...

是的,所以在布匹上面放了个编码器,每隔50MS采集一次进行PID的处理,来降低速度,谢谢回复

ersha4877 发表于 2015-8-2 20:12:04

_yuming 发表于 2015-8-2 19:47
给你个草图看一下。。所谓的张力就是要保证布与轴要有足够的摩擦力。。所谓的周长就是轴转一圈对应的计 ...

谢谢,兄弟辛苦了

Vmao 发表于 2015-8-2 20:29:29

ersha4877 发表于 2015-8-2 20:08
是的,所以在布匹上面放了个编码器,每隔50MS采集一次进行PID的处理,来降低速度,谢谢回复 ...

PID 用于 变频器调速,但是 距离要用 编码器计数才准确啊

ersha4877 发表于 2015-8-2 20:33:19

Vmao 发表于 2015-8-2 20:29
PID 用于 变频器调速,但是 距离要用 编码器计数才准确啊

是的,这个编码器还用于计数的。谢谢

cl1cl1cl1cl1 发表于 2015-8-2 20:48:01

在编码器棍上加条压轮增加计数准确度。

ersha4877 发表于 2015-8-2 21:06:25

cl1cl1cl1cl1 发表于 2015-8-2 20:48
在编码器棍上加条压轮增加计数准确度。

谢谢,到时试试

mtswz.213 发表于 2015-8-2 22:01:13

你这个控制电流恒定,就是电机的输出力矩是恒定的,但是布匹的转经是变化的,这会导致布匹的张力不恒定,正确的方法是把布匹的转经考虑进去,电机的电流是递增的,这样才能保证力矩恒定;你也可以在机械上做改动,好像有一种计米器,自带张紧装置,可以保证力矩恒定。

ersha4877 发表于 2015-8-2 22:46:18

本帖最后由 ersha4877 于 2015-8-2 22:49 编辑

mtswz.213 发表于 2015-8-2 22:01
你这个控制电流恒定,就是电机的输出力矩是恒定的,但是布匹的转经是变化的,这会导致布匹的张力不恒定,正 ...

谢谢了,我这个应该是递减的吧,毕竟布匹越厚,速度越慢,布匹的转经是什么?

iskywolf 发表于 2015-8-2 23:16:44

我看到的复卷机上有张力控制,可以分别调节放卷和收卷的张力,具体怎么实现的不清楚,反正看到很多转轴。你搜一下“复卷机张力控制”。

xuehu5808 发表于 2015-8-2 23:49:44

控制张力可以用磁粉刹车。

elecfun 发表于 2015-8-3 01:38:45

你这变量取的名字真是长

ersha4877 发表于 2015-8-3 06:09:08

xuehu5808 发表于 2015-8-2 23:49
控制张力可以用磁粉刹车。

谢谢到时考虑下

ersha4877 发表于 2015-8-3 06:10:32

iskywolf 发表于 2015-8-2 23:16
我看到的复卷机上有张力控制,可以分别调节放卷和收卷的张力,具体怎么实现的不清楚,反正看到很多转轴。你 ...

谢谢提示,回头找找

Flyback 发表于 2015-8-3 08:36:20

恒张力收卷      

RobotRD 发表于 2015-8-3 08:59:01

LZ还是考虑使用复卷系统(收放卷)

mtswz.213 发表于 2015-8-3 12:27:57

你也可以用带收放卷的变频器,类似于拉丝机,我上面说的其实就是你把收放卷的一部分功能自己做进去了

ersha4877 发表于 2015-8-3 16:25:39

谢谢楼上各位,好象是编码器读到的数据进行了平移滤波了,所以这样,今天测试去掉了,好象好了,明天在去试试。

rainbow 发表于 2015-8-3 17:11:31

在帘布上每隔60cm打两排孔(一排一个,一排两个),测到一排一个开始减速,测到一排两个就停。

ersha4877 发表于 2015-8-3 18:29:13

rainbow 发表于 2015-8-3 17:11
在帘布上每隔60cm打两排孔(一排一个,一排两个),测到一排一个开始减速,测到一排两个就停。 ...

谢谢,这个不能打孔的

即墨丰禾 发表于 2015-8-3 20:16:57

你用变频器加编码器,变频器与单片机隔离了?信号线要加屏敝。

ersha4877 发表于 2015-8-3 20:18:31

即墨丰禾 发表于 2015-8-3 20:16
你用变频器加编码器,变频器与单片机隔离了?信号线要加屏敝。

编码器用光偶隔离了,变频器没有,直接输出4---20MA的电流

CCS 发表于 2015-8-4 09:21:10

我以前搞纺织设备的时候,卷布和送经轴是用步进电机或伺服电机控制的,比用变频电机好控制一些。布的张力和速度控制起来仍然是很难办的事情,尤其是停车痕问题。
页: [1]
查看完整版本: 用变频电机带动连杆卷布匹,如何保持每次停止的长度不.....