Welcome::欢迎来访

============================================================================

欢迎阁下光临 云飞机器人实验室

博主 戴晓天 (Yunfei) 致力于嵌入式系统与机器人研究。

● 云飞机器人实验室是什么?

云飞机器人实验室是一个 “专注于嵌入式系统应用,致力于智能系统研究” 的个人科技博客。

实验室专注于嵌入式系统、计算机与机器人领域,包括嵌入式处理、程序语言、实时系统、机器人系统和智能控制等。

● 目标与愿景

云飞实验室的宗旨是:“让机器充满智慧”,旨在利用嵌入式和机器人技术改变人类的生活方式。

● 沟通与交流

欢迎其他有相关爱好的个人或组织与我沟通交流。同时本网站接受电子产品评测、电子类文章约稿等服务。如要交换链接请与我邮件联系,接受各种电子、科技与工程类博客。

● 版权声明

本网站所有内容除特别声明,均为云飞机器人实验室原创。作者保留对文章的一切权力。转载请注明原文出处,并保留原文的版式与结构。

============================================================================

About this blog >>

Welcome to Yunfei Robotics Laboratory. I am Xiaotian Dai from University of York and this is my personal tech website. This blog provides topics on embedded systems and robotics. The majority of the articles on this blog are based on my original work, while few videos and photos are shared from other technical websites.

Topics covered in this blog include intelligent robots, computer vision, Raspberry Pi, Arduino, embedded Linux, electronics, high performance microcontrollers, computer art and graphic user interface.

This website is original in Chinese but the support of English is in process. You can follow this link to see all posts in English. If you have any suggestions and ideas about my blog, please feel free to leave a comment or simply send me an email: automatic.dai (at) gmail.com. To know more about me, please follow this link.

============================================================================

YunFeiLogo_01

============================================================================

Specials::特别专题>>

RaspberryPi_Logo      arduino_logo_text      gameduino2_logo
ros_logo      stm32_logo      c-prog

============================================================================

News::网站动态 >>

2016/05/26   最近一直在做家庭服务器的构建,有很多成果等待发布,敬请期待。

2016/04/20   推荐博文: 树莓派3代介绍及历代树莓派比较

2015/11/01   网站总访问量突破10万了,感谢广大读者的支持!

2014/10/29   Gameduino 2中文参考手册历时数月翻译完成,现已正式发布!点击下载

2014/09/23   网站全新改版:支持宽屏浏览,图片和标题都更加清晰,同时网站正在逐步支持多语言。

2014/08/03   项目上线: Gameduino 2 (Arduino图形界面扩展板)  点击访问

2013/06/11   项目上线: 妖姬 - 互联网时代的电子植物

2013/03/24   专栏: 树莓派Raspberry PI,点击访问

2013/01/11   项目上线: 机器人室内定位项目立项,点击查看

Read more »

This is a sticky post! continue reading?

【C语言深入】陷阱:数组指针作为函数参数返回

再来看一个指针问题,同样的来自一个本科生的代码。这段代码想要实现将一个全是小写字母的字符串转换成对应的大写字母字符串:

char *covert_to_upper_case(char *string) {
    char p[100];
    int i = 0;
    
    for(; i < strlen(string); i++ ) {
            p[i] = string[i] - ('a' - 'A'); 
    }
    p[i] = '\0';
    
    return p;
    
}

然而这段代码没有能实现期望的功能。原因如下:

  1. 主程序调用convert_to_upper_case()函数后,堆栈为p分配了内存空间;
  2. 函数体正确修改了p对应字符数组的内容,并将p的首地址作为指针返回;
  3. 函数返回后,所有临时变量从堆栈中弹出,包括p[100];
  4. 主程序得到返回的指针,对其进行解析。然而指针指向的字符数组此时已经从堆栈中弹出,解析后的数据无法被定义。

要想正确实现对应的功能,应该将目标指针作为额外参数传递给该函数,并由上层调用者提供内存空间的创建。当然也可以使用malloc()将内存分配在堆中,但是需要注意使用对应的free()释放空间,否则会有内存泄露的问题。

【C语言深入】指针的一个错误赋值

关于指针总是有说不完的故事。

最近给本科的学生带Embedded System课程设计,遇到了一个非常奇怪的bug。有一段代码需要实现I2C通信,核心代码已经由软件库提供了,学生只需要设置结构体后调用API即可。一个学生的代码是这样的:

