通信原理课设(gec6818) 008:LED+蜂鸣器+串口+MQ01+GY39+RFID

目录

1、LED和蜂鸣器

a. 安装驱动

b. 代码

2、串口

3、MQ01烟雾传感器

4、GY39


1、LED和蜂鸣器

a. 安装驱动

在开发板上要使用led和蜂鸣器需要安装对应的驱动

链接:https://pan.baidu.com/s/15I1kGKhT1kENqplu5Dmg5Q?pwd=lebe 
提取码:lebe

将上面的两个文件放到开发板上面去

使用insmod命令加载驱动:

insmod led_drv.ko

insmod pwm.ko

去/dev文件夹,如果看到led_drv和pwm,就是驱动加载成功

如果在加载驱动的过程中,提示文件繁忙,那就先卸载驱动,再重新下载:

rmmod gec6818_beep.ko
再insmod pwm.ko

b. 代码

led大家都很熟悉了,概念和原理啥的就跳过

为了在后面的gy39和mq01使用中,当数值超过一定阈值时,能调用led,所以我定义了变量state,num,直接调led函数,并传相应的值就能实现led灯的亮灭,蜂鸣器也是如此。

led.c :

#include "led.h"
//state:灯的状态,是开还是关  1:开 0:关  
//num:灯的编号,亮哪个灯
int state = 0; //灯默认为关
int num;
void led(int state,int num)
{
	int fd,ret;
	char led_ctrl[2]; //0 --> 灯的状态  1 --->灯编号
	//[1]
	fd = open("/dev/led_drv",O_RDWR);
	if(fd < 0)
	{
		printf("open led_drv failed\n");
	}

	led_ctrl[1] = num;  //
	led_ctrl[0] = state; //on
	ret = write(fd,led_ctrl,sizeof(led_ctrl));
	  
	if( ret != 2)
	{
		perror("write");
	}

	close(fd);
}

led.h :

#ifndef _LED_H_
#define _LED_H_

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

void led(int state,int num);

#endif

beep.c :

#include "beep.h"
int sound = 0; //默认不响
void beep(int sound)
{
	int fd,ret;
	char beep_ctrl[1]; //0 --> 不响  1 --->响
	//[1]
	fd = open("/dev/pwm",O_RDWR);
	if(fd < 0)
	{
		printf("open /dev/pwm failed\n");
	}

	beep_ctrl[0] = sound; 	//响
    ret = write(fd,beep_ctrl,sizeof(beep_ctrl));
    if( ret == -1)
	{
	    perror("write");
	}	

	close(fd);	

}

beep.h :

#ifndef __BEEP_H__
#define __BEEP_H__

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

void beep(int sound);

#endif

2、串口

在linux里面串口也是一个文件
    "/dev/ttySAC1" -> 串口1
    "/dev/ttySAC2" -> 串口2
    "/dev/ttySAC3" -> 串口3

我们在使用串口之前要设置这个串口的波特率以及其他的属性,调用int init_serial(const char *file, int baudrate)这个函数。

serial_init.c :

#include "serial_init.h"

//初始化串口,把 open 和 初始化 结合在一起了
int init_serial(const char *file, int baudrate)
{ 
	int fd;
	//打开串口
	fd = open(file, O_RDWR);
	if (fd == -1)
	{
		perror("open device error:");
		return -1;
	}

	struct termios myserial;
	//清空结构体
	memset(&myserial, 0, sizeof (myserial));
	//O_RDWR               
	myserial.c_cflag |= (CLOCAL | CREAD);
	//设置控制模式状态,本地连接,接受使能
	//设置 数据位
	myserial.c_cflag &= ~CSIZE;   //清空数据位
	myserial.c_cflag &= ~CRTSCTS; //无硬件流控制
	myserial.c_cflag |= CS8;      //数据位:8

	myserial.c_cflag &= ~CSTOPB;//   //1位停止位
	myserial.c_cflag &= ~PARENB;  //不要校验
	//myserial.c_iflag |= IGNPAR;   //不要校验
	//myserial.c_oflag = 0;  //输入模式
	//myserial.c_lflag = 0;  //不激活终端模式

	switch (baudrate)
	{
		case 9600:
			cfsetospeed(&myserial, B9600);  //设置波特率
			cfsetispeed(&myserial, B9600);
			break;
		case 115200:
			cfsetospeed(&myserial, B115200);  //设置波特率
			cfsetispeed(&myserial, B115200);
			break;
		case 19200:
			cfsetospeed(&myserial, B19200);  //设置波特率
			cfsetispeed(&myserial, B19200);
			break;
	}
	
	/* 刷新输出队列,清除正接受的数据 */
	tcflush(fd, TCIFLUSH);

	/* 改变配置 */
	tcsetattr(fd, TCSANOW, &myserial);

	return fd;
}

