×
单片机 > 单片机程序设计 > 详情

基于EVK1105开发平台设计的交互式机器人小车

发布时间:2020-09-03 发布时间:
|

一. 正文

(1)、项目摘要

交互式机器人小车是可以通过wifi实现数据的采集,视频监控等功能的智能控制平台。它集娱乐、现场勘测等于一体,采用了具有超强的音频解码和流媒体处理能力的AT32UC3A0512作为核心,在EVK1105开发平台上成功嵌入网页。并且实现无需插件或asp、php等语言,仅依靠html语言的交互式控制。交互式机器人小车还可以完成视频的动态监控,无需任何插件即可在网页查看相关媒体。小车的控制也是直接在网页上完成,无需任何软件。如手机上有wifi,经测试也可直接登录控制。而且在小车上增加相关传感器模块,还可直接把数据发到网页上,再结合浏览器插件便可将数据直接导入相关数据库或上传到internet。

 

(2)、硬件原理

2.1 系统结构图

 

 

2.2、小车驱动模块

为了加强小车的野外数据采集能力,我们将小车设计为四驱结构并且全部采用360度舵机控制。这样虽然会降低小车的运行速度,但却让小车获得较大力矩和载重能力,使其在崎岖不平的草地上一样可以行动自如。在整个交互式机器人小车结构设计上我们一共采用了6个舵机:DS04-NFC 和 FUTABA3010。

 

DS04-NFC是360°舵机,主要用来驱动小车前进。它的控制信号是50HZ方波信号,一个高电平脉冲持续的时间对应一个速度。高电平为1毫秒~1.5毫秒时,舵机正转(1毫秒时正转速度最快,越接近1.5毫秒越慢,1.5毫秒时舵机停转),高电平为1.5毫秒~2毫秒时舵机反转(1.5毫秒时舵机停转,越接近2毫秒反转的速度越快,2毫秒时以最快的速度反转),转弯用差速控制。FUTABA3010则拥有摄像头云台,是180°舵机,根据所给PWM占空比不同可控制摄像头的左右转和上下转。

 

2.3 、Arduino控制板

在本次设计中我们采用了arduino328驱动电机,它主要是以Atmel的Atmega328作为核心,将MCU内部所有资源都编为开源的函数,可直接调用、查看、修改。具体原理图如下:

 

 

2.4、 DC-DC升压模块

这一模块主要是用于为无线路由器提供电源,具体电路如下:

 

                    

图(4):DC—DC升压电路

 

 

(3)、软件架构

软件部分我们主要分为三块:无线路由加motion摄像头监控、EVK1105上的Websever、Arduino上的舵机驱动。

 

3.1 无线路由模块

在无线路由上我们嵌入了openwrt操作系统用于管理网络连接、自动拨号、wifi控制等。UVC摄像头我们也是挂在路由器上的,采用了motion做视频管理。具体编辑如下:

root@OpenWrt:~# opkg install motion

Installing motion (3.2.11.1-1) to root...

Downloading http://downloads.x-wrt.org/xwrt/backfire/10.03/brcm63xx/packages/motion_3.2.11.1-1_brcm63xx.ipk.

Installing libjpeg (6b-1) to root...

Downloading http://downloads.x-wrt.org/xwrt/backfire/10.03/brcm63xx/packages/libjpeg_6b-1_brcm63xx.ipk.

Configuring libjpeg.

Configuring motion.

root@OpenWrt:~# vi /overlay/etc/motion.conf

# Rename this distribution example file to motion.conf

#

# This config file was generated by motion "3.2.11.1"

 

############################################################

# Daemon

############################################################

 

# Start in daemon (background) mode and release terminal (default: off)

daemon off (on->off)

 

# File to store the process ID, also called pid file. (default: not defined)

process_id_file /var/run/motion/motion.pid

 

############################################################

# Basic Setup Mode

############################################################

 

# Start in Setup-Mode, daemon disabled. (default: off)

setup_mode off

 

###########################################################

# Capture device options

############################################################

 

# Videodevice to be used for capturing (default /dev/video0)

# for FreeBSD default is /dev/bktr0

videodevice /dev/video0

 

# Image width (pixels). Valid range: Camera dependent, default: 352

width 320 (视频宽)

 

# Image height (pixels). Valid range: Camera dependent, default: 288

height 240 (视频高)

 

# Motion Detection Settings:

############################################################

 

# Threshold for number of changed pixels in an image that

# triggers motion detection (default: 1500)

threshold 1500 (灵敏度调节)

# Automatically tune the threshold down if possible (default: off)

threshold_tune off

 

# Noise threshold for the motion detection (default: 32)

noise_level 32

 

# Automatically tune the noise threshold (default: on)

noise_tune on

 

# Live Webcam Server

############################################################

 

# The mini-http server listens to this port for requests (default: 0 = disabled)

webcam_port 8081 #远程端口

# Quality of the jpeg images produced (default: 50)

webcam_quality 50

 