struct I2C_CONFIG {
  // ...
  char *i2c_buff;
  int length;
  // ...
};

struct I2C_CONFIG cfg;
char *i2c_buff;

void I2C_init() 
{
  // ...
  cfg.buff = i2c_buff;
  cfg.length = sizeof(buff);
  // ...
}

void I2C_send(new_buff)
{
  // ...
  i2c_buff = new_buff;
  I2C_MasterTransferData(LPC_I2C1, cfg);
  // ...
}

初看一下没有什么问题:在I2C_init()函数中首先对结构体cfg进行初始化,而在I2C_send()函数中设置了需要发送的数据指针,之后使用I2C的API发送数据。

因为代码一直无法实现期望的功能,我又仔细看了一下其中的蹊跷。我注意到,这段代码中使用了一个中间变量:char *i2c_buff。在I2C_init()中虽然将cfg.buff指向了i2c_buff,但是因为cfg.buff本身也是指针变量,而非"指向指针的指针",所以这里只实现了简单的按值传递,即将i2c_buff的值 (初始值为0) 赋给了cfg.buff。之后虽然在I2C_send()中修改了临时变量i2c_buff指向的位置,但却没有影响到cfg.buff中的内容,cfg.buff依然指向之前i2c_buff初始化时指向的内存地址,所以需要发送的缓冲指针new_buff其实并没有传递给之后的I2C_MasterTransferData()函数!为了解决这个问题,必须将更改后的i2c_buff的值再次赋给cfg.buff,即:

void I2C_send(new_buff)
{
  // ...
  i2c_buff = new_buff;
  cfg.buff = i2c_buff;
  I2C_MasterTransferData(LPC_I2C1, cfg);
  // ...
}

另外这段代码还有一个不容易注意的bug,就是在I2C_init()中使用了sizeof()来判断buffer的大小。因为sizeof()函数得到的只是数据类型的大小,所以对于指针char *i2c_buff来说,sizeof(i2c_buff) = 4,而不会返回buffer的实际大小。指针的大小并不等于指针指向缓冲的大小!

The Limitations of Classical PID Controller and Its Advanced Derivations

Since founded by N. Weiner in 1947, the control theory has been evolved for more than 60 years and is still full of challenges and opportunities. The most important principle of the control theory, in my opinion, is the feedback mechanism. Without feedback and closed-loop, almost no algorithm and control technique can be implied. The idea of feedback is that by comparing the reference input and the actual output, an error signal can be obtained and then can be used by the controller to trace and eliminate the difference between the input and the output. Apart from Watt’s steam engine, one could say that the first formally implication of (negative) feedback is the amplifier invented by H.S. Black. It is a genius idea when first came out in 1927 and was proved to be an extremely useful way to solve electronic and control problems. The idea of output feedback has also been extended to state feedback and error feedback to achieve state control and estimation in more advanced control techniques.

Classical control is the foundation of control theory and it is more concentrated on analysing the stability and performance of a controlled plant. However, only linear and SISO systems have been discussed in classical control theory. Although traditional control techniques such as PID controller are still widely used in industry, they cannot handle more complex engineering scenarios such as aerospace, chemistry and biology. Another problem of classical control is that all parameters are designed and tuned based on the current system model, in which case the system will be more vulnerable to further disturbance and parameters varying.

In order to solve these problems of classical PID controller which mentioned before, more advanced approaches have been derived nowadays. If using classical approach to control a MIMO system, one should divide the system into different modes and control each mode separately. However if the system inputs and outputs are coupled with each other, it cannot be decoupled and this method will not be practicable anymore. Here comes the state-space method, which solved the limitation of classical control by using state variables. The advantage of state-space is that it can be represented by matrices and such is very computer-friendly. State-space representation is actually defined in time domain instead of frequency domain and every state can have some extend of physical meaning which gives some clues about what is happening inside a controlled plant. One milestone which makes the state-space method more practicable is the invention of Kalman filter. Kalman filter uses a series of history measurements in the presence of noise to estimate the current state of the system. Kalman filter can work as a state estimator or simply a special filter which uses the physical system model to remove the process and the measurement noise.

