项目的github地址:https://github.com/zhangruyi3906/smartFarm/
总结:
第一天实训总体十分的轻松
每天坚持写技术日志
认真写好工程实践报告
M0开发板的控制命令的格式:
环境:十六进制 36字节 BB ID 24 00 命令格式: 十六进制 ---- 36个字节
DD id 24 00 00 --- 开灯 DD id 24 00 01 --- 关灯 DD id 24 00 02 -- 开蜂鸣器 DD id 24 00 03 -- 关蜂鸣器 DD id 24 00 04 --- 开风扇 DD id 24 00 08 --- 关风扇
eg:dd 09 24 00 01
linux基础
常用命令
1、打开终端:
-
双击图标
-
ctrl alt + t
2、创建文件夹
-
mkdir 文件名
dpkg -l 查看所有已经安装的软件
dpkg -s vim 查看某一个软件的安装状态
cd 直接进入的就是家目录=/home/zhangruyi
根目录下是共享的,公有的文件,普通用户没有操作权限
sudo apt-get remove vim
sudo apt-get install vim
在线从某一个网站上下载软件包到本地
3、进入文件夹
-
cd 文件名
-
cd .. 返回上一级目录
4、查询当前目录文件
-
ls
5、vi编辑器
-
命令行模式
-
yy 复制一行
-
dd 删除/剪切
-
p 粘贴
-
u 撤销
-
xyy 复制多行
-
xdd 删除多行
-
-
插入模式
-
a i o 进入插入模式
-
-
底行模式(退出插入模式 ESC)
-
:w 保存
-
:q 退出
-
:wq 保存并退出
-
6、gcc 编译器
-
gcc test.c //默认生成a.out可执行文件
-
gcc test.c -o test //生成test可执行文件
ps -ef | grep nginx
和 ps aux | grep nginx
都可以用来查看包含 "nginx" 关键词的进程信息,只是显示的格式略有不同。
ps -ef
和 ps aux
都是用于查看系统中的进程信息的命令。
-
|
是管道符号,用于将前一个命令的输出作为后一个命令的输入。 -
grep nginx
用于过滤出包含 "nginx" 关键词的进程信息。
所用指令:
touch 1.c
ls
gcc 1.c
vi 1.c
./a.out 执行二进制文件
a9开发板
m0开发板
zigbee模块:
智能农场
-
需求:温湿度、光照、浴霸、排风扇、报警、自动浇水、摄像头
-
怎么来实现?
总结:
要用到的技术
-
编程语言:C语言、C++
-
开发平台:linux系统、QT
-
v4l2编程(摄像头采集图像)
-
zigbee编程
-
网络编程
最终实现效果图
系统架构图:
Zigbee协调器节点(建立网络,配对和终端节点连接)和终端节点(接收数据,从温湿度传感器等接收数据)
打开USB0串口,调用函数进行串口属性初始化
创建camera_fd套接字
一个qt客户端的代码文件,主要是qt的ui界面及其公共按钮监听,就是按下后发送命令,
三个系统:虚拟机、本机windows和能够烧录Linux系统的A9开发板,本机负责安装和启动QT客户端,虚拟机负责将运行在开发板上的服务器端代码.c文件进行编译为可执行文件默认为a.out,也可以改名字,再将可执行文件通过scp命令传给开发板执行,而后开发板通过串口连接的zigbee模块,与控制电路(智能农场)交互信息,控制电路(也就是风扇、小灯的那块板子m0)的代码是提前写好烧制的,中间可以用串口调试助手来预调试。
最后是win上的QT客户端-----网线局域网-------》linux服务器主板(arm-cortexA9)--->(串口线)----> zigbee协调器+摄像头-->(m0上的zigbee终端)+M0(stm32类型的)
服务器主板:1.电源线 2.超级终端控制线 3. 串口线(摄像头+zigbee协调器)4.网线(局域网+通过ssh协议安全接收传输过来的文件)
透传数据
电阻R、电容C、串口线、SD卡烧录镜像8GB、zigbee
大小端: pc-小端 网络字节序:大端
tcp/ip中的大小端是什么
在计算机中,大小端(Endianness)是指数据在内存中的存储方式。具体来说,大小端描述了多字节数据在内存中的字节顺序。
小端(Little Endian)是指数据的低位字节存储在内存的低地址处,而高位字节存储在内存的高地址处。这意味着在小端系统中,较低有效位的字节会先存储在内存中。
大端(Big Endian)则相反,是指数据的高位字节存储在内存的低地址处,而低位字节存储在内存的高地址处。在大端系统中,较高有效位的字节会先存储在内存中。
在网络通信中,TCP/IP协议规定了网络字节序(Network Byte Order),即数据在网络中传输的字节顺序。TCP/IP协议要求使用大端字节序进行数据传输,也就是说,数据在网络中传输时,高位字节先传输,低位字节后传输。
为了在不同大小端系统之间进行数据传输,通常需要进行字节序转换。在C语言中,可以使用函数如htons和htonl将主机字节序转换为网络字节序,使用函数如ntohs和ntohl将网络字节序转换为主机字节序。
(在大端系统中,高位字节存储在低地址,低位字节存储在高地址;而在小端系统中,高位字节存储在高地址,低位字节存储在低地址。)
· ping命令:测试网络连通性 导致ping不通的原因: 1)双方不在同网段 2)防火墙拦截
涉及的参与方
(1)客户端(Qt上位机)
(2)服务端 + 摄像头 处理数据及中间通道
中间桥梁 串口(传输数据)、zigbee网络
(3)设备端:M0采集数据(实现相应的功能)
网络编程
文件描述符 : 文件的唯一标识
套接字
-
TCP 传输控制协议、有连接、保证数据可靠性;
-
两种模型
-
b/s (b 浏览器 s 服务器)
-
c/s (c 客户端 s 服务器)
-
ip:用来区分主机的唯一标识;
端口号:用来判断主机接收到的数据,应该交给那个任务去处理
TCP服务器的搭建流程:
-
创建套接字 socket()
-
绑定ip、端口号 bind()
-
监听连接 listen()
-
建立连接 accept()
-
通信 read()/write()
-
关闭套接字 close()
socket()
功能:创建套接字
头文件: #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> 函数原型: int socket(int domain, int type, int protocol); 参数: domain: AF_INET ipv4的协议 type: SOCK_STREAM 流式套接字 protocol: 传0,使用默认协议 返回值: 成功:返回新创建的套接字 失败:返回-1 返回0代表程序执行成功 返回-1代表程序执行失败 eg: int sockfd = socket(AF_INET,SOCK_STREAM,0); if(sockfd == -1) { perror("socket"); return -1; } 缩进命令:gg = G
bind()
功能:绑定ip、端口号
头文件: #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> 函数原型: int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen); 参数: sockfd: 创建的套接字 addr: 地址结构体 addrlen: 地址结构体的长度 返回值: 成功:返回0 失败:返回-1 //通用地址结构体 struct sockaddr { sa_family_t sa_family; char sa_data[14]; } //ipv4地址结构体 struct sockaddr_in { sa_family_t sin_family; /* address family: AF_INET */ in_port_t sin_port; /* port in network byte order */ struct in_addr sin_addr; /* internet address */ }; /* Internet address. */ struct in_addr { uint32_t s_addr; /* address in network byte order */ }; eg: struct sockaddr_in saddr; bzreo(&saddr,sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_port = htons(6666); saddr.sin_addr.s_addr = inet_addr("192.168.6.33"); if(-1 == bind(sockfd, (struct sockaddr *)&saddr,sizeof(saddr))) { perror("bind"); return -1; }
listen()
eg: if(-1 == listen(sockfd, 5)) { perror("listen"); return -1; }
accept()
eg: int connfd = accept(sockfd, NULL, NULL); if(connfd == -1) { perror("connfd"); return -1; } read()/write(); close(connfd); close(sockfd);
tcp/ip协议通信示意图
/i/ll/?i=57129c6b6dc0410797aa2560bfb080c9.png#pic_center
华清张路东老师-----网络通信相关
-
下述命令找不到
使用:sudo apt-get install lib32z1
#
*【ARM】arm-linux-gcc 没有那个文件或目录*
【ARM】arm-linux-gcc 没有那个文件或目录_linux 怎么找到arm-linux-gcc存放的路径-CSDN博客【ARM】arm-linux-gcc 没有那个文件或目录_linux 怎么找到arm-linux-gcc存放的路径-CSDN博客v100pc_search_result_base4&utm_term=zhangruyi%40zhangruyi-virtual-machine%3A%7E%2Fgcc-4.6.4%2Fbin%24%20arm-linux-gcc%20-v%20bash%3A%20%2Fhome%2Fzhangruyi%2Fgcc-4.6.4%2Fbin%2Farm-linux-gcc%3A%20No%20such%20file%20or%20directory%20zhangruyi%40zhang&spm=1018.2226.3001.4187
由以下问题所引发的上述问题:
-
虚拟机连外网ping命令,和tracecert命令都是检查网络的可达性和网络情况的,基于icmp网络报文控制协议。
-
实验设备
-
需要安装一个dll文件
(1)XShell的使用文档,
连接服务器如虚拟机Linux,
串口配置
弹出下面对话框
选本地有的串口,波特率选115200
虚拟机配置
(2)windows版本的Qt安装方法
1、 先断网(wifi和有限网络都断开)
2、 点击安装包
3、 一直点击下一步,直到下面的页面
4、选择MinGW 5.10.1 32bit
5、继续安装直到完成。
(3)网络编程相关知识
1.网络编程: 0.地址结构: 1.IP地址: typedef uint32_t in_addr_in;
struct in_addr { in_addr_in s_addr; }; #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netinet/ip.h> 将字符型ip转成整型ip: in_addr_t inet_addr(const char *cp) 将整型ip转成字符型ip: char *inet_ntoa(struct in_addr in); 使用任意IP:htonl(INADDR_ANY); 2.通用地址结构: struct sockaddr { u_short sa_family; char sa_data[14]; }; 3.Internet协议地址结构: struct sockaddr_in { u_short sin_family; //地址族 AF_INET u_short sin_port; //端口号,4位,0~65535,0~1023被系统占用,普通应用程序用1024以上端口,如8080,8888等等,赋值htons(8080)或者htons(8080) struct in_addr sin_addr; //IPV4地址,服务器地址,inet_addr(const char *cp) char sin_zero[8]; //字节的补充 };
1.创建服务器: 0.套接字: 文件描述符-->唯一标识一个打开或者创建的文件 PID -->唯一标识一个进程 套接字-->标识一个服务器/客户端(特殊的文件描述符) IP: IP地址 端口:标识发到哪个进程 1.创建套接字: #include <sys/types.h> #include <sys/socket.h> /* See NOTES */
函数原型: int socket(int domain, int type, int protocol); 函数功能: 创建套接字 参数: domain -- AF_INET type -- SOCK_STREAM protocol-- 0 返回值: 成功:套接字 失败:-1
2.绑定服务器IP、端口等:{ #include <sys/types.h> #include <sys/socket.h> /* See NOTES */ 函数原型: int bind(int sockfd, const struct sockaddr *addr, int addrlen) 函数功能: 绑定服务器IP、端口 参数: sockfd -- 套接字 addr -- 地址结构(通用地址结构) addrlen-- 地址结构的长度 返回值: 成功0 失败-1 }
3.设置监听数:{ #include <sys/types.h> #include <sys/socket.h> /* See NOTES */ 函数原型: int listen(int sockfd, int backlog); 函数功能: 设置监听数 参数: sockfd -- 套接字 backlog -- 最大等待队列长度 返回值: 成功返回0,失败返回-1 } 4.等待连接:{ #include <sys/types.h> #include <sys/socket.h> /* See NOTES */ 函数原型: int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 函数功能: 等待连接 参数: sockfd -- 监听套接字 addr -- 客户端的地址结构 addrlen-- 客户端地址结构长度 返回值: 成功返回客户端读写套接字,失败返回-1 } 5.通信: 收: read: #include <unistd.h> 函数原型: ssize_t read (int fd, void *buf, size_t count); 函数功能: 读 参数: fd --打开的文件的文件描述符 buf --从fd中读,存放到buf中 count--读多少字节 返回值: 成功返回实际读到的字节数,返回0代表读到文件末尾,失败返回-1
发:write: #include <unistd.h> 函数原型: ssize_t write(int fd, const void *buf, size_t count); 函数功能: 写 参数: fd --写入的文件的文件描述符 buf --从哪里写 count--写多少字节 返回值: 成功返回实际写入的字节数,返回0代表读完了,失败返回-1
6. 关闭:{ #include <unistd.h> 函数原型: int close(int fd) 函数功能: 关闭 参数: fd -- 打开的文件的文件描述符 返回值: 成功返回0,失败返回-1 } } 2.创建客户端: 1.创建套接字: #include <sys/types.h> #include <sys/socket.h> /* See NOTES */ 函数原型: int socket(int domain, int type, int protocol); 函数功能: 创建套接字 参数: domain -- AF_INET type -- SocK_STREAM protocol--0 返回值: 成功:套接字 失败:-1
2.连接服务器IP、端口等: # include <sys/types.h > # include <sys/socket.h > 函数原型: int connect(int sockfd, struct sockaddr *addr, int addrlen); 函数功能: 连接服务器IP、端口等 参数: sockfd -- 套接字 addr -- 服务端的地址结构(通用地址结构) addrlen -- 地址结构的长度 返回值: 成功0 失败-1
3.通信: 收: read: #include <unistd.h> 函数原型: ssize_t read (int fd, void *buf, size_t count); 函数功能: 读 参数: fd --打开的文件的文件描述符 buf --从fd中读,存放到buf中 count--读多少字节 返回值: 成功返回实际读到的字节数,返回0代表读到文件末尾,失败返回-1
发:write: #include <unistd.h> 函数原型: ssize_t write(int fd, const void *buf, size_t count); 函数功能: 写 参数: fd --写入的文件的文件描述符 buf --从哪里写 count--写多少字节 返回值: 成功返回实际写入的字节数,返回0代表读完了,失败返回-1
4. 关闭:{ #include <unistd.h> 函数原型: int close(int fd) 函数功能: 关闭 参数: fd -- 打开的文件的文件描述符 返回值: 成功返回0,失败返回-1 } }
标签:include,字节,--,农场,联网,int,接字,嵌入式,addr From: https://blog.csdn.net/m0_63267586/article/details/139587282