【Arm+Qt】基于Nanopi duo2的WiFi智能摄像头

1.固件包烧录

https://wiki.friendlyelec.com/wiki/index.php/NanoPi_Duo2/zh#.E8.BF.9E.E6.8E.A5WiFi
固件包链接以及烧录工具都在上面链接中
在这里插入图片描述
烧录过程
使用读卡器将SD卡插入到电脑,然后打开烧录工具
在这里插入图片描述

在这里插入图片描述

2.通过串口工具连接板子使其连接WiFi

对应的串口工具,就是这个HyperTerminal
在这里插入图片描述
由于是第一次启动板子,板子还没有连接WiFi,所以需要通过该软件来连接
在这里插入图片描述
然后需要连接WiFi(root账号的密码为fa)
在这里插入图片描述
使用ifconfig命令查看给板子分配的IP地址
在这里插入图片描述
然后就不需要串口线,我们只需要对板子供电即可
接着我们直接使用云服务器来访问板子,通过给板子分配的ip地址,用户名为root,密码为fa
在这里插入图片描述
此时我们可以理解该云服务器就是这块Linux板子,也可以直接在这个上面编译,但是不建议
在Nanopi duo2板子会在云服务器上搭建,而确实也可以直接在板子上编译,但是由于Linux板子其CPU,内存等资源相对有限,所以我们会使用交叉编译,在虚拟机中编译好,然后将编译好的程序发送到云服务器上跑。
板子对应的架构是ARM,而虚拟机在电脑上是X86架构,二者对应生成的二进制文件不太一样,就相当于一个是中文版的,一个是英文版的,我们需要在虚拟机中使用交叉编译器将代码编译,然后发送到板子对应的云服务器下,就可以直接在板子上跑了

3.交叉编译器的下载

在这里插入图片描述

在这里插入图片描述
将下载包直接拖动到虚拟机上根目录的opt下
在这里插入图片描述
在这里插入图片描述
使用命令将其解压形成4.9.3

tar -xz arm-cortexa9-linux-gnueabihf-4.9.3-20160512.tar.xz

在/opt/4.9.3/bin/可以找到arm-linux-gcc交叉编译器,但是还是不能之间使用该命令进行编译,需要将该交叉编译器的路径导入到环境变量中就可以了。
使用root账户vim打开文件/root/.bashrc
在这里插入图片描述
退出来记得使用指令让配置文件生效

source /root/.bashrc

随便写一段代码
在这里插入图片描述
然后使用交叉编译器编译

arm-linux-gcc -o tt tt.c

在这里插入图片描述
使用file命令查看tt二进制文件信息
在这里插入图片描述
发现是ARM架构的,现在就可以下载到板子上了,通过下面的指令

在这里插入图片描述

4.mjpg-streamer

在Nanopi duo2上会带mjpg-streamer,摄像头会将采集到的摄像头数据放到/dev/video0文件中去,而mjpg-streamer会将/dev/video通过输入文件读到mjpg-streamer tcp服务器上,然后通过socket输出文件到网页上去,因为板子连接到路由器,我们就可以在浏览器上通过访问分配给板子的ip地址+端口号8080,就可以获得摄像头了,不过需要先编译形成输入库文件和输出库文件
在这里插入图片描述

在这里插入图片描述
如果没有的话需要使用make指令编译makefile,使其产生,然后运行start.sh即可
在这里插入图片描述
在浏览器上输入ip地址+端口号8080
在这里插入图片描述
就可以看到摄像头采集的图像
如果要修改分辨率的话,使视频更流程,我们可以降低分辨率通过设置start.sh文件

 vim start.sh

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.通过板子控制舵机转动

因为要使摄像头转动,我们使用到舵机,我们直接在板子上编译程序实现舵机转动,舵机转动的原理及操作方法在我之前的博客上有用到,通过设置PWM
在这里插入图片描述

首先需要上述操作进行编译安装
在这里插入图片描述
在这里插入图片描述

通过./bulid将二进制文件下载到开发板上

在这里插入图片描述
通过gpio readall指令查看
在这里插入图片描述
找到我们要操作的引脚
在这里插入图片描述
如图是我们接舵机的引脚,GPIOA11对应13号引脚

#include <wiringPi.h>
int main(void)
{
   
   
  wiringPiSetup() ;
  pinMode (13, OUTPUT) ;
  for(;;)
  {
   
   
    digitalWrite(13, HIGH) ;
    delay (1.5) ;
    digitalWrite(13,  LOW) ;
    delay (1.5) ;
  }
}

在这里插入图片描述
高电平为0.5ms为转0°,高电平为1.5ms为转90°,高电平为2.5ms为转180°
编译并运行

gcc  -o pwm pwm.c -lwiringPi -lpthread    
./pwm

在这里插入图片描述

6.代码编写

1.摄像头主程序

使用socket(tcp)
1.摄像头发送请求连接阿里云服务器



2.接收阿里云服务器的端口号信息

{
   
   "cmd":"port_info","port":9000} //云服务器返回端口号用于UDP连接接收视频数据

3.云服务器负责转发来自APP的控制到板子

{
   
   "cmd":"control","action":"left","appid":"1000","deviceid":"0001"} //服务器收到控制指令,转发给板子通过socket,tcp