serial_init.h :

#ifndef __SERIAL_INIT__
#define __SERIAL_INIT__

#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>



//初始化串口,把 open 和 初始化 结合在一起了
int init_serial(const char *file, int baudrate);


#endif

3、MQ01烟雾传感器

基本流程:

1、初始化串口

2、发送命令:FF 01 86 00 00 00 00 00 79

3、MQ采集数据

4、处理数据,将返回值第2个字节左移8位并于第3个字节相或

注意,烟雾传感器MQ是发送一次命令,返回一次信息。

MQ01.c :

#include "MQ01.h"

extern int state; //灯默认为关
extern int num;

void Z_MQ(void)
{
    int Z_MQ_fd = 0;
    unsigned char yanwucmd[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};
    unsigned char yanwu_buf[100]={0};
    int yanwu;
    Z_MQ_fd = init_serial("/dev/ttySAC2",9600);
    while(1)
    {
        write(Z_MQ_fd,yanwucmd,9);
        read(Z_MQ_fd,yanwu_buf,9);
        yanwu = yanwu_buf[2]<<8 | yanwu_buf[3];
        printf("烟雾值:%d\n",yanwu);
        if(yanwu>=300)
        {
            led(1,9);  //led9 亮
            beep(1);   //蜂鸣器响
            sleep(5);//持续5s
            beep(0);   //蜂鸣器关
        }
        else{
            led(0,9);  //led9 灭
            beep(0);   //蜂鸣器关
        }
        sleep(1);
    }
    close(Z_MQ_fd);
}


MQ01.h :

#ifndef __MQ01_H__
#define __MQ01_H__

//#include <stdio.h>
#include "serial_init.h"
#include <unistd.h>
#include "led.h"
#include "beep.h"


void Z_MQ(void);

#endif

4、GY39

基本流程:

1、初始化串口

2、发送命令

      当发送命令为:0xA5+0x81+0x26时,只输出光照
      当发送命令为:0xA5+0x82+0x27时,只输出温度、气压、湿度、海拔
      当发送命令为:0xA5+0x83+0x28时,输出全部:光照、温度、气压、湿度、海拔

3、采集数据

4、处理数据

光照强度计算方法(当 Byte2=0x15 , 数据 :Byte4~Byte7 ) :
Lux=( 前高 8 <<24) | ( 前低 8 <<16) | ( 后高 8 <<8) | 后低 8 位 单位 lux
例:一帧数据
<5A- 5A- 15 -04- 00 -00- FE- 40 - 0B >
Lux=(0x00<<24)|(0x00<<16)|(0xFE<<8)|0x40
Lux=Lux/100 =650.88 (lux)
温度、气压、湿度、海拔,计算方法(当 Byte2=0x45 时):
温度: Byte4~Byte5
T=( 8 <<8)| 8
T=T/100 单位℃
气压: Byte6~Byte9
P=( 前高 8 <<24) | ( 前低 8 <<16) | ( 后高 8 <<8) | 后低 8
P=P/100 单位 pa
湿度: Byte10~Byte11
Hum=( 8 <<8)| 8
Hum=Hum/100 百分制
海拔: Byte12~Byte13

H=(高 8 <<8)|8 单位 m

例:一帧数据
< 5A -5A -45 -0A - 0B -2D -00 -97 -C4 -3F -12- 77 -00- 9C - FA >
T=(0x0B<<8)|0x2D=2861
温度 T=2861/100=28.61 ( )
P=(0x00<<24)|(0x97<<16)|(C4<<8)|3F=9946175
气压 P=9946175/100=99461.75 (pa)
Hum=(0x12<<8)| 77=4727
湿度 Hum=4727/100=47.27 (%)
海拔 H=(0x00<<8)|0x9c=156 (m)

   

GY39.c :

#include "GY39.h"

extern int state; //灯默认为关
extern int num;

void printGy39Data(unsigned char *recvdata,int n)
{
	int i;
	for(i = 0;i < n;i++)
	{
		printf("%x ",recvdata[i]);
	}
	printf("\n");
	int LUX,T,P,HUM,H;//光照,气温,气压,湿度,海拔
	LUX = (recvdata[4]<<24 | recvdata[5]<<16 | recvdata[6]<<8 | recvdata[7]) / 100; 
	T = (recvdata[13]<<8 | recvdata[14]) / 100; 
	P = (recvdata[15]<<24 | recvdata[16]<<16 | recvdata[17]<<8 | recvdata[18]) / 100; 
	HUM = (recvdata[19]<<8 | recvdata[20]) / 100; 
	H = recvdata[21]<<8 | recvdata[22];
	printf("LUX:%d T:%d P:%d HUM:%d H:%d\n",LUX,T,P,HUM,H);

	if(T>28)
	{
		led(1,8);  //led9 亮
        beep(1);   //蜂鸣器响
        sleep(5);//持续5s
        beep(0);   //蜂鸣器关
	}
	else{
		led(0,8);  //led8灭
		led(0,9);
	}
}

