安防监控项目---web点灯(网页发送命令控制A9的led)

这篇具有很好参考价值的文章主要介绍了安防监控项目---web点灯(网页发送命令控制A9的led)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

书接上期,和大家分享的是web点灯,哈哈哈,谈论起点灯这个词,这么久以来我已然已经成长为一名合格的点灯大师了;点灯是一个很好的测试办法,不仅要去测试开发板是否正常,也要去测试网页是否能够顺利下发数据,接下俩让我们仔细来看一下这个过程!!!


一、web点亮LED流程

先来理一下流程,之后呢我们按照这个流程来一步步实现相应的功能;

html的数据发送到A9期间经历了这么几个过程:
安防监控项目---web点灯(网页发送命令控制A9的led),安防监控项目,arm开发,linux,嵌入式硬件,zigbee,安防监控
接下来咱们就根据上面流程图一步步来看一下每一步的具体实现!

二、静态网页设计(html界面)

以下呢就是默认index.html网页的具体设计;代码还是比较简单的,没啥技术含量,大家只要能读懂,在这个基础上可以根据自己的需求去修改就可以了;

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<title>登录界面</title>
	</head>

	<body>

		<body  background="./images/ckp00.png">
			<div align="center">
				<table width="900" border="0" background="./images/ckp3.png">
					<tr>
						<th width="385" height="320" scope="col">&nbsp;</th>
						<th width="385" scope="col">&nbsp;</th>
						<th width="70" scope="col">&nbsp;</th>
					</tr>
					<tr>
						<td height="50">&nbsp;</td>
						<td>
							<div align="center"></div>
						</td>
						<td>&nbsp;</td>
					</tr>
				</table>
			</div>
			<div></div>
			<div align="center">
				<table width="900" border="0">
					<tr>
						<td>
							<form onsubmit="return isValidate(myform)" action="cgi-bin/login.cgi" method="post">
								用户名: <input type="text" name="username" id="username"> 密码: <input type="password" name="userpass" id="userpass">
								<input type="submit" value="登录" id="button">
							</form>

						</td>
					</tr>
				</table>
			</div>

			<!--<p>&nbsp;</p>-->

			<div align="center">
				<table width="900" height="467" border="0" background="./images/ckp4.jpg">
					<tr>
						<td width="126" height="248">&nbsp;</td>
						<td width="351"></td>
						<td width="101">&nbsp;</td>
					</tr>
					<tr>
						<td></td>
						<td>&nbsp;</td>
					</tr>
					<tr>
						<td>
							<form name="myform" method="get" action="cgi-bin/login.cgi" onsubmit="return isValidate(myform)"></form>
						</td>
					</tr>
			</div>
		</body>

</html>

网页打开如下:
安防监控项目---web点灯(网页发送命令控制A9的led),安防监控项目,arm开发,linux,嵌入式硬件,zigbee,安防监控
在这里呢需要用户名和密码来进行登录;那接下来肯定是看一下怎样进行登录了呀!

三、 CGI和BOA在本项目中的使用

用户名和密码由网页端发送BOA服务器,接收到数据后CGI进行数据的解析,那接下来看下CGI的程序到底是如何编写的!

#include <stdio.h>   
#include <stdlib.h>   
#include <string.h>   

char name[64];   
char pass[64];  
  
char* getcgidata(FILE* fp, char* requestmethod)   
{   
	char* input;   
	int len;   
	int size = 1024;   
	int i = 0;   
	  
	if (!strcmp(requestmethod, "GET"))   {   
		 input = getenv("QUERY_STRING");   
		 return input;   
	}   
	else if (!strcmp(requestmethod, "POST"))   {   
		 len = atoi(getenv("CONTENT_LENGTH"));   
		 input = (char*)malloc(sizeof(char)*(size + 1));   
		   
		 if (len == 0)   {   
			input[0] = '\0';   
			return input;   
		 }   
		   
		 while(1)   
		 {   
			input[i] = (char)fgetc(fp);   
			if (i == size)   {   
				 input[i+1] = '\0';   
				 return input;   
			}   										  
			--len;   
			if (feof(fp) || (!(len)))   {   
				 i++;   
				 input[i] = '\0';   
				 return input;   
			}   
			i++;   
						  
		 }   
	}   
	return NULL;  
}	