# Output frames at 1 fps when no motion is detected and increase to the

# rate given by webcam_maxrate when motion is detected (default: off)

webcam_motion off

 

# Maximum framerate for webcam streams (default: 1)

webcam_maxrate 1

 

# Restrict webcam connections to localhost only (default: on)

webcam_localhost off

 

# Limits the number of images per connection (default: 0 = unlimited)

# Number can be defined by multiplying actual webcam rate by desired number of seconds

# Actual webcam rate is the smallest of the numbers framerate and webcam_maxrate

webcam_limit 0

 

target_dir /tmp/cam1 保存目录

 

############################################################

# HTTP Based Control

############################################################

 

# TCP/IP port for the http server to listen on (default: 0 = disabled)

control_port 8080

 

# Restrict control connections to localhost only (default: on)

control_localhost on

 

# Output for http server, select off to choose raw text plain (default: on)

control_html_output on

 

# Authentication for the http based control. Syntax username:password

# Default: not defined (Disabled)

; control_authentication username:password

 

##############################################################

# Thread config files - One for each camera.

# Except if only one camera - You only need this config file.

# If you have more than one camera you MUST define one thread

# config file for each camera in addition to this config file.

##############################################################

 

# Remember: If you have more than one camera you must have one

# thread file for each camera. E.g. 2 cameras requires 3 files:

# This motion.conf file AND thread1.conf and thread2.conf.

# Only put the options that are unique to each camera in the

# thread config files.

thread /etc/thread1.conf

thread /etc/thread2.conf

# thread /etc/thread3.conf

# thread /etc/thread4.conf[page]

3.2 EVK1105模块

这一模块中我们主要是基于Lwip在Atmel公司的EVK1105开发平台上构建一个websever,完成人与车间的互动和数据的采集。具体界面如下:

 

 

 

下面是关于web的一段代码:

#if (HTTP_USED == 1)

/* Standard includes. */

#include

#include

 

#include "conf_eth.h"

 

/* Scheduler includes. */

#include "FreeRTOS.h"

#include "task.h"

#include "semphr.h"

#include "partest.h"

#include "serial.h"

 

/* Demo includes. */

/* Demo app includes. */

#include "portmacro.h"

 

/* lwIP includes. */

#include "lwip/api.h"

#include "lwip/tcpip.h"

#include "lwip/memp.h"

#include "lwip/stats.h"

#include "netif/loopif.h"

 

/* ethernet includes */

#include "ethernet.h"

 

#include "gpio.h"

 

#define GPIO_PIN_EXAMPLE_1  0            //传输控制代码

#define GPIO_PIN_EXAMPLE_2  1

#define GPIO_PIN_EXAMPLE_3  29

#define GPIO_PIN_EXAMPLE_4  30

 

//#include "usart.h"

 

/*! The size of the buffer in which the dynamic WEB page is created. */

#define webMAX_PAGE_SIZE    3072

 

/*! Standard GET response. */

#define webHTTP_OK   "HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n"

 

/*! The port on which we listen. */

#define webHTTP_PORT             ( 80 )

 

/*! Delay on close error. */

#define webSHORT_DELAY        ( 10 )

 

/*! Format of the dynamic page that is returned on each connection. */

/*!网页上按钮是用表单来构建的,不同的按钮发送不同的表单数值 */

#define webHTML_START \

"\

\

\

#39;index.html39;",1000)\" bgcolor=\"#FFFFFF\" text=\"#2477E6\">\

\r\n

2011 AVR Campus Design Competition

\

      

Jiangnan University

\

      

Interactive robot control platform car

\

\

\

\

\

\

\

\

 

\

\

 \

 \

\

\

\

\

 

\

  \r\n

\

\r\n\

\r\n\

  \r\n

\

 \r\n

\

\r\n\

\r\n\

  \r\n

\

\

\r\n\

\r\n\

 \r\n

\

 \r\n

\

\r\n\

\r\n\

 \r\n

\

 \r\n

\

\r\n\

\r\n\

 \r\n

\

 \r\n

\

\r\n\

\r\n\

 \r\n

"

#define webHTML_END \

"\r\n\

\r\n\

"

 

portCHAR cDynamicPage[ webMAX_PAGE_SIZE ];

portCHAR cPageHits[ 11 ];

int f;

 

/*! Function to process the current connection */

static void prvweb_ParseHTMLRequest( struct netconn *pxNetCon );

 

/*! \brief WEB server main task

 *         check for incoming connection and process it

 *

 *  \param pvParameters   Input. Not Used.

 *

 */

portTASK_FUNCTION( vBasicWEBServer, pvParameters )

