Archive for 三月, 2013

Arduino机器人开发指南(六)wifi通信篇

星期六, 三月 30th, 2013 3,608 views

这里的wifi模块即之前已经采购的TP-LINK wr703n无线路由器。
在使用之前,我们需要对路由器进行改装,主要硬件工作如图

引出TTL的RX线及TX线,这里将其连接到了miniUSB口上了。自制一根miniUSB排线,另外加天线及扩展内存、闪存(这个属于非必须工作,扩展后性能会有一个提升)

软件方面的工作是刷路由系统为openwrt,安装ser2net(串口命令转发,tcp向ttl转发,感兴趣的朋友可以去看看源码 )及摄像头支持组件(mjpg-streamer 如果不用到摄像头也可以不装)

这些在论坛上有详细的资料和方法(需要注意,刷机风险很大,容易变砖),或者可以直接购买改装路由,改装路由是已经刷好系统并安装好组件的。
详细过程不在本篇的介绍范围,有机会的话,后续会开篇。

测试前,首先在Arduino上烧入一个串口监听程序,由于有了LCD模块,所以一并用上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "Wire.h"
#include "LiquidCrystal.h"
String incomingStr;
LiquidCrystal lcd(0);

void setup() {

    Serial.begin(9600);
    lcd.begin(16, 2);
    lcd.setBacklight(HIGH);

}

void loop() {

    if (Serial.available() > 0) {

        lcd.setCursor(0, 0);
        lcd.clear();

        while(Serial.available() > 0){
            incomingStr += char(Serial.read());
        }
        lcd.print(incomingStr);
        Serial.print("I received: ");
        Serial.println(incomingStr);
        incomingStr = "";
    }

}

此程序用于在LCD及监视端回显串口信息,大家可以根据自己的情况更改。
(更多…)

Arduino机器人开发指南(五)LCD篇

星期四, 三月 28th, 2013 551 views

LCD即我们常见的液晶显示屏,通过LCD我们可以有效并即时的获取Arduino的信息。本篇中选用的LCD为常见的1062字符型LCD,同时需要一块 IIC-LCD 转接板,如果没有的话也可以实现,连线稍微复杂一些。而通过转接版将能够节约4个端口。

在此篇中我们将用到IIC通信协议,在不同的Arduino主板上,IIC通信协议的端口略有不同:

Board I2C / TWI pins
Uno, Ethernet A4 (SDA), A5 (SCL)
Mega2560 20 (SDA), 21 (SCL)
Leonardo 2 (SDA), 3 (SCL)
Due 20 (SDA), 21 (SCL), SDA1, SCL1

SLC为时钟信号,SDA为数据信号。转接板背面如图:

根据自己的arduino版本找到对应的SDA、SCL端口,DAT连接SDA,CLK连接SCL,注意DAT端口右侧的螺丝,是一个可调电位器,用于调整LCD显示,以显示出清晰的图片。

Mega加上传感器扩展板后的接线如图,红黑为正负,白线为数据线,棕线为时钟线

  (更多…)

Arduino机器人开发指南(四)舵机篇

星期三, 三月 27th, 2013 315 views

首先了解一下本篇所选用舵机的一些参数

这里我们注意两点即可:
无负载操作速度:0.1秒/60度(4.8V)
扭矩:1.6kg·cm(4.8V)
角速度为 0.1s/60°,那么在满载情况下旋转一周需要0.6s。
扭矩表示力矩大小,1.6kg·cm意为在使用1cm的杠杆时可以举起1.6kg的物体。

此舵机基本满足摄像头或超声波云台的旋转速度及动力,如果要做到反应更加迅捷灵敏,则需要更换更好的舵机。(此舵机市场价格为¥10上下)
关于舵机的运行原理,不在本篇的介绍范围,大家感兴趣可以自行百度。

舵机接线如同

(更多…)

Arduino机器人开发指南(三)超声波传感器篇

星期二, 三月 26th, 2013 398 views

首先认识一下两个新的模块

如图,左边的是传感器扩展版,这里选择的是 Electronic Brick Shield 系列,另一个是超声波发射接收装置。