void Gy39GetData()
{
	int fd = init_serial("/dev/ttySAC1",9600);
	unsigned char cmd[3] = {0xA5,0x83,0x28};
	
	int r = write(fd,cmd,3);
	printf("write r = %d\n",r);
	usleep(500000);
	int gy39_i = 0;
	unsigned char recvdata[24] = {0};
	int timeout = 0;
	while(1)
	{
		r = read(fd,recvdata + gy39_i,1);
		if(0 == r)
		{
			timeout++;
			usleep(1000);
			if(timeout > 1000)//连续两秒没有回应
			{
				printf("超时\n");
				timeout = 0;
				break;
			}
			continue;
		}
		timeout = 0;
		gy39_i++;
		switch(gy39_i)
		{
			case 1:if(recvdata[0] != 0x5a){gy39_i = 0;}break;
			case 2:if(recvdata[1] != 0x5a){gy39_i = 0;}break;
			case 3:if(recvdata[2] != 0x15){gy39_i = 0;}break;			
			case 4:if(recvdata[3] != 0x04){gy39_i = 0;}break;
			case 24:printGy39Data(recvdata,24);gy39_i = 0;break;//接收完毕
			default:
				if(gy39_i > 24 || gy39_i < 0)
				{
					gy39_i = 0;
					sleep(1);
				}
				break;			
		}		
	}
}

GY39.h :

#ifndef __GY39_H__
#define __GY39_H__

//#include <stdio.h>
#include <unistd.h>
#include "serial_init.h"
#include "beep.h"
#include "led.h"
void printGy39Data(unsigned char *recvdata,int n);
void Gy39GetData();
//int gy39_getlux(void);

#endif

---------------------------------------------------补充-----------------------------------------------------------------------

5、RFID识别

#include "rifd.h"

//获取校验和
char get_BCC(char *cmd)
{
	char BCC = 0;
	int i;
	for(i = 0;i < cmd[0] - 2;i++)
	{
		//BCC = BCC ^ cmd[i];
		BCC ^= cmd[i];
	}
	
	return ~BCC;
}


/*
	防碰撞
	
*/
void CascAnticollRfidCmd(int fd)
{
	char cmd[8] = {0};
	cmd[0] = 0x08;
	cmd[1] = 0x02;
	cmd[2] = 0x42;
	cmd[3] = 0x02;
	cmd[4] = 0x93;//使用ALL模式
	cmd[5] = 0x00;
	cmd[6] = get_BCC(cmd);
	cmd[7] = 0x03;
	//将这个命令发送给rfid 
	write(fd,cmd,cmd[0]);
	
	//稍微延时一会 0.1s
	usleep(100000);
	
	//收rfid的回应
	unsigned char buf[10] = {0};
	int r = read(fd,buf,10);
	if(r == 10)
	{		
		if(buf[2] == 0)
		{
			int getUID  = buf[4] | buf[5] << 8 | buf[6] << 16 | buf[7] << 24;
			printf("getUID = %x\n",getUID);//卡序列号
		}
	}
	else
	{
		perror("read CascAnticollRfidCmd error");
	}
	
	
}


/*
	这个函数是对rfid进行请求的
	成功返回0  失败返回-1
*/
int RequestRfidCmd(int fd)
{
	unsigned char cmd[7] = {0};
	cmd[0] = 0x07;
	cmd[1] = 0x02;
	cmd[2] = 0x41;
	cmd[3] = 0x01;
	cmd[4] = 0x52;//使用ALL模式
	cmd[5] = get_BCC(cmd);
	cmd[6] = 0x03;
	//将这个命令发送给rfid 
	write(fd,cmd,cmd[0]);
	
	//稍微延时一会 0.1s
	usleep(1000000);
	
	//等待rfid的回应
	char buf[8] = {0};
	int r = read(fd,buf,8);
	if(r == 8)
	{
		if(buf[2] == 0)//请求成功
		{	
			switch(buf[4])
			{
				case 0x04:
					printf("S50\n");  //卡片类型
					break;
				case 0x02:
					printf("S70\n");
					break;
			}
			
			return 0;
		}
		return -1;
		
	}
	else
	{
		perror("请求失败\n");
		//将蜂鸣器弄的不响
		
		return -1;
	}
}