Optimal control method such as MPC and LQR is another derivation of classical control. In most circumstances, there are more than one possible control inputs which can drive the system to work properly, but we need is to find the optimal one. Optimal control actually transforms the control problem into an optimal problem which tries to minimise an objective function to get the best outcome. Another advantage of optimal control is that it can take constraints into consideration. One defect of PID controller is that it cannot handle system constraints like actuator saturation or output limitation. In the optimal case control, design a controller with constraints could be feasible.

It is also known that no system is constant and some parameters are likely to vary with time or to the working condition. In classical control, the controller is designed just for the current system model and thus may loss performance or even be unstable due to the system change and uncertainties. In such aspect, adaptive control or robust control may be more applicable. Both adaptive control and robust control are designed to cope with uncertainties. The difference is that adaptive control identifies the system model and changes its parameters in real-time, but robust control fixed its parameters after deployed to the plant. For the truth that adaptive control has to calculate the system model every few periods, it needs much more computational time. What’s more, since the control parameters in the adaptive controller are changing every time, it may be difficult to prove its stability.  On the other hand, the gain of robust controller has already been designed before applied to the system, so it doesn’t need to do additional calculation during the operation. Since robust controller is globally optimised and especially designed to handle uncertainties, it may not have a performance as good as other controllers. But since the real control problems are always not ideal, it is meaningful to take uncertainties and disturbance into the system model.

Some more advanced control techniques such as neural network and expert control are being discussed today. In my opinion, these new approaches have the potential to be the next generation of control theory. With the developing of computer science, it is now possible to model extremely complex networks. This kind of controller can actually take all the possible system states and its corresponding solutions into a database and each time just search for the best solution according to the current system data.  New techniques such as machine learning can also be absorbed into the controller and make the controller more flexible which can handle different control problems using a same configuration.

However, no matter how powerful the control method is, there are rarely situations where we do not need to make trade-offs. As human-beings, we always need to make decisions and balance the income and the expense. Being too greedy is like giving an infinite gain to a helicopter, which may work at the beginning but will suddenly crash whenever there is any disturbance. So push yourself while keep in mind that you have limitation. Take it easy, be adaptive to the environment and always try to get the optimal solution of your life.

REFERENCES

[1] R.C. Dorf & R.H. Bishop, Modern Control Systems (Twelfth Edition), Pearson, USA.

[2] Wikipedia, Harold Stephen Black. Available at: http://en.wikipedia.org/wiki/Harold_Stephen_Black. Last accessed 26th Mar 2014

[3] E.F. Camacho and C. Bordons, Modern Predictive Control, Springer, London, 2003

【RPi树莓派使用指南】树莓派官方7寸屏入门指南

1. 引子

在树莓派官方触摸屏发布之前,市场上可用的屏幕有以下三种:

  • 直接和GPIO插口对接的屏幕,使用SPI与CPU进行通信。需要特殊的驱动程序将framebuffer的内容发送到LCD控制器上,一般带有触屏功能,大小以3.5寸为主流。受限于SPI通信速度,刷新速率不高;
  • 专用USB接口的屏幕,如RoboPeak Mini USB Display。这类屏幕通过USB连接,需要本地运行驱动程序;
  • 通用LCD屏幕,通过HDMI和树莓派连接。因其通用性不需要特殊的驱动程序,但是很多都不支持触屏功能,而且都需要额外的转接板,体积较大;

rpilcd-front-with-base
▲ 图.  树莓派官方7寸屏实拍

我自己的需求是将树莓派作为信息显示中心,在屏幕上显示我的HP服务器的运行信息,另外提供一些快捷的传感器监控和控制操作接口。最初一直在官方屏幕和HDMI屏幕之间犹豫,最后还是选择了官方触摸屏。归结起来主要有几个原因:

  • 官方屏的LCD模组最有保证,淘宝上的HDMI LCD一般成像质量不高;
  • 官方屏的触摸功能在所有方案中是支持的最好的,有十点电容触摸(目前Raspbian还只支持单点,以后会升级),且不需要额外驱动。而HDMI接口的LCD如果有触摸功能,都需要额外接一根USB用于提供触摸控制;
  • 官方触屏和树莓派3可以直接通过铜柱物理连接,无需额外的驱动电路板。连线也非常少,只需要一根DSI软排线和供电接口即可。

总体上来说,虽然官方屏的价格高了一些,但是却是所有方案中最可靠、简洁的,所以最后也没有多犹豫就从网上下单了。rpilcd-front-without-base
▲ 图. 树莓派官方LCD屏实拍 - 正面

 

