嵌入式开发日记(4)——编写程序,使检测到震动时LED灯亮

时间:2019-04-15
本文章向大家介绍嵌入式开发日记(4)——编写程序,使检测到震动时LED灯亮,主要包括嵌入式开发日记(4)——编写程序,使检测到震动时LED灯亮使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

今天主要是把前几天成果结合起来,通过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/python/python-lists.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;
}