-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathindex.html
executable file
·685 lines (633 loc) · 38.1 KB
/
index.html
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="generator" content="pandoc">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>硬件开发指南 – </title>
<style type="text/css">code{white-space: pre;}</style>
<style type="text/css">
div.sourceCode { overflow-x: auto; }
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
margin: 0; padding: 0; vertical-align: baseline; border: none; }
table.sourceCode { width: 100%; line-height: 100%; }
td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
td.sourceCode { padding-left: 5px; }
code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
code > span.dt { color: #902000; } /* DataType */
code > span.dv { color: #40a070; } /* DecVal */
code > span.bn { color: #40a070; } /* BaseN */
code > span.fl { color: #40a070; } /* Float */
code > span.ch { color: #4070a0; } /* Char */
code > span.st { color: #4070a0; } /* String */
code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
code > span.ot { color: #007020; } /* Other */
code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
code > span.fu { color: #06287e; } /* Function */
code > span.er { color: #ff0000; font-weight: bold; } /* Error */
code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
code > span.cn { color: #880000; } /* Constant */
code > span.sc { color: #4070a0; } /* SpecialChar */
code > span.vs { color: #4070a0; } /* VerbatimString */
code > span.ss { color: #bb6688; } /* SpecialString */
code > span.im { } /* Import */
code > span.va { color: #19177c; } /* Variable */
code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code > span.op { color: #666666; } /* Operator */
code > span.bu { } /* BuiltIn */
code > span.ex { } /* Extension */
code > span.pp { color: #bc7a00; } /* Preprocessor */
code > span.at { color: #7d9029; } /* Attribute */
code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
</style>
<link rel="stylesheet" href="style.css">
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
<meta name="viewport" content="width=device-width">
</head>
<body>
<h1>写给软件工程师看的硬件编程指南</h1>
<p>By <a href="https://www.phodal.com/">Phodal</a> (Follow Me: <a href="http://weibo.com/phodal">微博</a>、<a href="https://www.zhihu.com/people/phodal">知乎</a>、<a href="https://segmentfault.com/u/phodal">SegmentFault</a>)
</p>
<p>我的其他电子书:</p>
<ul>
<li>《<a href="https://github.com/phodal/ideabook">Phodal's Idea实战指南</a>》</li>
<li>《<a href="https://github.com/phodal/designiot">一步步搭建物联网系统</a>》</li>
<li>《<a href="https://github.com/phodal/github-roam">GitHub 漫游指南</a>》</li>
<li>《<a href="https://github.com/phodal/repractise">RePractise</a>》</li>
<li>《<a href="https://github.com/phodal/growth-ebook">Growth: 全栈增长工程师指南</a>》</li>
<li>《<a href="https://github.com/phodal/growth-in-action">Growth: 全栈增长工程师实战</a>》</li>
<li>《<a href="https://github.com/phodal/fe">我的职业是前端工程师</a>》</li>
</ul>
<p>微信公众号</p>
<p><img src="http://articles.phodal.com/qrcode.jpg" alt=""/></p>
<p>
当前为预览版,在使用的过程中遇到任何遇到请及时与我联系。阅读过程中问题,不烦在GitHub上提出来:
<a href="https://github.com/phodal/hardware-guide/issues">Issues</a>
</p>
<p>
阅读过程中遇到语法错误、拼写错误、技术错误等等,不烦来个Pull Request,这样可以帮助到其他阅读这本电子书的童鞋。
</p>
<div style="width:800px">
<nav id="TOC">
<ul>
<li><a href="#前言">前言</a><ul>
<li><a href="#关于作者">关于作者</a></li>
</ul></li>
<li><a href="#基础篇">基础篇</a><ul>
<li><a href="#arduino-vs-esp8266-vs-raspberry-pi">Arduino vs ESP8266 vs Raspberry Pi</a><ul>
<li><a href="#arduino">Arduino</a></li>
</ul></li>
<li><a href="#概念">概念</a></li>
<li><a href="#pcb">PCB</a><ul>
<li><a href="#fritzing">Fritzing</a></li>
</ul></li>
<li><a href="#硬件">硬件</a></li>
<li><a href="#mcu-vs-cpu">MCU vs CPU</a></li>
<li><a href="#通讯">通讯</a></li>
</ul></li>
<li><a href="#第一部分-arduino-篇">第一部分 Arduino 篇</a></li>
<li><a href="#arduino-hello-world">Arduino Hello, World</a><ul>
<li><a href="#开发板选择">开发板选择</a></li>
<li><a href="#hello-world">hello, world</a><ul>
<li><a href="#setup">setup()</a></li>
<li><a href="#loop">loop()</a></li>
</ul></li>
<li><a href="#输入控制输出">输入控制输出</a><ul>
<li><a href="#电路图">电路图</a></li>
</ul></li>
</ul></li>
<li><a href="#arduino-传感器控制">Arduino 传感器控制</a><ul>
<li><a href="#传感器入门">传感器入门</a><ul>
<li><a href="#模拟元件与数字元件">模拟元件与数字元件</a></li>
</ul></li>
<li><a href="#超声波传感器">超声波传感器</a></li>
<li><a href="#控制继电器">控制继电器</a></li>
</ul></li>
<li><a href="#arduino-5110-显示">Arduino 5110 显示</a><ul>
<li><a href="#lcd">LCD</a></li>
<li><a href="#安装库">安装库</a></li>
<li><a href="#输出-hello-world">输出 hello, world</a></li>
</ul></li>
<li><a href="#arduino-processing">Arduino Processing</a><ul>
<li><a href="#串口输出">串口输出</a></li>
<li><a href="#复杂的例子mpu-6050">复杂的例子:MPU 6050</a></li>
</ul></li>
<li><a href="#arduino-ble-控制">Arduino BLE 控制</a><ul>
<li><a href="#蓝牙串口">蓝牙串口</a></li>
<li><a href="#与手机通讯">与手机通讯</a></li>
</ul></li>
<li><a href="#arduino-扩展板使用">Arduino 扩展板使用</a><ul>
<li><a href="#继电器">继电器</a></li>
<li><a href="#网络">网络</a></li>
</ul></li>
<li><a href="#arduino-esp8266-wifi">Arduino ESP8266 WiFi</a><ul>
<li><a href="#esp8266-设置">ESP8266 设置</a></li>
<li><a href="#arduino-wifi">Arduino WiFi</a></li>
</ul></li>
<li><a href="#第二部分-esp8266">第二部分 ESP8266</a></li>
<li><a href="#esp8266-基础">ESP8266 基础</a><ul>
<li><a href="#设置与-at-指令">设置与 AT 指令</a></li>
<li><a href="#nodemcu">NodeMCU</a></li>
</ul></li>
<li><a href="#esp8266-arduino-ide-展示">ESP8266 Arduino IDE 展示</a></li>
<li><a href="#esp8266-连接-arduino-uno">ESP8266 连接 Arduino UNO</a></li>
<li><a href="#esp8266-上传传感器数据">ESP8266 上传传感器数据</a><ul>
<li><a href="#adc-数据">ADC 数据</a></li>
<li><a href="#发送请求">发送请求</a></li>
<li><a href="#上传">上传</a></li>
</ul></li>
<li><a href="#esp8266-mqtt-控制">ESP8266 MQTT 控制</a><ul>
<li><a href="#mqtt">MQTT</a></li>
<li><a href="#moquitto">moquitto</a></li>
<li><a href="#section"></a></li>
</ul></li>
<li><a href="#esp8266-http-服务器">ESP8266 HTTP 服务器</a><ul>
<li><a href="#simple-http-server">Simple HTTP Server</a></li>
</ul></li>
<li><a href="#超越-esp8266">超越 ESP8266</a></li>
<li><a href="#第三部分-raspberry-pi">第三部分 Raspberry Pi</a></li>
<li><a href="#raspberry-pi-hello-world">Raspberry Pi Hello, world!</a><ul>
<li><a href="#镜像烧录">镜像烧录</a></li>
<li><a href="#ssh-连接">SSH 连接</a></li>
<li><a href="#python-控制-gpio">Python 控制 GPIO</a></li>
</ul></li>
<li><a href="#node.js-服务基础">Node.js 服务基础</a><ul>
<li><a href="#安装-node.js">安装 Node.js</a></li>
<li><a href="#express-hello-world">Express Hello, world</a></li>
<li><a href="#开机启动">开机启动</a></li>
</ul></li>
<li><a href="#摄像头-传感器-智能家居">摄像头 + 传感器 = 智能家居?</a><ul>
<li><a href="#红外传感器">红外传感器</a></li>
<li><a href="#视频流">视频流</a></li>
<li><a href="#拍照blabla">拍照,blabla</a></li>
</ul></li>
<li><a href="#与-esp8266-无线通讯">与 ESP8266 无线通讯</a><ul>
<li><a href="#建立服务">建立服务</a></li>
<li><a href="#广播">广播?</a></li>
</ul></li>
<li><a href="#arduino-ota-更新">Arduino OTA 更新</a><ul>
<li><a href="#服务端读取代码">服务端读取代码</a></li>
<li><a href="#arduino-cli-更新硬件">arduino-cli 更新硬件</a></li>
</ul></li>
<li><a href="#使用-mqtt-服务器">使用 MQTT 服务器</a><ul>
<li><a href="#mqtt-客户端">MQTT 客户端</a></li>
<li><a href="#使用-mosquittto">使用 mosquittto</a></li>
</ul></li>
<li><a href="#跟上潮流docker硬件微服务">跟上潮流:Docker、硬件微服务</a><ul>
<li><a href="#使用-docker">使用 Docker</a></li>
<li><a href="#硬件微服务">硬件微服务</a></li>
</ul></li>
<li><a href="#home-assistant-搭建">Home Assistant 搭建</a></li>
<li><a href="#home-assistant-整合">Home Assistant 整合</a></li>
<li><a href="#homekit-搭建">Homekit 搭建</a></li>
<li><a href="#homekit-整合">Homekit 整合</a></li>
<li><a href="#raspberry-pi-与智能音箱">Raspberry Pi 与智能音箱</a></li>
<li><a href="#raspberry-pi-自制智能音箱">Raspberry Pi 自制智能音箱</a></li>
<li><a href="#超越-raspberry-pi">超越 Raspberry Pi</a></li>
</ul>
</nav>
<h1 id="前言">前言</h1>
<p>最近这些日子里,当我和女朋友搬到了新的合租屋里,有了更大的空间——可以再次折腾硬件。便开始去玩一些硬件家居相关的内容,也顺便接上了 Amazon Echo、小米传感器、Broadlink、ESP8266 等等的硬件。</p>
<p>再加上正在编写的『玩点什么』网站,便也想整理一下硬件相关的资料。想着想着,便有了这一系列的电子书。</p>
<p>这是一本写给软件工程师看的硬件指南。</p>
<h2 id="关于作者">关于作者</h2>
<p>黄峰达(Phodal Huang)是一个创客、工程师、咨询师和作家。他毕业于西安文理学院电子信息工程专业,现作为一个咨询师就职于 ThoughtWorks 深圳。长期活跃于开源软件社区 GitHub,目前专注于物联网和前端领域。</p>
<p>作为一个开源软件作者,著有 Growth、Stepping、Lan、Echoesworks 等软件。其中开源学习应用 Growth,广受读者和用户好评,可在 APP Store 及各大 Android 应用商店下载。</p>
<p>作为一个技术作者,著有《自己动手设计物联网》(电子工业出版社)、《全栈应用开发:精益实践》(电子工业出版社,正在出版)。并在 GitHub 上开源有《Growth: 全栈增长工程师指南》、《GitHub 漫游指南》等七本电子书。</p>
<p>作为技术专家,他为英国 Packt 出版社审阅有物联网书籍《Learning IoT》、《Smart IoT》,前端书籍《Angular 2 Serices》、《Getting started with Angular》等技术书籍。</p>
<p>他热爱编程、写作、设计、旅行、hacking,你可以从他的个人网站:<a href="https://www.phodal.com/" class="uri">https://www.phodal.com/</a> 了解到更多的内容。</p>
<p>其它相关信息:</p>
<ul>
<li>微博:<a href="http://weibo.com/phodal" class="uri">http://weibo.com/phodal</a></li>
<li>GitHub: <a href="https://github.com/phodal" class="uri">https://github.com/phodal</a></li>
<li>知乎:<a href="https://www.zhihu.com/people/phodal" class="uri">https://www.zhihu.com/people/phodal</a></li>
<li>SegmentFault:<a href="https://segmentfault.com/u/phodal" class="uri">https://segmentfault.com/u/phodal</a></li>
</ul>
<p>当前为预览版,在使用的过程中遇到任何问题请及时与我联系。阅读过程中的问题,不妨在GitHub上提出来: <a href="https://github.com/phodal/fe/issues">Issues</a></p>
<p>阅读过程中遇到语法错误、拼写错误、技术错误等等,不妨来个Pull Request,这样可以帮助到其他阅读这本电子书的童鞋。</p>
<p>其他电子书:</p>
<ul>
<li>《<a href="https://github.com/phodal/ideabook">Phodal’s Idea实战指南</a>》</li>
<li>《<a href="https://github.com/phodal/designiot">一步步搭建物联网系统</a>》</li>
<li>《<a href="https://github.com/phodal/github-roam">GitHub 漫游指南</a>》</li>
<li>《<a href="https://github.com/phodal/repractise">RePractise</a>》</li>
<li>《<a href="https://github.com/phodal/growth-ebook">Growth: 全栈增长工程师指南</a>》</li>
<li>《<a href="https://github.com/phodal/growth-in-action">Growth: 全栈增长工程师实战</a>》</li>
<li>《<a href="http://github.com/phodal/fe">我的职业是前端工程师</a>》</li>
</ul>
<h1 id="基础篇">基础篇</h1>
<h2 id="arduino-vs-esp8266-vs-raspberry-pi">Arduino vs ESP8266 vs Raspberry Pi</h2>
<p>在这一系列的文章里,我们使用三个主要的开发板:</p>
<ul>
<li>Arduino。</li>
<li>ESP8266。</li>
<li>Raspberry Pi。</li>
</ul>
<p>这三个硬件分别代表着,三种不同类型的硬件爱好者的开发板。</p>
<h3 id="arduino">Arduino</h3>
<blockquote>
<p>Arduino,是一个开放源代码的单片机微控制器,它使用了Atmel AVR单片机,采用了开放源代码的软硬件平台,建构于简易输出/输入(simple I/O)接口板,并且具有使用类似Java、C语言的Processing/Wiring开发环境。<a href="#fn1" class="footnoteRef" id="fnref1"><sup>1</sup></a></p>
</blockquote>
<p>其包含了以下的特性<a href="#fn2" class="footnoteRef" id="fnref2"><sup>2</sup></a>:</p>
<ul>
<li>基于知识共享开放源代码的电路图设计。</li>
<li>免费下载,也可依需求自己修改,但需遵照姓名标示。您必须按照作者或授权人所指定的方式,表彰其姓名。</li>
<li>依相同方式分享,若您改变或转变著作,当散布该派生著作时,您需采用与本著作相同或类似的授权条款。</li>
<li>Arduino 可使用 ICSP 在线烧入器,将 Bootloader 烧入新的 IC 芯片。</li>
<li>可依据 Arduino 官方网站,获取硬件的设计档,加以调整电路板及组件,以匹配自己实际设计的需求</li>
<li>可简单地与感测器,各式各样的电子组件连接,如红外线、超音波、热敏电阻、光敏电阻、伺服马达…等。</li>
<li>支持多样的交互程序,如Adobe Flash, Max/MSP, VVVV, Pure Data, C, Processing…等。</li>
<li>使用低价格的微处理控制器(Atmel AVR)(ATMEGA 8,168,328等)。</li>
<li>USB接口,不需外接电源。另外有提供直流(DC)电源输入。</li>
</ul>
<p>当然,其最大的特色是,<strong>完善的社区及生态系统</strong>。几乎我们能想到的 Arduino 相关的创意,都可以在网上找到。如果没有的话,那么可能是你的创意不适合用于 Arduino。</p>
<p>Arduino 已然有一系列的相关硬件,就目前而言,最广泛的开发板,或者说是标准开发板是 Arduino UNO。</p>
<p>TODO: 相关 Arduino 硬件介绍</p>
<p>Arduino 最吸引人的是开创性的引入电子积木的概念,即开发板的扩展板可以直接叠加在开发板上使用,而无需额外的硬件。</p>
<p>TODO: 扩展板介绍。</p>
<p>Arduion IDE 基于 Processing 开发环境而开发的。</p>
<h2 id="概念">概念</h2>
<p>引脚</p>
<p>模电</p>
<p>数电</p>
<p>电流、电阻、电压</p>
<p>etc..</p>
<h2 id="pcb">PCB</h2>
<p>为了更好的向读者展示硬件连线,我们将使用 Fritzing 汇制硬件电路图。</p>
<h3 id="fritzing">Fritzing</h3>
<blockquote>
<p>Fritzing 是一个开源的硬件计划(initiative),它可以使电子元件变成任何人的创意素材。Fritzing 提供一个软件工具、一个社区网站,以及本着 Processing 和 Arduino 精神的服务,培养创造性的生态系统,允许用户记录他们的原型,与他人分享、用于课堂上的电子相关教学,以及布局和制造专业的pcb。</p>
</blockquote>
<p>Fritzing 的官网是:<a href="http://fritzing.org/" class="uri">http://fritzing.org/</a>。</p>
<p>因此,在开始之前我们需要在 Fritzing 的官网下载 Fritzing。当前它可以支持主流的操作系统:Windows、Linux、macOS,当然如果你想自己从源码编译一个 Fritzing,那也是可以的。除了中文和英语外,它还支持其它 17 种语言。</p>
<p>在其官网,除了能下载到该软件,还可以看到其它用户上传、汇制的 Fritzing 电路图等,它们可以免费下载,并引用到你的项目中。</p>
<p>LCEDA</p>
<h2 id="硬件">硬件</h2>
<p>Nokia 5110</p>
<p>温度、红外、距离、土壤</p>
<h2 id="mcu-vs-cpu">MCU vs CPU</h2>
<p>Input -> MCU -> Output</p>
<h2 id="通讯">通讯</h2>
<p>蓝牙、有线、</p>
<p>专用协议,blabla</p>
<h1 id="第一部分-arduino-篇">第一部分 Arduino 篇</h1>
<ul>
<li>Arduino + LED + 按钮控制</li>
<li>Arduino 读取传感器</li>
<li>Arduion + LCD 5100 显示传感器</li>
<li>Arduino 蓝牙通讯</li>
<li>Arduino Processing 可视化数据</li>
<li>Arduino 上传数据</li>
<li>Arduino 的可能性:+ Fritzing / Arduino + Johnny-Five</li>
</ul>
<h1 id="arduino-hello-world">Arduino Hello, World</h1>
<p>幸运的是,今天对硬件编程已经有了更多的方式,可以使用更高级的语言。除了在 Arduion 上使用 Processing 语言(可以视为 C)进行编程,还可以使用 JavaScript 等语言。我们会在后面的介绍:如何使用这些高级的语言来编程。</p>
<h2 id="开发板选择">开发板选择</h2>
<figure>
<img src="./images/arduino/arduinos.jpg" alt="Arduino 开发板示例" /><figcaption>Arduino 开发板示例</figcaption>
</figure>
<figure>
<img src="./images/arduino/shields.jpg" alt="扩展板" /><figcaption>扩展板</figcaption>
</figure>
<p>Arduino IDE 默认会安装相应环境的包,如果你的开发板不在这些环境里,如你使用的是 Arduino M0 开发板。那么,系统可能会检测出来,并自动为你安装相应的环境,如下图所示。</p>
<figure>
<img src="./images/arduino/arduino-install-package.png" alt="Arduino IDE 安装 Arduino M0 环境" /><figcaption>Arduino IDE 安装 Arduino M0 环境</figcaption>
</figure>
<p><code>注意</code>:安装过程中会下载一系列的工具,在这个过程里,可能会遇到一些“网络问题”。请尝试更换网络,或直到到“墙”的那外一边。</p>
<p>对于非官方的开发板来说,则需要开发者自己手动通过『开发板管理器』来安装,如 ESP8266 开发板。</p>
<h2 id="hello-world">hello, world</h2>
<p>与桌面端使用 print、puts、console.log 来输出 Hello, world 不同的是,点亮一个 LED 是 电子世界的 Hello, world。</p>
<p>在硬件世界里,没有 stdlib.h 这样的库,对于多数嵌入式系统来说,也没有屏幕。在这个时候,想要知道设备的状态,最简单的方式就是 LED。常见的,如路由器、电视等家电电器上的灯,都是嵌入式设备的状态。</p>
<p>官方的 Blink 示例如下:</p>
<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span> setup() {
<span class="co">// initialize digital pin LED_BUILTIN as an output.</span>
pinMode(LED_BUILTIN, OUTPUT);
}
<span class="co">// the loop function runs over and over again forever</span>
<span class="dt">void</span> loop() {
digitalWrite(LED_BUILTIN, HIGH); <span class="co">// turn the LED on (HIGH is the voltage level)</span>
delay(<span class="dv">1000</span>); <span class="co">// wait for a second</span>
digitalWrite(LED_BUILTIN, LOW); <span class="co">// turn the LED off by making the voltage LOW</span>
delay(<span class="dv">1000</span>); <span class="co">// wait for a second</span>
}</code></pre></div>
<p>接下来,要做的事情就比较简单了。从工具( Tools )中选择对应的开发板和端口,如下图所示:</p>
<figure>
<img src="./images/arduino/arduino-devices.png" alt="Arduino 选择设备" /><figcaption>Arduino 选择设备</figcaption>
</figure>
<p>我这里使用设置是 <code>Arduino M0 Pro</code>,对应的端口是:<code>/dev/tty.usbmodem1412</code>。</p>
<p>对于 Windows 用户来说,则是 COM 口——从设备管理器中找到对应的端口。</p>
<p>然后点击菜单中的 -> 号,即上传(Upload,又可以称为烧录)。</p>
<figure>
<img src="./images/arduino/arduino-menu.png" alt="Arduino 菜单" /><figcaption>Arduino 菜单</figcaption>
</figure>
<p>再看看你的 Arduion,就发现上面的 LED 正在闪烁——一秒开一秒关。</p>
<h3 id="setup">setup()</h3>
<p>源码中的:</p>
<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span> main(<span class="dt">void</span>)
{
init();
setup();
<span class="cf">for</span>(;;)
loop();
<span class="cf">return</span> <span class="dv">0</span>;
}</code></pre></div>
<h3 id="loop">loop()</h3>
<h2 id="输入控制输出">输入控制输出</h2>
<p>GOAL</p>
<p>SMART 原则</p>
<p>仍然采用的是官方的示例:</p>
<figure>
<img src="./images/arduino/fritzing-button.png" alt="Arduino 控制 LED 示例" /><figcaption>Arduino 控制 LED 示例</figcaption>
</figure>
<p>官方示例(<a href="https://www.arduino.cc/en/Tutorial/DigitalReadSerial">Digital Read Serial</a>)代码:</p>
<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">// digital pin 2 has a pushbutton attached to it. Give it a name:</span>
<span class="dt">int</span> pushButton = <span class="dv">2</span>;
<span class="co">// the setup routine runs once when you press reset:</span>
<span class="dt">void</span> setup() {
<span class="co">// initialize serial communication at 9600 bits per second:</span>
Serial.begin(<span class="dv">9600</span>);
<span class="co">// make the pushbutton's pin an input:</span>
pinMode(pushButton, INPUT);
}
<span class="co">// the loop routine runs over and over again forever:</span>
<span class="dt">void</span> loop() {
<span class="co">// read the input pin:</span>
<span class="dt">int</span> buttonState = digitalRead(pushButton);
<span class="co">// print out the state of the button:</span>
Serial.println(buttonState);
delay(<span class="dv">1</span>); <span class="co">// delay in between reads for stability</span>
}</code></pre></div>
<h3 id="电路图">电路图</h3>
<p>使用 Fritzing 画板时</p>
<figure>
<img src="./images/arduino/fritzing-example.jpg" />
</figure>
<p>我们所需要的连线图</p>
<figure>
<img src="./images/arduino/arduino-button.jpg" />
</figure>
<h1 id="arduino-传感器控制">Arduino 传感器控制</h1>
<h2 id="传感器入门">传感器入门</h2>
<blockquote>
<p>传感器是一种物理装置或生物器官,能够探测、感受外界的信号、物理条件(如光、热、湿度)或化学组成(如烟雾),并将探知的信息传递给其他装置或器官。“传感器”在新韦式大词典中定义为:“从一个系统接受功率,通常以另一种形式将功率送到第二个系统中的器件”。根据这个定义,传感器的作用是将一种能量转换成另一种能量形式,所以不少学者也用“换能器-Transducer”来称谓“传感器-Sensor”。[^wiki_sensor]</p>
</blockquote>
<p>[^wiki_sensor] : https://zh.wikipedia.org/wiki/%E4%BC%A0%E6%84%9F%E5%99%A8</p>
<h3 id="模拟元件与数字元件">模拟元件与数字元件</h3>
<h2 id="超声波传感器">超声波传感器</h2>
<figure>
<img src="./images/arduino/arduino-hs-sr04.png" alt="Arduion 超声波传感器连线图" /><figcaption>Arduion 超声波传感器连线图</figcaption>
</figure>
<p>使用到库:[NewPing],GitHub 地址:<a href="https://github.com/PaulStoffregen/NewPing" class="uri">https://github.com/PaulStoffregen/NewPing</a></p>
<figure>
<img src="./images/arduino/download-zip.png" alt="下载 Zip 格式" /><figcaption>下载 Zip 格式</figcaption>
</figure>
<p>添加库</p>
<figure>
<img src="./images/arduinoadd-zip-library.png" alt="添加 NewPing 库" /><figcaption>添加 NewPing 库</figcaption>
</figure>
<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="pp">#include </span><span class="im"><NewPing.h></span>
<span class="pp">#define TRIGGER_PIN 12 </span><span class="co">// Arduino pin tied to trigger pin on the ultrasonic sensor.</span>
<span class="pp">#define ECHO_PIN 11 </span><span class="co">// Arduino pin tied to echo pin on the ultrasonic sensor.</span>
<span class="pp">#define MAX_DISTANCE 200 </span><span class="co">// Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.</span>
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); <span class="co">// NewPing setup of pins and maximum distance.</span>
<span class="dt">void</span> setup() {
Serial.begin(<span class="dv">115200</span>); <span class="co">// Open serial monitor at 115200 baud to see ping results.</span>
}
<span class="dt">void</span> loop() {
delay(<span class="dv">50</span>); <span class="co">// Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.</span>
Serial.print(<span class="st">"Ping: "</span>);
Serial.print(sonar.ping_cm()); <span class="co">// Send ping, get distance in cm and print result (0 = outside set distance range)</span>
Serial.println(<span class="st">"cm"</span>);
}</code></pre></div>
<figure>
<img src="serial-output-example.png" alt="输出示例" /><figcaption>输出示例</figcaption>
</figure>
<h2 id="控制继电器">控制继电器</h2>
<h1 id="arduino-5110-显示">Arduino 5110 显示</h1>
<h2 id="lcd">LCD</h2>
<h2 id="安装库">安装库</h2>
<p>项目地址:<a href="https://github.com/adafruit/Adafruit-PCD8544-Nokia-5110-LCD-library">Adafruit PCD8544</a></p>
<figure>
<img src="./images/arduino/manage-library.png" alt="添加库" /><figcaption>添加库</figcaption>
</figure>
<figure>
<img src="./images/arduino/arduino-nokia-5110.png" alt="Arduino IDE 安装 5110" /><figcaption>Arduino IDE 安装 5110</figcaption>
</figure>
<p>一般来说,在安装完库后,都会有对应的示例。但是,这里的示例,稍微有一些复杂。</p>
<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="pp">#include </span><span class="im"><Arduino.h></span>
<span class="pp">#include </span><span class="im"><SPI.h></span>
<span class="pp">#include </span><span class="im"><Adafruit_GFX.h></span>
<span class="pp">#include </span><span class="im"><Adafruit_PCD8544.h></span>
<span class="co">// Pins</span>
<span class="dt">const</span> <span class="dt">int8_t</span> RST_PIN = D2;
<span class="dt">const</span> <span class="dt">int8_t</span> CE_PIN = D1;
<span class="dt">const</span> <span class="dt">int8_t</span> DC_PIN = D6;
<span class="co">//const int8_t DIN_PIN = D7; // Uncomment for Software SPI</span>
<span class="co">//const int8_t CLK_PIN = D5; // Uncomment for Software SPI</span>
<span class="dt">const</span> <span class="dt">int8_t</span> BL_PIN = D0;
<span class="co">// Software SPI with explicit CE pin.</span>
<span class="co">// Adafruit_PCD8544 display = Adafruit_PCD8544(CLK_PIN, DIN_PIN, DC_PIN, CE_PIN, RST_PIN);</span>
<span class="co">// Software SPI with CE tied to ground. Saves a pin but other pins can't be shared with other hardware.</span>
<span class="co">// Adafruit_PCD8544(int8_t CLK_PIN, int8_t DIN_PIN, int8_t DC_PIN, int8_t RST_PIN);</span>
<span class="co">// Hardware SPI based on hardware controlled SCK (SCLK) and MOSI (DIN) pins. CE is still controlled by any IO pin.</span>
<span class="co">// NOTE: MISO and SS will be set as an input and output respectively, so be careful sharing those pins!</span>
Adafruit_PCD8544 display = Adafruit_PCD8544(DC_PIN, CE_PIN, RST_PIN);
<span class="dt">void</span> setup() {
Serial.begin(<span class="dv">9600</span>);
Serial.println(<span class="st">"</span><span class="sc">\n\n</span><span class="st">WeMos D1 Mini + Nokia 5110 PCD8544 84x48 Monochrome LCD</span><span class="sc">\n</span><span class="st">Using Adafruit_PCD8544 and Adafruit_GFX libraries</span><span class="sc">\n</span><span class="st">"</span>);
<span class="co">// Turn LCD backlight on</span>
pinMode(BL_PIN, OUTPUT);
digitalWrite(BL_PIN, HIGH);
display.begin();
display.setContrast(<span class="dv">60</span>); <span class="co">// Adjust for your display</span>
Serial.println(<span class="st">"Show Adafruit logo bitmap"</span>);
<span class="co">// Show the Adafruit logo, which is preloaded into the buffer by their library</span>
<span class="co">// display.clearDisplay();</span>
delay(<span class="dv">2000</span>);
display.clearDisplay();
display.setTextSize(<span class="dv">1</span>);
display.setTextColor(BLACK);
display.setCursor(<span class="dv">0</span>,<span class="dv">0</span>);
display.println(<span class="st">"Hello, world!"</span>);
display.display();
}
<span class="dt">void</span> loop() {
}</code></pre></div>
<h2 id="输出-hello-world">输出 hello, world</h2>
<h1 id="arduino-processing">Arduino Processing</h1>
<h2 id="串口输出">串口输出</h2>
<h2 id="复杂的例子mpu-6050">复杂的例子:MPU 6050</h2>
<h1 id="arduino-ble-控制">Arduino BLE 控制</h1>
<h2 id="蓝牙串口">蓝牙串口</h2>
<p>Bluno 等自带蓝牙的开发板</p>
<h2 id="与手机通讯">与手机通讯</h2>
<p>React Native / Cordova ???</p>
<h1 id="arduino-扩展板使用">Arduino 扩展板使用</h1>
<p>I don’t know</p>
<h2 id="继电器">继电器</h2>
<h2 id="网络">网络</h2>
<figure>
<img src="./images/arduino/arduino-ethernet.png" alt="Arduion 以太网扩展板" /><figcaption>Arduion 以太网扩展板</figcaption>
</figure>
<h1 id="arduino-esp8266-wifi">Arduino ESP8266 WiFi</h1>
<h2 id="esp8266-设置">ESP8266 设置</h2>
<h2 id="arduino-wifi">Arduino WiFi</h2>
<h1 id="第二部分-esp8266">第二部分 ESP8266</h1>
<ul>
<li>ESP8266 基础 + 连接 WiFi / NodeMCU</li>
<li>ESP8266 Arduino IDE ??</li>
<li>ESP8266 上传 Arduino 数据</li>
<li>? ESP8266 读取传感器(ADC?)),并上传数据</li>
<li>ESP8266 MQTT 示例</li>
<li>ESP8266 作为 HTTP 服务器示例</li>
<li>更多的可能性探索:Mongoose OS、Johnny-Five、智能家居</li>
</ul>
<h1 id="esp8266-基础">ESP8266 基础</h1>
<h2 id="设置与-at-指令">设置与 AT 指令</h2>
<h2 id="nodemcu">NodeMCU</h2>
<h1 id="esp8266-arduino-ide-展示">ESP8266 Arduino IDE 展示</h1>
<h1 id="esp8266-连接-arduino-uno">ESP8266 连接 Arduino UNO</h1>
<h1 id="esp8266-上传传感器数据">ESP8266 上传传感器数据</h1>
<h3 id="adc-数据">ADC 数据</h3>
<h3 id="发送请求">发送请求</h3>
<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/**</span>
<span class="co"> * BasicHTTPClient.ino</span>
<span class="co"> *</span>
<span class="co"> * Created on: 24.05.2015</span>
<span class="co"> *</span>
<span class="co"> */</span>
<span class="pp">#include </span><span class="im"><Arduino.h></span>
<span class="pp">#include </span><span class="im"><ESP8266WiFi.h></span>
<span class="pp">#include </span><span class="im"><ESP8266WiFiMulti.h></span>
<span class="pp">#include </span><span class="im"><ESP8266HTTPClient.h></span>
<span class="pp">#define USE_SERIAL Serial</span>
ESP8266WiFiMulti WiFiMulti;
<span class="dt">void</span> setup() {
USE_SERIAL.begin(<span class="dv">115200</span>);
<span class="co">// USE_SERIAL.setDebugOutput(true);</span>
USE_SERIAL.println();
USE_SERIAL.println();
USE_SERIAL.println();
<span class="cf">for</span>(<span class="dt">uint8_t</span> t = <span class="dv">4</span>; t > <span class="dv">0</span>; t--) {
USE_SERIAL.printf(<span class="st">"[SETUP] WAIT %d...</span><span class="sc">\n</span><span class="st">"</span>, t);
USE_SERIAL.flush();
delay(<span class="dv">1000</span>);
}
WiFiMulti.addAP(<span class="st">"SSID"</span>, <span class="st">"PASSWORD"</span>);
}
<span class="dt">void</span> loop() {
<span class="co">// wait for WiFi connection</span>
<span class="cf">if</span>((WiFiMulti.run() == WL_CONNECTED)) {
HTTPClient http;
USE_SERIAL.print(<span class="st">"[HTTP] begin...</span><span class="sc">\n</span><span class="st">"</span>);
<span class="co">// configure traged server and url</span>
<span class="co">//http.begin("https://192.168.1.12/test.html", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS</span>
http.begin(<span class="st">"http://192.168.1.12/test.html"</span>); <span class="co">//HTTP</span>
USE_SERIAL.print(<span class="st">"[HTTP] GET...</span><span class="sc">\n</span><span class="st">"</span>);
<span class="co">// start connection and send HTTP header</span>
<span class="dt">int</span> httpCode = http.GET();
<span class="co">// httpCode will be negative on error</span>
<span class="cf">if</span>(httpCode > <span class="dv">0</span>) {
<span class="co">// HTTP header has been send and Server response header has been handled</span>
USE_SERIAL.printf(<span class="st">"[HTTP] GET... code: %d</span><span class="sc">\n</span><span class="st">"</span>, httpCode);
<span class="co">// file found at server</span>
<span class="cf">if</span>(httpCode == HTTP_CODE_OK) {
String payload = http.getString();
USE_SERIAL.println(payload);
}
} <span class="cf">else</span> {
USE_SERIAL.printf(<span class="st">"[HTTP] GET... failed, error: %s</span><span class="sc">\n</span><span class="st">"</span>, http.errorToString(httpCode).c_str());
}
http.end();
}
delay(<span class="dv">10000</span>);
}</code></pre></div>
<h3 id="上传">上传</h3>
<h1 id="esp8266-mqtt-控制">ESP8266 MQTT 控制</h1>
<h3 id="mqtt">MQTT</h3>
<h3 id="moquitto">moquitto</h3>
<h3 id="section"></h3>
<p><a href="https://github.com/tuanpmt/esp_mqtt" class="uri">https://github.com/tuanpmt/esp_mqtt</a></p>
<h1 id="esp8266-http-服务器">ESP8266 HTTP 服务器</h1>
<h3 id="simple-http-server">Simple HTTP Server</h3>
<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="pp">#include </span><span class="im"><ESP8266WiFi.h></span>
<span class="pp">#include </span><span class="im"><ESP8266WebServer.h></span>
ESP8266WebServer server(<span class="dv">80</span>);
<span class="dt">void</span> setup() {
Serial.begin(<span class="dv">115200</span>);
WiFi.begin(<span class="st">"Network name"</span>, <span class="st">"Password"</span>); <span class="co">//Connect to the WiFi network</span>
<span class="cf">while</span> (WiFi.status() != WL_CONNECTED) { <span class="co">//Wait for connection</span>
delay(<span class="dv">500</span>);
Serial.println(<span class="st">"Waiting to connect…"</span>);
}
Serial.print(<span class="st">"IP address: "</span>);
Serial.println(WiFi.localIP()); <span class="co">//Print the local IP</span>
server.on(<span class="st">" / other"</span>, []() { <span class="co">//Define the handling function for the path</span>
server.send(<span class="dv">200</span>, <span class="st">"text / plain"</span>, <span class="st">"Other URL"</span>);
});
server.on(<span class="st">" / "</span>, handleRootPath); <span class="co">//Associate the handler function to the path</span>
server.begin(); <span class="co">//Start the server</span>
Serial.println(<span class="st">"Server listening"</span>);
}
<span class="dt">void</span> loop() {
server.handleClient();
}
<span class="dt">void</span> handleRootPath() {
server.send(<span class="dv">200</span>, <span class="st">"text/plain"</span>, <span class="st">"Hello world"</span>);
}</code></pre></div>
<h1 id="超越-esp8266">超越 ESP8266</h1>
<h1 id="第三部分-raspberry-pi">第三部分 Raspberry Pi</h1>
<ul>
<li>Hello, world!</li>
<li>Node.js 服务 - 开机启动,blabla</li>
<li>连接 Arduino、自动编程? OTA ?</li>
<li>Raspberry Pi as PC Camera + Sensors ???</li>
<li>Raspberry Pi <-> ESP8266 / Node.js Example</li>
<li>MQTT Server</li>
<li>IoT Server + Database?</li>
</ul>
<h1 id="raspberry-pi-hello-world">Raspberry Pi Hello, world!</h1>
<h3 id="镜像烧录">镜像烧录</h3>
<h3 id="ssh-连接">SSH 连接</h3>
<h3 id="python-控制-gpio">Python 控制 GPIO</h3>
<h1 id="node.js-服务基础">Node.js 服务基础</h1>
<h3 id="安装-node.js">安装 Node.js</h3>
<h3 id="express-hello-world">Express Hello, world</h3>
<h3 id="开机启动">开机启动</h3>
<h1 id="摄像头-传感器-智能家居">摄像头 + 传感器 = 智能家居?</h1>
<h3 id="红外传感器">红外传感器</h3>
<h3 id="视频流">视频流</h3>
<h3 id="拍照blabla">拍照,blabla</h3>
<h1 id="与-esp8266-无线通讯">与 ESP8266 无线通讯</h1>
<h3 id="建立服务">建立服务</h3>
<h3 id="广播">广播?</h3>
<h1 id="arduino-ota-更新">Arduino OTA 更新</h1>
<h3 id="服务端读取代码">服务端读取代码</h3>
<h3 id="arduino-cli-更新硬件">arduino-cli 更新硬件</h3>
<h1 id="使用-mqtt-服务器">使用 MQTT 服务器</h1>
<h3 id="mqtt-客户端">MQTT 客户端</h3>
<h3 id="使用-mosquittto">使用 mosquittto</h3>
<h1 id="跟上潮流docker硬件微服务">跟上潮流:Docker、硬件微服务</h1>
<h3 id="使用-docker">使用 Docker</h3>
<h3 id="硬件微服务">硬件微服务</h3>
<h1 id="home-assistant-搭建">Home Assistant 搭建</h1>
<h1 id="home-assistant-整合">Home Assistant 整合</h1>
<h1 id="homekit-搭建">Homekit 搭建</h1>
<h1 id="homekit-整合">Homekit 整合</h1>
<h1 id="raspberry-pi-与智能音箱">Raspberry Pi 与智能音箱</h1>
<h1 id="raspberry-pi-自制智能音箱">Raspberry Pi 自制智能音箱</h1>
<h1 id="超越-raspberry-pi">超越 Raspberry Pi</h1>
<section class="footnotes">
<hr />
<ol>
<li id="fn1"><p>源自维基百科,https://zh.wikipedia.org/wiki/Arduino<a href="#fnref1">↩</a></p></li>
<li id="fn2"><p>源自维基百科,https://zh.wikipedia.org/wiki/Arduino<a href="#fnref2">↩</a></p></li>
</ol>
</section>
</body>
</html>