void unencode_for_name_pass(char *input)
{
	int i = 0;   
	int j = 0;   
	
		// 我们获取的input字符串可能像如下的形式   
		// Username="admin"&Password="aaaaa"   
		// 其中"Username="和"&Password="都是固定的   
		// 而"admin"和"aaaaa"都是变化的,也是我们要获取的   
		  
		// 前面9个字符是UserName=   
		// 在"UserName="和"&"之间的是我们要取出来的用户名   	
	for ( i = 9; i < (int)strlen(input); i++ )  {   
		 if (input[i] == '&')   {   
			name[j] = '\0';   
			break;   
		 }                                       
		 name[j++] = input[i];   
	}   
   
	// 前面9个字符 + "&Password="10个字符 + Username的字符数   
	// 是我们不要的,故省略掉,不拷贝   
	for ( i = 19 + strlen(name), j = 0; i < (int)strlen(input); i++ ){   
		 pass[j++] = input[i];   
	}   
	pass[j] = '\0';   	
	
	//printf("Your Username is %s<br> Your Password is %s<br> \n", name, pass);   
	
	printf("Content-type: text/html\n\n");   //告诉编译器,用html语法来解析
	if((strcmp(name,"Romeo") == 0)&&(strcmp(pass,"123") == 0))		//html登陆的用户名和密码
	{
		printf("<script language='javascript'>document.location = 'http://192.168.1.100/choose.html'</script>"); //自动跳转到这个页面	
	}
	else{
		printf("用户名或密码错误<br><br>");  
		//exit(-1);
	}
}

int main()   
{   
	char *input;   
	char *req_method;   
 
	printf("Content-type: text/html\n\n");   //告诉编译器,用html语法来解析
	printf("The following is query reuslt:<br><br>");   

	req_method = getenv("REQUEST_METHOD");   
	input = getcgidata(stdin, req_method);   //获取URL 编码的数据
	
	unencode_for_name_pass(input);   //解码,并判断用户名,密码,如果正确,跳转至选择界面,否则提示错误	
	return 0;   
}   

上述代码就能够实现自动解析用户名和密码并且实现在登陆成功后跳转至二级页面的操作;
二级页面如下:
安防监控项目---web点灯(网页发送命令控制A9的led),安防监控项目,arm开发,linux,嵌入式硬件,zigbee,安防监控
三级页面如下:
安防监控项目---web点灯(网页发送命令控制A9的led),安防监控项目,arm开发,linux,嵌入式硬件,zigbee,安防监控
四级页面如下:
安防监控项目---web点灯(网页发送命令控制A9的led),安防监控项目,arm开发,linux,嵌入式硬件,zigbee,安防监控
到这里呢我们就可以开始点灯了,但是我们必须清楚,网页下发指令后BOA服务器和CGI究竟是如何进行相应的;下来看一下cgi的工程框架:
安防监控项目---web点灯(网页发送命令控制A9的led),安防监控项目,arm开发,linux,嵌入式硬件,zigbee,安防监控

下面看一下这个是a9_led.c的CGI代码:

#include <stdio.h> 
#include "cgic.h" 
#include <string.h> 
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#define N 8

struct msg
{
	long type;
	long msgtype;
	unsigned char text[N];
};


int cgiMain() 
{ 
	key_t key;
	char buf[N];
	char sto_no[2];
	int msgid;
	struct msg msg_buf;
	memset(&msg_buf,0,sizeof(msg_buf));
	
	cgiFormString("led",buf,N);				//bled网页键值进行接收,接收8个字节
	cgiFormString("store",sto_no,2);

	if((key = ftok("/tmp", 'g')) < 0)		//创建IPC对象键值(生成一个IPC对象),用于消息队列,参数1是指定的文件名,参数2是子序号
	{
		perror("ftok");
		exit(1);
	}

	if((msgid = msgget(key, 0666)) < 0)		//创建一个消息队列
	{
		perror("msgget");
		exit(1);
	}

	bzero (msg_buf.text, sizeof (msg_buf.text));

	//如果是打开的按钮
	if (buf[0] == '1')
	{
		//开灯
		msg_buf.text[0] = ((sto_no[0] - 48)) << 6 | (0x0 << 4) | (1 << 0);
	}
	else
	{
		msg_buf.text[0] = ((sto_no[0] - 48)) << 6 | (0x0 << 4) | (0 << 0);
	}

	msg_buf.type = 1L;		//1L表示home1,也表示消息队列的消息类型
	msg_buf.msgtype = 1L;	//表示led设备的消息类型
	
	//向消息队列中写入消息,将消息发出,在A9端进行接收
	//这里发送的字节数为sizeof(msg_buf)-sizeof(long)的原因是由于不需要传送消息类型,只需要传送具体的消息大小即可(也就是msg结构体的第一个变量不需要作为发送的有效字节传送)
	msgsnd(msgid, &msg_buf,sizeof(msg_buf)-sizeof(long),0);

	sto_no[0] -= 48;	//为了后面生成是哪一个操作引起网页反馈(生成二级网页名序号)

	cgiHeaderContentType("text/html\n\n"); 
	fprintf(cgiOut, "<HTML><HEAD>\n"); 
	fprintf(cgiOut, "<TITLE>My CGI</TITLE></HEAD>\n"); 
	fprintf(cgiOut, "<BODY>"); 

	fprintf(cgiOut, "<H2>send sucess</H2>");

	//fprintf(cgiOut, "<a href='.html'>返回</a>"); 
	fprintf(cgiOut, "<meta http-equiv=\"refresh\" content=\"1;url=../a9_zigbee%d.html\">", sto_no[0]);
	fprintf(cgiOut, "</BODY>\n"); 
	fprintf(cgiOut, "</HTML>\n"); 


	return 0; 
} 

