无线视频监控小车
各个模块
micro2440,1个
usb无线网卡TL-WN721N,1个
usb摄像头zp0301,1个
L298N直流电机驱动模块,2个
小车主体,1个
视频稍后
源码:
micro2440,1个
usb无线网卡TL-WN721N,1个
usb摄像头zp0301,1个
L298N直流电机驱动模块,2个
小车主体,1个
视频稍后
//在micro2440上操作 [root@FriendlyARM plg]# ls bin-song bin-song.tgz dc_motor_driver.ko server usb-wifi-kits-for-mini2440-linux-2.6.32.2-20100728.tar.gz [root@FriendlyARM plg]# [root@FriendlyARM plg]# scan-wifi //扫描无线路由器 57% ChinaNet-TEXj(Security) 57% iTV-TEXj(Security) 56% ZXDSL531BII-539490 91% MERCURY_C93C2E(Security)//找到了 (Security) 39% ChinaNet-rwXE(Security) 37% iTV-rwXE(Security) 7 Access Point Found [root@FriendlyARM plg]# start-wifi wpa2 MERCURY_C93C2E qwertyuiop//连接至无线路由器,密码是qwertyuiop udhcpc (v1.13.3) started Sending discover... Sending discover... Sending discover... Sending discover... cfg80211: Calling CRDA for country: US Sending discover... Sending select for 192.168.1.101... Lease of 192.168.1.101 obtained, lease time 7200 deleting routers route: SIOCDELRT: No such process adding dns 192.168.1.109 [root@FriendlyARM bin-song]# ifconfig eth0 down //暂时禁用本地网卡 [root@FriendlyARM plg]# insmod dc_motor_driver.ko //加载驱动 smart_car initialized [root@FriendlyARM plg]# ./server &//启动服务器,监听3333端口,udp模式 [root@FriendlyARM plg]# DBG(/opt/FriendlyARM/mini2440/smart_car/dc_motor/dc_motor_driver.c, misc_open(), 146): open DBG(server.c, main(), 63): sock sucessful DBG(server.c, main(), 78): bind sucess [root@FriendlyARM plg]# cd bin-song/ [root@FriendlyARM bin-song]# ./mjpg_streamer -i input_uvc.so -o "output_http.so -w ./www" //开启mjpg的web服务器,8080端口 //在虚拟机上操作 [root@localhost dc_motor]# ./client //此时按下上下左右键开始控制吧
源码:
/*******************************dc_motor_driver.c**************/ //操作io口,使用8个点, //分配给每个L298N模块4个点 //如下 #include <linux/miscdevice.h> #include <linux/delay.h> #include <asm/irq.h> #include <mach/regs-gpio.h> #include <mach/hardware.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/mm.h> #include <linux/fs.h> #include <linux/types.h> #include <linux/time.h> #include <linux/timer.h> #include <linux/moduleparam.h> #include <linux/slab.h> #include <linux/errno.h> #include <linux/ioctl.h> #include <linux/cdev.h> #include <linux/string.h> #include <linux/list.h> #include <linux/pci.h> #include <linux/gpio.h> #include <asm/uaccess.h> #include <asm/atomic.h> #include <asm/unistd.h> #define DEBUG #ifdef DEBUG #define DBG(...) printk(" DBG(%s, %s(), %d): ", __FILE__, __FUNCTION__, __LINE__); printk(__VA_ARGS__) #else #define DBG(...) #endif #define DEVICE_NAME "smart_car" #define delay_time_ms 1000 int ret; unsigned long motor_table [] = { S3C2410_GPF(0),//EA S3C2410_GPF(2),//EB S3C2410_GPF(4),//EC S3C2410_GPF(6),//ED S3C2410_GPF(1),//IA,the back-right wheel ,1 on,0 back S3C2410_GPF(3),//IB,the front-right wheel ,1 on,0 back S3C2410_GPF(5),//IC,the back-left wheel ,1 on,0 back S3C2410_GPG(0),//ID,the back-right wheel ,1 on,0 back }; unsigned int motor_cfg_table [] = { S3C2410_GPIO_OUTPUT, S3C2410_GPIO_OUTPUT, S3C2410_GPIO_OUTPUT, S3C2410_GPIO_OUTPUT, S3C2410_GPIO_OUTPUT, S3C2410_GPIO_OUTPUT, S3C2410_GPIO_OUTPUT, S3C2410_GPIO_OUTPUT, }; #define SET_EA_HIGH (s3c2410_gpio_setpin(motor_table[0],1)) #define SET_EA_LOW (s3c2410_gpio_setpin(motor_table[0],0)) #define SET_EB_HIGH (s3c2410_gpio_setpin(motor_table[1],1)) #define SET_EB_LOW (s3c2410_gpio_setpin(motor_table[1],0)) #define SET_EC_HIGH (s3c2410_gpio_setpin(motor_table[2],1)) #define SET_EC_LOW (s3c2410_gpio_setpin(motor_table[2],0)) #define SET_ED_HIGH (s3c2410_gpio_setpin(motor_table[3],1)) #define SET_ED_LOW (s3c2410_gpio_setpin(motor_table[3],0)) #define SET_IA_HIGH (s3c2410_gpio_setpin(motor_table[4],1)) #define SET_IA_LOW (s3c2410_gpio_setpin(motor_table[4],0)) #define SET_IB_HIGH (s3c2410_gpio_setpin(motor_table[5],1)) #define SET_IB_LOW (s3c2410_gpio_setpin(motor_table[5],0)) #define SET_IC_HIGH (s3c2410_gpio_setpin(motor_table[6],1)) #define SET_IC_LOW (s3c2410_gpio_setpin(motor_table[6],0)) #define SET_ID_HIGH (s3c2410_gpio_setpin(motor_table[7],1)) #define SET_ID_LOW (s3c2410_gpio_setpin(motor_table[7],0)) #define UP 1 #define DOWN 6 #define RIGHT 3 #define LEFT 4 #define STOP 5 ssize_t misc_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { DBG("write \n"); int ret; char *commad=0; if (count == 0) { return count; } commad=kmalloc(count+1,GFP_KERNEL);//need print it using %s, so plus 1 byte for '\0' ret = copy_from_user(commad, buf, count);//if success,ret=0 if (ret) { return ret; } commad[count]='\0'; DBG("commad=%s\n",commad); DBG("ret=%d\n",ret); //to test the command "set to 1" or "clear to 0" if correct 代码做管脚测试用到 if(strncmp(commad,"SET_EA_HIGH",count)==0) {SET_EA_HIGH;DBG("excuting SET_EN_HIGH succes !\n");} if(strncmp(commad,"SET_EA_LOW",count)==0) {SET_EA_LOW;DBG("excuting SET_EN_LOW succes !\n");} if(strncmp(commad,"SET_EB_HIGH",count)==0) {SET_EB_HIGH;DBG("excuting SET_EB_HIGH succes !\n");} if(strncmp(commad,"SET_EB_LOW",count)==0) {SET_EB_LOW;DBG("excuting SET_EB_LOW succes !\n");} if(strncmp(commad,"SET_EC_HIGH",count)==0) {SET_EC_HIGH;DBG("excuting SET_EC_HIGH succes !\n");} if(strncmp(commad,"SET_EC_LOW",count)==0) {SET_EC_LOW;DBG("excuting SET_EC_LOW succes !\n");} if(strncmp(commad,"SET_ED_HIGH",count)==0) {SET_ED_HIGH;DBG("excuting SET_ED_HIGH succes !\n");} if(strncmp(commad,"SET_ED_LOW",count)==0) {SET_ED_LOW;DBG("excuting SET_ED_LOW succes !\n");} if(strncmp(commad,"SET_IA_HIGH",count)==0) {SET_IA_HIGH;DBG("excuting SET_IA_HIGH succes !\n");} if(strncmp(commad,"SET_IA_LOW",count)==0) {SET_IA_LOW;DBG("excuting SET_IA_LOW succes !\n");} if(strncmp(commad,"SET_IB_HIGH",count)==0) {SET_IB_HIGH;DBG("excuting SET_IB_HIGH succes !\n");} if(strncmp(commad,"SET_IB_LOW",count)==0) {SET_IB_LOW;DBG("excuting SET_IB_LOW succes !\n");} if(strncmp(commad,"SET_IC_HIGH",count)==0) {SET_IC_HIGH;DBG("excuting SET_IC_HIGH succes !\n");} if(strncmp(commad,"SET_IC_LOW",count)==0) {SET_IC_LOW;DBG("excuting SET_IC_LOW succes !\n");} if(strncmp(commad,"SET_ID_HIGH",count)==0) {SET_ID_HIGH;DBG("excuting SET_ID_HIGH succes !\n");} if(strncmp(commad,"SET_ID_LOW",count)==0) {SET_ID_LOW;DBG("excuting SET_ID_LOW succes !\n");} return ret ? ret : count; } ssize_t misc_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { DBG("read \n"); return 0; } static int misc_release(struct inode *inode, struct file *filp) { DBG("release \n"); return 0; } static int misc_open(struct inode *inode, struct file *filp) { DBG("open \n"); return 0; } static inline void go_on() { SET_EA_HIGH; SET_IA_HIGH; SET_EB_HIGH; SET_IB_HIGH; SET_EC_HIGH; SET_IC_HIGH; SET_ED_HIGH; SET_ID_HIGH; } static inline void go_back() { SET_EA_HIGH; SET_IA_LOW; SET_EB_HIGH; SET_IB_LOW; SET_EC_HIGH; SET_IC_LOW; SET_ED_HIGH; SET_ID_LOW; } static inline void go_right() { SET_EA_LOW; SET_EB_HIGH; SET_IB_HIGH; SET_EC_LOW; SET_ED_HIGH; SET_ID_HIGH; } static inline void go_left() { SET_EA_HIGH; SET_IA_HIGH; SET_EB_LOW; SET_EC_HIGH; SET_IC_HIGH; SET_ED_LOW; } static inline void stop() { SET_EA_LOW; SET_EB_LOW; SET_EC_LOW; SET_ED_LOW; } static int misc_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg) { int i=0; DBG("cmd=%x\n",cmd); DBG("arg=%x\n",arg); if (cmd==UP) // go on { go_on(); }else if(cmd==DOWN){ //go back go_back(); }else if(cmd==RIGHT){ //go right go_right(); }else if(cmd==LEFT){ //go left go_left(); }else if(cmd==STOP){ //stop stop(); } return 0; } static struct file_operations dev_fops = { .owner = THIS_MODULE, .open = misc_open, .read = misc_read, .write = misc_write, .release= misc_release, .ioctl= misc_ioctl, }; static struct miscdevice misc = { .minor = MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &dev_fops, }; static int __init dev_init(void) { int ret; int i; for (i = 0; i < 8; i++) {//配置管脚的out in 模式 s3c2410_gpio_cfgpin(motor_table[i], motor_cfg_table[i]); s3c2410_gpio_setpin(motor_table[i], 0); } ret = misc_register(&misc); //InitRc522() ;//初始化 printk (DEVICE_NAME"\tinitialized\n"); //open_flag=0; return ret; } static void __exit dev_exit(void) { DBG (DEVICE_NAME"\texit\n"); misc_deregister(&misc); } module_init(dev_init); module_exit(dev_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Song.");
//server.c //运行在micro2440,监听本地udp 3333端口 #include<stdio.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<unistd.h> #include<errno.h> #include<string.h> #include<stdlib.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <fcntl.h> #include <linux/fs.h> #define DEBUG #ifdef DEBUG #define DBG(...) fprintf(stderr, " DBG(%s, %s(), %d): ", __FILE__, __FUNCTION__, __LINE__); fprintf(stderr, __VA_ARGS__) #else #define DBG(...) #endif #define SERV_PORT 3333 #define UP_KEY 0x41 #define DOWN_KEY 0x42 #define RIGHT_KEY 0x43 #define LEFT_KEY 0x44 #define STOP_KEY 0x20 #define UP 1 #define DOWN 6 #define RIGHT 3 #define LEFT 4 #define STOP 5 int main(int argc,char* argv[]) { //open the device int fd = open("/dev/smart_car", O_RDWR|O_CREAT,00100); if (fd < 0) { perror("open file "); return 1; } int sock_fd; //套接子描述符号 if(argc==1) { //for the socket int recv_num; int send_num; int client_len; char recv_buf[1]; struct sockaddr_in addr_serv; struct sockaddr_in addr_client;//服务器和客户端地址 sock_fd = socket(AF_INET,SOCK_DGRAM,0); if(sock_fd < 0){ DBG("socket"); exit(1); } else{ DBG("sock sucessful\n"); } //初始化服务器断地址 memset(&addr_serv,0,sizeof(struct sockaddr_in)); addr_serv.sin_family = AF_INET;//协议族 addr_serv.sin_port = htons(SERV_PORT); addr_serv.sin_addr.s_addr = htonl(INADDR_ANY); client_len = sizeof(struct sockaddr_in); /*绑定套接子*/ if(bind(sock_fd,(struct sockaddr *)&addr_serv,sizeof(struct sockaddr_in))<0 ){ DBG("bind"); exit(1); } else{ DBG("bind sucess\n"); } //monitor the socket while(1){ recv_num = recvfrom(sock_fd,recv_buf,sizeof(recv_buf),0,(struct sockaddr *)&addr_client,&client_len); if(recv_num < 0){ DBG("bad\n"); DBG("again recvfrom"); exit(1); } else{ DBG("recv sucess:%x\n",recv_buf[0]); switch(recv_buf[0]) { case UP_KEY: { ioctl(fd,UP); DBG("UP\n");break; } case DOWN_KEY: { ioctl(fd,DOWN); DBG("DOWN\n");break; } case RIGHT_KEY: { ioctl(fd,RIGHT); DBG("RIGHT\n");break; } case LEFT_KEY: { ioctl(fd,LEFT); DBG("LEFT\n");break; } case STOP_KEY: { ioctl(fd,STOP); DBG("STOP\n");break; } } } } } else if(argc==2)//to test { int len=write(fd,argv[1],strlen(argv[1])); if (len > 0) { DBG("len= %d\n",len); DBG("%s,%d\n",argv[1],strlen(argv[1])); } else { DBG("error:"); return 1; } } //close socket close(sock_fd); //clode device close(fd); return 0; }
//client.c //运行在主机,向micro2440的udp 3333端口发送控制数据 #include<stdio.h> #include<string.h> #include<errno.h> #include<stdlib.h> #include<unistd.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #define DEBUG #ifdef DEBUG #define DBG(...) fprintf(stderr, " DBG(%s, %s(), %d): ", __FILE__, __FUNCTION__, __LINE__); fprintf(stderr, __VA_ARGS__) #else #define DBG(...) #endif #define DEST_PORT 3333 #define DSET_IP_ADDRESS "192.168.1.101" #include <termios.h> static struct termios stored_settings; void set_keypress(void) { struct termios new_settings; tcgetattr(0,&stored_settings); new_settings = stored_settings; /* Disable canonical mode, and set buffer size to 1 byte */ new_settings.c_lflag &= (~ICANON); new_settings.c_cc[VTIME] = 0; new_settings.c_cc[VMIN] = 1; tcsetattr(0,TCSANOW,&new_settings); return; } void reset_keypress(void) { tcsetattr(0,TCSANOW,&stored_settings); return; } int main() { int sock_fd;/*套接字文件描述符*/ int send_num; int recv_num; int dest_len; char send_buf[1]; struct sockaddr_in addr_serv;/*服务端地址,客户端地址*/ set_keypress(); sock_fd = socket(AF_INET,SOCK_DGRAM,0);//创建套接子 //初始化服务器端地址 memset(&addr_serv,0,sizeof(addr_serv)); addr_serv.sin_family = AF_INET; addr_serv.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS); addr_serv.sin_port = htons(DEST_PORT); dest_len = sizeof(struct sockaddr_in); //response for key char ch; while(1)//may use ctrl+c to kill { ch=getchar(); DBG("ch=%x\n",ch); send_num = sendto(sock_fd,&ch,sizeof(ch),0,(struct sockaddr *)&addr_serv,dest_len); if(send_num < 0){ DBG("sendto"); exit(1); } else{ DBG("send sucessful\n"); } } close(sock_fd); reset_keypress(); return 0; }