嵌入式开发-基于物联网的智能农场项目

项目的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、打开终端:

  1. 双击图标

  2. ctrl alt + t

2、创建文件夹

  1. mkdir 文件名

dpkg -l 查看所有已经安装的软件

dpkg -s vim 查看某一个软件的安装状态

cd 直接进入的就是家目录=/home/zhangruyi

根目录下是共享的,公有的文件,普通用户没有操作权限

sudo apt-get remove vim

sudo apt-get install vim

在线从某一个网站上下载软件包到本地

3、进入文件夹

  1. cd 文件名

  2. cd .. 返回上一级目录

4、查询当前目录文件

  1. ls

5、vi编辑器

  1. 命令行模式

    1. yy 复制一行

    2. dd 删除/剪切

    3. p 粘贴

    4. u 撤销

    5. xyy 复制多行

    6. xdd 删除多行

  2. 插入模式

    1. a i o 进入插入模式

  3. 底行模式(退出插入模式 ESC)

    1. :w 保存

    2. :q 退出

    3. :wq 保存并退出

6、gcc 编译器

  1. gcc test.c //默认生成a.out可执行文件

  2. gcc test.c -o test //生成test可执行文件

ps -ef | grep nginxps aux | grep nginx 都可以用来查看包含 "nginx" 关键词的进程信息,只是显示的格式略有不同。

ps -efps aux 都是用于查看系统中的进程信息的命令。

  • | 是管道符号,用于将前一个命令的输出作为后一个命令的输入。

  • grep nginx 用于过滤出包含 "nginx" 关键词的进程信息。

所用指令:

touch 1.c

ls

gcc 1.c

vi 1.c

./a.out 执行二进制文件

a9开发板

IMG_20240607_111715(1)

m0开发板

IMG_20240607_111706

zigbee模块:

IMG_20240607_111709

智能农场

  1. 需求:温湿度、光照、浴霸、排风扇、报警、自动浇水、摄像头

  2. 怎么来实现?

19d9834caf66116c94d331e1a1d442a2

总结:

要用到的技术

  1. 编程语言:C语言、C++

  2. 开发平台:linux系统、QT

  3. v4l2编程(摄像头采集图像)

  4. zigbee编程

  5. 网络编程

最终实现效果图

image-20240605213805603

系统架构图:

3ffc500a3b850cfa463895956d00dbae

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采集数据(实现相应的功能)

网络编程

文件描述符 : 文件的唯一标识

套接字

  1. TCP 传输控制协议、有连接、保证数据可靠性;

  2. 两种模型

    1. b/s (b 浏览器 s 服务器)

    2. c/s (c 客户端 s 服务器)

ip:用来区分主机的唯一标识;

端口号:用来判断主机接收到的数据,应该交给那个任务去处理

TCP服务器的搭建流程:

  1. 创建套接字 socket()

  2. 绑定ip、端口号 bind()

  3. 监听连接 listen()

  4. 建立连接 accept()

  5. 通信 read()/write()

  6. 关闭套接字 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协议通信示意图

https://img-blog.csdnimg.cn/57129c6b6dc0410797aa2560bfb080c9.png#pic_center

cf0368a96ea8a837114d447d12e9be0d

image-20240605210243370

华清张路东老师-----网络通信相关

  1. 下述命令找不到

d333c42082284d6cc15b442acb7e3d1a

使用: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

由以下问题所引发的上述问题:

img

img

  1. 虚拟机连外网ping命令,和tracecert命令都是检查网络的可达性和网络情况的,基于icmp网络报文控制协议。

  2. 实验设备

    869ae8b4a2da36c48515107e276f7e67

  3. 105b72307d94aedfbf023ae890983db9

    需要安装一个dll文件

    image-20240605210038457

(1)XShell的使用文档,

连接服务器如虚拟机Linux,

串口配置

img

弹出下面对话框

img

选本地有的串口,波特率选115200

img

虚拟机配置

img

img

img

(2)windows版本的Qt安装方法

1、 先断网(wifi和有限网络都断开)

2、 点击安装包

img

3、 一直点击下一步,直到下面的页面

img

4、选择MinGW 5.10.1 32bit

img

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 ​ } ​ }

  • 23
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值