从零开始学习嵌入式_智能小车实例拓展 | 青训营笔记

141 阅读3分钟

智能小车

理论+实战 1.C复习

2.IO➡️文件➡️open/close read/write (IO操作串口文件)

引言

挺无聊的真的,学了半天才学到控制智能小车,还是继续加油吧,简单记录了一下智能小车与服务端以及客户端的控制,后面再映射在其他地方吧。

构造

1.路由板:由Linux系统搭建,作为服务器

2.STM32板:

(1)gpio:

「1」电机

「2」摄像头

网络体系结构

OSI

TCP

ip地址

在网络中唯一标识一台主机的符号

网络协议

在网络通信中对某种通信规则的约定

TCP/ip 协议:应用层-》传输层-〉网络层-》网络接口和物理层

端口号

区分应用程序 1-65535 1024~65535

字节序

不同的CPU主机存储多字节的方式

有大端主机和小端主机字节序,大小端由cpu决定

0x12345678,两位两位放

大端序主机:数据的高字节存放在内存的低地址

小端序主机:数据的高字节存放在内存的高地址

由于机型系统不同,所以我们需要将主机字节序-》网络字节序 :htons htonl

基于TCP协议的网络客户端和服务端

服务端:socket-》bind-〉listen-》accept-〉IO函数

客户端:socket-》connect-〉IO函数

在Linux中实践

vi tcp Client.c ​ cd.. mkdir xawl605 cd xawl605/

socket:

int socket(int domain, int type, int protocol);

bind:

int bind(int sockfd,const struct sockaddr *addr, socklen_t addrlen);

listen:

#include <sys/types.h> #include <sys/socket.h> int listen(int sockfd, int backlog);

accept:

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

recv:

ssize_t recv(int sockfd, void *buf, size_t len, int flags); //通道、容器,长度,判断

tcpserver.c:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h> //sockaddr
#include <string.h>
​
#define BUF_SIZE 100
int main(){
  //1.socket:创建Socket通道
  int iServer = socket(AF_INET,SOCK_STREAM,0);
  if(-1 == iServer)
  {
    printf("create socket error!--------------\r\n");
    return -1; //失败就返回-1
  }
  printf("1:create socket ok!-----------------\r\n");
  //2.bind
  struct sockaddr_in stServer;
  stServer.sin_family = AF_INET;
  stServer.sin_port = htons(8888);
  stServer.sin_addr.s_addr = inet_addr("127.0.0.1");
  int ret = bind(iServer,(struct sockaddr *)&stServer,sizeof(struct sockaddr));
  if(-1 == ret)
  {
    printf("bind error!-------------------\r\n");
    return -1;
  }
  printf("bind ok!-----------------------\r\n");
  //3.listen侦听
  ret = listen(iServer,5);
  if(-1 == ret){
    printf("listen error!----------------\r\n");
    return -1;
  }
  printf("listen ok!-------------------\r\n");
  //4.accept
  struct sockaddr_in stClient;
  socklen_t len = sizeof(struct sockaddr_in); //sizeof运算符
  char buf[BUF_SIZE];
  while(1){
    memset(buf,0,BUF_SIZE); //清空数组内容
    memset(&stClient,0,len); //对应上面的len
    int iClient = accept(iServer,(struct sockaddr *)&stClient,&len);
    if(-1 == iClient){
      printf("accept error!-----------------\r\n");
      return -1;
    }
    printf("accept OK!---------------------\r\n");
    //5.recv/send
    //recv
    ret = recv(iClient,buf,BUF_SIZE,0);
    if(ret<=0){
      close(iClient);
      continue;
    }
    printf("recv data:%s ret=%d\r\n",buf,ret)
    //send
    ret = send(iClient,buf,BUF_SIZE,0);
    printf("send data:%s ret=%d\r\n",buf,ret);
    close(iClient);
  }
  return 0;
}

最后编译运行:

gcc -o tcpserver tcoserver.c
gcc -o tcp_client tcp_client.c

连接客户端与服务器:

./tcp_client
./tcpserver

智能小车运行环境

PC环境

1.连接Wi-Fi:farsight001

2.配置虚拟机桥接到PC的无线网卡上:打开虚拟机->编辑“虚拟网络编辑器”->桥接模式->网卡选择本机的无线网卡->最后点击应用;

虚拟机设置->设置->网络适配器->自定义->选择VMnet0(桥接模式)

选中右上角的网络配置图标->关闭wired connection1->再打开wired connection1->shell终端输入ifconfig来查看ip是否同步了

3.在虚拟机的shell终端:ping 192.168.1.1,查看是否跟小车ping的通

4.在虚拟机的目录下运行客户端程序:

./tcpClient
forward //前进指令
back //后退指令
left //向左指令
right //向右指令

注意:先运行智能小车上的服务器程序,再运行虚拟机中的客户端程序。

小车环境

1.需要将在虚拟机中编译好的服务端代码servertest1,远程拷贝到智能小车系统中:

$:sudu scp servertest1 root@192.168.1.1:/root

2.从虚拟机的shell界面远程登录到智能小车系统中:

$:sudo ssh 192.168.1.1
  sudo ssh-keygen -f"/root/.ssh/known_hosts" -R 192.168.1.1
  sudo ssh 192.168.1.1
root@openwrt$:

3.进入智能小车系统后

root@openwrt$:ps //ps:查看系统运行的进程

找到ser2net进程对应的进程号,假设对应的进程号是1000那么用kill指令杀死该进程

root@openwrt$:kill -9 1000
root@openwrt$:ls
root@openwrt$:./servertest1