彭水网站建设/惠州seo网站推广
文章目录
- 前言
- 一、zigbee的CGI接口
- 二、请求线程和硬件控制
- 三、现象展示
- 总结
前言
书接上期,我们可以看一下前面的功能设计的部分,网页端的控制还有一个,那就是通过网页来控制zigbee上的风扇节点,这部分的工作量是相当大的,既要实现HTML发送控制命令到A9平台进行接收,又要实现A9平台串口通信控制zigbee协调器,通过zigbee协调器控制zigbee终端节点(这一步是建立在zigbee协调器和终端节点调试好的基础上的);最终呢实现网页控制zigbee节点,这也实现了无线控制!
一、zigbee的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("fan",buf,N);cgiFormString("store",sto_no,2);if((key = ftok("/tmp", 'g')) < 0){perror("ftok");exit(1);}if((msgid = msgget(key, 0666)) < 0){perror("msgget");exit(1);}bzero (msg_buf.text, sizeof (msg_buf.text));switch (buf[0]){case '0':{msg_buf.text[0] = (0 << 6) | (2 << 4) | (0 << 0);break;}case '1':{msg_buf.text[0] = (0 << 6) | (2 << 4) | (1 << 0);break;}}msg_buf.type = 1L;msg_buf.msgtype = 4L;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;
}
这里呢我也没有给出过多的注释,其实流程和前面的led和beep的代码基本一致,且框架结构也都一致;这就是一个好的框架所带来的优势,使得开发起来比较容易;
二、请求线程和硬件控制
请求线程只需要在switch…case语句中添加控制类型即可;这里控制的流程直接写在了switch中,也可以将其写在单独的处理线程中;这里用到了Linux下的串口编程,所以需要包含头文件linuxuart.h这个头文件;
#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,没有则创建并返回创建消息队列的idif(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;case 2L://2L表示beep的消息类型//这里呢相信大家天赋异禀,看懂了上面led的,beep也不是问题pthread_mutex_unlock(&mutex_buzzer);printf("hello beep1\n");pthread_mutex_lock(&mutex_buzzer);cmd_buzzer = msgbuf.text[0];pthread_mutex_unlock(&mutex_buzzer);pthread_cond_signal(&cond_buzzer);break;case 3L:pthread_mutex_lock(&mutex_led);printf("hello seg\n");cmd_seg = msgbuf.text[0];pthread_mutex_unlock(&mutex_led);pthread_cond_signal(&cond_led);break;case 4L:pthread_mutex_lock(&mutex_sqlite);printf("hello fan\n");cmd_fan = msgbuf.text[0];int fan_fd = open_port("/dev/ttyUSB0"); //打开设备if(fan_fd < 0){printf("open failed\n");}set_com_config(fan_fd, 115200, 8, 'N', 1); //设置串口参数char cmdbuf[4] = {0};if(cmd_fan == 0x21){strcpy(cmdbuf,"1\n"); //注意点,一定要加上\n,因为串口助手是默认添加\n的,所以这里我们需要手动添加write(fan_fd,cmdbuf,sizeof(cmdbuf)/sizeof(cmdbuf[0]));sleep(2);}if(cmd_fan == 0x20){strcpy(cmdbuf,"0\n");write(fan_fd,cmdbuf,sizeof(cmdbuf)/sizeof(cmdbuf[0]));sleep(2);}char buf[32] = {0};//get data from zigbeeread(fan_fd,&buf,sizeof(buf));printf("sizeof(buf) = %d.\n",sizeof(buf));printf(">>>>>>%s\n",buf);sleep(1);pthread_mutex_unlock(&mutex_sqlite);break;default:break;}}
}
#endif
接下来看一下linux下的串口编程,为什么要学习这个呢,其实就是要通过USB去和zigbee模块通信,那么无非就是设置通信速率,校验位,停止位等这些参数:
先看一下linuxuart.h文件:
#ifndef __LINUX_UART_H_
#define __LINUX_UART_H_#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>#include <termios.h>
#include <string.h>
#include "data_global.h"extern int set_com_config(int fd, int baud_rate, int data_bits, char parity, int stop_bits);
extern int open_port(char *com_port);
extern void USB_UART_Config(char* path, int baud_rate);
#endif
再来看一下linuxuatr.c文件:
#include "linuxuart.h"int set_com_config(int fd, int baud_rate, int data_bits, char parity, int stop_bits)
{struct termios new_cfg, old_cfg;int speed;/*保存原有串口配置*/if (tcgetattr(fd, &old_cfg) != 0){perror("tcgetattr");return -1;}new_cfg =old_cfg;/*配置为原始模式*/cfmakeraw(&new_cfg);new_cfg.c_cflag &= ~CSIZE;/*设置波特率*/switch (baud_rate){case 2400:{speed = B2400;break; }case 4800:{speed = B4800;break;}case 9600:{speed = B9600;break;}case 19200:{speed = B19200;break;}case 38400:{speed = B38400;break;}default:case 115000:{speed = B115200;break;}}cfsetispeed(&new_cfg, speed);cfsetospeed(&new_cfg, speed);/*设置数据位*/switch (data_bits){case 7:{new_cfg.c_cflag |= CS7;break;} default: case 8:{new_cfg.c_cflag |= CS8;break;}}/*设置奇偶校验位*/switch (parity){default:case 'n':case 'N':{new_cfg.c_cflag &= ~PARENB;new_cfg.c_iflag &= ~INPCK;break;}case 'o':case 'O':{new_cfg.c_cflag |= (PARODD |PARENB);new_cfg.c_iflag |= INPCK;break;}case 'e':case 'E':{new_cfg.c_cflag |= PARENB;new_cfg.c_cflag &= ~PARODD;new_cfg.c_iflag |= INPCK;break;}case 's':case 'S':{new_cfg.c_cflag &= ~PARENB;new_cfg.c_cflag &= ~CSTOPB;break;}}/*设置停止位*/switch (stop_bits){default:case 1:{new_cfg.c_cflag &= ~CSTOPB;break;} case 2:{new_cfg.c_cflag |= CSTOPB;break;}}/*设置等待时间和最小接收字符*/new_cfg.c_cc[VTIME] = 0;new_cfg.c_cc[VMIN] = 1;tcflush(fd, TCIFLUSH);if ((tcsetattr(fd, TCSANOW, &new_cfg)) != 0){perror("tcsetattr");return -1;}return 0;
}int open_port(char *com_port)
{int fd;/*打开串口*/fd = open(com_port, O_RDWR|O_NOCTTY|O_NDELAY);if (fd < 0){perror("open serial port");return -1;}/*恢复串口阻塞状态*/if (fcntl(fd, F_SETFL, 0) < 0){perror("fcntl F_SETFL\n");}/*判断是否为终端设备*/if (isatty(fd) == 0){perror("This is not a terminal device");}return fd;
}/*--------------------CH340Ƥ׃---------------------------*/
void USB_UART_Config(char* path, int baud_rate)
{int fd;fd = open_port(path);if(fd < 0){printf("open %s failed\n",path);return ;}if (set_com_config(fd, baud_rate, 8, 'N', 1) < 0){perror("set_com_config");return ;}close(fd);return ;
}
这些函数是不是挺熟悉的,其实就是我们经常使用的串口助手呗!软件化了,没有图形化界面了!
三、现象展示
风扇静止的时候如下:
下图是风扇转动起来的图片:
下图是终端显示的控制命令字:
打开显示:
关闭显示:
这里也可以看出跟代码信息是一致的;消息类型是4L,控制命令字为0x21和0x20;且打印信息也正确;
总结
本期的分享就到这里结束了,需要注意的是zigbee大家必须先调整好,保证其正常工作,进而学习Linux串口编程,再将这些融合到项目中,就能够实现网页控制zigbee终端节点硬件了;最后,各位小伙伴们如果有收获,可以点赞收藏哦,你们的认可是我创作的动力,一起加油!
相关文章:

安防监控项目---web网页通过A9控制Zigbee终端节点的风扇
文章目录 前言一、zigbee的CGI接口二、请求线程和硬件控制三、现象展示总结 前言 书接上期,我们可以看一下前面的功能设计的部分,网页端的控制还有一个,那就是通过网页来控制zigbee上的风扇节点,这部分的工作量是相当大的&#x…...

Ubuntu 22.04 在登录界面循环
问题描述 https://blog.csdn.net/weixin_44023406/article/details/134092271?spm1001.2014.3001.5502 接上一篇,磁盘满了,扩展空间之后能正常开机,进到登录界面,输密码3秒后又回到登录界面 分析解决问题 命令行能登录&#…...

【C++ 系列文章 -- 程序员考试 201805 下午场 C++ 专题 】
文章目录 1.1 C 题目六1.1.1 填空(1)详解1.1.1.1 C 纯虚函数介绍 1.1.2 填空(2)详解1.1.2.1 父类声明了带参构造函数1.1.2.2 子类中构造函数的构造原则 1.1.3 填空(3)详解1.1.4 填空(4ÿ…...

Python如何使用datetime模块进行日期和时间的操作
目录 一、引言 二、datetime模块的基本使用 三、日期的运算 四、注意事项 总结 本文将对Python的datetime模块进行深入探讨,阐述如何使用该模块进行日期和时间的各种操作。我们将介绍日期和时间的基本操作,以及格式化、时区处理等高级操作ÿ…...

flutter之bloc使用详解
flutter中一切皆为Widget,因此在我们开发中,往往业务和UI逻辑写在一起,这样不利于代码维护,因此状态管理框架久诞生了,这篇就开始讲一讲Bloc。 对于Bloc库有两个,如下图: flutter_bloc其实是对…...

记一次 .NET 某工厂无人车调度系统 线程爆高分析
一:背景 1. 讲故事 前些天有位朋友找到我,说他程序中的线程数爆高,让我帮忙看下怎么回事,这种线程数爆高的情况找问题相对比较容易,就让朋友丢一个dump给我,看看便知。 二:为什么会爆高 1. …...

高等数学啃书汇总重难点(九)多元函数微分法及其应用
下册最重要也是个人认为偏恶心的一节(主要东西是真不少....)重点在于会计算偏导、能理解全微分及隐函数求导3个核心内容,至于后面的关于几何层面的应用,建议掌握计算方法即可,学有余力再死磕推导过程等内容~ 1.平面点集…...

Vue3前端100个必要的知识点
为什么是必要的,就是这100个知识点学完后,能独立完成一个小项目。最终能得到一个解决方案。也算是前端知识的积累。如果后面有需要的地方可以回来查。100个其实比较多,我会按新手老鸟,大神来分成3个等级,话不多说&…...

CCS3列表和超链接样式
在默认状态下,超链接文本显示为蓝色、下画线效果,当鼠标指针移过超链接时显示为手形,访问过的超链接文本显示为紫色;而列表项目默认会缩进显示,并在左侧显示项目符号。在网页设计中,一般可以根据需要重新定…...

vue手机项目如何控制蓝牙连接
要控制蓝牙连接,您需要使用Vue的蓝牙插件或库,例如BLE-Peripheral或cordova-plugin-ble-central。以下是一些基本步骤: 导入蓝牙插件或库。在Vue组件中创建一个蓝牙对象并初始化它。扫描周围的蓝牙设备并连接到所需的设备。一旦连接成功&…...

遥遥领先,免费开源的django4-vue3项目
星域后台管理系统前端介绍 🌿项目简介 本项目前端基于当下流行且常用的vue3作为主要技术栈进行开发,融合了typescript和element-plus-ui,提供暗黑模式和白昼模式两种主题以及全屏切换,开发bug少,简单易学,…...

视频平台跨网级联视频压缩解决方案
一、 简介 视频监控领域对带宽有着较大的需求,这是因为视频流需要实时占用网络带宽资源。视频监控的传输带宽是组网结构的基础保障,关系到视频监控的稳定性、可靠性和可拓展性等因素。例如,720P的视频格式每路摄像头的比特率为2Mbpsÿ…...

利用python进行数据分析 pdf
利用python进行数据分析 pdf 介绍 在现代社会中,随着大数据时代的到来,数据分析的需求越来越大。而Python作为一门简洁且易于学习的编程语言,具有强大的数据分析能力,成为了广大数据分析师的首选工具之一。本文将指导一位刚入行的…...

Day46.算法训练
518. 零钱兑换 II class Solution {public int change(int amount, int[] coins) {int dp[] new int[amount 1];dp[0] 1;// 遍历物品for (int i 0; i < coins.length; i) {// 遍历背包 从小到大for (int j coins[i]; j < amount; j) {dp[j] dp[j - coins[i]]; …...

基于YOLOv8模型暗夜下人脸目标检测系统(PyTorch+Pyside6+YOLOv8模型)
摘要:基于YOLOv8模型暗夜下人脸目标检测系统可用于日常生活中检测与定位黑夜下人脸目标,利用深度学习算法可实现图片、视频、摄像头等方式的目标检测,另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检测算法…...

如何在 Photoshop 中使用位图模式制作自定义音乐海报
如何在 Photoshop 中使用位图创建炫酷的音乐海报设计。 1.如何设置新的 Photoshop 文件 步骤1 在 Photoshop中,转到 “文件”>“新建”。将文档命名为 “音乐海报”。 将宽度设置 为 1270 px , 高度 设置为 1600 px。将分辨率 设置 为 72 像素/英寸…...

1 — NLP 的文本预处理技术
一、说明 在本文中,我们将讨论以下主题:1为什么文本预处理很重要?2 文本预处理技术。这个文对预处理做一个完整化、程序化处理,这对NLP处理项目中有很大参考性。 二、为什么文本预处理很重要? 数据质量显着影响机器学习…...

TypeScript之泛型
一、是什么 泛型程序设计(generic programming)是程序设计语言的一种风格或范式 泛型允许我们在强类型程序设计语言中编写代码时使用一些以后才指定的类型,在实例化时作为参数指明这些类型 在typescript中,定义函数,…...

一个小妙招从Prompt菜鸟秒变专家!加州大学提出PromptAgent,帮你高效使用ChatGPT!
夕小瑶科技说 原创 作者 | 谢年年、王二狗 有了ChatGPT、GPT4之后,我们的工作学习效率得到大大提升(特别在凑字数方面୧(๑•̀◡•́๑)૭)。 作为一个工具,有人觉得好用,自然也有人觉得难用。 要把大模型用得6&am…...

Netty通信框架
Netty框架的底层是NIO,NIO:non-blocking io 非阻塞IO 一个线程可以处理多个通道,减少线程创建数量; 读写非阻塞,节约资源:没有可读/可写数据时,不会发生阻塞导致线程资源的浪费 一…...

6西格玛质量标准: 提升业务效率的关键
在现代竞争激烈的商业环境中,企业需要不断提高效率,降低成本,同时确保产品和服务的质量。为了达到这个目标,许多企业已经转向了6西格玛质量标准。这个方法旨在通过最小化缺陷和提高流程稳定性来优化业务运作,为客户提供…...

OpenGL ES相关库加载3D 车辆模型
需求类似奇瑞的这个效果,就是能全方位旋转拖拽看车,以及点击开关车门车窗后备箱等 瑞虎9全景看车 (chery.cn) 最开始收到这个需求的时候还有点无所适从,因为以前没有做过类似的效果,后面一经搜索后发现实现的方式五花八门…...

云原生环境下JAVA应用容器JVM内存如何配置?—— 筑梦之路
Docker环境下的JVM参数非定值配置 —— 筑梦之路_docker jvm设置-CSDN博客 之前简单地记录过一篇,这里在之前的基础上更加细化一下。 场景说明 使用Java开发且设置的JVM堆空间过小时,程序会出现系统内存不足OOM(Out of Memory)的…...

防雷接地测试方法完整方案
防雷接地是保障电力系统、电子设备和建筑物安全的重要措施,防雷接地测试是检验防雷接地装置是否合格的必要手段。本文介绍了防雷接地测试的原理、方法和注意事项,以及如何编写防雷接地测试报告。 地凯科技防雷接地测试的原理 防雷接地测试的基本原理是…...

【云原生-K8s】Kubernetes安全组件CIS基准kube-beach安装及使用
基础介绍kube-beach介绍kube-beach 下载百度网盘下载wget下载 kube-beach安装kube-beach使用基础参数示例结果说明 基础介绍 为了保证集群以及容器应用的安全,Kubernetes 提供了多种安全机制,限制容器的行为,减少容器和集群的攻击面…...

玩家必备,2款顶级游戏录屏软件!
“游戏怎么录屏呀?最近迷上了网游,觉得自己的游戏技术挺厉害的,想把游戏视频录下来出一个教程,方便给朋友进行参考,但是我不会录屏,大家有没有游戏录屏的软件或者方法推荐一下。” 随着游戏产业的飞速发展…...

七、W5100S/W5500+RP2040树莓派Pico<UDP 组播>
文章目录 1. 前言2. 相关简介2.1 简述2.2 优点2.3 应用 3. WIZnet以太网芯片4. UDP 组播回环测试4.1 程序流程图4.2 测试准备4.3 连接方式4.4 相关代码4.5 测试现象 5. 注意事项6. 相关链接 1. 前言 UDP组播是一种基于UDP协议的通信方式,它允许一台计算机通过发送单…...

Wonder3D:用单张图片生成纹理网格
Wonder3D 只需 2 ∼ 3 分钟即可从单视图图像重建高度详细的纹理网格。 Wonder3D首先通过跨域扩散模型生成一致的多视图法线图和相应的彩色图像,然后利用新颖的法线融合方法实现快速、高质量的重建。 推荐:用 NSDT编辑器 快速搭建可编程3D场景 1、推理准…...

macOS 创建Flutter项目
参考在 macOS 上安装和配置 Flutter 开发环境 - Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 这个文档,配置好flutter的环境 编辑器可以选择vscode或者IDEA。 我这里以IDEA为例 打开 IDE 并选中 New Flutter Project。 选择 Flutter,验证 F…...

【微服务 Spring Cloud Alibaba】- Nacos 服务注册中心
目录 1. 什么是注册中心? 1.2 注册中心的作用 2. SpringBoot 整合 Nacos 实现服务注册中心 2.1 将服务注册到 Nacos 2.2 实现消费者 3. 服务列表各个参数的含义、作用以及应用场景 1. 什么是注册中心? 注册中心是微服务架构中的一个重要组件&…...