传感器扩展版将Arduino复杂的传感器线路连接进行了规整,类似于一个线路整理器,我们可以看到在上面除去两个电阻之外就没有别的元件了,基本上都是引脚的归纳。同时,扩展版是支持完美插入Arduino板卡的,在后面的图片中可以看到。
(更多…)

Arduino机器人开发指南(二)串口篇

星期二, 三月 26th, 2013 619 views

本篇主要讲解一下Arduino的串口及其编程方法。

串口是Arduino与其他设备进行通信的接口,需要用到“Serial”系列函数。

一共有以下10个子函数(新版本加入了更多):
Serial.begin() //开启串口
Serial .end() //关闭串口
Serial .available() //判断串口缓冲器是否有数据装入
Serial .read() //读取串口数据
Serial .peek() //返回下一个字节(字符)输入数据,但不删除它
Serial .flush() //清空串口缓存
Serial .print() //写入字符串数据到串口
Serial .println() //写入字符串数据带换行到串口
Serial .write() //写入二进制数据到串口
Serial .SerialEvent() //read时触发的事件函数
Serial.readBytes(buffer, length) //读取固定长度的二进制流

先看例子吧

1
2
3
4
5
6
7
void setup() {                
    Serial.begin(9600);  
}

void loop() {
    Serial.println("BeiTown");
}

(更多…)

Arduino机器人开发指南(一)基础篇

星期六, 三月 23rd, 2013 258 views

首先是硬件部分的知识,关于Arduino开发板的相关资料及选择,开发者论坛上有很多,这里主要阐述一下整个软件编码部分的开发流程及技术难点。板子选择的是MEGA2560,如图:

黑白两根线分别为电源和数据线,黄灯为板载灯L,绿灯为Power。其他的串口后面用到的时候再说吧。

首先是搭建Arduino的开发环境。Arduino是基于C语言开发的,在VS及Eclipse上均有插件,不过设置略显麻烦。简单起见,选择官方自己的IDE吧(下载地址)
(更多…)

wr703n路由器刷openwrt系统后的联网解决方案

星期五, 三月 22nd, 2013 750 views

今天刚入手 TP-lINK 的 WR703N 无线路由,甚是小巧。准备装在Arduino机器人上做视频传输模块,当然一方面还可以解决下宿舍的无线网络问题。避免麻烦直接买了改装好TTL引线并扩展到64MB内存外加SAM天线的WR703N ,openwrt系统也已刷好。

试用了下视频传输模块一切正常。接下来进入正题,如何让这个改装后的无线路由器发挥它的原本的上网功能。
折腾了一下午得出以下两种方案:

方案一:添加WAN口

WR703N有一个LAN/WAN口是可以插水晶头的,Openwrt刷好后默认是没有Wan口的,从192.168.1.1进入系统,可以看到虽然我们已经插好了网线但WAN口仍旧处于未连接状态。

(更多…)

PHP常见BUG修复笔记(长期更新)

星期一, 三月 18th, 2013 29 views

 

1
2
3
4
5
错误提示:Fatal error: Call to undefined function session_register() in ...

错误原因: 版本错误 PHP4.2以上版本不需要用session_register()注册SESSION变量

修复方法: 去掉session_register()  直接用 $_SESSION["string"]=“string" 赋值

 

1
2
3
4
5
错误提示:Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by  in ...

错误原因: 由于在调用Session_Start()之前有输出导致,任何空字符都不被允许

修复方法:  将session_start();.......?>放到文件首,并且<? 前面不能有任何字符。记事本编写后可能会产生空字符,DW下注意去掉BOM即可。

 

1
2
3
4
5
错误现象:session无法跨页传递

错误原因: 除了网上常有的几种原因之外,有一种特别诡异,即编码问题照成上文的错误,虽然是警告,但同时影响了session的使用,如果经过几种尝试,仍旧无法解决,多半是编码错误。

修复方法: 编辑php的配置文件php.ini中的 default_charset = “utf-8″ 即使php支持当前脚本的默认语言

 

