分类目录其他作料

卡尔曼滤波算法实现

    卡尔曼滤波(Kalman filtering)是一种利用线性系统状态方程,通过系统输入输出观测数据,对系统状态进行最优估计的算法。由于观测数据中包括系统中的噪声和干扰的影响,所以最优估计也可看作是滤波过程。
    数据滤波是去除噪声还原真实数据的一种数据处理技术,Kalman滤波在测量方差已知的情况下能够从一系列存在测量噪声的数据中,估计动态系统的状态。(百度百科)
    实际应用中,我们陀螺仪实验的时候,会发现获取的数值抖动太大,不够平滑;这样的数值在应用时会导致很多问题,因此需要通过一定的算法将数值转换的更平滑。如下采集数据:
105.87231557, 108.0076993, 85.64052734, 84.23328308, 124.71488794, 102.91086635, 96.6229862, 93.07739765, 98.52594135, 111.79610743, 94.78393208, 105.27301268, 87.23224952, 89.71036819, 117.43724425, 64.70525616, 75.48832499, 91.99249324, 105.44355624, 84.93538347
    上面的数据是获取的陀螺仪Roll方向20次样本数据,可见数值波动很大,如84都124,89到117等。下面我们将尝试卡尔曼算法,实现数值降噪滤波。
代码示例:

#!/usr/bin/env python
#coding:utf-8

'''
from JiuJiang
树莓酱的操作实例
https:://www.suhmeijiang.com
'''
import matplotlib.pyplot as plt

#滤波类
class kalman_filter:
    def __init__(self,Q,R):
        self.Q = Q
        self.R = R

        self.P_k_k1 = 1
        self.Kg = 0
        self.P_k1_k1 = 1
        self.x_k_k1 = 0
        self.ADC_OLD_Value = 0
        self.Z_k = 0
        self.kalman_adc_old=0

    def kalman(self,ADC_Value):

        self.Z_k = ADC_Value

        if (abs(self.kalman_adc_old-ADC_Value)>=60):
            self.x_k1_k1= ADC_Value*0.382 + self.kalman_adc_old*0.618
        else:
            self.x_k1_k1 = self.kalman_adc_old;

        self.x_k_k1 = self.x_k1_k1
        self.P_k_k1 = self.P_k1_k1 + self.Q
        self.Kg = self.P_k_k1/(self.P_k_k1 + self.R)

        kalman_adc = self.x_k_k1 + self.Kg * (self.Z_k - self.kalman_adc_old)
        self.P_k1_k1 = (1 - self.Kg)*self.P_k_k1
        self.P_k_k1 = self.P_k1_k1

        self.kalman_adc_old = kalman_adc

        return kalman_adc

if __name__ == '__main__':
    kalman_filter =  kalman_filter(0.001,0.1)

    #陀螺仪测试数据
    test_array = [105.87231557, 108.0076993, 85.64052734, 84.23328308, 124.71488794, 102.91086635, 96.6229862, 93.07739765, 98.52594135, 111.79610743, 94.78393208, 105.27301268, 87.23224952, 89.71036819, 117.43724425, 64.70525616, 75.48832499, 91.99249324, 105.44355624, 84.93538347, 105.87231557, 108.0076993, 85.64052734, 84.23328308, 124.71488794, 102.91086635, 96.6229862, 93.07739765, 98.52594135, 111.79610743, 94.78393208, 105.27301268, 87.23224952, 89.71036819, 117.43724425, 64.70525616, 75.48832499, 91.99249324, 105.44355624, 84.93538347]

    print(test_array)
    n = len(test_array)

    #卡尔曼过滤
    new_array=[]
    for i in range(n):
        new_array.append(int(kalman_filter.kalman(test_array[i])))

    #滤波后数据
    print(new_array)

    #图形生成展示
    plt.plot(new_array)
    plt.plot(test_array)
    plt.show()
效果如图:
执行效果
    上图可见,我们通过vnc进入可视化桌面,然后命令行执行程序文件,左侧是输出的数据;右侧是图表化滤波数据和原值数据,蓝色是滤波后数据,黄色是原值数据。可见,滤波后数据变的平滑很多。
    算法部分来源于大神文章:https://blog.csdn.net/moge19/article/details/82531119
    图形化展示部分,使用的是matplotlib,Python的2D绘图库;系统默认是没有安装的,需要自己安装,由于默认安装的matplotlib版本执行一直有问题,所以安装时指定了版本:

pip install matplotlib==2.0.2
    安装后执行如果报问题:Couldn't find foreign struct converter for 'cairo.Context',那么执行如下命令:

 sudo apt-get install python-gi-cairo
