├── .gitignore
├── .nojekyll
├── Licence.txt
├── Makefile
├── README.md
├── build
├── 1.1.anywhere-html.md.html
├── 1.2.anywhere-javascript.md.html
├── 1.3.anywhere-css.md.html
├── 1.4.anywhere-hjc.md.html
├── 1.5.linux.md.html
├── 1.6.arduino.md.html
├── 1.7.python.md.html
├── 1.8.rpi.md.html
├── 1.9.server.md.html
├── 1.pre.md.html
├── 2.0.webservices.md.html
├── 2.1.http.md.html
├── 2.1.restful.md.html
├── 2.2.init_env.md.html
├── 2.3.create_laravel.md.html
├── 2.5.frontend.md.html
├── 2.intro.md.html
├── 3.1.coap.md.html
├── 3.1.iot-coap.md.html
├── 3.2.mqtt.md.html
├── 4.0.easyiot.md.html
├── 5.0.android.md.html
├── designiot.epub
├── designiot.mobi
└── qa.md.html
├── css
└── vendor.css
├── designiot.jpg
├── end
└── iot.md
├── help.md
├── images
├── 88x31.png
├── arch.jpeg
├── arduino.png
├── box-model.gif
├── change.png
├── dom_tree.jpg
├── edit.png
├── flow.png
├── fullconnected.png
├── getjson.png
├── gnu_linux.png
├── gpio.png
├── hardware.jpg
├── hwcnt.png
├── linux_kernel.jpg
├── lnmp.gif
├── lnmp.jpg
├── nostyle.png
├── origin.png
├── pm.png
├── python.png
├── raspberrypi_flow.png
├── redfonts.png
├── rpi.jpg
├── shell.png
├── star.png
├── temperture.png
├── uno.png
├── webkitflow.png
└── xml-vs-json.png
├── index.html
├── iot.html
├── src
├── 1.1.anywhere-html.md
├── 1.2.anywhere-javascript.md
├── 1.3.anywhere-css.md
├── 1.4.anywhere-hjc.md
├── 1.5.linux.md
├── 1.6.arduino.md
├── 1.7.python.md
├── 1.8.rpi.md
├── 1.9.server.md
├── 2.0.webservices.md
├── 2.1.http.md
├── 2.1.restful.md
├── 2.2.init_env.md
├── 2.3.create_laravel.md
├── 2.5.frontend.md
├── 3.1.coap.md
├── 3.1.iot-coap.md
├── 4.0.easyiot.md
├── 5.0.android.md
├── end
│ └── qa.md
├── futrue
│ └── 3.2.mqtt.md
└── pre
│ ├── 1.pre.md
│ └── 2.intro.md
└── template
├── head-chapter.html
├── head.html
├── headpdf.html
├── pdf.html
└── template.tex
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/*
2 | build/iot.pdf
3 | build/designiot.pdf
4 | Makefile.old
5 | build/pdf.html
--------------------------------------------------------------------------------
/.nojekyll:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | pandoc -s -V geometry:margin=1in --number-sections --highlight-style pygments -S --toc -c css/vendor.css -B template/head.html src/pre/*.md src/*.md src/end/*.md -o index.html
3 |
4 | iot:
5 | pandoc -s -V geometry:margin=1in --number-sections --highlight-style pygments -S --toc -c css/vendor.css -B template/head.html end/iot.md -o iot.html
6 |
7 | chapter:
8 | find src/ -name \*.md -type f -exec pandoc -s -V geometry:margin=1in --number-sections --highlight-style pygments -S --toc -c css/vendor.css -B template/head-chapter.html -o {}.html {} \;
9 | mv src/*/*.html build/
10 | mv src/*.html build/
11 |
12 | epub:
13 | pandoc -s -V geometry:margin=1in --number-sections --highlight-style pygments -S --toc -c css/vendor.css -B template/headpdf.html src/pre/*.md src/*.md src/end/*.md -o build/pdf.html
14 | pandoc build/pdf.html -o build/designiot.epub
15 |
16 | release:
17 | pandoc -s -V geometry:margin=1in --number-sections --highlight-style pygments -S --toc -c css/vendor.css -B template/headpdf.html src/pre/*.md src/*.md src/end/*.md -o build/pdf.html
18 | pandoc --template=template/template.tex build/pdf.html -o build/iot.pdf --latex-engine=xelatex
19 | pandoc build/pdf.html -o build/designiot.epub
20 | pandoc build/pdf.html -o build/designiot.mobi
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 《[一步步搭建物联网系统](http://phodal.github.io/designiot/)》
2 | ===
3 |
4 | 《自己动手设计物联网》现已出版:
5 |
6 | 
7 |
8 | 立即购买:[亚马逊](https://www.amazon.cn/dp/B01IBZWTWW/ref=wl_it_dp_o_pC_nS_ttl?_encoding=UTF8&colid=BDXF90QZX6WX&coliid=I19EB97K0GNLW8)、[京东](http://search.jd.com/Search?keyword=%E8%87%AA%E5%B7%B1%E5%8A%A8%E6%89%8B%E8%AE%BE%E8%AE%A1%E7%89%A9%E8%81%94%E7%BD%91&enc=utf-8&wq=%E8%87%AA%E5%B7%B1%E5%8A%A8%E6%89%8B%E8%AE%BE%E8%AE%A1%E7%89%A9%E8%81%94%E7%BD%91&pvid=k24y6hri.l4xi28)、[当当](http://product.dangdang.com/24000878.html)
9 |
10 | **在线查看**:[一步步搭建物联网系统](http://phodal.github.io/designiot/),主题:[Mifa Design](https://github.com/phodal/mifa)
11 |
12 | Android App版:
13 |
14 |
15 |
17 |
18 |
19 | ## 作者名单
20 |
21 | Github | Name
22 | |--------| ---------|
23 | [phodal](https://github.com/phodal) |[Phodal Huang](http://www.phodal.com)
24 | [Lboyve](https://github.com/Lboyve) | Xiaobing WANG
25 |
26 | ## License
27 |
28 | [](https://www.phodal.com/)
29 |
30 | © 2014~2016 [Phodal Huang](http://www.phodal.com).
31 |
32 | 本作品采用[知识共享署名-非商业性使用 4.0 国际许可协议](http://creativecommons.org/licenses/by-nc/4.0/)进行许可。
33 |
34 | [待我代码编成,娶你为妻可好](http://www.xuntayizhan.com/blog/ji-ke-ai-qing-zhi-er-shi-dai-wo-dai-ma-bian-cheng-qu-ni-wei-qi-ke-hao-wan/)
35 |
36 |
--------------------------------------------------------------------------------
/build/1.1.anywhere-html.md.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
某一天,正走在回学校的路上的我突然想到:“未来将会是一个科技的时代——虽然现在也是——只是在未来,科技将会无处不在。如果我们依旧对周围这些无处不在的代码一无所知的话,或许我们会成为黑客帝国之中被控制的普通人。”于是开始想着,有一天人们会像学习一门语言一样开始学习编程,直到又有一天我看到了学习编程如同学习一门语言的说法。这又恰好在我做完最小物联网系统之后,算是一个有趣的时间点,我开始想着像之前做最小物联网系统的那些步骤一样,写一个简单的入门。也可以补充好之前在这个最小物联网系统缺失的那些东西,给那些正在开始试图去解决编程问题的人。
76 |让我们先从身边的语言下手,也就是现在无处不在的html+javascript+css。
77 |之所以从html开始,是因为我们不需要配置一个复杂的开发环境,也许你还不知道开发环境是什么东西,不过这也没关系,毕竟这些知识需要慢慢的接触才能有所了解,尤其是对于普通的业余爱好者来说,当然,对于专业选手言自然不是问题。HTML是Web的核心语言,也算是比较基础的语言。
79 |Hello,world是一个传统,所以在这里也遵循这个有趣的传统,我们所要做的事情其实很简单,虽然也有一点点hack的感觉。——让我们先来新建一个文并命名为“helloworld.html”。
81 |(PS:大部分人应该都是在windows环境下工作的,所以你需要新建一个文本,然后重命名,或者你需要一个编辑器,在这里我们推荐用sublime text。破解不破解,注册不注册都不会对你的使用有太多的影响。)
82 |新建文件
hello,world
保存为->“helloworld.html”,
双击打开这个文件。 正常情况下都应该是用你的默认浏览器打开。只要是一个正常工作的现代浏览器,都应该可以看到上面显示的是“Hello,world”。
这才是最短的hello,world程序,但是呢?在ruby中会是这样子的
90 |2.0.0-p353 :001 > p "hello,world"
91 | "hello,world"
92 | => "hello,world"
93 | 2.0.0-p353 :002 >
等等,如果你了解过html的话,会觉得这一点都不符合语法规则,但是他工作了,没有什么比安装完Nginx后看到It works!更让人激动了。
95 |遗憾的是,它可能无法在所有的浏览器上工作,所以我们需要去调试其中的bug。
96 |我们会发现我们的代码在浏览器中变成了下面的代码,如果你和我一样用的是chrome,那么你可以右键浏览器中的空白区域,点击审查元素,就会看到下面的代码。
98 |<html>
99 | <head></head>
100 | <body>hello,world</body>
101 | </html>
这个才是真正能在大部分浏览器上工作的代码,所以复制它到编辑器里吧。
103 |106 | 超文本标记语言 107 |108 |
所以我们可以发现其中的关键词是标记——markup,也就是说html是一个markup,head是一个markup,body也是一个markup。
109 |然而,我们真正工作的代码是在body里面,至于为什么是在这里面,这个问题就太复杂了。打个比方来说:
110 |我们所使用的汉语是人类用智慧创造的,我们所正在学的这门语言同样也是人类创造的。
我们在自己的语言里遵循着桌子是桌子,凳子是凳子的原则,很少有人会问为什么。
所以我们也可以把计算机语言与现实世界里用于交流沟通的语言划上一个等号。而我们所要学习的语言,并不是我们最熟悉的汉语语言,所以我们便觉得这些很复杂,但是如果我们试着用汉语替换掉上面的代码的话
116 |<语言>
117 | <头><结束头>
118 | <身体>你好,世界<结束身体>
119 | <结束语言>
这看上去很奇怪,只是因为是直译过去的原因,也许你会觉得这样会好理解一点,但是输入上可就一点儿也不方便,因为这键盘本身就不适合我们去输入汉字,同时也意味着可能你输入的会有问题。
121 |让我们把上面的代码代替掉原来的代码然后保存,打开浏览器会看到下面的结果
122 |<语言> <头><结束头> <身体>你好,世界<结束身体> <结束语言>
更不幸的结果可能是
124 |<璇█> <澶�><缁撴潫澶�> <韬綋>浣犲ソ锛屼笘鐣�<缁撴潫韬綋> <缁撴潫璇█>
这是一个编码问题,对中文支持不友好。
126 |我们把上面的代码改为和标记语言一样的结构
127 |<语言>
128 | <头></头>
129 | <身体>你好,世界</身体>
130 | <结束语言>
于是我们看到的结果便是
132 |<语言> <头> <身体>你好,世界
被chrome浏览器解析成什么样了?
134 |<html><head></head><body><语言>
135 | <头><!--头-->
136 | <身体>你好,世界<!--身体-->
137 | <!--语言-->
138 | </body></html>
以
140 |结尾的是注释,写给人看的代码,不是给机器看的,所以机器不会去理解这些代码。
141 |但是当我们把代码改成
142 |<whatwewanttosay>你好世界</whatwewanttosay>
浏览器上面显示的内容就变成了
144 |你好世界
或许你会觉得很神奇,但是这一点儿也不神奇,虽然我们的中文语法也遵循着标记语言的标准,但是我们的浏览器不支持中文标记。
146 |结论:
147 |刚开始的时候不要对中文编程有太多的想法,这是很不现实的:
152 |我们离开话题已经很远了,但是这里说的都是针对于那些不满于英语的人来说的,只有当我们可以从头构建一个中文系统的时候才是可行的,而这些就要将cpu、软件、硬件都包含在内,甚至我们还需要考虑重新设计cpu的结构,在某种程度上来说会有些不现实。或许,需要一代又一代人的努力。忘记那些吧,师夷长之技以治夷。
157 |添加一个标题,
159 |<html>
160 | <head>
161 | <title>标题</title>
162 | </head>
163 | <body>hello,world</body>
164 | </html>
我们便可以在浏览器的最上方看到“标题”二字,就像我们常用的淘宝网,也包含了上面的东西,只是还包括了更多的东西,所以你也可以看懂那些我们可以看到的淘宝的标题。
166 |<html>
167 | <head>
168 | <title>标题</title>
169 | </head>
170 | <body>
171 | hello,world
172 | <h1>大标题</h1>
173 | <h2>次标题</h2>
174 | <h3>...</h3>
175 | <ul>
176 | <li>列表1</li>
177 | <li>列表2</li>
178 | </ul>
179 | </body>
180 | </html>
更多的东西可以在一些书籍上看到,这边所要说的只是一次简单的语言入门,其他的东西都和这些类似。
182 |我们简单地上手了一门不算是语言的语言,浏览器简化了这其中的大部分过程,虽然没有C和其他语言来得有专业感,但是我们试着去开始写代码了。我们可能在未来的某一篇中可能会看到类似的语言,诸如python,我们所要做的就是
184 |$ python file.py
185 | =>hello,world
然后在终端上返回结果。只是因为在我看来学会html是有意义的,简单的上手,然后再慢慢地深入,如果一开始我们就去理解指针,开始去理解类。我们甚至还知道程序是怎么编译运行的时候,在这个过程中又发生了什么。虽然现在我们也没能理解这其中发生了什么,但是至少展示了
187 |我们还没有试着去解决“某商店里的糖一颗5块钱,小明买了3颗糖,小明一共花了多少钱”的问题。也就是说我们学会的是一个还不能解决实际问题的语言,于是我们还需要学点东西,比如javascript,css。我们可以将Javascript理解为解决问题的语言,html则是前端显示,css是配置文件,这样的话,我们会在那之后学会成为一个近乎专业的程序员。我们刚刚学习了一下怎么在前端显示那些代码的行为,于是我们还需要Javascript。
195 | 196 | 197 | -------------------------------------------------------------------------------- /build/1.6.arduino.md.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |Arduino,是一个开放源代码的单芯片微电脑,它使用了Atmel AVR单片机,采用了基于开放源代码的软硬件平台,构建于开放源代码 simple I/O 接口板,并且具有使用类似Java,C 语言的Processing/Wiring开发环境。
76 |Arduino开发板封装了常用的库到开发环境中,可以让用户在开发产品时,将主要注意力放置于所需要实现的功能上,而不是开发的过程中。在为Arduino写串口程序时,我们只需要用Serial.begin(9600)以9600的速率初始化串口,而在往串口发送数据时,可以用Serial.write(‘1’)的方式向串口发送字串’1’。
77 |Arduino的出现很大程度上降低了电子制作的难度,初学者甚至不懂编程也可以上手Arduino,这也是它的魅力所在。
78 |为了满足各种需求,Arduino团队设计了很多款开发板,如UNO、Pro mini、Mega2560、Due、Leonardo、Yún、Pro、Fio、Nano等十几种 开发板和扩展板。最适合初学者的一款是Arduino UNO 。下图是Arduino UNO 的外观图:
80 |UNO
83 |注:后面的程序也是基于Arduino UNO开发板来讲解。
85 |Arduino
89 |开发环境如上图,十分简洁,编写代码需要知道两个基本的函数:
91 |void setup(){
92 |
93 | }
94 |
95 | void loop(){
96 |
97 | }
setup()
函数用于初始化(如GPIO初始化,串口初始化,定时器初始化等)特点是只执行一次;loop()
函数是一个死循环,可以看做C语言的while(1)
函数。
对初学者来说,点亮led已成为入门必修课,使用Arduino控制led十分简单,并且很容易理解。 使用到的函数:
101 |上一段代码分析:
106 |int led=13;
107 |
108 | void setup()
109 | {
110 | pinMode(led,OUTPUT);
111 | }
112 | void loop()
113 | {
114 | digitalWrite(led,HIGH);
115 | delay(1000);
116 | digitalWrite(led,LOW);
117 | delay(1000);
118 | }
该程序实现Arduino单片机13号引脚以1S时间电平翻转,如果外接一个led,就可以看到led以1S的间隔闪烁;函数pinMode()
有两个参数pin、value,pin参数用来指定引脚号,本程序中设置为13号引脚,mode用于设置引脚模式,有三个值:
INPUT
OUTPUT
INPUT_PULLUP
表示让某一个IO引脚作输入,反之,
126 |OUTPUT
则使一个IO引脚做输出INPUT_PULLUP
则配置一个IO引脚具有上拉输入功能(上拉电阻的目的是为了保证在无信号输入时输入端的电平为高电平),从英文意思也能很直观的看出来。理解了pinMode()
函数,digitalWrite()
就很容易理解啦,value的取值有两个HIGH
、LOW
,HIGH
表示让某一个引脚输出高电平,反之,LOW
则使某一个引脚输出低电平。 程序中还是用到delay(ms)
函数,它表示延时多少毫秒,例如延时500 ms ,直接调用delay(500);
就可以了。
如果你仔细查看我的描述,你会发现我没有讲13号引脚怎么来的,是这样的:Arduino团队为了简化对引脚描述,对每个引脚都进行了编号,以UNO开发板为例,可以发现开发板排座的附近有对应的白颜色的数字,那便是所有的引脚编号,A0~A5是6路ADC输入引脚,0-13表示13路基本IO,数字前面的~
表示该引脚具有PWM功能。如果要使用某一引脚,只需要知道引脚编号就可编写相应代码进行操作。
例如digitalWrite(2,LOW)
表示向2号引脚输出低电平。其他操作类似,是不是so easy - !
使用到的基本函数:
135 |在此项目中需要使用串口,Arduino串口初始化使用Serial.begin(9600);
,其传输波特率为9600,其他波特率也行,函数位于setup()
中,之后可以使用Serial.read()
、Serial.write()
读入一个字符,输出一个字符,使用Serial.print()
输出字符串.代码如下:
char ch='1';
143 | void setup()
144 | {
145 | Serial.begin(9600);
146 | }
147 | void loop()
148 | {
149 | Serial.write(ch);
150 | while(1)
151 | {
152 | if(Serial.available())
153 | {
154 | ch = Serial.read();
155 | Serial.print(ch);
156 | }
157 | }
158 | }
以上程序实现字符的输出(Serial.write(),Serial.print())和读入(Serial.read())。如果需要了解更多,可以参考:Arduino官网
160 |如果你对Arduino的Setup很疑惑的话,可以看看这里。下面Arduino源码目录中的main函数:
162 |#include <Arduino.h>
163 |
164 | int main(void)
165 | {
166 | init();
167 | setup();
168 | for (;;) {
169 | loop();
170 | if (serialEventRun) serialEventRun();
171 | }
172 | return 0;
173 | }
hwcnt
177 |Raspberry Pi
73 |Raspberry Pi是一款针对电脑业余爱好者、教师、小学生以及小型企业等用户的迷你电脑,预装Linux系统,体积仅信用卡大小,搭载ARM架构处理器,运算性能和智能手机相仿。在接口方面,Raspberry Pi提供了可供键鼠使用的USB接口,此外还有千兆以太网接口、SD卡扩展接口以及1个HDMI高清视频输出接口,可与显示器或者TV相连。
76 |Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的UNIX工具软件、应用程序和网络协议。它支持32位和64位硬件。Linux继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。
77 |Raspberry Pi相比于一般的ARM开发板来说,由于其本身搭载着Linux操作系统,可以用诸如Python、Ruby或Bash来执行脚本,而不是通过编译程序来运行,具有更高的开发效率。
78 |今天的Raspbian默认已经安装openssh-server
,并默认开启了OpenSSH-Server。
接着我们就可以看到系统启动了,要我们输入用户名和密码
81 |Raspbian GNU/Linux 7 raspberrypi ttyAMA0
82 |
83 | raspberrypi login: pi
84 | Password:
85 | Last login: Sat Apr 26 05:58:07 UTC 2014 on ttyAMA0
86 | Linux raspberrypi 3.10.25+ #622 PREEMPT Fri Jan 3 18:41:00 GMT 2014 armv6l
87 |
88 | The programs included with the Debian GNU/Linux system are free software;
89 | the exact distribution terms for each program are described in the
90 | individual files in /usr/share/doc/*/copyright.
91 |
92 | Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
93 | permitted by applicable law.
94 | ls
95 |
96 | NOTICE: the software on this Raspberry Pi has not been fully configured. Please run 'sudo raspi-config'
然后
98 |sudo raspi-config
选择第一个,下面就可以继续了
100 |Expand Filesystem Ensures that all of the SD card s
接着重启后,便可以扩展SD卡成功。
102 |注: Raspbian与一般的Debian系统使用起来区别不是太大(ps:命令上),由于CPU是不同的架构,在编译上可能有所区别。通常PC上的软件需要重新编译才能在RPi上运行,所以如果可以用apt-get安装的话,就不要自己编译了。
103 |105 |107 |General Purpose Input Output (通用输入/输出)简称为GPIO,或总线扩展器,利用工业标准I2C、SMBus或SPI接口简化了I/O口的扩展。当微控制器或芯片组没有足够的I/O端口,或当系统需要采用远端串行通信或控制时,GPIO产品能够提供额外的控制和监视功能。
106 |
GPIO
110 |服务器(Server)指:
35 |WEB服务器也称为WWW(WORLD WIDE WEB)服务器,主要功能是提供网上信息浏览服务。 WWW 是 Internet的多媒体信息查询工具,是 Internet 上近年才发展起来的服务,也是发展最快和目前用的最广泛的服务。正是因为有了WWW工具,才使得近年来 Internet 迅速发展,且用户数量飞速增长。
42 |LNMP
46 |Linux+Nginx+MySQL+PHP
48 |49 |51 |Nginx (“engine x”) 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru站点开发的,第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。
50 |
52 |54 |MySQL 是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司。MySQL是最流行的关系型数据库管理系统,在WEB应用方面MySQL是最好的RDBMS(Relational Database Management System:关系数据库管理系统)应用软件之一。MySQL是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。
53 |
55 |57 | 58 | 59 | -------------------------------------------------------------------------------- /build/1.pre.md.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |PHP于1994年由Rasmus Lerdorf创建,刚刚开始是Rasmus Lerdorf为了要维护个人网页而制作的一个简单的用Perl语言编写的程序。这些工具程序用来显示 Rasmus Lerdorf 的个人履历,以及统计网页流量。后来又用C语言重新编写,包括可以访问数据库。他将这些程序和一些表单直译器整合起来,称为 PHP/FI。PHP/FI 可以和数据库连接,产生简单的动态网页程序。
56 |
本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。
© 2014 Phodal Huang.
33 |设计物联网系统是件有意思的事情,它需要考虑到软件、硬件、通讯等多个不同方面。通过探索不同的语言,不同的框架,从而形成不同的解决方案。
35 |在这里,我们将对设计物联网系统有一个简单的介绍,并探讨如何设计一个最小的物联网系统。
36 |目标读者: 初入物联网领域,希望对物联网系统有一个大概的认识和把握,并学会掌握一个基础的物联网系统的设计。
38 |本文档对一些概念(如)只做了一些基本介绍,以方便读者理解。如果您想进一步了解这些知识,会列出一些推荐书目,以供参考。
53 |Web服务是一种服务导向架构的技术,通过标准的Web协议提供服务,目的是保证不同平台的应用服务可以互操作。
32 |根据W3C的定义,Web服务(Web service)应当是一个软件系统,用以支持网络间不同机器的互动操作。网络服务通常是许多应用程序接口(API)所组成的,它们透过网络,例如国际互联网(Internet)的远程服务器端,执行客户所提交服务的请求。
33 |尽管W3C的定义涵盖诸多相异且无法介分的系统,不过通常我们指有关于主从式架构(Client-server)之间根据SOAP协议进行传递XML格式消息。无论定义还是实现,WEB服务过程中会由服务器提供一个机器可读的描述(通常基于WSDL)以辨识服务器所提供的WEB服务。另外,虽然WSDL不是SOAP服务端点的必要条件,但目前基于Java的主流WEB服务开发框架往往需要WSDL实现客户端的源代码生成。一些工业标准化组织,比如WS-I,就在WEB服务定义中强制包含SOAP和WSDL。
34 |WEB服务实际上是一组工具,并有多种不同的方法调用之。三种最普遍的手段是:
35 |简单对象访问协议是交换数据的一种协议规范,使用在计算机网络Web服务中,交换带结构信息。SOAP为了简化网页服务器从XML数据库中提取数据时,节省去格式化页面时间,以及不同应用程序之间按照HTTP通信协议,遵从XML格式执行资料互换,使其抽象于语言实现、平台和硬件。
42 | 43 | 44 | -------------------------------------------------------------------------------- /build/2.1.restful.md.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |36 |38 |REST从资源的角度来观察整个网络,分布在各处的资源由URI确定,而客户端的应用通过URI来获取资源的表征。获得这些表征致使这些应用程序转变了其状态。随着不断获取资源的表征,客户端应用不断地在转变着其状态,所谓表征状态转移。
37 |
因为我们需要的是一个Machine到Machine沟通的平台,需要设计一个API。而设计一个API来说,RESTful是很不错的一种选择,也是主流的选择。而设计一个RESTful服务,的首要步骤便是设计资源模型。
39 |互联网上的一切信息都可以看作是一种资源。
41 |HTTP Method | 45 |Operation Performed | 46 |
---|---|
GET | 51 |Get a resource (Read a resource) | 52 |
POST | 55 |Create a resource | 56 |
PUT | 59 |Update a resource | 60 |
DELETE | 63 |Delete Resource | 64 |
设计RESTful API是一个有意思的话题。下面是一些常用的RESTful设计原则:
69 |xml-vs-json
89 |79 |81 |Laravel是一套简洁、优雅的PHP Web开发框架(PHP Web Framework)。它可以让你从面条一样杂乱的代码中解脱出来;它可以帮你构建一个完美的网络APP,而且每行代码都可以简洁、富于表达力。
80 |
这里不会再重述之前的问题,这里只是将需要的步骤一个个写下来,然后丢到这里好好说一下。至于RESTful是什么,前面已经介绍了,就不再重复了。那么下面,我们就用Laravel来搭建一个平台给物联网用的。
98 |GNU/Linux Ubuntu/OpenSUSE下可以执行
101 |$ curl -sS https://getcomposer.org/installer | php
102 | 请直接下载
104 | 105 |1.安装Composer
107 |brew install homebrew/php/composer
2.安装Laravel
109 |composer global require "laravel/installer=~1.1"
3.创建Laravel工程
111 |composer create-project laravel/laravel your-project-name --prefer-dist
1.下载laravel.phar
114 |wget http://laravel.com/laravel.phar
2.重命名
116 |mv laravel.phar laravel
3.移动到bin中
118 |sudo mv laravel /usr/local/bin
4.创建项目
120 |laravel new blog
出于某些原因,我建议用MariaDB替换MySQL,如果你"真正"需要mysql,将mariadb替换为mysql
ps: 在下文中我会继续用MySQL,而不是MariaDB,MairaDB是MySQL的一个分支,真正的开源分支。
125 |Ubuntu/Debian/Mint
126 |$ sudo apt-get install mariadb-server
Fedora/Centos
128 |$ sudo yum install mariadb-server
openSUSE
130 |$ sudo zypper install mariadb-server
Mac OS
132 |$ brew install mariadb
修改database.php
135 |app/config/database.php
要修改的就是这个
137 |'mysql' => array(
138 | 'driver' => 'mysql',
139 | 'host' => 'localhost',
140 | 'database' => 'iot',
141 | 'username' => 'root',
142 | 'password' => '940217',
143 | 'charset' => 'utf8',
144 | 'collation' => 'utf8_unicode_ci',
145 | 'prefix' => '',
146 | ),
如果你已经有phpmyadmin,似乎对你来说已经很简单了,如果没有的话,就直接用
148 |$ mysql -uroot -p
来创建一个新的
150 |CREATE DATABASE IF NOT EXISTS iot default charset utf8 COLLATE utf8_general_ci;
数据库的目的在于存储数据等等的闲话这里就不多说了,创建一个RESTful的目的在于产生下面的JSON格式数据,以便于我们在Android、Java、Python、jQuery等语言框架或者平台上可以调用,最主要的是可以直接用Ajax来产生更炫目的效果。
152 |{
153 | "id": 1,
154 | "temperature": 14,
155 | "sensors1": 12,
156 | "sensors2": 12,
157 | "led1": 0
158 | }
关于内容的选择,这是一个有意思的话题,因为我们很难判断不同的开发者用的是怎样的语言,用的是怎样的框架。
34 |于是我们便自作主张地选择了那些适合于理论学习的语言、框架、硬件,去除掉其他一些我们不需要考虑的因素,如语法,复杂度等等。当然,这些语言、框架、硬件也是最流行的。
35 |C都不懂还跑过来干嘛
。
大有以下两个原因
49 |这只是一个小小的建议,仅针对于在选择阅读上没有经验的读者。
55 |当前状态 | 59 |建议 | 60 |
---|---|
软件初学者 | 65 |从头阅读 | 66 |
硬件开发者 | 69 |从头阅读 | 70 |
没有web经验的开发者 | 73 |从第二部分开始 | 74 |
我们会在前面十章里简单介绍一些必要的基础知识,这些知识将会在后面我们构建物联网系统时用到。
78 | 79 | 80 | -------------------------------------------------------------------------------- /build/3.1.iot-coap.md.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |(注意
:windows系统npm install失败时,需要自己建立一个C:and Settings[USERNAME]Data文件)
npm install iot-coap
1.新建index.js
69 |注意
: 如果已经存在一个index.js文件,请将下面内容添加到文件末尾(create index.js, and add)
var iotcoap = require('iot-coap');
71 |
72 | iotcoap.run();
73 | iotcoap.rest.run();
注意
:在db配置可以选择mongodb和sqlite3,替换所需要的数据库即可。(you can choice db on iot.js with ‘sqlite’ or ‘mongodb’)
2.创建iot.js
76 |exports.config = {
77 | "db_name": "iot.db",
78 | "mongodb_name": "iot",
79 | "mongodb_documents": "iot",
80 | "db": "mongodb",
81 | "table_name": "basic",
82 | "keys":[
83 | "id",
84 | "value",
85 | "sensors1",
86 | "sensors2"
87 | ],
88 | "db_table": "id integer primary key, value text, sensors1 float, sensors2 float",
89 | "mongodb_init":[
90 | {
91 | id: 1,
92 | value: "is id 1",
93 | sensors1: 19,
94 | sensors2: 20
95 | },
96 | {
97 | id: 2,
98 | value: "is id 2",
99 | sensors1: 20,
100 | sensors2: 21
101 | }
102 | ],
103 | "init_table":[
104 | "insert or replace into basic (id,value,sensors1,sensors2) VALUES (1, 'is id 1', 19, 20);",
105 | "insert or replace into basic (id,value,sensors1,sensors2) VALUES (2, 'is id 2', 20, 21);"
106 | ],
107 | "query_table":"select * from basic;",
108 | "rest_url": "/id/:id",
109 | "rest_post_url": "/",
110 | "rest_port": 8848
111 | };
3.运行(run)
113 |node index.js
show:
115 |coap listening at coap://0.0.0.0:5683
116 | restify listening at http://0.0.0.0:8848
69 |71 |MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和致动器(比如通过Twitter让房屋联网)的通信协议。
70 |
早在1999年,IBM的Andy Stanford-Clark博士以及Arcom公司ArlenNipper博士发明了MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)技术[1] 。据Andy Stanford-Clark博士称,MQTT将在今年和明年呈现爆炸式增长。
72 |74 |76 |mqtt.js is a library for the MQTT protocol, written in JavaScript to be used in node.js.
75 |
var mqtt = require('mqtt')
77 |
78 | client = mqtt.createClient(1883, 'localhost');
79 |
80 | client.subscribe('presence');
81 | client.publish('presence', 'Hello mqtt');
82 |
83 | client.on('message', function (topic, message) {
84 | console.log(message);
85 | });
86 |
87 | client.end();
到这时,我们算搭建了一个简单的REST服务了。接着我们可以简单的做一个最小的物联网系统,将我们的单片机、MCU等等连上网。
75 |硬件结构图
78 |考虑到如果我们只是单一连接各个节点,那么系统的结构图,同下所示
80 |全连接
83 |下面的星形结构图类似于我们在接下来所要构建的系统
85 |星形结构图
88 |一个用于控制真实电器的硬件实物图
90 |简单实物图
93 |Arduino与Raspberry Pi通过串口通信的方式实现通信,相互传输所需要的数据,Raspberry Pi将资源传于互联网上对应的接口,接口可以在互联网上被访问。Laravel框架构架于服务器之上,将Raspbery Pi获取过来的数据存储于MySQL数据,再以REST服务的方式共享数据,互联网上的其他设备便可以通过网络来访问这些设备。Ajax用于将后台的数据以不需要刷新的方式传递到网站前台,通过HighCharts框架显示给终端用户。
97 |1.在Windows中的串口通常是COM1
,COM0
等等
ser=serial.Serial("COM0",9600)
2.Mac OS系统中位于/dev目录下,名字类似于tty.usbmodem1451
。
serial.Serial("/dev/tty.usbmodem1451",9600)
3.在Linux内核的系统中虚拟串口用的节点是ttyACM,位于/dev目录下。
103 | serial.Serial("/dev/ttyACM0",9600)
105 |107 |串行接口是一种可以将接受来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时可将接受的串行数据流转换为并行的数据字符供给CPU的器件。一般完成这种功能 的电路,我们称为串行接口电路。
106 |
便是打开这个设备,以9600的速率传输数据。
108 |程序框架如下所示:
109 |Raspberry Pi
112 |代码如下:
114 |import json
115 | import urllib2
116 | import serial
117 | import time
118 |
119 | url="http://www.xianuniversity.com/athome/1"
120 |
121 | while 1:
122 | try:
123 | date=urllib2.urlopen(url)
124 | result=json.load(date)
125 | status=result[0]["led1"]
126 | ser=serial.Serial("/dev/ttyACM0",9600)
127 | if status==1 :
128 | ser.write("1")
129 | elif status==0:
130 | ser.write("0")
131 | time.sleep(1)
132 | except urllib2.URLError:
133 | print "Bad URL or timeout"
python返回json数据
137 |系统还需要对上面的数据进行处理,只拿其中的结果
139 |python处理完后的结果
142 |当改变led的状态后,便可以得到下面的结果
144 |改变状态后的结果
147 |如果你用的是Ruby的话,可以尝试使用serialport
安装
151 |sudo gem install serialport
代码大致如下
153 |require 'serialport'
154 | sp = SerialPort.new "/dev/ACM0", 9600
155 | sp.write "1"
注意: 根据相关的系统修改相关的代码。
157 |这样我们在我们的Arduino上所要做的便是,读取串口的结果并控制IO口。
160 |int ledPort=13;
161 |
162 | void setup() {
163 | Serial.begin(9600);
164 | pinMode(ledPort,OUTPUT);
165 | }
166 |
167 | int serialData;
168 | void loop() {
169 | String inString = "";
170 | while (Serial.available()> 0)
171 | {
172 | int inChar = Serial.read();
173 | if (isDigit(inChar)) {
174 | inString += (char)inChar;
175 | }
176 | serialData=inString.toInt();
177 | Serial.print(serialData);
178 | }
179 | if(serialData==1){
180 | digitalWrite(ledPort,HIGH);
181 | }else{
182 | digitalWrite(ledPort,LOW);
183 | }
184 | }
如果结果是1的话,就让13口为高电平,也就是让灯亮起来。
186 |188 |190 |继电器(英文名称:relay)是一种电控制器件,是当输入量(激励量)的变化达到规定要求时,在电气输出电路中使被控量发生预定的阶跃变化的一种电器。它具有控制系统(又称输入回路)和被控制系统(又称输出回路)之间的互动关系。通常应用于自动化的控制电路中,它实际上是用小电流去控制大电流运作的一种“自动开关”。故在电路中起着自动调节、安全保护、转换电路等作用。
189 |
在这里我们可以默认为我们想要为单片机的5V电压控制220V的电器。
191 |最后我们便可以通过些来控制灯的开和关。
192 | 193 | 194 | -------------------------------------------------------------------------------- /build/5.0.android.md.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |由于在某些嵌入式系统中使用的是Android系统,这里给出一个简单的Android App的示例,具体代码可以从clone自https://github.com/phodal/iot-android
72 |代码说明,经过测试的版本有
73 |机型有
78 |应该可以在大部分的手机上工作。
85 |这里我们参考一篇文章来调用Web Services——Calling Web Services in Android using HttpClient
87 |在这里我们首先会定义四个REST方法GET、POST、PUT、DELETE
89 |public void Execute(RequestMethod method) throws Exception {
90 | switch (method) {
91 | case GET: {
92 | // add parameters
93 | String combinedParams = "";
94 | if (!params.isEmpty()) {
95 | combinedParams += "?";
96 | for (NameValuePair p : params) {
97 | String paramString = p.getName() + "="
98 | + URLEncoder.encode(p.getValue(), HTTP.UTF_8);
99 | if (combinedParams.length() > 1) {
100 | combinedParams += "&" + paramString;
101 | } else {
102 | combinedParams += paramString;
103 | }
104 | }
105 | }
106 |
107 | HttpGet request = new HttpGet(url + combinedParams);
108 | request.addHeader("Accept-Encoding", "gzip");
109 |
110 | // add headers
111 | for (NameValuePair h : headers) {
112 | request.addHeader(h.getName(), h.getValue());
113 | }
114 |
115 | executeRequest(request, url);
116 | break;
117 | }
118 | case POST: {
119 | HttpPost request = new HttpPost(url);
120 | request.addHeader("Accept-Encoding", "gzip");
121 |
122 | // add headers
123 | for (NameValuePair h : headers) {
124 | request.addHeader(h.getName(), h.getValue());
125 | }
126 | if (!data.equals("")) {
127 | request.setEntity(new StringEntity(data, HTTP.UTF_8));
128 | }
129 |
130 | if (!params.isEmpty()) {
131 | request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
132 | }
133 |
134 | executeRequest(request, url);
135 | break;
136 | }
137 | case PUT: {
138 | HttpPut request = new HttpPut(url);
139 | request.addHeader("Accept-Encoding", "gzip");
140 |
141 | // add headers
142 | for (NameValuePair h : headers) {
143 | request.addHeader(h.getName(), h.getValue());
144 | }
145 | if (!data.equals("")) {
146 | request.setEntity(new StringEntity(data, HTTP.UTF_8));
147 | }
148 |
149 | if (!params.isEmpty()) {
150 | request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
151 | }
152 |
153 | executeRequest(request, url);
154 | break;
155 | }
156 | case DELETE: {
157 | HttpDelete request = new HttpDelete(url);
158 | request.addHeader("Accept-Encoding", "gzip");
159 |
160 | // add headers
161 | for (NameValuePair h : headers) {
162 | request.addHeader(h.getName(), h.getValue());
163 | }
164 |
165 | executeRequest(request, url);
166 | break;
167 | }
168 | }
169 | }
这四个方法最后都执行executeRequest来获取响应结果。
171 |protected void executeRequest(HttpUriRequest request, String url) {
172 |
173 | HttpParams httpParameters = new BasicHttpParams();
174 | HttpConnectionParams.setConnectionTimeout(httpParameters,
175 | timeoutConnection);
176 | HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
177 |
178 | HttpProtocolParams.setUseExpectContinue(httpParameters, false);
179 | request.setParams(httpParameters);
180 |
181 | setOauth(request);
182 |
183 | DefaultHttpClient client = new DefaultHttpClient();
184 |
185 | HttpResponse httpResponse;
186 |
187 | try {
188 | httpResponse = client.execute(request);
189 | responseCode = httpResponse.getStatusLine().getStatusCode();
190 | message = httpResponse.getStatusLine().getReasonPhrase();
191 |
192 | HttpEntity entity = httpResponse.getEntity();
193 |
194 | if (entity != null) {
195 | InputStream instream = httpResponse.getEntity().getContent();
196 | Header contentEncoding = httpResponse
197 | .getFirstHeader("Content-Encoding");
198 |
199 | if (contentEncoding != null
200 | && contentEncoding.getValue().equalsIgnoreCase("gzip")) {
201 | instream = new GZIPInputStream(instream);
202 | }
203 |
204 | // instream = entity.getContent();
205 | response = convertStreamToString(instream);
206 |
207 | // Closing the input stream will trigger connection release
208 | instream.close();
209 | }
210 |
211 | } catch (ClientProtocolException e) {
212 | client.getConnectionManager().shutdown();
213 | e.printStackTrace();
214 | } catch (IOException e) {
215 | client.getConnectionManager().shutdown();
216 | e.printStackTrace();
217 | }
218 | }
接着,我们便可以执行getResponse()函数来获取结果。
220 |使用RESTClient时,便可以用下面的示例
222 |RestClient client = new RestClient(tUrl);
223 | try {
224 | client.Execute(RequestMethod.GET);
225 | if (client.getResponseCode() != 200) {
226 | //do something
227 | }
228 | //JSONArray jArray = new JSONArray(client.getResponse());
229 | } catch (Exception e) {
230 | //do something
231 | }
而这时,我们只需要对相应的数据进行处理就可以了,如
233 |JSONArray jArray = new JSONArray(client.getResponse());
234 | JSONObject jObj=jArray.getJSONObject(0);
235 | vshow.setText(jObj.toString());
236 |
237 | outputJSON(jObj);
将他转换为String,接着在Android端上显示最后的结果。
239 | 240 | 241 | -------------------------------------------------------------------------------- /build/designiot.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/build/designiot.epub -------------------------------------------------------------------------------- /build/qa.md.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |意见及建议: https://github.com/phodal/designiot/issues
35 |邮箱: h@phodal.com
36 | 37 | 38 | -------------------------------------------------------------------------------- /designiot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/designiot.jpg -------------------------------------------------------------------------------- /help.md: -------------------------------------------------------------------------------- 1 | ##如何编辑 2 | 3 | 只需要一点markdown的知识,别担心这货很简单。 4 | 5 | ###关于目录 6 | 7 | 编辑相关的目录 8 | 9 | - src/ 目录下放的是文档相关的markdown 10 | - src/pre 相当于一些书的前言及简介部分 11 | - images/ 目录下放的是相应的图片 12 | 13 | 生成文档相关的目录 14 | 15 | - template/ 里面放有latex及html的模板 16 | - build/ PDF版,MOBI版,EPUB版 17 | - end/ 毕业设计所在目录 18 | - css/ html版的css 19 | 20 | ###其他文件 21 | 22 | - index.html 你懂的 23 | - Makefile 一个简单的make 24 | - README.md github上显示的内容。 25 | - License.md 协议相关 26 | - CNAME 域名的CNAME 27 | 28 | ##章节及说明 29 | 30 | 以``1.2.anywhere-javascript.md``为例 31 | 32 | 1.2 33 | 34 | - 1说的是第一部分 35 | - 2说的是第二章 36 | 37 | 以此类推 38 | 39 | 目录一共有三个部分 40 | 41 | - 基础部分 42 | - HTTP版部分 43 | - 扩展部分(如coap,mqtt,biz等等) 44 | 45 | ##如何编译 46 | 47 | 如果你不是在类Unix平台上的话——说的是Windows,编译可能会很困难。 48 | 49 | ###编译所需要的软件 50 | 51 | 大致有下面三个 52 | 53 | - latex 54 | - pandoc 55 | - make 56 | 57 | 如果不需要生成pdf版,就不需要latex。 58 | 59 | ###编译命令 60 | 61 | 只需要在目录执行 62 | 63 | make -------------------------------------------------------------------------------- /images/88x31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/88x31.png -------------------------------------------------------------------------------- /images/arch.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/arch.jpeg -------------------------------------------------------------------------------- /images/arduino.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/arduino.png -------------------------------------------------------------------------------- /images/box-model.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/box-model.gif -------------------------------------------------------------------------------- /images/change.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/change.png -------------------------------------------------------------------------------- /images/dom_tree.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/dom_tree.jpg -------------------------------------------------------------------------------- /images/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/edit.png -------------------------------------------------------------------------------- /images/flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/flow.png -------------------------------------------------------------------------------- /images/fullconnected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/fullconnected.png -------------------------------------------------------------------------------- /images/getjson.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/getjson.png -------------------------------------------------------------------------------- /images/gnu_linux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/gnu_linux.png -------------------------------------------------------------------------------- /images/gpio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/gpio.png -------------------------------------------------------------------------------- /images/hardware.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/hardware.jpg -------------------------------------------------------------------------------- /images/hwcnt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/hwcnt.png -------------------------------------------------------------------------------- /images/linux_kernel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/linux_kernel.jpg -------------------------------------------------------------------------------- /images/lnmp.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/lnmp.gif -------------------------------------------------------------------------------- /images/lnmp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/lnmp.jpg -------------------------------------------------------------------------------- /images/nostyle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/nostyle.png -------------------------------------------------------------------------------- /images/origin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/origin.png -------------------------------------------------------------------------------- /images/pm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/pm.png -------------------------------------------------------------------------------- /images/python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/python.png -------------------------------------------------------------------------------- /images/raspberrypi_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/raspberrypi_flow.png -------------------------------------------------------------------------------- /images/redfonts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/redfonts.png -------------------------------------------------------------------------------- /images/rpi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/rpi.jpg -------------------------------------------------------------------------------- /images/shell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/shell.png -------------------------------------------------------------------------------- /images/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/star.png -------------------------------------------------------------------------------- /images/temperture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/temperture.png -------------------------------------------------------------------------------- /images/uno.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/uno.png -------------------------------------------------------------------------------- /images/webkitflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/webkitflow.png -------------------------------------------------------------------------------- /images/xml-vs-json.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/designiot/0b8332b85ed6fe10d81d8092188bc39da3610807/images/xml-vs-json.png -------------------------------------------------------------------------------- /src/1.1.anywhere-html.md: -------------------------------------------------------------------------------- 1 | 某一天,正走在回学校的路上的我突然想到:“未来将会是一个科技的时代——虽然现在也是——只是在未来,科技将会无处不在。如果我们依旧对周围这些无处不在的代码一无所知的话,或许我们会成为黑客帝国之中被控制的普通人。”于是开始想着,有一天人们会像学习一门语言一样开始学习编程,直到又有一天我看到了学习编程如同学习一门语言的说法。这又恰好在我做完最小物联网系统之后,算是一个有趣的时间点,我开始想着像之前做最小物联网系统的那些步骤一样,写一个简单的入门。也可以补充好之前在这个最小物联网系统缺失的那些东西,给那些正在开始试图去解决编程问题的人。 2 | 3 | 让我们先从身边的语言下手,也就是现在无处不在的html+javascript+css。 4 | 5 | #无处不在的HTML 6 | 7 | 之所以从html开始,是因为我们不需要配置一个复杂的开发环境,也许你还不知道开发环境是什么东西,不过这也没关系,毕竟这些知识需要慢慢的接触才能有所了解,尤其是对于普通的业余爱好者来说,当然,对于专业选手言自然不是问题。HTML是Web的核心语言,也算是比较基础的语言。 8 | 9 | ##html的hello,world 10 | Hello,world是一个传统,所以在这里也遵循这个有趣的传统,我们所要做的事情其实很简单,虽然也有一点点hack的感觉。——让我们先来新建一个文并命名为"helloworld.html"。 11 | 12 | (PS:大部分人应该都是在windows环境下工作的,所以你需要新建一个文本,然后重命名,或者你需要一个编辑器,在这里我们推荐用sublime text。破解不破解,注册不注册都不会对你的使用有太多的影响。) 13 | 14 | 1. 新建文件 15 | 16 | 2. 输入hello,world
17 |
18 | 3. 保存为->"helloworld.html",
19 |
20 | 4. 双击打开这个文件。 正常情况下都应该是用你的默认浏览器打开。只要是一个正常工作的现代浏览器,都应该可以看到上面显示的是"Hello,world"。
21 |
22 | 这才是最短的hello,world程序,但是呢?在ruby中会是这样子的
23 |
24 | ``` bash
25 | 2.0.0-p353 :001 > p "hello,world"
26 | "hello,world"
27 | => "hello,world"
28 | 2.0.0-p353 :002 >
29 | ```
30 |
31 | 等等,如果你了解过html的话,会觉得这一点都不符合语法规则,但是他工作了,没有什么比安装完Nginx后看到It works!更让人激动了。
32 |
33 | 遗憾的是,它可能无法在所有的浏览器上工作,所以我们需要去调试其中的bug。
34 |
35 | ###调试hello,world###
36 | 我们会发现我们的代码在浏览器中变成了下面的代码,如果你和我一样用的是chrome,那么你可以右键浏览器中的空白区域,点击审查元素,就会看到下面的代码。
37 |
38 | ``` html
39 |
40 |
41 | hello,world
42 |
43 | ```
44 |
45 | 这个才是真正能在大部分浏览器上工作的代码,所以复制它到编辑器里吧。
46 |
47 | ###说说hello,world##
48 | 我很不喜欢其中的<\*>*>,但是我也没有找到别的方法来代替它们,所以这是一个设计得当的语言。甚至大部分人都说这算不上是一门真正的语言,不过html的原义是
49 | 超文本标记语言50 | 所以我们可以发现其中的关键词是标记——markup,也就是说html是一个markup,head是一个markup,body也是一个markup。 51 | 52 | 然而,我们真正工作的代码是在body里面,至于为什么是在这里面,这个问题就太复杂了。打个比方来说: 53 | 54 | 1. 我们所使用的汉语是人类用智慧创造的,我们所正在学的这门语言同样也是人类创造的。 55 | 56 | 2. 我们在自己的语言里遵循着桌子是桌子,凳子是凳子的原则,很少有人会问为什么。 57 | 58 | 59 | ###想用中文?### 60 | 所以我们也可以把计算机语言与现实世界里用于交流沟通的语言划上一个等号。而我们所要学习的语言,并不是我们最熟悉的汉语语言,所以我们便觉得这些很复杂,但是如果我们试着用汉语替换掉上面的代码的话 61 | ```HTML 62 | <语言> 63 | <头><结束头> 64 | <身体>你好,世界<结束身体> 65 | <结束语言> 66 | ``` 67 | 这看上去很奇怪,只是因为是直译过去的原因,也许你会觉得这样会好理解一点,但是输入上可就一点儿也不方便,因为这键盘本身就不适合我们去输入汉字,同时也意味着可能你输入的会有问题。 68 | 69 | 让我们把上面的代码代替掉原来的代码然后保存,打开浏览器会看到下面的结果 70 | ```HTML 71 | <语言> <头><结束头> <身体>你好,世界<结束身体> <结束语言> 72 | ``` 73 | 74 | 更不幸的结果可能是 75 | 76 | ```HTML 77 | <璇█> <澶�><缁撴潫澶�> <韬綋>浣犲ソ锛屼笘鐣�<缁撴潫韬綋> <缁撴潫璇█> 78 | ``` 79 | 80 | 这是一个编码问题,对中文支持不友好。 81 | 82 | 我们把上面的代码改为和标记语言一样的结构 83 | 84 | ```HTML 85 | <语言> 86 | <头>头> 87 | <身体>你好,世界身体> 88 | <结束语言> 89 | ``` 90 | 91 | 于是我们看到的结果便是 92 | 93 | ```HTML 94 | <语言> <头> <身体>你好,世界 95 | ``` 96 | 97 | 被chrome浏览器解析成什么样了? 98 | 99 | ``` html 100 | <语言> 101 | <头> 102 | <身体>你好,世界 103 | 104 | 105 | ``` 106 | 107 | 以 108 | 109 | 110 | 结尾的是注释,写给人看的代码,不是给机器看的,所以机器不会去理解这些代码。 111 | 112 | 但是当我们把代码改成 113 | 114 | ```HTML 115 |