/*
	这个函数的功能是为了给rfid发送使能命令 
	并且专注这个rfid的返回信息
	fd:是你的初始化好了的串口
	成功返回0 失败返回-1
*/
int SendEnableCmd(int fd)
{
	unsigned char cmd[6] = {0};
	cmd[0] = 0x06;
	cmd[1] = 0x01;
	cmd[2] = 0x41;
	cmd[3] = 0x00;
	cmd[4] = get_BCC(cmd);
	cmd[5] = 0x03;
	
	//将这个命令发送给rfid 
	write(fd,cmd,cmd[0]);
	
	//稍微延时一会 0.1s
	usleep(100000);
	
	
	//等你的rfid回你的信息
	char buf[18] = {0};
	int r = read(fd,buf,18);
	//printf("%d %d\n",r,buf[2]);
	if(18 == r)//这样你才叫得到了完整信息
	{
		if(buf[2] == 0)//这样才叫准备好了
		{
			printf("yes\n");
			return 0;
		}		
		return -1;
	}	
	else
	{
        printf("SendEnableCmd read r = %d\n",r);
		perror("read error");
		return -1;
	}
}

  • 18
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
### 回答1: MQ2烟雾传感器可以检测空气中的烟雾、液化气、丙烷、甲烷、可燃气体等气体。它的浓度算法可以通过以下步骤实现: 1. 读取MQ2传感器的模拟输出值; 2. 根据传感器的响应特性,将模拟输出值转换为电阻值; 3. 根据电阻值,计算出空气中的气体浓度,通常使用下面的公式: Rs/Ro = a * pow(C, b) 其中,Rs是传感器在被检测气体存在下的电阻值;Ro是传感器在干净空气中的电阻值;C是被检测气体的浓度;a和b是常数,根据传感器的响应特性确定。 4. 通过调整a和b的值,来提高浓度算法的精度。 需要注意的是,MQ2烟雾传感器只能检测空气中的气体浓度,并不能判断具体的气体种类,因此在使用时需要根据实际情况进行判断和处理。 ### 回答2: MQ2烟雾传感器是一种常用的气体传感器,用于检测空气中的烟雾浓度。烟雾浓度算法是指通过传感器输出的模拟电压值,计算出空气中烟雾的浓度的一种方法。 MQ2烟雾传感器的工作原理是基于化学敏感材料对烟雾气体的吸附作用。当空气中存在烟雾时,烟雾颗粒会与化学敏感材料相互作用,导致传感器电阻值的变化。通过测量电阻的变化,可以得到烟雾浓度的信息。 为了得到准确的烟雾浓度值,需要对传感器的输出电压进行处理。首先,在正常空气中,烟雾传感器的输出电压为一个基准值。当烟雾浓度增加时,输出电压将发生变化。 为了转换电压值到浓度值,一种常用的方法是使用定标曲线。定标曲线是通过在已知烟雾浓度下进行实验测量得到的。通过将这些实验数据与传感器的输出电压进行对比,可以建立电压和烟雾浓度之间的关系。 在实际使用中,可以根据定标曲线的关系将传感器输出的电压值转换为对应的烟雾浓度值。这样就可以通过测量烟雾传感器的输出电压,得到相应的烟雾浓度。 需要注意的是,由于环境条件的变化和传感器的老化等因素,定标曲线可能会发生变化。因此,定期进行校准是确保烟雾浓度算法准确度的重要步骤。 ### 回答3: MQ2烟雾传感器是一种常见的气体传感器,主要用于检测空气中的有害烟雾气体浓度。烟雾传感器浓度算法是用来计算烟雾浓度的方法。 MQ2烟雾传感器测量烟雾浓度的原理是通过检测烟尘颗粒的导电性来判断烟雾浓度的高低。当空气中有烟尘颗粒存在时,传感器上的金属氧化物薄膜将吸附一部分电子,导致传感器电阻值降低,反之则上升。 在浓度算法中,首先要对传感器进行校准,以获取传感器的初始电阻值。校准时通常需要暴露传感器在干净空气中一段时间,记录下此时的电阻值。根据传感器特性和厂商提供的曲线,可以将电阻值转换为对应的烟雾浓度值。 经过校准后,烟雾传感器将不断检测空气中的烟雾颗粒,获取当前的电阻值。然后,通过比较当前电阻值与校准时的电阻值,可以计算出烟雾浓度的相对变化。 通常,根据传感器的特性和经验,可以将电阻值和烟雾浓度建立一种函数关系,如线性函数。利用这个函数关系,可以将当前电阻值转换为对应的烟雾浓度值。 需要注意的是,烟雾传感器算法中并不能直接给出准确的绝对浓度值,而是提供相对的浓度变化。所以在实际应用中,需要根据实际环境和需要设置适当的阈值,判断烟雾浓度是否超过安全范围。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Flying778

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值