其他滤波算法,还没尝试,如果有兴趣可以试一下:十种滤波算法的Python实现。

树莓派自制散热装置

    树莓派长时间启动运行时,会发现发热很严重;尤其是单板子放在桌子或其他物品上时,经常因为紧挨物品而无法很好散热;所以想了下自己弄了一个较好的散热装置用作参考。
    用到的物品如下:
材料:
(1)树莓派3b+;
(2)散热小风扇;
(3)散热铜柱10个(数量可自己调整);
(4)M3螺帽8个;
(5)M3*20螺丝两个;
(6)长度65雪糕片一个;
组装过程:
(1)两个铜柱组合,组个四组,目的提高离地间隙(根据自己需要);
(2)用螺丝组合雪糕片和散热小风扇;
(3)树莓派四个小孔扩大,此处用的直径4mm的钻头;
(4)组合好的铜柱分别安装到树莓派的四个孔,用作支撑角;效果如下:
(5)将组合好的散热小风扇,安装到树莓派尾部(TF卡端);
(6)小风扇的电源线连接树莓派,黑线接GND,红线接5V;
(7)树莓派开机,可见散热小风扇开始转动,给树莓派降温;
(8)组装完成,效果如下:
组装效果

键盘控制云台方向实验

    摄像头云台买了很久,今天才想起来尝试一下;时间有限,初步尝试用键盘操作一下云台四个方向操作;其中ad控制左右转动,ws控制前后转动;驱动板用的是pca9685。
    其中舵机驱动采用的是adafruit-circuitpython-pca9685,可以参考以前的文章:https://www.shumeijiang.com/2021/08/29/舵机的新驱动方式
组合效果:
代码示例:

#coding:utf-8

'''
from JiuJiang
树莓酱的操作实例
https:://www.shumeijiang.com
'''

import time
from board import SCL, SDA
import busio

from adafruit_pca9685 import PCA9685
from adafruit_motor import servo

#引入i2c
i2c = busio.I2C(SCL, SDA)

#实例化 此处是0x41 驱动板地址修改过导致
pca = PCA9685(i2c, address=0x40)  #地址可以修改  默认0x40
pca.frequency = 40

#左右
servo_0 = servo.Servo(pca.channels[0])
servo_0.set_pulse_width_range(min_pulse=500, max_pulse=2500)
base_0 = 60

#前后
servo_1 = servo.Servo(pca.channels[1])
servo_1.set_pulse_width_range(min_pulse=500, max_pulse=2500)
base_1 = 80

while True:
    code = input('方向是?')
    angle_n = 10
    if base_0+angle_n >= 180:
        continue
    if base_1+angle_n >= 180:
        continue
    if base_0 <= angle_n:
        continue
    if base_1 <= angle_n:
        continue

    if code == 'a':
        base_0 = base_0 - angle_n
    elif code == 'd':
        base_0 = base_0 + angle_n
    elif code == 'w':
        base_1 = base_1 + angle_n
    elif code == 's':
        base_1 = base_1 - angle_n

    servo_0.angle = base_0
    servo_1.angle = base_1
    time.sleep(0.2)
pca.deinit()
执行效果:

树莓派尝试web.py

    web.py是Python的web框架,它简单而且功能强大。它安装后启动服务,然后通过url和端口访问服务内容;下面将简单尝试一下,更多的内容可以参考官网内容:https://webpy.org/docs/0.3/
首先安装服务,可以采用pip安装,这边用的是Python3版本;

pip3 install web.py
模块安装后,启动服务,首先新建jiujiang.py,然后录入如下代码;

#!/usr/bin/env python
#coding:utf-8

'''
from JiuJiang
树莓酱的操作实例
https:://www.suhmeijiang.com
'''

#模块引入
import web

#路由规则定义
urls = (
    '/index/(.*)', 'index',
    '/jiujiang/(.*)', 'jiujiang'
)
app = web.application(urls, globals())

class index:
    def GET(self, name):
        if not name:
            name = 'World'
        return 'Hello, ' + name + '!'
#定义处理类
class jiujiang:
    def GET(self, data):
        return 'jiujiang test '+ data

#服务启动
if __name__ == "__main__":
    app.run()
文件保存后,执行命令,启动服务;其中2323是自定义端口,不写默认为8080;

python3 jiujiang.py  2323
服务启动后,我们可以用同局域网的电脑和手机访问;http://192.168.0.118:2323/jiujiang/webpy
浏览器访问效果
手机访问效果
接口访问后,可以看到服务端访问日志如下图:
访问日志
 其他操作或者效果可以参考网上其他讲解。