2. 入手简评

这款屏幕官方公布的主要参数有:

  • 分辨率800 x 480像素,刷新率60fps;
  • 10点电容触摸,但是目前只支持单点触控;
  • 背后有可供背挂的安装定位孔;
  • 可视角度70度 ,可视区域大约为155 x 86mm;
  • 非方形像素 - 大约为0.19 x 0.175mm;
  • 电源功耗:455mA - 470mA之间,约为2.3W。

虽然说这款屏幕是相对来说比较好的选择,但是拿到手之后还是发现了很多存在的问题:

  • 首先是这款屏幕的分辨率只有800 x 480,是WVGA标准,很多应用软件的界面都无法完全显示,使用时要经常拖动窗口来显示需要的信息;同样的,如果是自己开发图形界面,能够显示内容的空间也会比较有限(尤其考虑到任务栏也占用了一部分空间);
  • 其次是这个屏幕的可视角不大。现在主流的LCD屏幕可视角都是120度以上了,而这款屏只有70度,工作时只要稍微变换一下角度屏幕的内容就看不清楚了。可视角的问题在仰视时还可以接受,俯视的时候就非常明显了;
  • 最后就是这个屏幕比较吃电,如果和树莓派供用电源,会影响到树莓派的供电。如果出现供电不足的情况,屏幕的右上角就会时不时出现一个方形的彩虹图标。

总体来说这款屏幕从设置到使用还是比较方便的,但是作为官方发布的屏幕,同时再考虑其600块钱的定价,整体性价比就显得不高了。

 

3. 使用方法

3.1 注意事项(使用前必读)

1) 这款屏幕主要支持的树莓派型号是Model A+, B+, Pi 2和Pi 3。 Model A和B虽然也可以使用,但是会牺牲I2C的功能(因为这两个型号只有一组I2C,而其他型号有两组,可用其中一组作触屏接口);

2) 至于操作系统,推荐使用最新版原生Raspbian OS。目前对NOOBS系统支持不好,所以还是推荐安装Raspbian;如果已经在使用旧版Raspbian,但是不想重新安装最新的系统,可以使用以下命令升级系统:

sudo apt-get update
sudo apt-get install --reinstall libraspberrypi0 libraspberrypi-{bin,dev,doc} raspberrypi-bootloader
sudo reboot

以下是官方公布的操作系统支持情况:
- Raspbian - Supported
- Ubuntu MATE - Supported
- RetroPie - Supported
- OpenElec - Supported
- OSMC - Supported
- Arch - Display works, Touch may be tricky: https://www.raspberrypi.org/forums/viewtopic.php?f=108&t=128452
- Kano OS - Not supported

3) 确保使用官方电源(或其他品牌电流供应能力 > 2A以上的电源),保证屏幕可以正常供电;

4) FPC连接头很脆,安装的时候需要小心一点。确保FPC连接头可靠链接,连接端口的卡口扣下。

 

3.2 安装方法

打开包装后,屏幕背面接口的情况如下图所示:

rpilcd-back-without-base00
▲ 图. 树莓派官方LCD屏背面接口

这里主要需要连接的就是LCD软排线和电源供电接口。LCD软排线连接的时候问题不大,主要就是注意接口触电的方向是否正确,不要装反了。至于电源接口,这款屏幕提供三种供电方式:

1) GPIO引脚供电(树莓派向LCD供电)

可以直接从树莓派跳VCC和GND线进行连接,然后给树莓派供电,但是这样就无法使用其他IO扩展板了(如SenseHat)。

rpilcd-back-without-base1
▲图. GPIO供电连接方法

2) USB串联供电(LCD向树莓派供电)

将LCD的Power Out端连接至树莓派,然后给LCD电源接口供电。经测试,这种方式供电经常会遇到之前说的供电不足的情况,屏幕右上角会出现彩虹图标。

rpilcd-back-without-base2
▲图. USB串联供电连接方法

3) 双USB同时供电

两个USB都单独供电,但是要保证两个USB可以同时上电,否则会出现开机没有初始化屏幕,而没有图形显示的问题。

电源和软排线连线完成后就可以固定树莓派了。树莓派的安装方法有两种:正装和反装。所谓正装,就是将树莓派以相同方向安装在LCD的铜柱固定柱上。而反装,则是将树莓派面朝LCD驱动板进行安装。反装可以节省空间,但是反装就无法再使用GPIO引脚了,所以一般情况下都是正装的。