1
2
3
4
5
错误提示:Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in ...

错误原因:返回结果集中行的数目, 其中result是无效的。原因较多,需要逐一检查,语句,字段名,数据库表结构来确定。

修复方法:逐一排查,确认数据库有此表结构字段名,确定无语法错误,确定编码集统一。

未完待续

BeiTown

2013.03.18

Unity3D_TransForm相对世界坐标位移

星期四, 三月 14th, 2013 653 views

在Unity3D的简单位移教程里我们经常看到如下代码

1
2
3
4
function Update ()
{
        transform.Translate(new Vector3(1,0,0)*Time.deltaTime);
}

这里的Vector3 即创建一个方向向量,此时运行,物体会沿着其X轴方向位移,如图,即红色箭头方向

同理 修改Vector3的参数,即可使物体向任意一个方向进行位移,这里的Time.deltaTime在文档里的解释是:

“放在Update()函数中的代码是以帧来执行的.如果我们需要物体的移动以秒来执行.我们需要将物体移动的值乘以Time.deltaTime”

这样就确保了移动速度不至于过快

问题来了,这个物体的旋转方向已经改变,使用上文的方法,物体只会继续向着自身的x轴方向移动,如图,我们旋转角度已偏移,自身坐标角度与世界坐标角度已不重和

如果需要仍旧按照世界坐标的X轴方向运动
这里有两种方法,方法一,继续使用传统方法,但要进行一个向量的换算

方法二,查看API可以知道,translate这个方法其实还有第二个参数relativeTo(相对于)

function Translate (x : float, y : float, z : float, relativeTo : Space = Space.Self) : void

默认不写的话即为Space = Self,如果要相对于世界坐标的话,代码如下

1
2
3
4
function Update ()
{
        transform.Translate(new Vector3(1,0,0)*Time.deltaTime,Space.World);
}

此时即可相对于世界坐标的x轴方向运动了

同理如果希望相对于任意Gameobject的坐标进行运动,这里将Space.World 改成 GameObject.Transform 即可

虽然只是一个U3D函数拓展的使用方法,但常常容易被人们忽略,继而去自己编写向量转换或其他的方法。其实有时候多查一下API,看看是否已有可实现的方法,不失为一个好的习惯。

谢谢关注。共勉。

BeiTown
2013.03.14

Unity3D-FSM有限状态机的简单设计

星期三, 三月 13th, 2013 3,725 views

在之前的文章里介绍了一个基础U3D状态机框架(Unity3D游戏开发之状态流框架)即大Switch的枚举状态控制。这种方法虽然容易理解,编程方法也相对简单,但是弊端是当状态变得复杂之后,或需要添加一种新的状态时,会显得非常混乱并且难以下手。故我们需要引进一种更高级的状态机技术来避免这些问题。网上有一些讲述U3D-FSM状态机的文章,但都不针对基础讲解,而且大多带有冗余的与状态机不相关的代码,基础不好的读者容易看不清FSM状态机的核心所在。这里针对网上的一些文章和代码做了一个整理,意图使之简单易懂。

这里关于FSM有限状态机这类名词的解释这里就不再说明了,感兴趣的朋友可以自己去百度下(度娘链接),本文只说重点。

首先是状态机基类State.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
 * 状态基类
 */

public class State[entity_type>
{
    public entity_type Target;
    //Enter state  
    public virtual void Enter (entity_type entityType)
    {
       
    }
    //Execute state
    public virtual void Execute (entity_type entityType)
    {
       
    }
    //Exit state
    public virtual void Exit (entity_type entityType)
    {
       
    }

}

基类之所以设计成含有3个小的状态方法是因为,通常在游戏中有些行为都只是在进入或退出某个状态时出现的,并不会发生在通常的更新步骤中。这样设计就可以有效的将持续性调用语句和一次性调用语句有效的区分开来。(举例:发送技能时的特效,有些是持续性而有些又是一次性的)

接下来我们编写状态机代码,来使直接的这个基类的各个方法运作起来:
(更多…)