本帖最后由 wing 于 2014-2-18 21:14 编辑
本次实验的目的的是用web服务去控制电机的转速.
根据"xukai871105 "的提议,我决定加入 ajax 和 html5 这些比较潮流的前端技术来吸引你们的眼球。
也是基本这个原因,不是所有的浏览器都能支持本次实验。
以下浏览器是被测试过可以支持本次实验的:
1. IE10,然而IE系列的默认range样式都很丑陋,所以这里就不贴IE的效果图了。另外相信IE11也可以支持本次实验
2. Raspbian默认预装的Midori,这个发现令我觉得非常惊奇,想不到这种轻量级的浏览器也能提供这么好的支持
3. 安卓版的Chrome 31.0,
遗憾的是android 4.0的默认浏览器是不支持的,
传说中的国产神器 uc 8.3 也没能很好地支持本次实验所用的range类型,
迫于无奈只能装个安卓版的Chrome,视频中的控制端就是使用安卓平板的chrome
开发环境还是qtcreator,控制库还是wiringPi,
这两个东西的介绍可以参阅前面的笔记:RPI向小车迈进01:结合web服务的GPIO实验
工程文件- TEMPLATE = app
- CONFIG += console
- CONFIG -= qt
- SOURCES += main.c
- LIBS += -lwiringPi -lpthread
复制代码 其中要注意的是必须在工程文件中加入 -lwiringPi -lpthread 这两个库的编译链接
主程序main.c- #include<sys/socket.h>
- #include<errno.h>
- #include<netinet/in.h>
- #include<string.h>
- #include<stdio.h>
- #include<wiringPi.h>
- #include<softPwm.h>
- #define BUF_LEN 1028
- #define SERVER_PORT 8001
- #define pinNumber 7
- //200成功的头部信息
- const static char http_head_ok[] = "HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n";
- //控制页面 AJAX+HTML5
- const static char http_doc[] =
- "<html><head>"
- "<title>gpio_pwm_led</title>"
- "<style type="text/css">"
- "input.vertical { -webkit-appearance: slider-vertical; writing-mode: bt-lr; width:100px; height:400px; }"
- "</style>"
- "<script type="text/javascript">\r\n"
- "function myRange_on_mouseup(){\r\n"
- "var xmlhttp;\r\n"
- "xmlhttp=new XMLHttpRequest();\r\n"
- "xmlhttp.open("GET","http://192.168.1.21:8001/"+document.getElementById("myRange").value,true);\r\n"
- "xmlhttp.send();\r\n}\r\n"
- "</script>"
- "</head><body>"
- "<input type="range" min="0" max="100" value="50" class="vertical" ontouchend="myRange_on_mouseup()" onmouseup="myRange_on_mouseup()" id="myRange" />"
- "</body></html>";
- const static char http_OK[] ="OK";
- int level;
- //解析到HTTP请求的文件后,发送相应的网页信息
- int http_send_file(char *filename, int sockfd)
- {
- if(strcmp(filename, "/doc.act")==0){
- //返回控制页面
- write(sockfd, http_head_ok, strlen(http_head_ok));
- write(sockfd, http_doc, strlen(http_doc));
- }
- else{
- //改变亮度
- int level_new;
- level_new=atoi(filename+1);
- level=level_new;
- printf("%s\n",filename);
- printf("%d\n",level);
- softPwmWrite(pinNumber,level);
- write(sockfd, http_head_ok, strlen(http_head_ok));
- write(sockfd, http_OK, strlen(http_OK));
- }
- return 0;
- }
- //HTTP请求解析
- void serve(int sockfd){
- char buf[BUF_LEN];
- read(sockfd, buf, BUF_LEN);
- if(!strncmp(buf, "GET", 3)){
- char *file = buf + 4;
- char *space = strchr(file, ' ');
- *space = '\0';
- http_send_file(file, sockfd);
- }
- }
- void main(){
- //初始化wiringPi
- if (-1 == wiringPiSetup()) {
- return;
- }
- //默认输出全空
- softPwmCreate(pinNumber,0,100);
- level=0;
- softPwmWrite(pinNumber,level);
- int sockfd,err,newfd;
- struct sockaddr_in addr;
- //建立TCP套接字
- sockfd = socket(AF_INET, SOCK_STREAM, 0);
- if(sockfd < 0){
- return;
- }
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- //这里要注意,端口号一定要使用htons先转化为网络字节序,否则绑定的实际端口
- addr.sin_port = htons(SERVER_PORT);
- addr.sin_addr.s_addr = INADDR_ANY;
- if(bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in))){
- return;
- }
- listen(sockfd, 128);
- while(1){
- //不间断接收HTTP请求并处理,这里使用单线程
- newfd = accept(sockfd, NULL, NULL);
- serve(newfd);
- close(newfd);
- }
- }
复制代码 程序编译之后要以root身份运行
好了,程序方面介绍完毕了,下面说下硬件设备和接线:
本次使用的电机控制板是OCROBOT Motor Shield
关于这个控制板的详细介绍请参阅权威介绍:使用ocrobot motor shield 电机驱动板的简易说明
电机是常用的小车套件
传说中这种电机器的电压是3~6v的,
不过在实际测试中发现4枚AA充电(大约5V)是不能驱动 ocrobot motor shield 的,
后来加到8枚 ocrobot motor shield 才可以正常工作.
接线方式:
电机板 VIN -> 电池正极
电机板 GND -> 电池负极
电机板 -B -> 电机
电机板 +B -> 电机
电机板 GND -> RPI ground
电机板 D13 -> RPI ground
电机板 D8 -> RPI ground
电机板 D11 -> RPI GPIO 7
效果视频 1
效果视频 2
|