旋转质量轮实验对象上的传感器

一款手头的旧自动控制课程实验平台,对其进行分析和改造,为以后作为实验对象做准备。
 

01实验台简介


1.基本尺寸

旋转质量轮的结构如下图所示。黄铜的旋转质量轮的基本尺寸为:

  • 直径:100mm
  • 厚度:13.16mm

▲ 旋转质量轮实验装置

▲ 旋转质量轮实验装置

实验平台上的附件:

2.平台上的电子附件

1. 电机

2. 光电编码盘
质量轮通过左侧的齿轮带动光电码盘传感器,输出脉冲代表角度的变化。
光电码盘的接口如下图所示:

▲ 编码盘的位置和接口

▲ 编码盘的位置和接口

通过四芯扁平电缆将光电码盘引出。对应的接口定义如下:

序号 符号 功能
1 +5V 工作电源(白色标记点)
2 GND 工作底线
3 CHB 脉冲B相位
4 GHA 脉冲A相位

▲ 引出光电传感器接口信号功能定义

▲ 引出光电传感器接口信号功能定义

实际测量光电编码盘的信号。可以看信号的幅值以及CHA,CHB的相位关系。
▲ 晃动平台引起角度输出

▲ 晃动平台引起角度输出

▲ 接口输出的A、B两项的脉冲

▲ 接口输出的A、B两项的脉冲

通过逐步调制光电编码盘的工作电压,实验证明它的工作电压范围是:3.0V~5V.

02传感器控制电路1,2:


1.原理图

▲ 实验电路板

▲ 实验电路板

2.印刷电路板

▲ 实验电路PCB

▲ 实验电路PCB

3.底层固件命令

在INT0中断服务程序对输入的脉冲,按照极性进行计数。

//==============================================================================
#if INT0_EN
//------------------------------------------------------------------------------
void Int0ISR(void) interrupt 0 
{
    g_ucInt0Count ++;
    if(VAL(PULPOL)) g_nPulseCount ++;
    else g_nPulseCount --;
}
#endif // INT0_EN

通过设置IPH:bit0-bit1=3,设置INT0的中端级别为3,最高级别。

#if INT0_EN
    IT0 = 1;                                // 1 : Down edge; 0:Up and Down 
    EX0 = 1;
    IPH |= 3;                               // 3:The most signficant interrupt
    g_ucInt0Count = 0;
#endif //  INT0_EN

增加串口命令 SAMPLE,发送采集到的波形信息。

else IFARG0("sample") {
    g_nPulseCount = 0;
    sscanf(SDA(1), "%d", &nNumber);
    sscanf(SDA(2), "%d", &nPeriod);
    Base64ASCIIInit();
    for(i = 0; i < nNumber; i ++) {
        nCount = g_nPulseCount;
        Base64ASCIIPushByte((unsigned char)(nCount >> 8));
        Base64ASCIIPushByte(nCount);
        WaitTime(nPeriod);
    }
    Base64ASCIIFlushBuffer();
}

03振荡实验


1.实验过程

触动质量转盘,使其振动,然后通过命令采集每个2ms的数据,供10秒钟,观察波形,并且求取波形的参数。

在此过程中,铜盘质量块保持不旋转。

▲ 振荡质量块

▲ 振荡质量块

下面是截取的的角度振荡波形。

▲ 采集到的角度震荡曲线

▲ 采集到的角度震荡曲线

下面是将波形动态放大显示的结果。

▲ 放大后的振荡波形

▲ 放大后的振荡波形

pltgif = PlotGIF()
datalen = len(data)
curvelen = 500
steps = 50
steplen = int((datalen - curvelen) / steps)
for i in range(steps):
    startn = i * steplen
    endn = startn + curvelen
    plt.clf()
    plt.plot(ts[startn:endn], data[startn:endn], label='Angle')
    plt.xlabel("time(s)")
    plt.ylabel("Angle")
    plt.axis([startn*tss, endn*tss, -70, 70])
    plt.grid(True)
    plt.legend(loc="upper right")
    plt.draw()
    plt.pause(.1)
    pltgif.append(plt)
pltgif.save(r'd:\temp\1.gif')

2.数据处理

使用scipy.optimize中的curve_fit函数,对采集到的角度数据进行拟合,拟合的函数为:

f ( t ) = a exp ( t b ) sin ( 2 π m t + n ) + c f\left( t \right) = a \cdot \exp \left( {{{ - t} \over b}} \right) \cdot \sin \left( {2\pi \cdot m \cdot t + n} \right) + c

通过手工观察选择数据中的哪一段进行拟合。下面是进行拟合后的结果以及相应的参数:

▲ 拟合后的角度波形

▲ 拟合后的角度波形

a=-69.585734,b=1.372189,c=-0.804440,m=10.225953,n=-1.197423

其中正弦振荡的频率大约是:10.226Hz,振荡衰减的时间常数为1.372秒。

from scipy.optimize         import curve_fit
ts, data = tspload('sample', 'ts', 'data')
#------------------------------------------------------------
def func(x, a,b,c, m, n):
    return a * exp(-x/b) * sin(m * x * 2 * pi + n) + c