代码中注释的消息类型如下,这个是在通信结构体设计的分享中对应用层进程间通信使用消息队列机制的具体实现;
安防监控项目---web点灯(网页发送命令控制A9的led),安防监控项目,arm开发,linux,嵌入式硬件,zigbee,安防监控
那么当cgi发把消息写入到消息队列后,那应用层究竟是如何进行接收的呢,继续来看吧:
下图是应用层的框架:
安防监控项目---web点灯(网页发送命令控制A9的led),安防监控项目,arm开发,linux,嵌入式硬件,zigbee,安防监控
在pthread_client_request.c中,对消息队列进行了接收操作:

#include "data_global.h"
#include "linuxuart.h"

//消息队列id
extern int msgid;
//ipc对象键值
extern key_t key;
//锁资源
extern pthread_mutex_t mutex_client_request,
        		mutex_refresh,
        		mutex_sqlite,
	        	mutex_transfer,
	        	mutex_analysis,
	        	mutex_sms,
	        	mutex_buzzer,
	         	mutex_led,
	         	mutex_camera;
//条件变量
extern pthread_cond_t  cond_client_request,
        		cond_refresh,
        		cond_sqlite,
	        	cond_transfer,
	        	cond_analysis,
	        	cond_sms,
	        	cond_buzzer,
	         	cond_led,
	         	cond_camera;
//模块的控制命令字
extern unsigned char cmd_led;
extern unsigned char  cmd_buzzer;
extern unsigned char  cmd_fan;

//GPRS模块的电话号
extern char recive_phone[12] ;
extern char center_phone[12] ;

//消息队列通信结构体
struct msg msgbuf;


void *pthread_client_request(void *arg)
{
	if((key = ftok("/tmp",'g')) < 0){
		perror("ftok failed .\n");
		exit(-1);
	}

	msgid = msgget(key,IPC_CREAT|IPC_EXCL|0666); 		//检测消息队列中是否有这个键值,如果有则返回对应的-1,没有则创建并返回创建消息队列的id
	if(msgid == -1)	{
		if(errno == EEXIST){ 							//如果已经存在
			msgid = msgget(key,0777); 					//设置权限为0777
		}else{
			perror("fail to msgget");
			exit(1);
		}
	}
	printf("pthread_client_request\n");
	
	while(1){
		bzero(&msgbuf,sizeof(msgbuf)); 					//清理操作,但一般使用memset,功能更加强大一点
		printf("wait form client request...\n"); 
		msgrcv (msgid, &msgbuf, sizeof (msgbuf) - sizeof (long), 1L, 0); //从消息队列中读取消息
		printf ("Get %ldL msg\n", msgbuf.msgtype); 		//打印消息类型
		printf ("text[0] = %#x\n", msgbuf.text[0]); 	//打印消息内容

		//判断消息类型,从而确定是哪一个设备
		switch(msgbuf.msgtype){
			case 1L:
				//1L的类型是led的消息类型,此时上锁,等待消息内容也就是控制命令字复制完成后解锁,通过pthread_cond_signal唤醒pthread_led.c这个led线程,进行led的具体硬件操作
				pthread_mutex_lock(&mutex_led);
				printf("hello led\n");
				cmd_led = msgbuf.text[0];
				pthread_mutex_unlock(&mutex_led);
				pthread_cond_signal(&cond_led);
				break;
		}
	}

}
#endif 

下面来看一下led线程里都干了什么事情呢,代码如下:

#include "data_global.h"
#include "chrdev.h"
#include <unistd.h>