官方屏不含支架,可以去网上购买专用的LCD支架,像我买的这款用起来就不错:

rpilcd-back-with-base
▲图. LCD亚克力支架

 

3.3 使用虚拟键盘

对于想使用触摸屏进行全部操作的朋友,可以安装一个虚拟键盘进行文字输入:

3.3.1 Florence

Suggested on the Pi forums by Hove is Florence: http://xmodulo.com/onscreen-virtual-keyboard-linux.html. Install with:

sudo apt-get install florence

 

3.3.2 Matchbox

Suggested by Alex ( the almighty @raspitv ), and scattered on various blogs, is Matchbox, which you can install like so:

sudo apt-get install matchbox-keyboard

And then find in Accessories > Keyboard.

 

4. FAQ问题解答

Q: 屏幕上下180度翻转

A: 打开SD卡中的/boot/config.txt文件,增加以下一行:

lcd_rotate=2

也可以直接使用以下命令:

echo "lcd_rotate=2" | sudo tee -a /boot/config.txt

 

Q: 程序控制背光

A: 打开背光:

echo 0 > /sys/class/backlight/rpi_backlight/bl_power

关闭背光:

echo 1 > /sys/class/backlight/rpi_backlight/bl_power

 

Q: 在Pi A, B上使用

A: 首先需要将树莓派的IIC线与LCD控制板的IIC总线手动连线在一起,包括SDA ( http://pinout.xyz/pinout/pin3_gpio2) 和 SCL (http://pinout.xyz/pinout/pin5_gpio3)。之后修改配置,在IIC总线上识别LCD:

ignore_lcd=0

注意: 其他IIC设备将无法使用。

 

Q: 屏幕左上角出现方形彩虹图标

A: 电源供电不足,请使用电流供应能力 > 2A的电源。

 

Q: 如何使用Kivy图形库

A: Kivy介绍:Kivy is a Python GUI development system for cross-platform applications. It is designed to work with touchscreen devices (phones and tablets), but also runs on the Raspberry Pi. To install Kivy onto your Pi follow the instructions at https://kivy.org/docs/installation/installation-rpi.html.

如果需要在树莓派上正常识别触摸屏输入,需要将触摸屏在Kivy中配置成为输入源。打开配置文件 ~/.kivy/config.ini ,在 [input] 一栏增加以下命令:

mouse = mouse
mtdev_%(name)s = probesysfs,provider=mtdev
hid_%(name)s = probesysfs,provider=hidinput

 

Reference

[1] Official 7” Raspberry Pi Touch Screen FAQ, PIMORONI, http://forums.pimoroni.com/t/official-7-raspberry-pi-touch-screen-faq/959

[2] Getting Started with the Pi 7" Touchscreen LCD, PIMORONI, http://learn.pimoroni.com/tutorial/pi-lcd/getting-started-with-raspberry-pi-7-touchscreen-lcd

【C语言深入】C/C++变量命名规范

目前主流的C/C++命名风格有两种:一种是Windows风格的匈牙利命名法,主要是采用类型前缀 + 变量名首字母大写,另一个就是Unix/Linux命名习惯。我自己采用的是基于Unix的变种,融合了匈牙利命名法的一些优点,在这里分享给大家。

变量名的组成:(模块名) +  (作用域) + (类型前缀) + 变量名 + (变量名后缀),解释如下:

  • 变量名 以小写的英文字母构成,词与词之间用下划线连接,如key_value, data_src; 不可使用数字,不混用大小写;
  • 模块名 声明该变量属于的模块,防止模块与模块的命名冲突。如timer_prescalar_value, DMA_channel_name等;
  • 作用域前缀 (Scope Prefix) 标注变量的作用域,提高代码可读性:
    g_: 全局变量;
    n_: 局部变量;
    t_: 中间变量;
    s_: static静态变量;
  • 类型前缀 (Type Prefix) 指明变量的数据类型:
    ptr_: 指针变量,在程序中临时需要使用指针时,也常简写为p_,如*p_src;
    h_: 句柄,如h_file;
    n_: 整形,s_: 短整形,l_: 长整形, u_: 无符号整型,可增加数据位数,如u32;
    ch_: 字符型变量;
    f_: 浮点,d_: 双精度浮点;
    b_: boolean;
    by_: byte字节型(关注数据的位特性,需要位操作的情况下使用);
    reg_: 表示寄存器;
  • 后缀 (Suffix) 指明变量的性质:
    _src: 源,_dst: 目的;
    _str: 字符串;
    _t: 在声明数据类型时使用,表示为自定义的数据类型,如u32_t;
    _st: 表示为结构体;
    _buff: 数据缓冲, msg_buff;
    _arr, _a, _m: 数组或矩阵;

变量名的取名规则:

  • 循环控制变量 i, j, k, m, n,除循环控制外应避免使用这些变量名称;
  • 函数名 使用(模块名 + )动词 + 名词的形式,同样小写 + 下划线:sys_find_file(), IO_get_data(). 后者因为IO为专用名词故破例使用大写;
  • 类名或结构体名 使用首字母大写加下划线连接:如Mystring, Datetime_type;
  • 私有类成员 Private使用下划线_前缀,如_data_src_ptr, _init_module();
  • 宏定义或常量 使用全部大写:如MAX_NUMBER, LOOP_NUMBER;
  • 缩写 使用能广泛接受的缩写:如add, ans, avg, chk, cnt, col, ctrl, def, del, dst, disp, err, freq, idx, init, len, min, max, mid, msg, num, opt, pos, ptr, recv, res, ret, src, str, sub, num, ts (timestamp), val等。

本网站的所有实例代码和项目程序都将按此命名规范进行编写。

近日关注的几个KickStarter项目

KickStarter是国外最著名的众筹网站。项目发起者可以在只有基本idea的情况下提前发布产品信息,以获得来自个人的资金支持,达到满意的标准后再进行产品的实际生产,从而减少了产品发售的风险。 这几天在KS上比较热门的科技项目都是智能设备/可穿戴设备,这里我聊一聊几个我最近关注的项目。

1. Sweep激光雷达

项目主页:https://www.kickstarter.com/projects/scanse/sweep-scanning-lidar/description

sweep
▲ 图1. Sweep低成本激光雷达

激光雷达是机器人常用的传感器外设,用于快速扫描、感知环境存在中的障碍物。激光雷达通过激光旋转扫射,再测量激光返回时间的方式,对周围障碍物的距离进行快速估算。传感器输出的点云数据可以进行三维建模,最终辅助机器人进行导航。目前常用的激光传感器品牌为 HOKUYO,售价在几万至几十万元。传统的激光雷达使用光学振镜进行激光扫描,通过计算激光束相位差进行距离计算。而低成本的激光雷达通过电机控制激光的发射角度,使用视觉原理进行距离估算。在牺牲了扫描速度的情况下,大幅度降低了成本。关于低成本激光雷达的设计原理,可以参照CSK兄的博文:自制低成本3D激光扫描测距仪(3D激光雷达)

sweep-demo
▲ 图2. Sweep工作在四轴飞行器上(慢速摄影)

以下是由IEEE Spectrum网站整理的Sweep与其他常见激光雷达的参数对比。Sweep的价格只有专业激光雷达的1/5,但刷新速度(Scan Rate)只有专业传感器的1/4。其检测距离精度为1cm,精度为1 - 2%,可以满足一般的机器人地图构建与导航应用。图表中的 robopeak 现改名为 SLAMTECRPLIDAR 也在最近推出了新款 RPLIAR A2,在性能上相比一代做了很大提升 (10Hz刷新率),价格和Sweep也很相似。目前Sweep的众筹已经结束,最终筹款$272,990,共有1,010个支持者。官网上可以预购,价格为$255,折合人民币1680元。

sweep-spec
▲ 图3. Sweep与其他激光雷达的参数对比

 

2. Pebble 2智能手表

项目主页:https://www.kickstarter.com/projects/597507018/pebble-2-time-2-and-core-an-entirely-new-3g-ultra

pebble_cover
▲ 图4. Pebble智能手表第二代

大名鼎鼎的智能手表先祖Pebble再次回到KickStarter。这次他们带来的是最新的两款手表产品:Pebble 2和Pebble Time 2。前者是廉价型,后者为Premium高级版本。这次新版本的Pebble相比上一代的主要改变有:

1、增加了心率传感器。现在心率传感器已经是智能手表的标配了,Pebble自然要与时俱进;
2、增加了麦克风外设,支持语音信息回复,应该还可以通过Google Voice (Android) 和Siri (iOS) 进行语音控制);
3、核心处理器从Cortex M3升级为M4,有更大的信号处理能力;
4、在增加了额外的传感器之后,防水能力从50m下降到30m,但是依然足够日常使用;
5、Pebble Time 2实际上是上一代的Pebble Time Steel,Pebble Steel这个型号可能不会再推出。

