一款手头的旧自动控制课程实验平台,对其进行分析和改造,为以后作为实验对象做准备。
01实验台简介
1.基本尺寸
旋转质量轮的结构如下图所示。黄铜的旋转质量轮的基本尺寸为:
- 直径:100mm
- 厚度:13.16mm
▲ 旋转质量轮实验装置
实验平台上的附件:
2.平台上的电子附件
1. 电机
- 型号:Faulharber 2842S012C. 3606 Made in Germany
Faulhaber 网络资料
2. 光电编码盘
质量轮通过左侧的齿轮带动光电码盘传感器,输出脉冲代表角度的变化。
光电码盘的接口如下图所示:
▲ 编码盘的位置和接口
通过四芯扁平电缆将光电码盘引出。对应的接口定义如下:
序号 | 符号 | 功能 |
---|---|---|
1 | +5V | 工作电源(白色标记点) |
2 | GND | 工作底线 |
3 | CHB | 脉冲B相位 |
4 | GHA | 脉冲A相位 |
▲ 引出光电传感器接口信号功能定义
实际测量光电编码盘的信号。可以看信号的幅值以及CHA,CHB的相位关系。
▲ 晃动平台引起角度输出
▲ 接口输出的A、B两项的脉冲
通过逐步调制光电编码盘的工作电压,实验证明它的工作电压范围是:3.0V~5V.
02传感器控制电路1,2:
1.原理图
▲ 实验电路板
2.印刷电路板
▲ 实验电路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函数,对采集到的角度数据进行拟合,拟合的函数为:
通过手工观察选择数据中的哪一段进行拟合。下面是进行拟合后的结果以及相应的参数:
▲ 拟合后的角度波形
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电压下驱动铜盘旋转测量的结果
(2)DC电机驱动电压:6.18V:
测量参数:
a=-53.486541,b=1.618489,c=1.716874,m=4.840321,n=0.234798
▲ 直流电机在6.18V电压下驱动铜盘旋转测量的结果
(3)DC电机驱动电压:4.1V:
a=-49.869159,b=2.296448,c=-0.302789,m=5.070985,n=1.710855
▲ 直流电机在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会出现角度平移的情况;
- 增加对质量块转速测量,便于获得更加精确的转速关系。