//led的锁资源和条件变量,用来进行同步和互斥操作
extern pthread_mutex_t  	mutex_led;
extern pthread_cond_t      	cond_led;

extern unsigned char cmd_seg;

//流水灯
int fswaterled_control(int led_fd, int times);
//四位二进制表示十六进制
int fsled_control(int led_fd, unsigned char led_control_cmd);  //发送的数字
//关闭所有的灯
int fsled_close_all(int led_fd);



//:A9LED模块线程.
void *pthread_led(void *arg)
{
	printf("pthread_led\n");
	int i, j;
	int led_fd;
	led_desc_t led;

	led_fd = open(LED_DEV, O_RDWR);
	if(led_fd == -1){
		printf("open failed.\n");
	}
	printf("led_fd ;%d.\n",led_fd);

	while(1){
		pthread_mutex_lock(&mutex_led); 				//锁和条件变量的操作都是原子操作,不会被cpu的任务调度机制打断
		printf("led ioctl:***********\n");
		pthread_cond_wait(&cond_led,&mutex_led); 		//会主动释放上面的锁并且判断是否有唤醒信号,在被唤醒后主动又继续加上锁(wait前必须加锁)
		printf("led ioctl:***********\n");
		if(cmd_led == 0x41){
			fswaterled_control(led_fd, 2);
			cmd_led = 0;
		}

		int tmp = cmd_seg & 0xf0;

		if(!(tmp ^ 0x70)) {

			fsled_control(led_fd, cmd_seg);
		}
		pthread_mutex_unlock(&mutex_led);
	}
	
	close(led_fd);
	
}


int fsled_control(int led_fd, unsigned char led_control_cmd)
{
	int i = 0;
	led_desc_t led;
	led_control_cmd &= 0x0f;
	int shift_count = 1; //第0位,第1 - 3位 

	printf("led_control_cmd = %d.\n",led_control_cmd);
	fsled_close_all(led_fd);
	sleep(3);
	while(led_control_cmd){
		if(shift_count >= 5)
			break;
		if((led_control_cmd & 0x1) == 1){ //第0位开始 = LED2
			shift_count ++;  // = 2  LED2 
			printf("if shift_count :%d.\n",shift_count);
			led.which = shift_count; //led2 3 4 5 灯
			ioctl(led_fd,FSLEDON,&led);
			usleep(50000);  //让驱动响应的时间
		}else {
			shift_count ++;
			printf("else shift_count :%d.\n",shift_count);
			led.which = shift_count; //led2 3 4 5 灯
			ioctl(led_fd,FSLEDOFF,&led);
			usleep(50000);
		}
		led_control_cmd >>= 1;
	}

	return 0;
}


int fsled_close_all(int led_fd)
{
	int i = 0;
	led_desc_t led;	

	for(i = 2;i < 6;i ++){
		led.which = i;
		ioctl(led_fd,FSLEDOFF,&led);
		usleep(50000);
	}

	return 0;
}



int fswaterled_control(int led_fd, int times)
{
	int i = 0,j = 0;
	led_desc_t led;	

	for(j = 0;j < times;j ++){
		for(i = 2;i < 6;i ++){
			led.which = i;
			ioctl(led_fd,FSLEDON,&led);
			usleep(500000);

			led.which = i;
			ioctl(led_fd,FSLEDOFF,&led);
			usleep(500000);
		}
	}

	return 0;
}

当然这里不要忘记在跑主框架之前先要加载led的驱动模块哦,要不然我们前面写的再牛,这里的灯也是亮不起来的,哈哈哈哈!


总结

好啦,本期的分享大概就到这里结束了,是不是点个灯这个操作还是具有一定的难度的呢,虽然步骤过程很多,但是每一步都需要我们谨小慎微,把每一步做好,最后自然就能把灯点亮;不要着急,我饿能够按照步骤整理出来是因为我整个项目已经做完了,所以大家不要着急,还是需要一步步来,后面做完后大家肯定比我理解的更深刻!把灯点亮后,那后面蜂鸣器就不是什么问题了,都是一样的原理,是不是跃跃欲试了!加油哦!最后,各位小伙伴们如果有收获,可以点赞收藏哦,你们的认可是我创作的动力,一起加油!文章来源地址https://www.toymoban.com/news/detail-728446.html