树莓派Python-mongo操作

上面文章已经安装了mongo数据库,现在要通过Python操作mongo数据库,因此下面要进行一些操作。
参考文章: http://www.shumeijiang.com/2021/01/24/多个树莓派之间实现通信对话 
#首先要安装驱动pymongo
1、执行命令

sudo pip install pymongo==3.2
(指定版本是因为mongo有版本的要求,3.2实验不会报错,3.11会报错) 2、安装完成后查看版本是否正确
python
>>> import pymongo
>>> pymongo.version
'3.2'
#mongo连接

1  #coding:utf-8
2  from pymongo import MongoClient
3
4  USER = 'pi'  #用户名
5  PASS = 'shumeijiang'  #验证密码
6  ADDRESS = '192.168.0.120'  #数据库地址
7  PORT = 27017   #默认端口
8  DB_NAME = 'command'  #指定库
9  COLLECTION = 'master.command'  #指定集合(表)
10
11 conn = MongoClient("mongodb://"+USER+':'+PASS+'@'+ADDRESS, PORT)
12 db = conn[DB_NAME]
13 collect = db[COLLECTION]
14
15 for i in collect.find():   #数据查询
16     print(i)
#查询结果
查询结果

多个树莓派之间实现通信对话

#实验目的:在局域网内,通过在一个树莓派上安装mongo载体,然后设置其他树莓派可远程访问,从而实现多个树莓派之间消息传递,命令传递以及通信对话功能。
如图可见有两个树莓派,分别是120和118;数字的含义其实是他们各自的静态ip,因为涉及到彼此访问,因此需要首先设置静态ip。120的IP地址为192.168.0.120;118的IP地址为192.168.0.118。
#安装mongo
1、由于树莓派的软件源自带mongodb-server的安装包(此处用的是清华的软件源http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian),因此只需要执行

sudo apt-get install mongodb-server
2、不过安装的是32bit 的mongodb,数据库的大小会被限制在2GB;因此需要对旧数据添加一个合理的清理机制; 3、安装完成执行命令:
mongo
4、如下图所示则表示安装成功,120和118都需要安装;
初次启动
#设置通信
1、由于默认ip是127.0.0.1,无法远程连接,因此需要执行编辑配置文件,如果非root需要sudo vim /etc/mongodb.conf 
2、寻找bind_ip = 127.0.0.1这一行,注释掉;注释后可见 #bind_ip = 127.0.0.1 
3、由于默认登录权限设置是关闭的 对于通信非常的不安全,因此我们需要打开 auth=true这行; 
4、由于增加了权限 因此需要增加用户 见下图
5、保存文件,然后重启系统 sudo reboot 
添加用户
#通信实验
1、分别登录118和120机器,然后执行 mongo 192.168.0.120 -u "pi" -p "shumeijiang" --authenticationDatabase admin (其中-u为用户名 -p为密码)
2、然后在120执行
(1)use command
(2)db.master.command.insert({_id:1, data:'data', 'status':1})
3、然后在118机器执行 db.master.command.find({})
4、可见118读取到消息 { "_id" : 1, "data" : "data", "status" : 1 } 
5、同理118在mongo写入一条信息,120执行查询也可见消息;
6、如此实现一个双向的消息同步机制,后续增加消息的读取状态,以及消息的清理机制等。
#更多实验可见 https://www.shumeijiang.com/2021/07/21/树莓派语音识别-物联网实验/

直流可变降压稳压模块实验

#实验目的:通过旋转降压按钮,可见自带或外接电压显示表显示电压数值变化。
#接线示例1
示例1
#接线示例2
示例2
#实验效果:
1、示例1为自带电压显示模块,示例2为不带电压显示模块;
2、示例2后添加单独电压显示表,为示例2降压模块提供电压显示;
3、通过旋转示例1或示例2的降压变压旋转钮,可见电压表电压值在变化;如果无变化,需要多旋转几圈,直到数值变化;
4、示例1的降压模块还自带一个可显示输入电压按钮,通过按压按钮可见输入电压为12V;
5、变压后电压不会高于输入电压,同时最低电压也不会为0;
#视频效果地址:

数字信号和模拟信号区别

#直观理解:
1、数字信号用高电平和低电平标示,表示有或者无,高或者低;
2、模拟信号则可以表示多少;
如上图,用电池电量举例;数字信号表示电池有无电量,而模拟信息可以表示有多少电量。
#应用场景不同
1、有的传感器比如通电即量的LED灯,如果使用数字信号,则只可控制LED量或者熄灭;如果使用模拟信号则可以模拟LED亮度多少。