承接实训第四天:zigbee无线传感网实训---在LCD屏上显示JPG图片、 触摸屏、相册(The fourth day)
摄像头:
常见的摄像头:针孔摄像头(有线和无线)、红外摄像头(有线),usb摄像头;
摄像头采集图像的格式:yuyv 、jpeg(v4l2)
文件准备:libapi_v4l2_arm.so
api_v4l2.h
/*************************************************
File name : api_v4l2.h
Create date : 2014-07-01 19:42
Modified date : 2014-07-01 19:42
Author : heqingde
Email : [email protected]
***********************************************/
#ifndef API_V4L2_H_
#define API_V4L2_H_
#define VIDEO_WIDTH 640
#define VIDEO_HEIGHT 480
#define MAX_CAM_RES 32 //camres res
#define BUFFER_COUNT 4 //buffer zone
#define FPS 30
#define MAX_CAM_RES 32
//#define CAMERA_DEVICE "/dev/video1"
#define exit_error(s)\
do{\
printf("%s is error\n",s);\
return (-1);\
}while(0)
/*********************************
* NAME:VideoBuffer struct
* Function: Describe buffer V4L2 driver assigns and maps
* Member: start: point of buffer
* length: total length of buffer
**********************************/
typedef struct Video_Buffer
{
void *start;
int length;
}VideoBuffer;
/*******************************
* name :fream_buffer
* Function: save fream
* member: buf :point of buf
* length:total length op buf
********************************/
typedef struct Frame_Buffer
{
char buf[1843200];
int length;
}FrameBuffer;
/************************************
*name:CamRes
*Function:Camera format
*Member: width : format width
*height: format height
*/
typedef struct CamRes
{
int width;
int height;
}CamRes;
/*************************************
*name:CamResList struct
*Function:CamRes format list
*Member: cam_res :struct CamRes
*res_num:Camera format number
*/
typedef struct CamResList
{
struct CamRes *cam_res;
int res_num;
}CamResList;
/*************************************
*Name:open_device Function
*Function:open the device
*/
void linux_v4l2_open_device();
/*************************************
*name:device_init
*Function:Initial Camera v4l2
*/
int linux_v4l2_device_init(const char *dev);
/*************************************
*name: init_mmap
*Function: mmap
*/
int linux_v4l2_init_mmap();
/************************************
*name:start_capturing
*Function: starting Capture Options
*/
int linux_v4l2_start_capturing();
/************************************
*name:stop_capturing
*Function: stop Capture Options
*/
int linux_v4l2_stop_capturing();
/************************************
*name :device_uinit
*Function:uinit device
*/
int linux_v4l2_device_uinit();
/************************************
*name :linux_v4l2_get_fream
*Function:save device_stream data;
*/
int linux_v4l2_get_fream(FrameBuffer *freambuf);
#endif /*API_V4L2_H*/
camera.c
#include
#include
#include
#include /* See NOTES */
#include
#include
#include
#include
#include
#include "lcdjpg.h"
#include "api_v4l2.h" //包含摄像头的头文件
int lcd_draw_jpg(unsigned int x,unsigned int y,const char *pjpg_path,char *pjpg_buf,unsigned int jpg_buf_size,unsigned int jpg_half);
int iPhonex;
struct sockaddr_in phoneaddr;
//线程的功能函数,接收来自手机app发送的控制命令
void *myrecvmsg(void *arg)
{
char buf[200];
int addrsize=sizeof(phoneaddr);
while(1)
{
bzero(buf,200);//清零
//聊天,收发数据,接收手机发送过来的控制命令
recvfrom(iPhonex,buf,200,0,(struct sockaddr *)&phoneaddr,&addrsize);
printf("phone send msg is:%s ip:%s port:%hu\n",buf,inet_ntoa(phoneaddr.sin_addr),ntohs(phoneaddr.sin_port));
}
}
int main(void)
{
//买手机--->创建套接字
iPhonex = socket( AF_INET, SOCK_DGRAM,0);
// 定义一个ipv4地址结构体变量
struct sockaddr_in bindaddr;
bindaddr.sin_family = AF_INET;
bindaddr.sin_addr.s_addr = inet_addr("192.168.1.123");//绑定开发板无线网卡的ip
bindaddr.sin_port = htons(2234); //绑定端口号
//买卡--->绑定自己的ip
int ret = bind(iPhonex, (struct sockaddr *)&bindaddr, sizeof(bindaddr));
if(ret == -1)
{
printf("绑定失败!\n");
exit(0);
}
//打开摄像头
linux_v4l2_device_init("/dev/video7");
//启动摄像捕捉
linux_v4l2_start_capturing();
//开始捕捉
//创建线程,专门接受手机端发送过来的信息
pthread_t p_id;
pthread_create( &p_id, NULL, myrecvmsg, NULL);
FrameBuffer mybuf;
while(1)
{
linux_v4l2_get_fream(&mybuf);
//开发板显示摄像头拍摄的画面
lcd_draw_jpg(0,0,NULL,mybuf.buf,mybuf.length,0);
//将画面传输给手机
sendto(iPhonex,mybuf.buf,mybuf.length,0,(struct sockaddr *)&phoneaddr,sizeof(phoneaddr));
printf("phone ip:%s port:%hu\n",inet_ntoa(phoneaddr.sin_addr),ntohs(phoneaddr.sin_port));
//拍照....
}
return 0;
}
common.c
/****************************************************************************************
*Éè ¼Æ:ÎÂ×Óì÷
*ÈÕ ÆÚ:2015-5-29
*˵ Ã÷:³£Óú¯Êý
****************************************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
/****************************************************
*º¯ÊýÃû³Æ:file_size_get
*ÊäÈë²ÎÊý:pfile_path -Îļþ·¾¶
*·µ »Ø Öµ:-1 -ʧ°Ü
ÆäËûÖµ -Îļþ´óС
*˵ Ã÷:»ñÈ¡Îļþ´óС
****************************************************/
unsigned long file_size_get(const char *pfile_path)
{
unsigned long filesize = -1;
struct stat statbuff;
if(stat(pfile_path, &statbuff) < 0)
{
return filesize;
}
else
{
filesize = statbuff.st_size;
}
return filesize;
}
unsigned char bcc_check(unsigned char *buf, int n)
{
int i;
unsigned char bcc=0;
for(i = 0; i < n; i++)
{
bcc ^= *(buf+i);
}
return (~bcc);
}
lcdjpg.c
#include
#include
#include
#include
#include
#include
#include
#include "lcdjpg.h"
#if EN_LCD_SHOW_JPG
#include "jpeglib.h"
#endif
//#include "api_v4l2.h"
unsigned long file_size_get(const char *pfile_path);
static char g_color_buf[FB_SIZE]={0};
static int g_fb_fd;
static int *g_pfb_memory;
/* video_chat.c »ÖлÏÔʾµÄ×ø±ê */
volatile int g_jpg_in_jpg_x;
volatile int g_jpg_in_jpg_y;
//LCD»µã
void lcd_draw_point(unsigned int x,unsigned int y, unsigned int color)
{
*(g_pfb_memory+y*800+x)=color;
}
#if EN_LCD_SHOW_JPG
int lcd_draw_jpg(unsigned int x,unsigned int y,const char *pjpg_path,char *pjpg_buf,unsigned int jpg_buf_size,unsigned int jpg_half)
{
//³õʼ»¯LCD
g_fb_fd = open("/dev/fb0", O_RDWR);
if(g_fb_fd<0)
{
printf("open lcd error\n");
return -1;
}
g_pfb_memory = (int *)mmap( NULL, //Ó³ÉäÇøµÄ¿ªÊ¼µØÖ·£¬ÉèÖÃΪNULLʱ±íʾÓÉϵͳ¾ö¶¨Ó³ÉäÇøµÄÆðʼµØÖ·
FB_SIZE, //Ó³ÉäÇøµÄ³¤¶È
PROT_READ|PROT_WRITE, //ÄÚÈÝ¿ÉÒÔ±»¶ÁÈ¡ºÍдÈë
MAP_SHARED, //¹²ÏíÄÚ´æ
g_fb_fd, //ÓÐЧµÄÎļþÃèÊö´Ê
0 //±»Ó³Éä¶ÔÏóÄÚÈݵÄÆðµã
);
/*¶¨Òå½âÂë¶ÔÏ󣬴íÎó´¦Àí¶ÔÏó*/
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
char *pcolor_buf = g_color_buf;
char *pjpg;
unsigned int i=0;
unsigned int color =0;
unsigned int count =0;
unsigned int x_s = x;
unsigned int x_e ;
unsigned int y_e ;
int jpg_fd;
unsigned int jpg_size;
unsigned int jpg_width;
unsigned int jpg_height;
if(pjpg_path!=NULL)
{
/* ÉêÇëjpg×ÊÔ´£¬È¨Ï޿ɶÁ¿Éд */
jpg_fd=open(pjpg_path,O_RDWR);
if(jpg_fd == -1)
{
printf("open %s error\n",pjpg_path);
return -1;
}
/* »ñÈ¡jpgÎļþµÄ´óС */
jpg_size=file_size_get(pjpg_path);
/* ΪjpgÎļþÉêÇëÄÚ´æ¿Õ¼ä */
pjpg = malloc(jpg_size);
/* ¶ÁÈ¡jpgÎļþËùÓÐÄÚÈݵ½ÄÚ´æ */
read(jpg_fd,pjpg,jpg_size);
}
else
{
jpg_size = jpg_buf_size;
pjpg = pjpg_buf;
}
/*×¢²á³ö´í´¦Àí*/
cinfo.err = jpeg_std_error(&jerr);
/*´´½¨½âÂë*/
jpeg_create_decompress(&cinfo);
/*Ö±½Ó½âÂëÄÚ´æÊý¾Ý*/
jpeg_mem_src(&cinfo,pjpg,jpg_size);
/*¶ÁÎļþÍ·*/
jpeg_read_header(&cinfo, TRUE);
/*¿ªÊ¼½âÂë*/
jpeg_start_decompress(&cinfo);
if(jpg_half)
{
x_e = x_s+(cinfo.output_width/2);
y_e = y +(cinfo.output_height/2);
/*¶Á½âÂëÊý¾Ý*/
while(cinfo.output_scanline < cinfo.output_height)
{
pcolor_buf = g_color_buf;
/* ¶ÁÈ¡jpgÒ»ÐеÄrgbÖµ */
jpeg_read_scanlines(&cinfo,(JSAMPARRAY)&pcolor_buf,1);
/* ÔÙ¶ÁÈ¡jpgÒ»ÐеÄrgbÖµ */
jpeg_read_scanlines(&cinfo,(JSAMPARRAY)&pcolor_buf,1);
for(i=0; i<(cinfo.output_width/2); i++)
{
/* »ñÈ¡rgbÖµ */
color = *(pcolor_buf+2);
color = color | *(pcolor_buf+1)<<8;
color = color | *(pcolor_buf)<<16;
/* ÏÔʾÏñËصã */
lcd_draw_point(x,y,color);
pcolor_buf +=6;
x++;
}
/* »»ÐÐ */
y++;
x = x_s;
}
}
else
{
x_e = x_s+cinfo.output_width;
y_e = y +cinfo.output_height;
/*¶Á½âÂëÊý¾Ý*/
while(cinfo.output_scanline < cinfo.output_height )
{
pcolor_buf = g_color_buf;
/* ¶ÁÈ¡jpgÒ»ÐеÄrgbÖµ */
jpeg_read_scanlines(&cinfo,(JSAMPARRAY)&pcolor_buf,1);
for(i=0; i
lcdjpg.h
#ifndef __LCD_H__
#define __LCD_H__
#define LCD_WIDTH 800
#define LCD_HEIGHT 480
#define FB_SIZE (LCD_WIDTH * LCD_HEIGHT * 4)
#define EN_LCD_SHOW_JPG 1
/* video_chat.c 画中画显示的坐标 */
extern volatile int g_jpg_in_jpg_x;
extern volatile int g_jpg_in_jpg_y;
#endif
编译:
虚拟机:
arm-none-linux-gnueabi-gcc *.c -o main -I/home/gec/jpeg/include -L./ -lapi_v4l2_arm -lpthread -L/home/gec/jpeg/lib -ljpeg
//*号表示通配符
//-I --> 指明头文件的路径
//-L --> 指明库文件的路径
//-l --> 指定要连接的库名(去掉前缀lib 去掉后缀.** 剩下的就是库的名字)
LCD开发板:
$:tftp -g 192.168.1.147 -r main
$:chmod 777 main
$:./main
结果:
注:实训第六天将完成开发板WiFi:zigbee无线传感网实训---完成开发板WiFi(The Sixth day)