到了这里,关于安防监控项目---web点灯(网页发送命令控制A9的led)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 安防监控视频平台EasyCVR视频汇聚平台定制项目增加AI智能算法详细介绍

    安防视频集中存储EasyCVR视频汇聚平台,可支持海量视频的轻量化接入与汇聚管理。平台能提供视频存储磁盘阵列、视频监控直播、视频轮播、视频录像、云存储、回放与检索、智能告警、服务器集群、语音对讲、云台控制、电子地图、平台级联、H.265自动转码等功能。为了便

    2024年02月10日
    浏览(59)
  • 如何制作数据可视化、数孪、安防、区域人流量识别+控制的项目?

    制作与数据可视化、数字孪生、安防、区域人群识别和控制以及其他类似计划相关的项目需要仔细规划和执行。建议遵循以下通用框架来有效地开发这些项目: 定义项目目标:清楚地阐明项目目的和目标。确定要解决的具体问题、期望的结果以及衡量成功的关键绩效指标 (

    2024年02月09日
    浏览(45)
  • 松下PLC控制松下伺服电机(上位机发送控制命令)

    选型: PLC: AFPXHM8N30T (最大8CH) 伺服电机:MSMF022L1A1 伺服驱动器:MADLN15NE 实现目标:通过上位机发送命令,控制伺服电机实现运动控制,本例以单轴为例,实际运用 AFPXHM8N30T 可进行8轴控制 条件有限,实验通过控制单轴实现,也可以用触摸屏实现控制逻辑。 串口定义: 配线方

    2024年02月07日
    浏览(39)
  • Prometheus+Grafana+AlertManager监控SpringBoot项目并发送邮件告警通知

    Docker搭建并配置Prometheus Docker拉取并配置Grafana Docker安装并配置Node-Exporter Docker安装并配置cAdvisor Docker安装并运行Alertmanager 新建项目,引入依赖 新建接口,运行程序 Prometheus配置文件中已添加该项目地址,运行后到Prometheus页面中查看连接情况 成功 引入依赖 新增push接口,用于

    2024年02月11日
    浏览(45)
  • NodeMCU ESP8266构建Web Server网页端控制设备

    NodeMCU ESP8266 内部集成了 TCP/IP 协议栈,可以快速构建网络功能,搭建联网应用的硬件平台; ESP8266可以作为WiFi接入点( Station ),这样可以方便连接互联网,通过HTTP协议和云端服务器进行连接,数据处理; ESP8266可以作为热点( Access Point ),这样方便其他设备的接入,可以

    2024年02月05日
    浏览(49)
  • Web网页项目实战-----小兔鲜儿项目

              本网站是一个电商网站,主要由Html、CSS、JS来完成,实现的功能主要是可以购买产品,展示产品,查看订单等功能,效果如下,如有需要项目代码的可以私信我,或者文章底下评论,我给分享原项目和资源文件           学习路径: 1.精灵图 1)精灵图的介绍 a.场

    2024年02月05日
    浏览(49)
  • STM32通过串口发送指令控制LED灯亮灭OLED并显示命令

    先来看看程序运行的结果吧: 接下来就不说废话了,自己看源代码吧!每一行我都做了注释: 首先是主函数main.c文件: 接下来是LED.h文件: 接下来是LED.c文件: 记下来是串口相关的Serial.h文件: 接下来就是最后一个serial.c文件了: 所有文件在工程中的目录为: 工程编译后下

    2024年04月16日
    浏览(51)
  • 智能安防系统-视频监控系统

    一、智能安防系统 1、智能安防系统介绍 安全防范系统成为了智慧城市与物联网行业应用中的一个非常重要的子系统。 安防系统主要包括:视频监控系统、入侵报警系统、出入口控制系统、电子巡查系统以及智能停车场管理系统等5个子系统。 AI人工智能安防系统功能:基于

    2024年02月03日
    浏览(58)
  • Unity3d C#利用本地网页快速打开萤石云监控视频流(ezopen)实现云台,声音等控制,支持WebGL平台,替代UMP播放(含源码)

    之前我介绍了替代Universal?Media?PlayerUMP播放石云监控视频流(ezopen)的功能,效果还是很明显的,笔者的测试是差不多3-5秒就能打开监控画面,不过稍微遗憾的是,之前的功能是iframe打开石云提供的播放网页的形式,功能基本只有画质切换,声音开关等;具体可以移步查看(https

    2024年02月13日
    浏览(61)
  • 智能安防监控:基于Java+SpringBoot实现人脸识别搜索

    结合人脸识别技术,在工厂、学校、商场、餐厅等人流密集的场所进行监控,对人流进行自动统计、识别和追踪,同时标记存在安全隐患的行为及区域,并发出告警提醒,加强信息化安全管理,降低人工监督成本。 人脸识别搜索技术作为现代计算机视觉领域的重要研究方向之

    2024年02月13日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包