# 3. 文字的分类

Category 1. 生活类：备忘录、日记、随想等
Category 2. 严肃类：工作日志、读书笔记、文献记录等
Category 3. 专业类：博文、论文、出版物、专栏等

A. 记录：没有知识加工的过程，作为辅助记忆的手段。
B. 整理：对原输入数据进行一次滤波，小幅度修改原文的内容和结构，删去不需要的信息等。
C. 归纳：通过脑力活动，对数据进行结构化的整理。
D. 发布：对归纳后的信息进行文学化、排版、公开/或非公开的发布过程。
E. 记忆、索引、查阅：对A、B、C、D过程中产出的文字进行使用。

# 4. 文字产生的工作流

▲ Figure 1. 文字产生的work flow

1、删，删掉无用部分；
2、加，将有用的信息单独整理出来；
3、概，使用自己的语言梳理、分段概括原文的内容。

• 将新的博文添加到不同的分类目录下，并添加关键词标签；
• 所有生活日记、工作日志按年份进行整理，并放到Evernote的单独子目录下；
• 发现大量同质信息后，将其整理到一个单独的系统中（目前正在尝试将控制系统相关知识做成wiki [6]）。

# 5. 工具列表与比较

 工具 Good for Bad for Evernote raw资料收集，工作日志，随时随地有可能需要查看的内容。 ‘严肃的’文字生产，存在隐私和机密（日记等）。 Leanote 支持原生MD和LaTex，适合作为科研文字的生产平台。 可以快速发布blog和生成目录，适合知识的归档。 不适合：需要检索和长期存放的知识。 可靠性目前不如Evernote。 素签 对纯文字的记录，适合日记和文学创作（生活的、记录）。 LaTex 非常严肃的出版物（论文，pdf出版物）。 需要最终生成网页的知识（博文、wiki等），虽然有软件可以将LaTex转成网页，但是还需要将网页手工嵌入网站模板中。 共享程度不如博客，阅读群体数量少。 WordPress/Hexo/Jeklly 三个主流博客系统，适合知识的输出和共享。 尚未形成结构和体系的知识。 Mkdocs (Wiki) 体系、系统的知识整理。可以通过任意终端查阅、搜索。 尚未形成结构和体系的知识。 需要频繁添加、修改的知识。 OneNote 较为通用的知识，需要图片和文字共存，板式结构灵活。 缺乏对公式、程序代码的支持。 Tiddly Wiki 非线性、跳跃的知识管理和归档。 有明确层次和体系的知识

# 参考资料

[1] Leanote官方主页，我认为是一款针对程序员和科研人员的笔记软件，https://leanote.com/

[2] Evernote官方主页，一款全能型云同步笔记软件，https://evernote.com/intl/zh-cn/

[3] 知乎 – 如何构建自己的笔记系统，https://www.zhihu.com/question/23427617

[4] 万维钢 – 《万万没想到》，Part Two – 笔记本就是力量

[5] 罗辑思维，第205期：这一代人的学习

[6] 我正在做的控制系统维基，http://wiki.xiaotiandai.com/control/

## 【C语言深入】陷阱：数组溢出导致内存被意外修改

C语言的指针在提供编程便利的同时，却带来了很多潜在的内存安全问题。见以下例子：

#include <stdio.h>

int main() {

char string_buff[12];
unsigned int i_not_zero = 0xFF;

sprintf(string_buff, "Hello,world!");

printf("i = %x\r\n", i_not_zero);

return 0;
}


i = 0


## 你好，2017！

• 新增的”C语言深度”专题来源于我在嵌入式课程助教过程中发现的C语言的错误使用。我觉得C和C++是机器人领域最重要的两个语言，所以希望在这方面增加一些内容。
• 另几篇博文是介绍新发布的树莓派3代的。今年除了树莓派3，还入手了若干树莓派Zero。因为Zero很难买到，所以一下屯了5、6个。这批Zero准备用在智能家庭的节点中，但是应用场景目前还不明确，所以没有给大家做专题介绍。

• 承诺的智能家庭系统还没有完全开发完成，全部完成后会找时间公布。目前已完成的部分：中心服务器的部署，NAS，多媒体中心，一个传感器节点部署好了（已经上报了半年的温湿度数据）。二氧化碳、PM2.5传感器和无线组网模块选购好了，但还没有时间调试。另一个困难是控制数据的下发和传感器数据、系统参数的展现，我想基于BS架构（Flask + socket.io / Node.js + Ajax）。我没有网页编程的基础，而且中间涉及Real-time和asynchronous的问题，所以还没有时间解决。
• More topics on Robotics. 实验室还是以机器人为主题的，去年有点跑偏了（嵌入式系统），今年重新回归到主题上。重点我想要关注的内容点有：增强学习、概率决策、机器视觉、ROS、机器(深度)学习。
• 博主现在长期在国外生活，关于将网站转换为全英文的想法已有很久。但是还是一直很挣扎，考虑到很多内容对国内的读者会有帮助，所以今年还是保留双语写作。

## 【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. 主程序得到返回的指针，对其进行解析。然而指针指向的字符数组此时已经从堆栈中弹出，解析后的数据无法被定义。

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

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);
// ...
}


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


## 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

# 1. 引子

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

▲ 图.  树莓派官方7寸屏实拍

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

▲ 图. 树莓派官方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度，工作时只要稍微变换一下角度屏幕的内容就看不清楚了。可视角的问题在仰视时还可以接受，俯视的时候就非常明显了；
• 最后就是这个屏幕比较吃电，如果和树莓派供用电源，会影响到树莓派的供电。如果出现供电不足的情况，屏幕的右上角就会时不时出现一个方形的彩虹图标。

# 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 安装方法

▲ 图. 树莓派官方LCD屏背面接口

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

▲图. GPIO供电连接方法

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

▲图. USB串联供电连接方法

3) 双USB同时供电

▲图. 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

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.

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++变量命名规范

• 变量名 以小写的英文字母构成，词与词之间用下划线连接，如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等。