{

struct netconn *pxHTTPListener, *pxNewConnection;

 

       /* Create a new tcp connection handle */

       pxHTTPListener = netconn_new( NETCONN_TCP );

       netconn_bind(pxHTTPListener, NULL, webHTTP_PORT );

       netconn_listen( pxHTTPListener );

 

       /* Loop forever */

       for( ;; )

       {

              /* Wait for a first connection. */

              pxNewConnection = netconn_accept(pxHTTPListener);

              vParTestSetLED(webCONN_LED, pdTRUE);

              if(pxNewConnection != NULL)

              {

                     prvweb_ParseHTMLRequest(pxNewConnection);

              }/* end if new connection */

 

              vParTestSetLED(webCONN_LED, pdFALSE);

 

       } /* end infinite loop */

}

 

 

/*! \brief parse the incoming request

 *         parse the HTML request and send file

 *

 *  \param pxNetCon   Input. The netconn to use to send and receive data.

 *

 */

 

static void prvweb_ParseHTMLRequest( struct netconn *pxNetCon )

{

struct netbuf *pxRxBuffer;

portCHAR *pcRxString;

unsigned portSHORT usLength;

static unsigned portLONG ulPageHits;

 

       /* We expect to immediately get data. */

       pxRxBuffer = netconn_recv( pxNetCon );

 

       if( pxRxBuffer != NULL )

       {

              /* Where is the data? */

              netbuf_data( pxRxBuffer, ( void * ) &pcRxString, &usLength );

 

              /* Is this a GET?  We don't handle anything else. */

              if(( NULL != pcRxString               )

              && ( !strncmp( pcRxString, "GET", 3 ) ))

              {

                     /* Update the hit count. */

                     //ulPageHits++;addr

                     ulPageHits=pxRxBuffer->ptr->len;

 

                            //sendMessage("LwIP: DHCP Started");

                     //inet_ntoa(*(struct in_addr*)&(netif->ip_addr))

                     sprintf( cPageHits, "%d", (int)ulPageHits );

 

                     /* Write out the HTTP OK header. */

                     netconn_write( pxNetCon, webHTTP_OK, (u16_t) strlen( webHTTP_OK ), NETCONN_COPY );

 

                     /* Generate the dynamic page... First the page header. */

                     strcpy( cDynamicPage, webHTML_START );

                     /* ... Then the hit count... */

 

                     strcat( cDynamicPage, cPageHits );

                     //strcat( cDynamicPage, "

Task          State  Priority  Stack       [page]#
************************************************
" );

 

 

                     /* ... Then the list of tasks and their status... */

                     //vTaskList( ( signed portCHAR * ) cDynamicPage + strlen( cDynamicPage ) );

 

                     /* ... Finally the page footer. */

                     switch(ulPageHits)

                     {

                     case 310  :gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_1);

                     gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_2);

                     gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_3);

                     gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_4);

                              break;

                     case 311   :gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_1);

                     gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_2);

                     gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_3);

                     gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_4);

                                                   break;

                     case 312   :gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_1);

                     gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_2);

                     gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_3);

                     gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_4);

                                                   break;

                     case 313   :gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_1);

                     gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_2);

                     gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_3);

                     gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_4);

                                                   break;

                     case 314   :gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_1);

                     gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_2);

                     gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_3);

                     gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_4);

                                                   break;

                     case 315   :gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_1);

                     gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_2);

                     gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_3);

                     gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_4);

                                                   break;

                     case 316   :gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_1);

                     gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_2);

                     gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_3);

                     gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_4);

                                                   break;

                     case 317    :gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_1);

                     gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_2);

                     gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_3);

                     gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_4);

                                                   break;

                     case 318    :gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_1);

                     gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_2);

                     gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_3);

                     gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_4);

                                                   break;

                     case 319    :gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_1);

                     gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_2);

                     gpio_clr_gpio_pin(GPIO_PIN_EXAMPLE_3);

                     gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_4);

                                                   break;

                     default: gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_1);

                     gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_2);

                     gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_3);

                     gpio_set_gpio_pin(GPIO_PIN_EXAMPLE_4);

                break;

                     }

                     /*if(ulPageHits<310)

                            usart_putchar(EXAMPLE_USART, 0);

                     else if(ulPageHits<319)

                     {

                            f=ulPageHits-309;

                            usart_putchar(EXAMPLE_USART, f);

                     }

                     else if(ulPageHits==319)

                            usart_putchar(EXAMPLE_USART, 0x0a);

                            */

 

                     /* Write out the dynamically generated page. */

                     netconn_write( pxNetCon, cDynamicPage, (u16_t) strlen( cDynamicPage ), NETCONN_COPY );

              }

              netbuf_delete( pxRxBuffer );

       }

 

       netconn_close( pxNetCon );

       netconn_delete( pxNetCon );

}

 

#endif

(4)、实现功能

1、强大的越野能力,四路360°舵机强力驱动;

 

2、电脑、手机对小车的任意控制,无需任何插件、软件;

 

3、视频的同步监控;

 

4、数据的传输,可用于野外勘测、数据采集等方面;

 

5、可加载各种传感器,车上的控制单元都可在不拆卸的情况下直接下载升级。

				

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
如何为单片机选择合适的负载电容