pebble
▲ 图5. Pebble 2和Pebble Time 2

pebble2_colors
▲ 图6. Pebble 2有五种可选颜色

新产品的两个版本Pebble 2和Pebble Time 2两者的主要区别有:

1、Pebble Time 2的屏幕尺寸更大 ,同时使用的是彩色e-ink屏,而Pebble 2是黑白灰度e-ink屏 (e-ink即Kindle所使用的电纸屏,功耗极低);
2、外观和材质上,Pebble Time 2更佳,Pebble 2则看上去比较廉价;
3、当然,Pebble Time 2的价格比Pebble 2多70%。

Read more »

如何做一个好的博客

我从2010年开始写博客。在过去的五年多时间里,除了自然而然增长的博文数量外,我的博文质量也在潜移默化的提高。然而这种质量的提高并不完全是自然形成的,这是需要不断思考博客的核心价值,同时在不断迭代的设计中艰难地产生的。每个人对自己的博客有一个定位,也有自己对于好博客的一套衡量标准。我从我自己以往产生的经验,来谈谈我眼中的好博客应该是什么样子的。

首先,一个好的博客需要是原创的,至少是半原创的。没有人喜欢整个网站全是复制-粘贴来的博文,这不光来自复制过程中产生的版式错误,而是这种复制的方式的本质是欠思考的、不系统的。行为上的懒惰必然导致思维上的懒惰,这样得来的文章只会显得杂乱无章,而不能体现任何博主自身的意图。可惜的是,这样的博客占了很大一部分。我想很多人也许并无意将自己的博客给别人看,而只是作为自己知识的索引。然而即使是这样,系统的整理也是必须的。这是一个吸收与理解知识的最好机会,有时甚至比文章自身带来的价值更大。

