改进版代码的github地址如下,读取并记录到本地文件。https://github.com/hanjintao1996/jy61-/tree/master
如有帮助请在github点赞,感激不尽。
今天主要是把前几天成果结合起来,通过COM6端口接收传感器数据,处理后发送至Arduino驱动板,控制LED灯泡
代码:
-*- coding: UTF-8 -*-
import serial
import time #需要用到延时函数
def get_acc(self): #处理acc信息
try:
axh = int(datahex[6:8],16)
axl = int(datahex[4:6], 16)
ayh = int(datahex[10:12], 16)
ayl = int(datahex[8:10], 16)
azh = int(datahex[14:16], 16)
azl = int(datahex[12:14], 16)
except IOError:
print("ReadError: gyro_acc")
return (0, 0, 0)
else:
k_acc = 16
acc_x = (axh << 8 | axl) / 32768 * k_acc
acc_y = (ayh << 8 | ayl) / 32768 * k_acc
acc_z = (azh << 8 | azl) / 32768 * k_acc
if acc_x >= k_acc:
acc_x -= 2 * k_acc
if acc_y >= k_acc:
acc_y -= 2 * k_acc
if acc_z >= k_acc:
acc_z-= 2 * k_acc
return acc_x,acc_y,acc_z
def get_gyro(self): #处理gyro信息
try:
wxh = int(datahex[28:30], 16)
wxl = int(datahex[26:28], 16)
wyh = int(datahex[32:34], 16)
wyl = int(datahex[30:32], 16)
wzh = int(datahex[36:38], 16)
wzl = int(datahex[34:36], 16)
except IOError:
print("ReadError: gyro_acc")
return (0, 0, 0)
else:
k_gyro = 2000
gyro_x = (wxh << 8 | wxl) / 32768 * k_gyro
gyro_y = (wyh << 8 | wyl) / 32768 * k_gyro
gyro_z = (wzh << 8 | wzl) / 32768 * k_gyro
if gyro_x >= k_gyro:
gyro_x -= 2 * k_gyro
if gyro_y >= k_gyro:
gyro_y -= 2 * k_gyro
if gyro_z >=k_gyro:
gyro_z-= 2 * k_gyro
return gyro_x,gyro_y,gyro_z
def get_angle(self): #处理angle信息
try:
rxh = int(datahex[50:52], 16)
rxl = int(datahex[48:50], 16)
ryh = int(datahex[54:56], 16)
ryl = int(datahex[52:54], 16)
rzh = int(datahex[58:60], 16)
rzl = int(datahex[56:58], 16)
except IOError:
print("ReadError: gyro_acc")
return (0, 0, 0)
else:
k_angle = 180
angle_x = (rxh << 8 | rxl) / 32768 * k_angle
angle_y = (ryh << 8 | ryl) / 32768 * k_angle
angle_z = (rzh << 8 | rzl) / 32768 * k_angle
if angle_x >= k_angle:
angle_x -= 2 * k_angle
if angle_y >= k_angle:
angle_y -= 2 * k_angle
if angle_z >=k_angle:
angle_z-= 2 * k_angle
return angle_x,angle_y,angle_z
def shakecharge(self): #震颤判断函数
ifshake = 0 #震颤次数
ifshake_0 =0 #是否归零
limit_a1 = 0.5
limit_a2 = 0.8
limit_a3 = 1.2 #震动分级
interval_a = 5 #更新间隔
acc_fre[0] = acc_fre[0] + 1 #重要!不能用变量,要用list
print(acc_fre[0])
if acc_fre[0] % interval_a == 0: #采样
acc_old[0] = acc[0]
acc_old[1] = acc[1]
acc_old[2] = acc[2]
if acc_fre[0] % (interval_a * 10) == 0: #重置
if ifshake == ifshake_0: #如果没更新
ifshake = ifshake_0 = 0
print('——————重置!')
else: #更新归零阈值
ifshake_0 = ifshake
print('******更新! ')
else:
pass
if acc_fre[0] > interval_a*2 and (abs(acc[0] - acc_old[0]) > limit_a3 or acc[1] - acc_old[1] > limit_a3 or acc[2] - acc_old[2] > limit_a3) :
print("===重度震颤!!!!!") #LED灯亮
demo = b"3"
ser1.write(demo)
time.sleep(1)
ifshake = 0
elif acc_fre[0] > interval_a*2 and (abs(acc[0] - acc_old[0]) > limit_a2 or acc[1] - acc_old[1] > limit_a2 or acc[2] - acc_old[2] > limit_a2):
print("===中度震颤!!!!!")
demo2 = b"2"
ser1.write(demo2)
time.sleep(0.5)
ifshake = 0
elif acc_fre[0] > interval_a*2 and (abs(acc[0] - acc_old[0]) > limit_a1 or acc[1] - acc_old[1] > limit_a1 or acc[2] - acc_old[2] > limit_a1):
print("===轻度震颤!!!!!")
demo3 = b"1"
ser1.write(demo3)
time.sleep(0.5)
ifshake = 0
else:
demo4 = b"0"
ser1.write(demo4)
return
if __name__ == "__main__":
#ser = serial.Serial("com6", 115200, timeout=0.5) # 打开端口
ser1 = serial.Serial("com7", 9600, timeout=0.5) # 打开端口
#acc_old = [0,0,0]
acc_old = [0,0,0]
acc_fre = [1]
print(acc_fre)
print(acc_fre[0])
while(ser1.is_open):
ser = serial.Serial("com6", 115200, timeout=0.5) # 打开端口
#print(ser.is_open)
datahex = (ser.read(33).hex()) #读取传感器数据
acc = get_acc(datahex)
gyro = get_gyro(datahex)
angle = get_angle(datahex)
shakecharge(acc)
#print(acc_fre)
ser.close()
time.sleep(0.2)
'''print(datahex) # 读一个字节
print(acc)
print(gyro)
print(angle)'''
#print(acc_x,acc_y,acc_z)
小结:
1 python的基本数据类型梳理:
- 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
- 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。
运算符:算术运算,赋值运算,比较运算,逻辑运算,成员运算
基本数据类型:
数字—int 布尔值—bool类
字符串—str类(双引号或者单引号)(索引,切片,长度,遍历删除,分割,清除空白,大小写转换,判断开头等) 列表—list类
列表—list类 (可修改,方括号)(索引,切片,追加,拓展,插入,排序,移除)
元组—tuple类 (不可修改的列表,用圆括号)
字典—dict类 (一系列的键值对,键的定义不可变,值可以任意数据类型)
集合—set类(特性::去重,无序,每个元素都是不可变的类型即hashable类型)
参考网址 :http://www.runoob.com/python3/python3-data-type.html python基本数据类型
2 python全局变量的解决办法 http://www.javaxxz.com/thread-367807-1-1.html
3 time.sleep()的用法
4 列表操作(重要)http://www.runoob.com/python3/python3-list.html
5 出现LED闪烁不灵的情况,在加了sleep后得到解决,但是原因不明,有待进一步解决
6 下一步进行执行器的制造以及Python多线程编程,开发板移植等工作。
附:C语言处理源码
UARTTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "Com.h"
#include "windows.h"
#include "time.h"
#include "stdio.h"
#include "math.h"
unsigned char ucComNo[2] ={0,0};
signed char OpenCom(void)
{ static unsigned long ulNo=0;
signed char cResult= 0;
printf("等待插入Com%d! ",ucComNo[0]);
do
{
cResult = OpenCOMDevice(ucComNo[0],115200);
}while(cResult!=0);
printf("Com%d已插入\r\n",ucComNo[0]);
return 0;
}
double a[3],w[3],Angle[3],T;
double a_o[3],w_o[3],Angle_o[3],T_o; //记录过去传感器信息
int a_n = 1; //记录加速度采样次数
int ifshake= 0; //判断是否震颤
int ifshake_0 = 0; //判断是否归零
float limit_a = 0.5; //加速度的偏差阈值
float limit_a_2 = 0.8; //加速度的偏差阈值
float limit_a_3 = 1.2; //加速度的偏差阈值
int interval_a = 5; //加速度信息更新间隔
void DecodeIMUData(unsigned char chrTemp[]) {
//printf("limit_a =%f\n",limit_a); //printf("interval_a = %d\n",interval_a); // printf("a_n =%d \n",a_n);
switch(chrTemp[1]) {
case 0x51:
a_n = a_n+1;
a[0] = (short(chrTemp[3]<<8|chrTemp[2]))/32768.0*16;
a[1] = (short(chrTemp[5]<<8|chrTemp[4]))/32768.0*16;
a[2] = (short(chrTemp[7]<<8|chrTemp[6]))/32768.0*16;
T = (short(chrTemp[9]<<8|chrTemp[8]))/340.0+36.25;
if ( a_n %(interval_a*10) == 0) // 震颤归零
{ if (ifshake == ifshake_0)
{
ifshake_0 = ifshake = 0;
printf(" ----------------------------重置!!!!!");
}
else
{
ifshake_0 = ifshake;
printf(" *****************************更新");
Sleep(100);
}
}
if ( a_n %interval_a == 0) // 更新间隔
{
a_o[0] = a[0];
a_o[1] = a[1];
a_o[2] = a[2];
//printf("a_o = %4.3f\t%4.3f\t%4.3f\t\r\n",a_o[0],a_o[1],a_o[2]);
}
else
{
printf("\n");
}
//printf("a = %4.3f\t%4.3f\t%4.3f\t\r\n",a[0],a[1],a[2]);
if (abs(a[0] - a_o[0]) > limit_a_3 || abs(a[1] - a_o[1]) > limit_a_3 || abs(a[2] - a_o[2]) > limit_a_3) // 判断是否震颤
//if (abs(a[0] - a_o[0]) > 0.5 || abs(a[1] - a_o[1]) > 0.5 || abs(a[2] - a_o[2]) > 0.5) // 判断是否震颤
{
ifshake = ifshake + 1;
if(ifshake > 5) //抖动5次以上判断为震颤
{
printf(" ===============================================重度震颤!!!!!===============================================================\n");
Beep(5000,5);//控制蜂鸣器发声
ifshake = 0;
}
else
{
ifshake = ifshake;
}
}
else if(abs(a[0] - a_o[0]) > limit_a_2 || abs(a[1] - a_o[1]) > limit_a_2 || abs(a[2] - a_o[2]) > limit_a_2) // 判断是否震颤
//if (abs(a[0] - a_o[0]) > 0.5 || abs(a[1] - a_o[1]) > 0.5 || abs(a[2] - a_o[2]) > 0.5) // 判断是否震颤
{
ifshake = ifshake + 1;
if(ifshake > 5) //抖动5次以上判断为震颤
{
printf(" ===============================================中度震颤!!!!!===============================================================\n");
Beep(5000,5);//控制蜂鸣器发声
ifshake = 0;
}
else
{
ifshake = ifshake;
}
}
else if(abs(a[0] - a_o[0]) > limit_a || abs(a[1] - a_o[1]) > limit_a || abs(a[2] - a_o[2]) > limit_a) // 判断是否震颤
//if (abs(a[0] - a_o[0]) > 0.5 || abs(a[1] - a_o[1]) > 0.5 || abs(a[2] - a_o[2]) > 0.5) // 判断是否震颤
{
ifshake = ifshake + 1;
if(ifshake > 5) //抖动5次以上判断为震颤
{
printf(" ===============================================轻度震颤!!!!!===============================================================\n");
Beep(5000,5);//控制蜂鸣器发声
ifshake = 0;
}
else
{
ifshake = ifshake;
}
}
break;
case 0x52:
w[0] = (short(chrTemp[3]<<8|chrTemp[2]))/32768.0*2000;
w[1] = (short(chrTemp[5]<<8|chrTemp[4]))/32768.0*2000;
w[2] = (short(chrTemp[7]<<8|chrTemp[6]))/32768.0*2000;
T = (short(chrTemp[9]<<8|chrTemp[8]))/340.0+36.25;
//printf("w = %4.3f\t%4.3f\t%4.3f\t\r\n",w[0],w[1],w[2]);
break;
case 0x53:
Angle[0] = (short(chrTemp[3]<<8|chrTemp[2]))/32768.0*180;
Angle[1] = (short(chrTemp[5]<<8|chrTemp[4]))/32768.0*180;
Angle[2] = (short(chrTemp[7]<<8|chrTemp[6]))/32768.0*180;
T = (short(chrTemp[9]<<8|chrTemp[8]))/340.0+36.25;
//printf("Angle = %4.2f\t%4.2f\t%4.2f\tT=%4.2f\r\n",Angle[0],Angle[1],Angle[2],T);
break;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
char chrBuffer[1000];
unsigned char chrTemp[1000];
signed char cResult[2] = {0};
unsigned short usLength=0,usRxLength=0;
FILE *fp;
fp = fopen("Com.ini","r");
if (1!=fscanf(fp,"Com = %d",&ucComNo[0]))
{
printf("端口配置文件有误!");
Sleep(5000);
}
fclose(fp);
OpenCom();
chrBuffer[0] = 0x01;
SendUARTMessageLength(ucComNo[0],chrBuffer,1);
while(1)
{
usLength = CollectUARTData(ucComNo[0],chrBuffer);
if (usLength>0)
{
usRxLength += usLength;
while (usRxLength >= 11)
{
memcpy(chrTemp,chrBuffer,usRxLength);
if (!((chrTemp[0] == 0x55) & ((chrTemp[1] == 0x51) | (chrTemp[1] == 0x52) | (chrTemp[1] == 0x53))))
{
for (int i = 1; i < usRxLength; i++) chrBuffer[i - 1] = chrBuffer[i];
usRxLength--;
continue;
}
DecodeIMUData(chrTemp);
for (int i = 11; i < usRxLength; i++) chrBuffer[i - 11] = chrBuffer[i];
usRxLength -= 11;
}
}
Sleep(200);
}
return 0;
}