#------------------------------------------------------------
startn = 400
endn = 2500
drawlen = endn - startn
tss = 0.002
tdim = linspace(0, tss * drawlen, drawlen, endpoint=False)
param = [60,2,0, 10, 0]
param, conv = curve_fit(func, tdim, data[startn:endn], p0=param)
printf(param)

3.铜盘旋转采集的数据

(1)DC电机驱动电压:11.05V:

测量结果:
a=-65.042275,b=0.740667,c=2.096617,m=3.883897,n=0.897357
▲ 直流电机在11.05V电压下驱动铜盘旋转测量的结果

▲ 直流电机在11.05V电压下驱动铜盘旋转测量的结果

(2)DC电机驱动电压:6.18V:

测量参数:
a=-53.486541,b=1.618489,c=1.716874,m=4.840321,n=0.234798
▲ 直流电机在6.18V电压下驱动铜盘旋转测量的结果

▲ 直流电机在6.18V电压下驱动铜盘旋转测量的结果

(3)DC电机驱动电压:4.1V:

a=-49.869159,b=2.296448,c=-0.302789,m=5.070985,n=1.710855
▲ 直流电机在4.1V电压下驱动铜盘旋转测量的结果

▲ 直流电机在4.1V电压下驱动铜盘旋转测量的结果

4.对比不同的转速下振荡曲线参数

在电机不同的转速下,角度振荡参数以及衰减参数如下:

驱动电压 B M
0 1.372 10.223
4.1 2.3 5.07
6.18 1.62 4.84
11.05 0.74 3.884C

简单分析:

  • 转速对于衰减并没有太大的规律;
  • 转速降低了振荡的频率;这应该符合某种力学上的规律。

5.处理程序

#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST1.PY                     -- by Dr. ZhuoQing 2020-06-08
#
# Note:
#============================================================
from headm import *
import base64ascii
from tsmodule.tsstm32       import *
#------------------------------------------------------------
stm32cmd('CLEAR')
stm32cmd('sample 5000 1')
val = stm32val()[10]
while True:
    time.sleep(.2)
    valnew = stm32val()[10]
    if valnew == val: break
    val = valnew
time.sleep(2)
stm32cmd('COPY')
time.sleep(.2)
str = bytes(clipboard.paste(), 'utf-8')
printf(str)
data = base64ascii.Base64Ascii2Data(str)
printf(data)
ts = 0.002
datalen = len(data)
t = linspace(0, ts*datalen, datalen)
tspsave('sample', ts=t, data=data)
plt.plot(t, data, label='Angle')
plt.xlabel("Sample")
plt.ylabel("Angle")
plt.grid(True)
plt.legend(loc="upper right")
plt.show()
#------------------------------------------------------------
#        END OF FILE : TEST1.PY
#============================================================
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# BASE64ASCII.PY               -- by Dr. ZhuoQing 2020-06-08
#
# Note:
#============================================================
from head import *
def Base64Ascii2Bit(ascii):
    ascii = int(ascii)
    if ascii >= ord('A') and ascii <= ord('Z'): return ascii - ord('A')
    if ascii >= ord('a') and ascii <= ord('z'): return ascii - ord('a') + 26
    if ascii >= ord('0') and ascii <= ord('9'): return ascii - ord('0') + 52
    if ascii == ord('*'): return 62
    if ascii == ord('/'): return 63
    return 0
def Base64Ascii2Byte(fourb):
    data = bytearray()
    bits0 = Base64Ascii2Bit(fourb[0])
    bits1 = Base64Ascii2Bit(fourb[1])
    bits2 = Base64Ascii2Bit(fourb[2])
    bits3 = Base64Ascii2Bit(fourb[3])
    data.append(bits0 * 4 + int(bits1 / 16))
    data.append((bits1 & 0xf) * 16 + int(bits2 / 4))
    data.append((bits2 & 0x3) * 64 + bits3)
    if fourb[2] == ord('=') and fourb[3] == ord('='):
        data = data[0:1]
        return data
    if fourb[3] == ord('='):
        return data[0:2]
    return data
def Base64Ascii2Data(ascii):
    data = bytearray()
    length = len(ascii)
    for i in range(int(length / 4)):
        bytedata = Base64Ascii2Byte(ascii[i*4:i*4+4])
        if len(bytedata) > 0:
            data.extend(bytedata)
    valdim = [x*256+y for x,y in zip(data[0::2], data[1::2])]
    valdim = [(d & 0x7fff) - (d & 0x8000) for d in valdim]
    return valdim
#------------------------------------------------------------
#        END OF FILE : BASE64ASCII.PY
#============================================================

■ 结论


转动质量平台,提供了可以测量的角度传感器以及旋转质量块驱动直流电机。基于此实验平台,可以对物体旋转对于谐振系统的影响进行研究。

后面需要改进的成分包括:

  • 由于角度输出编码器为正交码,所以建议使用STM32的正交编码器来读取对应的角度信息。使用C51会出现角度平移的情况;
  • 增加对质量块转速测量,便于获得更加精确的转速关系。

  1. 实验AD工程文件:AD\Test\2020\TesetBoard\TestG8Count.SchDoc ↩︎

  2. C51工程文件:C51\STC\Test\2020\TestRotateCopperPlate\TestRot8G.uvproj ↩︎

猜你喜欢

转载自blog.csdn.net/zhuoqingjoking97298/article/details/106623007