4.创建线程完成向服务器发送视频数据

该部分代码在虚拟机中编写,然后交叉编译完,将生成的二进制文件发送到板子上跑
(但是我在虚拟机上写代码太卡了,于是我就在vscode上写好,然后发到虚拟机上去,交叉编译完了,在将二进制文件发到板子上跑)

#include <stdio.h>
#include <json-c/json.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <pthread.h>
uint16_t port=9000;
char* ip="47.121.24.16";

int main()
{
   
   


int sockfd=socket(AF_INET,SOCK_STREAM,0);  //创建套接字
if(sockfd<0)
{
   
   

    printf("socket error");
    exit(0);

}

  
  struct sockaddr_in aliserver;
  socklen_t len=sizeof(aliserver);
  aliserver.sin_family=AF_INET;
  aliserver.sin_port=htons(port);
  aliserver.sin_addr.s_addr=inet_addr(ip);
   

  if(connect(sockfd,(const struct sockaddr*)&aliserver,len)<0)   //连接服务器进行三次握手
  {
   
   
      printf("connect error");
      exit(1);


  }

  //使用json-c序列化请求
  struct json_object*obj=(struct json_object*)json_object_new_object();//new 一个json_object对象
  json_object_object_add(obj,"cmd",json_object_new_string("info"));//序列化
  json_object_object_add(obj,"deviceid",json_object_new_string("0001"));//序列化
  const char*s =json_object_to_json_string(obj);//将json_object对象转化为字符串
  if(send(sockfd,s,strlen,0)<0)//将请求发送到阿里云服务器
  {
   
   

    printf("send error");
      exit(2);





  }

   char buffer[256];
   if(recv(sockfd,buffer,sizeof(buffer),0)<0)//接收阿里云服务器的端口号信息
   {
   
   
     printf("recv error");
      exit(3);
   }
   

   struct json_object*json=json_tokener_parse(buffer);//将字符串转化为 json_object对象
   struct json_object*cmd,*port;//将json对象切割为两个对象
   cmd=json_object_object_get(json,"cmd");//以key来切割
   port=json_object_object_get(json,"port");//以key来切割
      uint16_t serverport;
      if(!strcmp((const char*)json_object_to_string(cmd),"port_info"))//如果返回是端口信息
   {
   
   


        serverport=json_object_to_int(port);//得到服务器端口号用于udp发送视频数据

   }

   //创建线程来实现发送视频数据到阿里云服务器
   //pthread_t tid;
   //pthread_create(&tid,nullptr,send_video,&serverport);//第一个参数为线程pid,
   ///第二个参数为结构体属性不需要,第三个为线程要执行函数(发送数据),第四个为向线程执行函数中传参端口号
   //由于未实现send_video函数,先注释掉


   while(1)   //在循环中接收服务器转发app的控制命令
   {
   
   

     memset(buffer,0,sizeof(buffer));
     if(recv(sockfd,buffer,sizoef(buffer),0)<0)
     {
   
   
         printf("recv error");
         exit(4);


     }
      struct json_object*tt=json_tokener_parse(buffer);//将字符串转化为 json_object对象
   struct json_object*cmd,*action;//将json对象切割为两个对象
   cmd=json_object_object_get(json,"cmd");//以key来切割
   action=json_object_object_get(json,"action");//以key来切割
   if(!strcmp((const char*)json_object_to_string(cmd),"control"))//如果接收到的是控制命令
      {
   
   

         const char* act=json_object_to_string(action);
         if(!strcmp(act,"left"))//摄像头左转
           {
   
   




           }
        else if(!strcmp(act,"right"))//摄像头右转
          {
   
   




          }

        else if(!strcmp(act,"up"))//摄像头上转
          {
   
   




          }

        else if(!strcmp(act,"down"))//摄像头下转
          {
   
   




          }





      }




   }



return 0;    
}

发送到桌面

sz ./test.c 

拖拽到虚拟机,但是现在先需要交叉编译json-c,交叉编译json-c,生成的库和test.c一起编译生成ARM架构的二进制文件

2.交叉编译json-c

1.将json-c-master下载并移动到虚拟机上(下载的话可以在github上下载)
在这里插入图片描述

2.在README中我们可以看到正常编译的步骤
在这里插入图片描述
我们直接按照步骤来
但在运行autogen.sh的时候需要先安装三个命令

apt-get install autoconf shtool libtool

这里如果出现网络不可达的话,就说明你的虚拟机没联网
虚拟机联网步骤
关闭虚拟机
在这里插入图片描述
3.运行./autogen.sh(生成configure)
4.运行configure(生成Makefile)

./configure --host=arm-linux --prefix=/home/xyd/smartcamera/install/

– – host表示要编译使用的编译器去掉后缀gcc, – --prefix指定头文件以及库文件的路径
5.make
这一步会有下面警告
在这里插入图片描述
解决方法:需要在Makefie中搜索到-Werror ,然后删除掉即可
在这里插入图片描述
6.重新make
7.make install
此时会在install下生成头文件,库文件
8.因为要编译 main.c 以及vedio.c 所以写一个makefil

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

#小多子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值