其次,是核心主题。所谓主题,就是整个博客中的博文是耦合或者是弱耦合的。制造主题的方式有很多,其中之一就是采用博文系列或专题的方式。比如云飞实验室以机器人和嵌入式为主题,也开发了热门的树莓派、Arduino和STM32等专题。正如写文章一样,博文的内容大多是围绕一个主题的。如果偏题太多,同样就会失去博客自己的特色。记住,你的博客是一个博客,而不是一个分享一切信息的网站。想要很好的做到这一点,你需要有自己假象的用户。比如对我自己而言,我的假象用户是嵌入式工程师,机器人爱好者,Makers。我每考虑创作写一篇博文,都会首先站在读者的角度去考虑。我会去判断这篇博文对读者的价值是多少?他们是否感兴趣?能不能帮助他们/引发更深层的扩展和思考?在这个过程中会有很多取舍。可能会遇到你很想发布,然而偏离主题,远离读者的博文。这是需要避免的。

再者,我就觉得是博客设计。我所说的设计,不仅包括网站的CSS版式,也包含了文章内部的组织。总体上来说,就是要做到简洁。简洁就是去除不必要的元素,避免华而不实的特效、动画、插件等。这些元素有时会破坏博客整体的平衡性,也会让读者分散精力。简洁可以给读者创造出纯净的阅读体验。而美就会略为主观了。我所理解的美,包括文章的段落结构,图片的尺寸、配色、位置,示例代码的优美性。以我的经验来看,美是需要用心才能做到的。需要让自己变得沉静,敏感,细腻。美的产生与其说是与生俱来,不如说是精雕细琢的产物。对美的感受也有进化的过程(但我觉得总体上是向正方向前进的)。很多时候,我会去看自己很久之前的博文,如果觉得做的还不够好,会再仔细修改。我也经常从别人的网站和博客中吸取经验,学习如何更好的排版、安插图片和代码等。这些需要一个人的审美层次,然而更多时候是花费时间和精力去雕琢而成的。

这些是我多年来一直在思考和遵循的原则,今日突然想与诸位分享之,便有此文。

戴晓天
2016年04月21日 于 英国约克

