最近网络环境一般化,一直安装不了Python相关的库。今天下午突然就人品爆棚,几次失败后终于成功安装了相关库:
小楊是在线安装的,命令如下:
python -m pip install --user numpy scipy matplotlib ipython jupyter pandas sympy nose
安装完Python后想起了前两天想拟合SHARP的GP2Y0A21YK0F红外测距传感器输出信号与距离的曲线关系,所以,动手咯!
前两天的文档可以先阅览一下,好理解下面的正文。相关文档链接如下:
1、数据采集并绘制曲线:
实测数据绘制图形与数据手册对比
代码:
import numpy as np
import matplotlib.pyplot as plt
from scipy import optimize
x=np.arange(0,81,5)
y=np.array([0,3.1, 2.25, 1.62, 1.32, 1.13,0.91,0.79, 0.75, 0.68,0.62, 0.57,0.55, 0.49, 0.43,0.41,0.40])
plt.plot(x,y)
plt.show()
观察发现在传感器的有效测距范围10-80cm内,曲线与反比例函数接近。
2、拟合曲线
接下来截取有效测距范围内的数据,通过Python的scipy库中optimize提供的一个专门用于曲线拟合的函数curve_fit()进行曲线拟合:
得到:
a = 15.231176863349042
b = 0.35759398578213786
代码如下:
#构建函数y=a*(1/x)+b
#使用optimize.curve_fit函数求出a、b的值
import numpy as np
import matplotlib.pyplot as plt
from scipy import optimize
def f_x(x, a, b):
return a*(1/x)+b
plt.figure()
#拟合点
x=np.arange(5,81,5)
y=np.array([3.1, 2.25, 1.62, 1.32, 1.13,0.91,0.79, 0.75, 0.68,0.62, 0.57,0.55, 0.49, 0.43,0.41,0.40])
#绘制散点
plt.scatter(x[:], y[:], 30, "red")
#直线拟合与绘制
a, b = optimize.curve_fit(f_x, x, y)[0]
print(a)
print(b)
y1 = a*(1/x)+b
plt.plot(x, y1, "blue")
plt.title("HeGuang Studios")
plt.xlabel('X:cm')
plt.ylabel('Y:v')
plt.show()
通过上以上数据得到y与x关系如下:
y = 15.231176863349042/x + 0.35759398578213786;
3、拟合结果验证:
结合单片机验证拟合结果是否可行:
代码如下:
// Visual Micro is in vMicro>General>Tutorial Mode
//
/*
Name: CeShi.ino
Created: 2018/8/13 21:03:35
Author: 禾灮\HeGuang
*/
void setup() {
Serial.begin(9600);
pinMode(14,INPUT);
delay(45);
}
void loop() {
float val = 5*analogRead(14)/1024.0;
long i = 1/((val - 0.35759398578213786)/15.231176863349042);
Serial.print("Y(v):");
Serial.println(val);
Serial.print("X(cm):");
Serial.println(i);
Serial.println("*******************");
delay(5000);
}
数据还是有误差的,曲线拟合图中就可以看出。
import numpy as np
import matplotlib.pyplot as plt
from scipy import optimize
x=np.arange(0,81,5)
y=np.array([0,3.1, 2.25, 1.62, 1.32, 1.13,0.91,0.79, 0.75, 0.68,0.62, 0.57,0.55, 0.49, 0.43,0.41,0.40])
plt.plot(x,y)
#构建函数y=a*(1/x)+b+c*x
#使用optimize.curve_fit函数求出a、b、c的值
def f_x(x, a, b, c):
return a*(1/x)+b+c*x
plt.figure()
#拟合点
x=np.arange(5,81,5)
y=np.array([3.1, 2.25, 1.62, 1.32, 1.13,0.91,0.79, 0.75, 0.68,0.62, 0.57,0.55, 0.49, 0.43,0.41,0.40])
#绘制散点
plt.scatter(x[:], y[:], 30, "red")
#直线拟合与绘制
a, b, c = optimize.curve_fit(f_x, x, y)[0]
print(a)
print(b)
print(c)
y1 = a*(1/x)+b+c*x
plt.plot(x, y1, "blue")
plt.title("HeGuang Studios")
plt.xlabel('X:cm')
plt.ylabel('Y:v')
plt.show()
得到:
a = 11.95996602305133
b = 0.8757100690367675
c = -0.00893829688786056
void loop() {
float y = 5.0*analogRead(14)/1024.0;
float a = 11.95996602305133;
float b = 0.8757100690367675;
float c = -0.00893829688786056;
float D = pow((y - b),2)-4*a*c;
//float x1 = ((y - b) + sqrt(D))/(2*c);
float x2 =((y - b) - sqrt(D))/(2*c);
Serial.print("Y(v):");
Serial.println(y);
//Serial.print("X1(cm):");
//Serial.println(x1);
Serial.print("X(cm):");
Serial.println(x2);
Serial.println("*******************");
delay(5000);
}
感谢一直关注着禾灮成长进步的朋友们。你们的信任、支持和鼓励,鞭策着我们一路走到了今天。
感谢所有的合作伙伴,我们相互促进,共同见证了彼此的成长。
感谢所有曾经在禾灮彼此倚靠、相互鼓励、携手同心、砥砺同行的兄弟姐妹。这里承载了我们的青春与热血。
禾灮,感谢有你。
未来,我们将一如既往,砥砺前行。
禾灮·小楊
2018.08.13