用变频电机带动连杆卷布匹,如何保持每次停止的长度不.....
用变频电机带动连杆卷布匹,布匹大概60厘米宽,51米长,开头定死在连杆上,然后一点一点的旋转把布匹卷起来,中间每隔60厘米长停一下,每次停止的长度固定都是60厘米,我现在使用编码器每隔10MS读取数据,判断长度,然后每隔50MS进行一次PID处理,控制电流输出去驱动变频器,用变频器驱动电机,发现跑起来转个10圈左右长度就短一点,跑完51米停止的长度会有四个梯次,每个梯次比上一个梯次要短1厘米左右,不知道那位高手遇到过这种情况,望指点,谢谢 本帖最后由 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
变频器接编码器
外面接的编码器,编码器上有个转盘,是放在布匹上的,跑一圈是300MM,谢谢 先判断编码器是否丢数,然后在解决 本帖最后由 _yuming 于 2015-8-2 19:32 编辑
你的编码器是不是装在布匹主轴上了,这样的话那你就不会获得准确的长度,想要获取准确的长度,不但是需要编码器的计数,还要知道布匹每一层的周长,因为每增加一层,每层的周长就会增加,这个是必须要考虑的,
如果你的编码器不是装在主轴上,而是安装在主轴之外单独的一个轴上,此轴只做计数只用,这样就会准确。
给你个草图看一下。。
_yuming 发表于 2015-8-2 19:19
你的编码器是不是装在布匹主轴上了,这样的话那你就不会获得准确的长度,想要获取准确的长度,不但是需要编 ...
这个编码器没有装载主轴上,主轴如你说的要考虑布匹厚度,所以没有装,我把编码器装在外面的,压在布匹上,布匹从编码器轮和一个固定的轴中间通过,转动的时候就如我上面说的那样了,会有梯次,但每个梯次中停止的又比较精确,谢谢你的回复 本帖最后由 _yuming 于 2015-8-2 19:36 编辑
ersha4877 发表于 2015-8-2 19:30
这个编码器没有装载主轴上,主轴如你说的要考虑布匹厚度,所以没有装,我把编码器装在外面的,压在布匹上 ...
你一定要保证计数轴与布匹没有打滑。一定要保证张力足够才可以。。。检测要用中断完成,不能用查询的方法。。还要考虑编码器的溢出计数。。。编码器上要安装一个与布匹等宽的光轴,而不是一个轮,要考虑轴的周长。。 _yuming 发表于 2015-8-2 19:34
你一定要保证计数轴与布匹没有打滑。一定要保证张力足够才可以。。。检测要用中断完成,不能用查询的方法 ...
谢谢了,张力还真没有考虑,请问如何保证张力,布匹输出端和布匹输入端都用变频电机吗? 编码器上要安装一个与布匹等宽的光轴,而不是一个轮,要考虑轴的周长。。这个什么意思啊,谢谢 跑一圈是300MM?如果是布匹在轴上连续缠若干圈,那么开头是300MM,后面应该比300MM大,多圈累计下来就产生了明显误差 本帖最后由 _yuming 于 2015-8-2 19:49 编辑
ersha4877 发表于 2015-8-2 19:40
编码器上要安装一个与布匹等宽的光轴,而不是一个轮,要考虑轴的周长。。这个什么意思啊,谢谢 ...
给你个草图看一下。。所谓的张力就是要保证布与轴要有足够的摩擦力。。所谓的周长就是轴转一圈对应的计数,做除法后得到每一个脉冲的长度。。。 bailao99 发表于 2015-8-2 19:45
跑一圈是300MM?如果是布匹在轴上连续缠若干圈,那么开头是300MM,后面应该比300MM大,多圈累计下来就产生 ...
是的,所以在布匹上面放了个编码器,每隔50MS采集一次进行PID的处理,来降低速度,谢谢回复 _yuming 发表于 2015-8-2 19:47
给你个草图看一下。。所谓的张力就是要保证布与轴要有足够的摩擦力。。所谓的周长就是轴转一圈对应的计 ...
谢谢,兄弟辛苦了 ersha4877 发表于 2015-8-2 20:08
是的,所以在布匹上面放了个编码器,每隔50MS采集一次进行PID的处理,来降低速度,谢谢回复 ...
PID 用于 变频器调速,但是 距离要用 编码器计数才准确啊 Vmao 发表于 2015-8-2 20:29
PID 用于 变频器调速,但是 距离要用 编码器计数才准确啊
是的,这个编码器还用于计数的。谢谢 在编码器棍上加条压轮增加计数准确度。 cl1cl1cl1cl1 发表于 2015-8-2 20:48
在编码器棍上加条压轮增加计数准确度。
谢谢,到时试试 你这个控制电流恒定,就是电机的输出力矩是恒定的,但是布匹的转经是变化的,这会导致布匹的张力不恒定,正确的方法是把布匹的转经考虑进去,电机的电流是递增的,这样才能保证力矩恒定;你也可以在机械上做改动,好像有一种计米器,自带张紧装置,可以保证力矩恒定。 本帖最后由 ersha4877 于 2015-8-2 22:49 编辑
mtswz.213 发表于 2015-8-2 22:01
你这个控制电流恒定,就是电机的输出力矩是恒定的,但是布匹的转经是变化的,这会导致布匹的张力不恒定,正 ...
谢谢了,我这个应该是递减的吧,毕竟布匹越厚,速度越慢,布匹的转经是什么?
我看到的复卷机上有张力控制,可以分别调节放卷和收卷的张力,具体怎么实现的不清楚,反正看到很多转轴。你搜一下“复卷机张力控制”。 控制张力可以用磁粉刹车。 你这变量取的名字真是长 xuehu5808 发表于 2015-8-2 23:49
控制张力可以用磁粉刹车。
谢谢到时考虑下 iskywolf 发表于 2015-8-2 23:16
我看到的复卷机上有张力控制,可以分别调节放卷和收卷的张力,具体怎么实现的不清楚,反正看到很多转轴。你 ...
谢谢提示,回头找找 恒张力收卷 LZ还是考虑使用复卷系统(收放卷) 你也可以用带收放卷的变频器,类似于拉丝机,我上面说的其实就是你把收放卷的一部分功能自己做进去了 谢谢楼上各位,好象是编码器读到的数据进行了平移滤波了,所以这样,今天测试去掉了,好象好了,明天在去试试。 在帘布上每隔60cm打两排孔(一排一个,一排两个),测到一排一个开始减速,测到一排两个就停。 rainbow 发表于 2015-8-3 17:11
在帘布上每隔60cm打两排孔(一排一个,一排两个),测到一排一个开始减速,测到一排两个就停。 ...
谢谢,这个不能打孔的 你用变频器加编码器,变频器与单片机隔离了?信号线要加屏敝。 即墨丰禾 发表于 2015-8-3 20:16
你用变频器加编码器,变频器与单片机隔离了?信号线要加屏敝。
编码器用光偶隔离了,变频器没有,直接输出4---20MA的电流 我以前搞纺织设备的时候,卷布和送经轴是用步进电机或伺服电机控制的,比用变频电机好控制一些。布的张力和速度控制起来仍然是很难办的事情,尤其是停车痕问题。
页:
[1]