【RPi树莓派使用指南】树莓派3代介绍及历代树莓派比较

树莓派自从12年02月最初发布之后,目前已突破800万的总销量。作为树莓派的早期支持者,云飞实验室也一直在关注着它的发展。如今在经历了4年的设计迭代之后,树莓派于16年02月推出了最新一代的树莓派3。树莓派3的本次发布与之前的2代只相差了整整一年时间,但是得益于目前芯片行业的快速发展,树莓派3的性能将会有很大的提升。这主要表现在以下几点:

  • 更高的处理速度。树莓派3首次采用了64位处理器:基于Cortex-A53的博通BCM2837。BCM2837为四处理器核心,主频也由树莓派2的900MHz提高到了1.2GHz。根据官方提供的数据,这将使树莓派3的处理速度较2代提高50%。如果和1代的700MHz单核相比,提升大约在3 - 4倍。更高的CPU速度使得树莓派可以胜任更大负荷的运算工作:如科学计算,机器人路径规划等。
  • 更高的互联性。树莓派3使用了集成蓝牙4.0和WiFi的设计。集成通信的设计的意义是多方面的。首先,使用者无需再购买额外的USB设备,从一定程度上来说,鼓励了用户在自己的设计中使用这些通信功能;其次,集成的通信模块可以进行更好的功耗管理,同时IO吞吐的性能也会得到提高;最后,可以更进一步的优化内核,只针对板载的芯片专门进行优化。避免可能出现的兼容性或者未优化的驱动导致通信性能下降问题。

rasp-pi-3-board
图1. 树莓派3外观

rasp-3_Model_B
图2. 树莓派3外观 (设计渲染图) 

从这两点来看,树莓派3代将很有可能再次扩展自己的使用领域,同时在物联网和机器人中得到应用。同类产品如果还是单从硬件角度进行提升,已经无法再与之竞争。因为性能的显著提升且维持原价,在树莓派2代出来时没有入手的玩家,这一次也难免蠢蠢欲动。同时因其性价比的纯粹提升,树莓派1代与2代的销量会大幅下降。因为2代只发布了1年,所以很可能成为绝版,如果出于收藏的目的可以尽早买之。总体上来说,这次树莓派3已经具备了IoT所需要的基本条件(性价比,互联性,体积与功耗)。今后的方向可能是增加更多的IO功能,如PWM和ADC等,是被大多数玩家需要却还没有被支持的。

以下是我对历代树莓派版本的整理与对比:

表1. 发布时间及主要特点

型号 发布时间 主要特点
PI 1 Model B 2012年02月 第一代树莓派。Model A不含以太网。
PI Compute Module 2014年04月 模块化设计,使用SODIMM大小的金手指接口。
PI 1 Model B+ 2014年07月 增加了2个USB接口,增加了9个GPIO:26脚->40脚。
使用MicroSD卡。
PI 2 Model B 2015年02月 升级处理器:四核900MHz Cortex-A9。升级为1GB RAM。
PI Zero 2015年11月 无网络通信功能,廉价,小尺寸。
PI 3 2016年02月 升级处理器:64bit四核1.2GHz Cortex-A53。
内置蓝牙4.0和WiFi。

 

表2. 树莓派历代版本硬件比较

型号 处理器 主频 内存 GPIO 互联性 功耗级别
PI 1 Model B BCM2835
(ARM11)
700MHz 512MB 26 2 USB
HDMI
10/100M Ethernet
700mA (3.5W)
PI Compute Module BCM2835
(ARM11)
700MHz 512MB 0 无。需要配合扩展板使用。 200mA (1W)
PI 1 Model B+ BCM2835
(ARM11)
700MHz 512MB 40 4 USB
HDMI
10/100M Ethernet
600mA (3W)
PI 2 Model B BCM2836
(Cortex-A9 四核)
900 MHz 1GB 40 4 USB
HDMI
10/100M Ethernet
800mA (4W)
PI Zero BCM2835
(ARM11)
1 GHz 512MB 40 (无排针) 1 Micro-USB
Mini HDMI
无板载网卡
160mA (0.8W)
PI 3 BCM2837
(Cortex-A53 64位四核)
1.2 GHz 1GB 40 4 USB
HDMI
Bluetooth 4.1
WiFi 802.11n
10/100M Ethernet
800mA (4W)

 

Read more »