panweitong %!s(int64=4) %!d(string=hai) anos
pai
achega
8269b86d92
Modificáronse 100 ficheiros con 2125 adicións e 0 borrados
  1. 1 0
      README.md
  2. 36 0
      aikit/A0.md
  3. 17 0
      aikit/A2.md
  4. 263 0
      aikit/AI_1.md
  5. 292 0
      aikit/AI_2.md
  6. 179 0
      aikit/AI_3.md
  7. 366 0
      aikit/AI_4.md
  8. 1 0
      aikit/overview.md
  9. 61 0
      changelog.md
  10. 445 0
      colorpicker.js
  11. 7 0
      docsify-themeable
  12. 0 0
      docsify.min.js
  13. 69 0
      extension/EX_01.md
  14. 131 0
      extension/EX_02.md
  15. 46 0
      extension/EX_03.md
  16. 1 0
      extension/overview.md
  17. 6 0
      faq.md
  18. 1 0
      getting-started.md
  19. 172 0
      index.html
  20. 18 0
      index.md
  21. 13 0
      lightbox-plus-jquery.min.js
  22. 0 0
      lightbox.min.css
  23. BIN=BIN
      media/EX/001.jpg
  24. BIN=BIN
      media/EX/002.jpg
  25. BIN=BIN
      media/EX/003.jpg
  26. BIN=BIN
      media/EX/003.png
  27. BIN=BIN
      media/EX/004.jpg
  28. BIN=BIN
      media/EX/005.jpg
  29. BIN=BIN
      media/EX/005.png
  30. BIN=BIN
      media/EX/006.jpg
  31. BIN=BIN
      media/EX/007.jpg
  32. BIN=BIN
      media/EX/008.jpg
  33. BIN=BIN
      media/EX/009.jpg
  34. BIN=BIN
      media/EX/010.jpg
  35. BIN=BIN
      media/EX/011.png
  36. BIN=BIN
      media/EX/012.jpg
  37. BIN=BIN
      media/EX/015.png
  38. BIN=BIN
      media/EX/016.png
  39. BIN=BIN
      media/EX/017.png
  40. BIN=BIN
      media/EX/018.jpg
  41. BIN=BIN
      media/EX/019.jpg
  42. BIN=BIN
      media/EX/019.png
  43. BIN=BIN
      media/EX/020.png
  44. BIN=BIN
      media/EX/021.png
  45. BIN=BIN
      media/EX/022.png
  46. BIN=BIN
      media/EX/023.png
  47. BIN=BIN
      media/EX/024.png
  48. BIN=BIN
      media/EX/025.png
  49. BIN=BIN
      media/EX/026.jpg
  50. BIN=BIN
      media/EX/027.png
  51. BIN=BIN
      media/EX/028.png
  52. BIN=BIN
      media/EX/029.png
  53. BIN=BIN
      media/EX/030.png
  54. BIN=BIN
      media/EX/031.png
  55. BIN=BIN
      media/EX/032.png
  56. BIN=BIN
      media/EX/033.png
  57. BIN=BIN
      media/EX/034.png
  58. BIN=BIN
      media/EX/035.png
  59. BIN=BIN
      media/EX/036.jpg
  60. BIN=BIN
      media/EX/037.png
  61. BIN=BIN
      media/EX/038.jpg
  62. BIN=BIN
      media/EX/039.png
  63. BIN=BIN
      media/EX/040.gif
  64. BIN=BIN
      media/EX/041.gif
  65. BIN=BIN
      media/EX/041.png
  66. BIN=BIN
      media/EX/042.gif
  67. BIN=BIN
      media/EX/043.jpg
  68. BIN=BIN
      media/EX/044.png
  69. BIN=BIN
      media/EX/045.png
  70. BIN=BIN
      media/EX/046.png
  71. BIN=BIN
      media/EX/047.png
  72. BIN=BIN
      media/EX/048.png
  73. BIN=BIN
      media/EX/049.jpg
  74. BIN=BIN
      media/EX/050.png
  75. BIN=BIN
      media/EX/051.png
  76. BIN=BIN
      media/EX/052.jpg
  77. BIN=BIN
      media/EX/053.png
  78. BIN=BIN
      media/EX/054.png
  79. BIN=BIN
      media/EX/055.png
  80. BIN=BIN
      media/EX/056.jpg
  81. BIN=BIN
      media/EX/w1.png
  82. BIN=BIN
      media/EX/w2.png
  83. BIN=BIN
      media/EX/w3.png
  84. BIN=BIN
      media/ai/AI_E1.png
  85. BIN=BIN
      media/ai/AI_E2.png
  86. BIN=BIN
      media/ai/AI_E3.png
  87. BIN=BIN
      media/ai/AI_I1.png
  88. BIN=BIN
      media/ai/AI_I10.png
  89. BIN=BIN
      media/ai/AI_I11.png
  90. BIN=BIN
      media/ai/AI_I12.png
  91. BIN=BIN
      media/ai/AI_I13.png
  92. BIN=BIN
      media/ai/AI_I14.png
  93. BIN=BIN
      media/ai/AI_I15.png
  94. BIN=BIN
      media/ai/AI_I17.png
  95. BIN=BIN
      media/ai/AI_I18.png
  96. BIN=BIN
      media/ai/AI_I19.png
  97. BIN=BIN
      media/ai/AI_I2.png
  98. BIN=BIN
      media/ai/AI_I20.png
  99. BIN=BIN
      media/ai/AI_I21.png.png
  100. BIN=BIN
      media/ai/AI_I3.png

+ 1 - 0
README.md

@@ -0,0 +1 @@
+To be edited.

+ 36 - 0
aikit/A0.md

@@ -0,0 +1,36 @@
+# <b>Uploader常见错误处理</b>
+### 1.	关键字:name 'xxxx' isn't defined
+描述:这个意思是有变量未定义,这种情况都是代码错误了。
+
+解决办法:和上传插件无关,看看积木是否搭建有问题。
+### 2.	关键字:'/private/tmp/PKInstallSandbox.rELsyx/tmp/python'
+描述:这个只有mac版本才有问题,意思是无法访问python,发生在用户安装的时候没有输入密码给软件绝对权限安装。
+
+解决办法:重启uploader即可。
+### 3.	关键字:Sipeed_M1 with kendryte-k210
+描述:摄像头没有插好或者坏了。
+
+解决办法:插好摄像头或者换壹个摄像头。
+### 4.	关键字:could not open port 'xxx': PermissionError
+问题:usb接口给其他程序占用了,通常有两种情况,一种是因为真的打开其他程序占用了,第二种就是重复点击上传按钮。
+
+解决办法:拔掉模块重新插入,重新打开uploader。
+### 5.	关键字:Timeout
+描述:模块还在连接中或者是启动中或者模块的串口芯片坏了。
+
+解决办法:等壹下再上传,或者是换新的模块。
+### 6.	关键字:file “<stadin>” line xx in <module>
+描述:代码运行错误。
+
+解决办法:固件是旧版本的,导致有些函数不支持,更新壹下固件,或者是代码写错了,修改代码积木。
+
+### 7.	上传一直卡在77%的问题
+描述:windows电脑有多个版本的python。
+
+解决办法:卸载电脑所有的python版本,然后重新安装uploader如下图:<br>
+1、点击控制面板<br>
+ <img src="/media/EX/w1.png" width="400"/><br>
+2、点击程序里面的卸载程序<br>
+  <img src="/media/EX/w2.png"/><br>
+3、找到所有的python,全部右键卸载<br>
+   <img src="/media/EX/w3.png"/><br>

+ 17 - 0
aikit/A2.md

@@ -0,0 +1,17 @@
+# <b>AI模块更新固件步骤说明</b>
+### 1.	打开x.cocoro.cn网页下载最新版的固件文件以及内存卡文件
+<img src="/media/ai/AI_update.png" width="350"/>
+
+### 2.	找到下载好的内存卡文件并解压
+
+### 3.  取出AI模块中的内存卡,使用读卡器删除里面的所有文件,并复制图片中的所有文件到内存卡中
+<img src="/media/ai/AI_file.png" width="350"/>
+
+### 4.  打开CocoBlockly X Uploader,右键电脑右下角CocoBlockly X Uploader图标,选择AI模块固件更新选项
+<img src="/media/ai/AI_update_file.png" width="350"/>
+
+### 5.  进入AI模块固件更新页面,选择打开下载好的固件文件,点击下载即可
+<img src="/media/ai/AI_update_fireware.png" width="350"/>
+
+### 6.  固件更新过程大概需要2到3分钟,当出现下面弹窗,固件更新完毕
+<img src="/media/ai/AI_update_finish.png" width="350"/>

+ 263 - 0
aikit/AI_1.md

@@ -0,0 +1,263 @@
+# 认识CocoBlockly X编程环境
+---
+## A.	认识AI模组及应用
+
+## 模组简介
+
+CocoRobo AI模组是CocoRobo为了推广人工智能教育而研发的「即插即用式」的可编程电子模组。AI模组套装是由AI推理模组、AI摄影镜头模组及AI萤幕模组三部份组成。
+
+## AI模组
+
+<table style="margin-top:20px;">
+	<tr>
+		<td width="50%"><img src="/media/ai/AI_zhengmian.png" width="350"/></td>
+		<td width="50%"><img src="/media/ai/AI_fanmian.png" width="350"/></td>
+	</tr>
+	<tr>
+		<td>正面</td>
+		<td>反面</td>
+	</tr>
+</table>
+
+AI 模组作为人工智能相关应用的主控模组,拥有基础计算机视觉识别功能和机器学习模型的推理功能,可帮助老师实现入门和进阶级别的 AI 应用。
+<br>
+#### 功能组成及应用:
+1. 自带WIFI功能,可联网发送或者接收数据
+2. 支援Micro SD卡存取影像、视讯、机器学习模型、音乐等资料
+3. 集成摄影镜头模块的插座,供后置拍摄使用
+
+## 摄影镜头模组
+
+<table style="margin-top:20px;">
+	<tr>
+		<td width="50%"><img src="/media/ai/AI_photozheng.png" width="350"/></td>
+		<td width="50%"><img src="/media/ai/AI_photofan.png" width="350"/></td>
+	</tr>
+	<tr>
+		<td>正面</td>
+		<td>反面</td>
+	</tr>
+</table>
+
+200w像素摄影镜头,可分别插在萤幕模组或者 AI 模组上,前拍后拍都可以。并且摄影镜头的影像尺寸有320 x 240 px及160 x 120 px两款,使用时可自行选择。
+
+## 萤幕模组
+
+<table style="margin-top:20px;">
+	<tr>
+		<td width="50%"><img src="/media/ai/AI_screenzheng.png" width="350"/></td>
+		<td width="50%"><img src="/media/ai/AI_screenfan.png" width="350"/></td>
+	</tr>
+	<tr>
+		<td>正面</td>
+		<td>反面</td>
+	</tr>
+</table>
+
+#### 功能组成及应用:
+1. 集成摄影镜头模组插座,供前置拍照使用;
+2. 1.54 寸 LCD 全彩萤幕,绘制JPG, BMP等格式图片;
+3. 可用于外接的 3.5mm 音频介面;
+4. 板载功放晶片及扬声器,支援播放WAV格式的音讯档案;
+
+## 模组连接及使用
+1)连接AI模组、摄影镜头模组和萤幕模组三部分,按照如下图所示的位置进行连接
+<table style="margin-top:20px;">
+	<tr>
+		<td width="50%"><img src="/media/ai/AI_anzhuang_1.png" width="350"/></td>
+		<td width="20%"><img src="/media/ai/AI_anzhuang_3.png" width="350"/></td>
+    <td width="30%"><img src="/media/ai/AI_anzhuang_2.png" width="350"/></td>
+	</tr>
+</table>
+
+2)使用Micro USB数据线连接AI模组和电脑
+<table style="margin-top:20px;">
+	<tr>
+		<td width="50%"><img src="/media/ai/AI_usb_1.png" width="350"/></td>
+		<td width="50%"><img src="/media/ai/AI_usb_2.png" width="350"/></td>
+	</tr>
+	<tr>
+		<td>Micro USB数据线连接电子模组</td>
+		<td>Micro USB数据线连接电脑</td>
+	</tr>
+</table>
+
+连接完成后,便可看到初始介面,按如下图所示的步骤即可体验AI模组的功能样例。<br>
+<img src="/media/ai/AI_connectfinish.png" width="350"/>
+<br>STEP 1:将模组通过数据线连接到电脑的USB端口,启动AI模组;
+<br>STEP 2:模组顶部左侧按钮左移,右侧按钮右移,按右侧按钮右移到Try Demos,按底部左边按钮确认,即可进入AI样例体验选单;
+<br>STEP 3:在AI体验列表介面,按右侧按钮可实现翻页操作,再按底部确定按钮即可进行体验。
+
+---
+## B.	CocoBlockly X
+CocoBlockly X图形化编程工具,是可用于学习Python基础以及AI模组的在线编程环境。通过这款工具可以给IoT模组和AI推理模组编写程式及上传程式。<br>
+在Chrome浏览器输入网址 http://x.cocorobo.hk ,即可开始在CocoBlockly X编程。<br>
+<img src="/media/ai/AI_coco1.png" width="350"/>
+1. 文档存取区:程式项目命名、保存(保存为.xml档)、删除所有积木及所有积木一键截图
+2. 模式切换区:样例加载、模式切换(主机板模组与 AI 模组)<br>
+<img src="/media/ai/AI_coco2.png" width="350"/>
+3. 辅助区:学习资料、项目档导入及导出、语言设置、以及用户登入
+<br>其中,学习资料按钮,可以跳转至EDU或者AI HUB学习平台:<br>
+<img src="/media/ai/AI_coco3.png" width="350"/>
+<img src="/media/ai/AI_coco4.png" width="350"/>
+4.	积木指令区:除基础积木以外(由「逻辑」至「序列埠通讯」),不同模式下拥有不同的扩展积木
+5.	积木编程区:将积木拖入此区域中以进行程式编写
+6.	Python编程区:当用户将积木拖入积木编程区以后,此处将会生成对应的Python源代码,支持用户对代码进行编辑、复制、下载及上传,下载后缀为 .py格式的python文档<br>
+<img src="/media/ai/AI_coco5.png" width="350"/>
+7.	上传区:用户可选择使用有线或者无线上传模式
+
+---
+## C.	CocoBlockly Uploader
+CocoBlockly Uploader是一款跨平台的上传插件,安装后可以使CocoBlockly X实现浏览器、IoT模组和AI推理模组间的通讯,将编写完成的程式上传到相关模组。安装方法如下:
+1. 进入CocoBlockly X编程平台,http://x.cocorobo.hk <br>
+<img src="/media/ai/AI_uploader1.png" width="350"/>
+2.	将滑鼠移向右下方「上传区域」的「下载」图示位置,点按「Windows」下载Uploader,如果是Mac系统,则点按「Mac」进行下载。<br>
+<img src="/media/ai/AI_uploader2.png" width="350"/>
+
+#### Windows系统下的安装:
+1. 下载完成后执行安装档,点按「安装」按钮,进行安装<br>
+<img src="/media/ai/AI_upload1.png" width="210"/>
+<img src="/media/ai/AI_upload2.png" width="210"/>
+<br><br><B>注意,已安装其它版本Python的用户请先卸载Python。</B><br><br>
+2. 安装程式会启动Python安装视窗,在选单中点按「Repair」,开始进行Python安装程式<br>
+<img src="/media/ai/AI_upload3.png" width="210"/>
+<img src="/media/ai/AI_upload4.png" width="210"/>
+3. 安装完成后点按「Close」按钮<br>
+<img src="/media/ai/AI_upload5.png" width="210"/>
+4. 继续安装Uploader,按照安装程式执行<br>
+<img src="/media/ai/AI_upload6.png" width="210"/>
+<img src="/media/ai/AI_upload7.png" width="210"/>
+<img src="/media/ai/AI_upload8.png" width="210"/><br>
+5. 最后,点按「完成」结束Uploader安装程式 <br>
+<img src="/media/ai/AI_upload9.png" width="210"/>
+<img src="/media/ai/AI_upload10.png" width="210"/><br>
+6. 点击GO TO COCOBLOCKLY X即可进入积木编程页面
+
+#### Mac系统下的安装:
+1)「Mac」用户右键点击安装档案,选择“安装程式(预设值)”进行安装<br>
+<img src="/media/ai/AI_macupload1.png" width="210"/><br>
+2) 进入安装页面,点击“继续”,之后点击“安装“
+<img src="/media/ai/AI_macupload2.png" width="210"/>
+<img src="/media/ai/AI_macupload3.png" width="210"/><br>
+3) 验证你的密码,然后点击“安装软件”进入正在安装页面,等待即可<br>
+<img src="/media/ai/AI_macupload4.png" width="210"/>
+<img src="/media/ai/AI_macupload5.png" width="210"/><br>
+4) 出现下图“已成功安装“页面,则表示uploader已成功安装,即可看到程式图标<br>
+<img src="/media/ai/AI_macupload6.png" width="210"/>
+<img src="/media/ai/AI_macupload7.png" width="210"/><br>
+
+---
+## D.	上传程式
+将IoT模组或AI推理模组,通过USB接驳线与电脑连接。打开CocoBlockly X编程工具。
+1.	进入CocoBlockly X编程平台,http://x.cocorobo.hk
+<br>
+<img src="/media/ai/AI_shangchuan1.png" width="350"/><br>
+2.	在上方「切换区域」选择AI模组:
+<br>
+<img src="/media/ai/AI_shangchuan2.png" width="350"/><br>
+3.	在右下方「上传区域」检查以下设定:
+<br>
+<img src="/media/ai/AI_shangchuan3.png" width="350"/><br>
+4.	在「上传区域」点按如下图所示中,左下角位置的「运行」按钮上传程式到AI模组中。
+<br>
+<img src="/media/ai/AI_shangchuan4.png" width="350"/><br>
+
+上传失败或出现其他错误,请参阅:[Uploader常见错误处理](/aikit/A0.md)。
+
+##### 注意:
+
+1)上图中左下角第一个按钮为「运行程式」按钮,即运行当前blockly中的程式,断开连接后,再次接通,不会继续运行当前程式,而是显示初始化菜单介面:
+<br>
+<img src="/media/ai/AI_shangchuan5.png" width="300"/><br>
+且选择「Run Last」选项,也不会运行之前的程式,如果想要再次运行,需要再次点击运行按钮
+<br>
+2)左下角第二个按钮为「上传程式」按钮,将程式上传到AI模组中,便会存储在模组中,断开连接,再次接通后,选择「Run Last」选项,即可运行上次的程式。
+<br>
+3)如果上传出现问题,或者加载AI模组的插件出现问题,则可以点击右下角「重启设备」按钮,尝试解决。
+
+---
+## E.	串口互动窗
+串口互动窗用于显示或查看AI模组上的数据,是测试数据(感应器、网路请求)的好帮手。在「代码区」点按「串口互动窗」。在积木指令区点按「序列埠通讯」,在积木编程区放置【打印】指令<img src="/media/ai/AI_E1.png" width="250"/>。然后在「上传区域」点按「运行代码」按钮,当显示「上载成功!100%」后在「代码区」点按「串口互动窗」,会显示「Hello World!」<br>
+Windows系统:
+<br>
+<img src="/media/ai/AI_E2.png" width="300"/><br>
+Mac系统:
+<br>
+<img src="/media/ai/AI_E3.png" width="300"/><br>
+
+---
+## F.	CocoBlockly X编程体验
+##### 1.	在萤幕模组显示Hello World !
+<table style="margin-top:20px;">
+	<tr>
+		<td width="50%">在积木指令区点按以下指令,并依次放在积木编程区:<br>
+1)AI模组|图像处理:「萤幕初始化」、「创建空白画布」、「设定画布坐标」<br><br>
+2)循环:「重复执行」<br><br>
+3)AI模组|图像处理:「萤幕文字」并输入「Hello World!」<br><br>
+(其中「文字大小」可通过修改数字改变;颜色可选择,此处选为红色)
+</td>
+		<td width="50%"><img src="/media/ai/AI_f1.png" width="350"/><img src="/media/ai/AI_f2.png" width="350"/></td>
+	</tr>
+	<tr>
+		<td colspan=2>完成编程后,在「上传区域」点按「运行代码」,观察AI萤幕模组的变化。<br>
+运行结果:
+<br>
+<img src="/media/ai/AI_f3.png" width="250"/><br>
+</td>
+	</tr>
+</table>
+
+##### 2.	在萤幕中心显示Hello World !
+<table style="margin-top:20px;">
+	<tr>
+		<td width="50%">
+1)AI模组|图像处理:「萤幕初始化」、「创建空白画布」、「设定画布坐标」<br><br>
+2)循环:「重复执行」<br><br>
+3)AI模组|图像处理:「萤幕文字」并输入「Hello World!」<br><br>
+4)修改座标的X值及Y值,使「Hello World!放置萤幕正中心位置。
+</td>
+		<td width="50%"><img src="/media/ai/AI_f4.png" width="350"/><img src="/media/ai/AI_f5.png" width="350"/></td>
+	</tr>
+	<tr>
+		<td colspan=2>完成编程后,在「上传区域」点按「运行代码」,观察AI萤幕模组的变化。<br>
+运行结果:
+<br>
+<img src="/media/ai/AI_f6.png" width="250"/><br>
+</td>
+	</tr>
+</table>
+
+##### 3.	按钮控制
+<table style="margin-top:20px;">
+	<tr>
+		<td width="50%">在积木指令区点按以下指令,并依次放在积木编程区:<br>
+1)1.	AI模组|图像处理:「萤幕初始化」、「创建空白画布」、「设定画布坐标」<br><br>
+2)循环:「重复执行」<br><br>
+3)逻辑:「逻辑判断」<br><br>
+4)AI模组|基础:「按钮状态」<br><br>
+5)AI模组|图像处理:「萤幕文字」(颜色为白色)
+</td>
+		<td width="50%"><img src="/media/ai/AI_f7.png" width="350"/><img src="/media/ai/AI_f8.png" width="350"/></td>
+	</tr>
+	<tr>
+		<td colspan=2>运行结果:当按钮A按下,显示Hello World!,否则不显示任何文字。<br>
+未按键:
+<img src="/media/ai/AI_f9.png" width="150"/>
+按A键:
+<img src="/media/ai/AI_f10.png" width="150"/>
+</td>
+	</tr>
+</table>
+
+
+##### 补充:
+上面第三步「逻辑判断」积木块的实现方式如下:<br>
+1)选择:
+<br>
+<img src="/media/ai/AI_f11.png" width="250"/><br>
+2)点击左上角图标,显示如下:
+<br>
+<img src="/media/ai/AI_f12.png" width="250"/><br>
+3)拖拽「否则」积木块到右侧,放到「如果」下面,即可显示出「否则」部分:
+<br>
+<img src="/media/ai/AI_f13.png" width="250"/><br>

+ 292 - 0
aikit/AI_2.md

@@ -0,0 +1,292 @@
+# 认识萤幕模组
+---
+
+## 	A.萤幕模组
+模组连接一个LCD彩色萤幕显示器,萤幕解析度为240 x 240 px (像素),可显示JPG, BMP 等格式图片。像素,组成点阵数位影像的最小方块单位,每个方块都有一个明确的位置和被分配的色彩数值,小方格颜色和位置就决定该图像所呈现出来的样子。如下图所示:
+<br>
+<img src="/media/ai/AI_g1.png" width="300"/><br>
+我们以坐标系(X, Y)标明方块的位置,X代表水准方向(X轴),Y代表垂直方向(Y轴),列萤幕的左上角为起始点(0, 0)(代表第一行,第一列),最大值为(239, 239)。<br>
+例如方块(4, 3),指方块的位置由左而右第5列,由上至下第4行(因为X、Y座标均从0开始)。
+<table style="margin-top:20px;">
+	<tr>
+		<td width="50%"><img src="/media/ai/AI_g2.png" width="350"/></td>
+		<td width="50%"><img src="/media/ai/AI_g3.png" width="350"/></td>
+	</tr>
+	<tr >
+		<td colspan=2>活动:列出方格A及方格B的座标系:A __________ B __________</td>
+	</tr>
+</table>
+
+---
+## 	B.萤幕模组介绍
+<table style="margin-top:20px;">
+	<tr>
+		<td width="50%">积木</td>
+		<td width="20%">指令</td>
+    <td width="30%">说明</td>
+	</tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_h1.png" width="200"/></td>
+    <td width="20%">初始化</td>
+    <td width="30%">初始化萤幕</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_h2.png" width="200"/><img src="/media/ai/AI_h3.png" width="200"/></td>
+    <td width="20%">改变萤幕状态</td>
+    <td width="30%">旋转萤幕方向、萤幕镜面翻转<img src="/media/ai/AI_h4.png" width="200"/></td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_h5.png" width="200"/></td>
+    <td width="20%">改变萤幕颜色</td>
+    <td width="30%">填充萤幕颜色:<img src="/media/ai/AI_h6.png" width="200"/></td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_h7.png" width="200"/></td>
+    <td width="20%">自定义萤幕颜色</td>
+    <td width="30%">填入不同的RGB(红绿蓝)值,达到自定义颜色的效果</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_h8.png" width="200"/></td>
+    <td width="20%">清除萤幕</td>
+    <td width="30%">清除萤幕</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_h9.png" width="200"/><img src="/media/ai/AI_h10.png" width="200"/><img src="/media/ai/AI_h11.png" width="200"/></td>
+    <td width="20%">参数调节</td>
+    <td width="30%">改变RGB值、XY坐标值和宽高值</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_h12.png" width="200"/></td>
+    <td width="20%">建立画布</td>
+    <td width="30%">建立画布并定义画布的大小</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_h13.png" width="200"/></td>
+    <td width="20%">自定画布幕颜色</td>
+    <td width="30%">填入不同的RGB(红绿蓝)值,达到自定义颜色的效果</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_h24.png" width="200"/></td>
+    <td width="20%">建立画布</td>
+    <td width="30%">建立并储存画布在SD记忆卡</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_h14.png" width="200"/></td>
+    <td width="20%">显示画布</td>
+    <td width="30%">定义画布在萤幕上的起始位置</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_h15.png" width="200"/></td>
+    <td width="20%">绘制文字</td>
+    <td width="30%">萤幕可以同时显示文字及图形,特别适合用作图像识别。必须同时使用「建立画布」及「显示画布」指令。</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_h16.png" width="200"/></td>
+    <td width="20%">绘制直线</td>
+    <td width="30%">在画布上绘画直线,输入起点及终点坐标。可以选择线条颜色及厚度。</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_h17.png" width="200"/></td>
+    <td width="20%">绘制矩形</td>
+    <td width="30%">在画布上绘画矩形,可以是实心或空心,输入起点坐标及尺寸。可以选择线条颜色及厚度。</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_h18.png" width="200"/></td>
+    <td width="20%">绘制圆形</td>
+    <td width="30%">在画布上绘画圆形,可以是实心或空心,输入圆心的坐标及半径。可以选择线条颜色及厚度。</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_h19.png" width="200"/></td>
+    <td width="20%">绘制十字标</td>
+    <td width="30%">在画布上绘画十字标,输入中心坐标。可以选择线条延伸长度、厚度及颜色。</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_h20.png" width="200"/></td>
+    <td width="20%">绘制箭头</td>
+    <td width="30%">在画布上绘画箭头,输入起点及终点坐标。可以选择线条颜色及厚度。</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_h21.png" width="200"/></td>
+    <td width="20%">绘制图片</td>
+    <td width="30%">在画布上绘画图片,图片从SD卡的档路径中选取,输入起点坐标及缩放比例。</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_h22.png" width="200"/></td>
+    <td width="20%">显示画布</td>
+    <td width="30%">显示指定画布,画布名可修改</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_h23.png" width="200"/></td>
+    <td width="20%">清除画布</td>
+    <td width="30%">清除所选画布中的所有内容</td>
+  </tr>
+</table>
+
+---
+## I.	基础编程
+##### 活动一:在萤幕上显示矩形图案,设定坐标系(0,0)
+<table style="margin-top:20px;">
+<tr>
+  <td>1)AI模组|图像处理:「萤幕初始化」、「创建空白画布」、「设定画布坐标」<br><br>
+2)循环:「重复执行」<br><br>
+3)AI模组|图像处理:「绘制矩形」<br><br>
+4)AI模组|图像处理:「显示画布」
+</td>
+  <td><img src="/media/ai/AI_I1.png" width="350"/><img src="/media/ai/AI_I2.png" width="350"/></td>
+</tr>
+</table>
+以上活动首先会建立一幅空白画布并命名为「canvas」,画布的大小设定为240 x 240。接著输入「重复执行」指令,使萤幕不断显示矩形图案,如果没有使用该指令,矩形图案只会显示一次就消失。在「重复执行」指令中加入「绘制矩形」及「显示画布」指令并输入参数如下:
+<table style="margin-top:20px;">
+	<tr>
+		<td width="50%">绘制矩形</td>
+		<td width="50%">矩形样式:实心<br>
+起始座标:X=0, Y=0<br>
+尺寸:寛=1, 高=1<br>
+颜色:红色<br>
+厚度:1<br>
+</td>
+	</tr>
+	<tr>
+		<td>显示画布</td>
+		<td>起始座标:X=0, Y=0</td>
+	</tr>
+</table>
+注:「建立画布」是指建立图像变数,将获取的影像存放在变数中,作进一步使用。<br>
+运行结果:
+<img src="/media/ai/AI_I3.png" width="200"/>
+
+##### 活动二:修改活动一程式,在萤幕上显示延长横线
+<table style="margin-top:20px;">
+<tr>
+  <td>1)循环:「计次」<br>
+将指令并合在「重复执行」指令内,范围设定为0-239,间隔=1<br>
+2)变数:「i」<br>
+将变数「i」放在「绘制矩形」座标参数中的X值处
+</td>
+  <td><img src="/media/ai/AI_I4.png" width="350"/><img src="/media/ai/AI_I5.png" width="350"/></td>
+</tr>
+<tr><td colspan=2>点按「运行」后观察萤幕的变化,并简短描述如下:<br><img src="/media/ai/AI_I8.png" width="350"/></td></tr><tr>
+<td colspan=2>运行结果:不断延长的直线<br><img src="/media/ai/AI_I6.png" width="200"/><img src="/media/ai/AI_I7.png" width="200"/> </td></tr>
+</table>
+
+##### 挑战一:
+<table style="margin-top:20px;">
+<tr>
+  <td colspan=2>修改活动二的程式,在萤幕上显示一个红色方块,由左向右移动,每次移动一格。<br>
+提示:尝试运用以下积木<br>
+<img src="/media/ai/AI_I9.png" width="350"/>
+</td>
+</tr>
+<tr>
+<td colspan=2>参考程式:<br><img src="/media/ai/AI_I10.png" width="200"/><img src="/media/ai/AI_I11.png" width="200"/> </td>
+</tr>
+<tr >
+<td colspan=2>运行结果:<br><img src="/media/ai/AI_I12.png" width="200"/><img src="/media/ai/AI_I13.png" width="200"/> </td>
+</tr>
+</table>
+
+##### 活动三:建立画布显示矩形图案
+<table style="margin-top:20px;">
+<tr>
+  <td >在积木指令区点按以下指令,并依次放在积木编程区:<br>
+1)AI模组|图像处理:「萤幕初始化」<br>
+2)AI模组|图像处理:「建立画布」、「设定画布起始坐标」<br>
+3)循环:「重复执行」<br>
+4)AI模组|图像处理:「绘制矩形」<br>
+5)AI模组|图像处理:「显示画布」
+</td><td>
+<img src="/media/ai/AI_I14.png" width="350"/>
+</td>
+</tr>
+<tr >
+<td colspan=2>运行结果:<br><img src="/media/ai/AI_I15.png" width="200"/></td>
+</tr>
+</table>
+此活动目标为理解路径的概念:<br>
+从SD卡档夹中读取图像,使用该图像作为画布,显示在荧幕上,然后在此画布上画白色的矩形块,学生可自行修改矩形块位置、大小及颜色。
+
+##### 活动四:建立画布显示方框文字
+<table style="margin-top:20px;">
+<tr>
+  <td >在积木指令区点按以下指令,并依次放在积木编程区:<br>
+1)重复活动一的程式<br>
+2)AI模组|图像处理:「绘制文本」放在「绘制矩形」指令之下<br>
+3)AI模组|图像处理:「显示画布」(必要积木,否则不会显示任何讯息)
+</td><td>
+<img src="/media/ai/AI_I21.png" width="350"/><img src="/media/ai/AI_I17.png" width="350"/>
+</td>
+</tr>
+<tr>
+<td  colspan=2>运行结果:<br><img src="/media/ai/AI_I18.png" width="200"/></td>
+</tr>
+</table>
+
+##### 挑战二:
+<table style="margin-top:20px;">
+<tr>
+  <td colspan=2>编写程式,在萤幕正中心位置显示白色方框,框内打印你的英文名。如下图所示:<br>
+<img src="/media/ai/AI_I19.png" width="350"/><br>
+提示:需要计算文字及方框的尺寸,对应萤幕的面积尺寸,修改文字及方框的座标位置,使二者能显示在萤幕的正中心位置。
+</td>
+</tr>
+<tr colspan=2>
+<td>参考程式:<br><img src="/media/ai/AI_I20.png" width="200"/></td>
+</tr>
+</table>
+
+---
+## C.	专题学习
+硬体设备:AI推理模组、萤幕模组<br>
+任务目标:运用「变数」及「循环」,用【线条】指令制作一个万花筒动画<br>
+基本流程/步骤:<br>
+<img src="/media/ai/AI_j1.png" width="200"/><br>
+第一步:模组初始化<br>
+<table style="margin-top:20px;">
+<tr>
+  <td >在积木指令区点按以下指令,并依次放在积木编程区:<br>
+1)AI模组|图像处理:「萤幕初始化」、「建立画布」、「设定画布起始坐标」<br>
+2)循环:「重复执行」<br>
+3)AI模组|图像处理:「清除画布」
+</td><td>
+<img src="/media/ai/AI_j2.png" width="350"/>
+</td></tr>
+</table>
+
+第二步:绘画直线万花筒<br>
+放置【For循环】,设定变数i:由0-240,每次循环自动增加数值5,即i = 0, 5, 10, 15, ……, 240,目的是利用数值变化改变绘画直线的座标位置,使其形成万花筒效果。<br>
+<table style="margin-top:20px;">
+<tr>
+  <td >在步骤3【清除画布】积木指令下,放置下列积木指令:<br>
+4)循环:【For循环】<br>
+5)AI模组|图像处理:【绘制直线】<br>
+6)AI模组|图像处理:【显示画布】<br>
+7)时间:【等待】
+</td><td>
+<img src="/media/ai/AI_j3.png" width="350"/>
+</td>
+</table>
+观察结果:<br>
+<table style="margin-top:20px;">
+<tr>
+  <td ><img src="/media/ai/AI_j4.png" width="350"/>
+</td><td>
+<img src="/media/ai/AI_j5.png" width="350"/>
+</td><td>
+<img src="/media/ai/AI_j6.png" width="350"/>
+</td></tr>
+<tr>
+<td colspan=3>参考程式:<br><img src="/media/ai/AI_j7.png" width="350"/><img src="/media/ai/AI_j11.png" width="350"/>
+</td>
+</tr>
+</table>
+
+##### 挑战题:
+<table style="margin-top:20px;">
+<tr>
+  <td >如何透过【For循环】方法,延续上面绘画的直线,在余下的空间位置绘画直线,如下图所示:<img src="/media/ai/AI_j8.png" width="350"/>
+</td></tr>
+<tr>
+<td >参考程式:<br><img src="/media/ai/AI_j9.png" width="350"/><img src="/media/ai/AI_j10.png" width="350"/>
+</td>
+</tr>
+</table>

+ 179 - 0
aikit/AI_3.md

@@ -0,0 +1,179 @@
+# 认识摄影镜头模组
+---
+
+## A.	摄影镜头模组
+详情参见[认识CocoBlockly X编程环境](/aikit/AI_1.md)中“A.认识AI模组及应用”部分。
+
+---
+## B.	相机积木介绍
+<table style="margin-top:20px;">
+	<tr>
+		<td width="50%">积木</td>
+		<td width="20%">指令</td>
+    <td width="30%">说明</td>
+	</tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_l1.png" width="200"/></td>
+    <td width="20%">初始化</td>
+    <td width="30%">汇入相机的程式库,可设定以下两项属性:<br>
+影像尺寸:320x240及160x120<br>
+影像色彩:彩色 及 黑白
+</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_l2.png" width="200"/></td>
+    <td width="20%">影像尺寸</td>
+    <td width="30%">设定影像的显示尺寸,最大尺寸可输入:宽240 高240
+</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_l3.png" width="200"/></td>
+    <td width="20%">获取影像</td>
+    <td width="30%">获取从摄影镜头拍摄的影像
+</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_l4.png" width="200"/></td>
+    <td width="20%">校正图像</td>
+    <td width="30%">对广角镜头获取的图片进行校正
+</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_l5.png" width="200"/></td>
+    <td width="20%">属性设定</td>
+    <td width="30%">设定「启用」或「停用」以下五个属性:<img src="/media/ai/AI_l6.png" width="200"/>
+</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_l7.png" width="200"/></td>
+    <td width="20%">属性设定</td>
+    <td width="30%">设定影像的对比度、亮度及色彩饱和度等数值属性,范围定为-3至3
+</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_l8.png" width="200"/></td>
+    <td width="20%">录制影片</td>
+    <td width="30%">设定影片录制参数,包括储存路径、影片宽度及高度
+</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_l9.png" width="200"/></td>
+    <td width="20%">画布录制</td>
+    <td width="30%">录制影片
+</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_l10.png" width="200"/></td>
+    <td width="20%">停止录影</td>
+    <td width="30%">停止录影
+</td>
+  </tr>
+</table>
+
+---
+## C.	基础编程
+##### 活动一:启用AI摄影镜头
+<table style="margin-top:20px;">
+<tr>
+  <td>1.	AI模组|图像处理:【萤幕初始化】、【创建空白画布】、【设定起始点坐标】<br>
+2.	AI模组|相机:【相机初始化】<br>
+3.	AI模组|相机:【影像尺寸】<br>
+4.	循环:【重复执行】<br>
+5.	变数:建立变数命名为【canvas】<br>
+6.	AI模组|相机:【获取影像】<br>
+7.	AI模组|图像处理:【显示画布】<br>
+</td>
+  <td><img src="/media/ai/AI_m1.png" width="350"/></td>
+</tr>
+<tr><td colspan=2>运行结果:启用AI摄影镜头并在萤幕上出现画面<br><img src="/media/ai/AI_m2.png" width="350"/></td></tr>
+</table>
+
+##### 活动二:每隔1秒拍照并储存相片
+<table style="margin-top:20px;">
+<tr>
+  <td>重复活动一的程式,在步骤5及7中间加入以下积木指令:<br>
+1.	AI模组|图像处理:【储存影像】,
+位置:/sd/user/saved.jpg
+在步骤6之后加入以下积木指令:<br>
+2.	时间:【等候】设定为1000毫秒<br>
+
+</td>
+  <td><img src="/media/ai/AI_m3.png" width="350"/></td>
+</tr>
+<tr><td colspan=2>运行结果:每隔1秒会自动拍照1次,影像显示在萤幕上并储存在SD记忆卡中。从AI推理模组取出SD记忆卡,透过电脑打开影像档案:user/saved.jpg<br><img src="/media/ai/AI_m4.png" width="350"/></td></tr>
+</table>
+思考问题:上面程式运行一段时间后,为什么SD记忆卡仍只有一幅影像档案?
+<br><img src="/media/ai/AI_s9.png" width="350"/>
+
+##### 挑战一:
+<table style="margin-top:20px;">
+<tr>
+  <td >修改上面程式,每次拍照并储存图像时均会将新的图像存进SD卡。<br>
+提示:尝试运用以下的积木<br>
+<img src="/media/ai/AI_m5.png" width="200"/>
+<img src="/media/ai/AI_m6.png" width="200"/>
+</td></tr>
+<tr><td >参考程式:<br><img src="/media/ai/AI_m7.png" width="350"/></td></tr>
+</table>
+
+##### 活动三:透过按动按钮拍照并储存相片
+<table style="margin-top:20px;">
+<tr>
+  <td>使用活动一程式,在步骤5及7之间加入以下程式:<br>
+1.	逻辑:【逻辑判断】<br>
+2.	AI模组|基础:【按钮状态】<br>
+3.	AI模组|图像处理:【储存影像】<br>
+4.	AI模组|图像处理:【显示画布】<br>
+5.	时间:【等候】设定为1000毫秒<br>
+</td>
+  <td><img src="/media/ai/AI_m8.png" width="350"/></td>
+</tr>
+<tr><td colspan=2>运行结果:即时影像显示在萤幕上,当按钮B按下时,会将即时影像储存在SD记忆卡并在萤幕上停顿显示1秒,随后再次显示即时影像。</td></tr>
+</table>
+
+##### 活动四:录制影片
+<table style="margin-top:20px;">
+<tr>
+  <td>1.	AI模组|图像处理:【萤幕初始化】、【创建空白画布】、【设定起始点坐标】<br>
+2.	AI模组|相机:【相机初始化】<br>
+3.	AI模组|相机:【影像尺寸】<br>
+4.	AI模组|视讯处理:【录制影片】<br>
+5.	循环:【重复执行】<br>
+6.	变数:建立变数命名为【camera】<br>
+7.	AI模组|相机:【获取影像】<br>
+8.	AI模组|视讯处理:【画布录制】<br>
+9.	萤幕|图像处理:【显示画布】<br>
+10.	AI模组|视讯处理:【停止录制】<br>
+
+</td>
+  <td><img src="/media/ai/AI_m9.png" width="350"/></td>
+</tr>
+<tr><td colspan=2><img src="/media/ai/AI_m10.png" width="350"/></td></tr>
+<tr><td colspan=2>运行结果:从AI模组取出SD记忆卡,在电脑开启影片档案(路径:/sd/user/record.avi)查看影片是否录制成功。</td></tr>
+</table>
+
+
+##### 活动五:透过按钮录制影片
+<table style="margin-top:20px;">
+<tr>
+  <td>1.	AI模组|图像处理:【萤幕初始化】、【创建空白画布】、【设定起始点坐标】<br>
+2.	AI模组|相机:【相机初始化】<br>
+3.	AI模组|相机:【影像尺寸】<br>
+4.	AI模组|视讯处理:【录制影片】<br>
+5.	循环:【重复执行】<br>
+6.	变数:建立变数命名为【camera】<br>
+7.	AI模组|相机:【获取影像】<br>
+8.	萤幕|图像处理:【显示画布】<br>
+9.	逻辑:【逻辑判断】<br>
+10.	AI模组|基础:【按钮状态】<br>
+11.	如按钮A按下:AI模组|视讯处理:【画布录制】<br>
+如按钮A松开:AI模组|视讯处理:【停止录制】
+
+</td>
+  <td><img src="/media/ai/AI_m11.png" width="350"/></td>
+</tr>
+<tr><td colspan=2>参考程式:<img src="/media/ai/AI_m12.png" width="350"/></td></tr>
+<tr><td colspan=2>运行结果:即时影像显示在萤幕上并录制。<br>
+当按钮A按下时,开始录像并会将即时影像储存在SD记忆卡中,不按则只显示即时画面不录影。
+</td></tr>
+</table>

+ 366 - 0
aikit/AI_4.md

@@ -0,0 +1,366 @@
+# 认识物体识别
+---
+
+##  A.	图像识别与计算机视觉
+#####  1.	图像识别
+在学习物体识别前,我们先来认识下图像识别。<br>
+图像识别,简单地来说,就是一个将图像与特定的词语对应起来的过程。从技术上来看,是利用电脑对图像进行处理、分析和理解,以识别各种不同模式的目标和对象的过程。图像识别的发展经历了三个阶段:文字识别、数字图像处理与识别、物体识别。<br>
+文字识别的研究是从 1950年开始的,一般是识别字母、数字和符号,从印刷文字识别到手写文字识别,应用非常广泛。<br>
+<img src="/media/ai/AI_n1.png" width="300"/><img src="/media/ai/AI_n2.png" width="350"/><br>
+数字图像处理和识别的研究开始于1965年。数字图像与模拟图像相比具有存储、传输方便可压缩、传输过程中不易失真、处理方便等巨大优势,这些都为图像识别技术的发展提供了强大的动力。
+<br><img src="/media/ai/AI_n3.png" width="350"/><br>
+物体识别主要指对三维世界的物体及环境的感知和认识,属于高级的计算机视觉范畴。它是以数字图像处理与识别为基础的结合人工智能、系统学等学科的研究方向,其研究成果被广泛应用在各种工业及机器人中。
+<br><img src="/media/ai/AI_n4.png" width="350"/><br>
+了解了这些知识,我们再来看下面这四幅图,第一张图片是手写数字,可以看到电脑将它正确地识别为了425,后三张图片则分别分类为猫、人和车。
+<br><img src="/media/ai/AI_n5.png" width="350"/><br>
+这就是文字识别和物体识别的一些应用,电脑可通过深度学习算法,对输入的图像进行识别,并给出每幅图片的识别结果。<br>
+在人工智能领域,识别问题又可以归类为分类问题,所以物体识别,也可以称之为物体分类。<br>
+
+
+#####  2.	计算机视觉
+我们前面提到了,图像识别就是电脑获取,处理和分析图像数据的过程,这个过程其实也就是计算机视觉的实现过程。简而言之,计算机视觉使得电脑能够“看”事物——甚至包括人类无法看到的事物。然而,要想让电脑做到人类无法做到的事情,我们必须首先使电脑能够做到人类可以做的事情:看到并标记物体和生物。这是图像识别的主要功能。<br>
+我们先来看下下面这四幅猫的图片,我们可以很轻松地分辨出这四张图片都是猫,即使它们外形长相完全不同,且体态各异,即使它只露出了一截尾巴,但我们仍然可以分辨的出来。<br>
+但这对电脑来说却十分困难,因为电脑并没有像我们人类大脑这样复杂的系统。
+<br><img src="/media/ai/AI_n6.png" width="350"/><br>
+那么,到底电脑是如何识别图片的呢?我们来看下一节内容。<br>
+
+---
+##  B.	神经网路与深度学习
+电脑想要正确分类图片,就需要像我们人类一样去学习,知道图片中大量的资讯。目前,最有可能让电脑实现“看”的能力的技术叫做深度学习(Deep Learning,简称DL),它是一种让电脑从图片中学习的方法。学习的过程称为训练,识别的过程称为推理(测试)。
+<br><img src="/media/ai/AI_n7.png" width="350"/><br>
+电脑要识别图片,前提便是需要大量的图片数据作为输入,传入电脑以供其学习。<br>
+我们以识别猫为例,前期需要先准备大量的各种品类的猫,并且打上标签,告诉电脑:这些是猫,也就是这些图片的分类,然后电脑将这些数据输入网路,执行训练,通过不断地迭代进行学习,达到正确认识这些猫的目的。<br>
+然后,我们输入电脑一张新的猫的图片,进行测试,电脑执行测试演算法,便可给出输入图片的正确分类。<br>
+这个过程就是电脑“看”事物(学习),并给出答案(识别)的过程。<br>
+###### 我们再来看一下学术的解释:
+深度学习就是一种机器学习框架,通过模仿人类的神经元系统,为电脑提供自主学习能力。因此,电脑可以自动识别与发掘图像数据的特征,准确识别图片中的内容,而无需根据指令或手动编码来实现(但它需要大量的数据),并大大提高了计算精度及识别准确率。<br>
+而模仿人类神经元系统的方法,在人工智能领域被称为神经网路(Neural Networks)。<br>
+下面,我们以图像识别的入门级应用:MNIST手写数字识别为例,来认识神经网路与深度学习的原理。其中,MNIST是一个手写数字的图片数据集。<br>
+
+---
+## C.	MNIST手写数字识别
+手写识别是常见的图像识别任务。电脑通过手写体图片来识别出图片中的字,与印刷字体不同的是,不同人的手写体风格迥异,大小不一, 造成了电脑对手写识别任务的一些困难。 <br>
+在研究过程中,数字手写体识别由于其有限的类别(0~9共10个数字)成为了相对简单的手写识别任务。所以,我们从简单的手写数字识别入手,来认识实现图像识别的演算法。<br>
+##### 1.	人类学习和认识数字的过程
+前面已经提到,电脑需要像人一样思考学习,才能识别出图像,我们不妨反推一下,想一想我们小时候是怎样学习数字的,大家总结回想一下,我们学习数字的思维过程。为什么我们可以看到各式各样形状的数字,依旧可以知道它们分别是多少呢?
+<br><img src="/media/ai/AI_p1.png" width="350"/><br>
+这个过程也就是电脑要模仿的,我们把这个学习步骤写出来。
+<br><img src="/media/ai/AI_p2.png" width="350"/><br>
+这个就是人类学习和认知的过程,也就是机器要模仿的,现在我们将人的学习方式类比到电脑中,就会知道电脑学习并识别数字的过程了。
+##### 2.	电脑学习并认识数字的过程
+###### 1)	图像在电脑中的样子
+我们向电脑输入正确的带有标签的图像数据,电脑看到的并不是像我们人类看到的那样,如下图左边的图片,而是下图右边数字矩阵的样子。电脑中处理图像,处理的是图像中每一个像素(像素是电脑萤幕上所能显示的最小单位,是用来表示图像的单位)。
+<br><img src="/media/ai/AI_p3.png" width="350"/><br>
+上一节我们提到了,深度学习需要大量的数据作为输入,在手写数字识别系统中,数据来自于MNIST数据集,它包含60000个训练集和10000测试数据集。分为图片和标签,图片是28*28的像素矩阵,标签为0~9共10个数字。
+###### 2)	模型训练——神经网路
+有了数据集,下一步,便是将数据输入到深度学习网路中,也就是神经网路中(这里采用的是LeNet-5卷积神经网路模型,卷积神经网路是深度学习神经网路中最常见的一种),进行自动的特征提取及学习,这个过程就是前面提到过的训练过程。<br>
+我们知道,人类大脑的神经网路是由神经元和突触组成,它们协同工作,完成对外界资讯的处理与传递。
+<br><img src="/media/ai/AI_p4.png" width="350"/><img src="/media/ai/AI_p5.png" width="350"/><br>
+那么,人脑的神经网路对比到深度学习中,就是如下图所示的网路。
+<br><img src="/media/ai/AI_p6.png" width="350"/><br>
+大量的手写数字图像就是输入数据,作为第一层:输入层(一般情况下,输入层不在网路结构中体现,而在后面训练开始时给出),因为每张图像的像素是28x28,所以每张图像一共有784个像素,电脑中的索引一般从0开始,所以输入x即为x0-x783。 <br>
+中间部分称为隐藏层,在LeNet-5网路中,主要采用的是:卷积层Convolutional Layer(启动层为ReLu Layer)、池化层Pooling Layer以及全连接层Fully Connected Layer。<br>
+全连接层中加入启动函数:Softmax,这是一个回归模型,用于分类过程,可解决多分类问题。这里的手写数字识别就是一个多分类问题,0-9共10类,所以最后的输出层y的结果为y0-y9。
+<br><img src="/media/ai/AI_p7.png" width="350"/><br>
+并且Softmax也是一个概率函数,它可以给出输入图像识别为不同类别的概率,以此来让使用者判断输入图像中的数字更像哪一个识别结果。<br>
+这部分就是神经网路的网路结构,是深度学习演算法实现图像处理及学习的根本。
+###### 3)	人类学习过程和电脑学习过程的对比
+前面我们给出了人类学习和认识数字的过程,也就是下图左边的部分,通过上一节的学习,我们知道了电脑学习并认识数字的过程,那么总结起来,就是下图右边所示的步骤。
+<br><img src="/media/ai/AI_p8.png" width="350"/><br>
+###### 4)	手写数字识别的实现演示
+我们知道了手写数字识别的原理,那么,现在就来看看实际电脑中是如何实现图像识别的吧。
+打开网址:https://ai-blockly.cocorobo.hk/ ,进入AI blockly页面。<br>
+进入后,首先选择Examples选项。
+<br><img src="/media/ai/AI_p9.png" width="350"/><br>
+然后,继续选择Tensor Flow选项,然后选择Digit Recognition选项,并选择OK。
+<br><img src="/media/ai/AI_p10.png" width="350"/><img src="/media/ai/AI_p11.png" width="350"/><br>
+然后,就会出现如下图所示的积木程式块。
+<br><img src="/media/ai/AI_p12.png" width="350"/><br>
+继续点击右下角区域中的RUN按钮,即可开始训练。
+<br><img src="/media/ai/AI_p13.png" width="350"/><br>
+训练的迭代过程中,会产生如下图所示的函数曲线图及网路结构资讯(Model Architecture),可通过观察曲线图的变化,来判断训练执行的状态及模型的训练效果。
+<br><img src="/media/ai/AI_p14.png" width="350"/><br>
+如上图所示,是演示的最终效果,左边是曲线图,第一副图是训练集(loss)和验证集(val_loss)的loss变化曲线,loss是损失函数,即模型预测出的结果与标签标注的真实值的差值。这个差值是随著训练轮数Epoch的增加而逐渐减小的。<br>
+第二幅图是训练集(acc)和验证集(val_acc)的准确率变化曲线,准确率为识别正确的图像个数除以总的图像数的比值,该值随著Epoch的增加而逐渐增大。<br>
+右侧为推理测试区,在画布中写出你要测试的数字,点击Detect,即可得到最终的识别结果。<br>
+其结果将打印显示在右上方区域的Console中。
+<br><img src="/media/ai/AI_p15.png" width="350"/><img src="/media/ai/AI_p16.png" width="350"/><br>
+手写数字识别的整个实现过程到这里就结束了。<br>
+接下来,我们来学习今天最重要的部分——物体识别。
+
+---
+## D.	物体识别与YOLO演算法
+物体识别(Object Recognition)是计算机视觉中的一个应用,目的是让电脑去分析一张图片或者一段影片中的物体,并标注出其中物体所属的类别。
+<br><img src="/media/ai/AI_q1.png" width="350"/><br>
+###### YOLO演算法介绍:
+<br><img src="/media/ai/AI_q2.png" width="350"/><br>
+YOLO是目前应用非常广泛的一种物体识别演算法。YOLO的意思是You only look once,也就是你只看一眼,就能认出这是什么物体,体现YOLO演算法识别的精度和速度。<br>
+YOLO是基于Pascal VOC2012数据集的目标检测系统。它能够检测到20种Pascal的目标类别,包括:<br>
+- 人
+- 鸟,猫,牛,狗,马,羊
+- 飞机,自行车,船,汽车,摩托车,火车
+- 瓶子,椅子,桌子,盆栽植物,沙发,电视或者显示器<br>
+YOLO演算法目前最新的已经迭代到了v4版本,各个版本的应用场景都是相同的,区别只在于识别精度及速度。这里,视频中展示的是YOLOv3的应用及识别结果,但这并不影响学习,我们这里主要讲的是入门级的YOLOv1的原理。<br>
+YOLO演算法的识别过程分为两个部分,这也基本是所有视觉领域内的深度学习演算法的实现过程。<br>
+1.  训练图像数据,迭代过程优化参数,获得最终模型;
+2.  输入新的图像数据,调用模型,实现推理(inference)过程,也称为测试过程。
+我们先来看下第一步的原理:<br>
+训练就需要有网路,YOLO的网路结构如下图所示,整个检测网路包括24个卷积层和2个全连接层。其中,卷积层用来提取图像特征,全连接层用来预测图像位置和类别概率值。
+<br><img src="/media/ai/AI_q3.png" width="350"/><br>
+第二步:推理过程:
+<br><img src="/media/ai/AI_q4.png" width="350"/><br>
+加载网路模型后,其推理的计算流程如图所示,我们可以将最终识别结果之前的步骤都看做一个函数计算,通过这个计算过程,就可以得到最后的物体识别结果了。<br>
+那么,YOLO具体是如何实现物体识别的呢?我们来深入地学习一下它的内部原理。
+<br><img src="/media/ai/AI_q5.png" width="350"/><br>
+如上图所示,YOLO演算法将输入图片划分成7x7=49个网格(即上图中左边第一副图,S=7),如果一个物体的中心落在某网格(cell)内,则相应网格负责检测该物体。<br>
+每个网格预测两个边界框(Bounding boxes),一共预测49x2=98个边界框(上图中位于上面的那副图)。可以近似理解为在输入图片上粗略的选取98个候选区,这98个候选区覆盖了图片的整个区域,进而用回归预测这98个候选框对应的边界框。<br>
+除了给出边界框,也就是图像的位置资讯外,还会给出对应的置信度(confidence)和分类结果(categories)。其中,置信度代表了所预测的 box 中含有 object 的置信度(概率)和这个 box 预测目标位置的准确度这两重资讯。<br>
+最后,网路就给出了图像的最终识别结果,如下图所示。
+<br><img src="/media/ai/AI_q6.png" width="350"/><br>
+
+---
+## E.	AI模型积木说明
+在学习了解了深度学习与物体识别的原理之后,我们开始积木程式块的学习,将理论与实践相结合,才能更好地学习并认识物体识别。
+<table style="margin-top:20px;">
+	<tr>
+		<td width="50%">积木</td>
+		<td width="20%">指令</td>
+    <td width="30%">说明</td>
+	</tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_r1.png" width="300"/></td>
+    <td width="20%">载入模型</td>
+    <td width="30%">载入人工智能模型,可以从选单中选择常用识别模型<img src="/media/ai/AI_r2.png" width="300"/></td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_r3.png" width="300"/></td>
+    <td width="20%">获取识别结果</td>
+    <td width="30%">获取当前结果,可选择数字识别的结果或者识别为某个数字的置信度<img src="/media/ai/AI_r4.png" width="300"/></td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_r5.png" width="300"/></td>
+    <td width="20%">物体识别</td>
+    <td width="30%">获取物体识别真假值,如果识别到物体会返回「真」值,否则返回「假」值</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_r6.png" width="300"/></td>
+    <td width="20%">物体识别结果的参数</td>
+    <td width="30%">获取识别到的每个物体的各项参数,包括:<img src="/media/ai/AI_r7.png" width="300"/></td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_r8.png" width="300"/></td>
+    <td width="20%">人脸识别</td>
+    <td width="30%">获取人脸识别真假值,如果识别到人脸会返回「真」值,否则返回「假」值</td>
+  </tr>
+  <tr>
+    <td width="50%"><img src="/media/ai/AI_r9.png" width="300"/></td>
+    <td width="20%">人脸识别结果的参数</td>
+    <td width="30%">获取识别到的每个人脸的各项参数,包括:<img src="/media/ai/AI_r10.png" width="300"/></td>
+  </tr>
+<tr>
+    <td width="50%"><img src="/media/ai/AI_r11.png" width="300"/></td>
+    <td width="20%">加载客制化模型</td>
+    <td width="30%">从指定路径加载用户预训练好的客制化模型:/sd/user/mymodel.kmodel
+并根据要识别的物体种类来设定客制化物体的类别名称:Object Name
+</td>
+  </tr>
+<tr>
+    <td width="50%"><img src="/media/ai/AI_r12.png" width="300"/></td>
+    <td width="20%">客制化的物体识别</td>
+    <td width="30%">获取客制化物体识别真假值,如果识别到客制化物体会返回「真」值,否则返回「假」值</td>
+  </tr>
+<tr>
+    <td width="50%"><img src="/media/ai/AI_r13.png" width="300"/></td>
+    <td width="20%">客制化物体识别结果的参数</td>
+    <td width="30%">获取识别到的每个客制化物体的各项参数,包括:<img src="/media/ai/AI_r14.png" width="300"/></td>
+  </tr>
+</table>
+
+---
+## F.	基础编程
+##### 活动一:物体检测并显示识别结果在「串口互动窗」
+<table style="margin-top:20px;">
+<tr>
+  <td colspan=2>在积木指令区点按以下指令,并依次放在积木编程区:<br>
+1.	AI模组|图像处理:【相机初始化】<br>
+2.	循环:【一直重复执行】<br>
+3.	AI模组|AI模型:【加载预设模型】
+选择:模型:「常见物体检测模型」  图像:「img_objectrecognition」<br>
+4.	变数:【设定变数】img_objectrecognition<br>
+5.	AI模组|相机:【获取相机捕捉的图像】<br>
+6.	逻辑:【逻辑判断】<br>
+7.	AI模组|模型:【识别到了任意常见物体】<br>
+8.	序列埠通讯|打印:【打印文字】
+识别到物体则显示「Object Detected」,否则「Nothing Detected」<br>
+</td>
+</tr>
+<tr >
+<td><img src="/media/ai/AI_s1.png" width="300"/></td>
+<td>注意:步骤4必须使用内建变数「img_objectrecognition」,所以首先要在步骤3使用「加载预设模型」指令,然后才进行步骤4及步骤5。</td>
+</tr>
+<tr >
+<td><img src="/media/ai/AI_s2.png" width="300"/></td>
+<td><img src="/media/ai/AI_s3.png" width="300"/></td>
+</tr>
+<tr >
+<td>测试结果:在「代码区」点按「串口互动窗」,将模组向四周扫描,并观察显示的结果如下,当检测到有物体时会显示「Object Found」,否则会显示「Nothing」</td>
+<td><img src="/media/ai/AI_s4.png" width="300"/></td>
+</tr>
+</table>
+
+##### 活动二:物体检测并显示物体名称
+<table style="margin-top:20px;">
+<tr>
+  <td colspan=2>重复活动一的程式,在步骤8「显示文字」指令修改如下:<br>
+1.	循环:【For循环】<br>
+2.	AI模组|模型:【识别到了任意常见物体】<br>
+3.	序列埠通讯:【打印】<br>
+4.	AI模组|模型:【获取物体参数】选择「物体名称」<br>
+</td>
+</tr>
+<tr >
+<td colspan=2><img src="/media/ai/AI_s5.png" width="300"/></td>
+</tr>
+<tr >
+<td><img src="/media/ai/AI_s6.png" width="300"/></td>
+<td><img src="/media/ai/AI_s7.png" width="300"/></td>
+</tr>
+<tr >
+<td>测试结果:点按「串口互动窗」,将模组向四周扫描,并观察显示的结果如下,当检测到有物体时会显示「物体名称」,否则会显示「Nothing」</td>
+<td><img src="/media/ai/AI_s8.png" width="300"/></td>
+</tr>
+</table>
+思考问题:活动二的程式运用「物体检测模型」,判断摄影镜头拍摄到的图像,并输出物体名称,此名称是如何决定?「物体检测模型」是否能够判断所有物体,输出正确名称?
+<br><img src="/media/ai/AI_s9.png" width="300"/>
+
+---
+## G.	专题学习
+硬体设备:AI推理模组、萤幕模组、摄像头模组<br>
+任务目标:利用摄影镜头将影像显示在萤幕模组上,载入物体识别模型,将识别到的物体在萤幕上标示出来。<br>
+基本流程/步骤:
+<br><img src="/media/ai/AI_t1.png" width="350"/><br>
+
+###### 第一步:模组初始化
+<table style="margin-top:20px;">
+<tr >
+<td>在积木指令区点按以下指令,并依次放在积木编程区:<br>
+1.	AI模组|萤幕:【初始化】<br>
+2.	AI模组|相机:【初始化】<br>
+3.	循环:【重复执行】<br>
+</td>
+<td><img src="/media/ai/AI_t2.png" width="300"/></td>
+</tr>
+</table>
+
+###### 第二步:获取影像,载入物体识别模型,进行物体识别
+<table style="margin-top:20px;">
+<tr>
+  <td colspan=2>在【重复执行】积木指令内,放置下列积木指令:<br>
+4.	AI模组|AI模型:【加载模型】
+(模型:常见物体识别模型 图像:img_objectrecognition)<br>
+5.	变数:【赋值】(名称:img_objectrecognition)<br>
+6.	AI模组|相机:【获取影像】<br>
+7.	变数:【建立变数】(名称:img_display)<br>
+8.	AI模组|图像处理:【调整画布尺寸】<br>
+9.	AI模组|图像处理:【图像转换】<br>
+</td>
+</tr>
+<tr >
+<td colspan=2><img src="/media/ai/AI_t3.png" width="300"/></td>
+</tr>
+<tr >
+<td><img src="/media/ai/AI_t4.png" width="300"/></td>
+<td><img src="/media/ai/AI_t5.png" width="300"/></td>
+</tr>
+</table>
+
+###### 第三步:获取影像,载入物体识别模型,进行物体识别
+<table style="margin-top:20px;">
+<tr>
+  <td colspan=2>在【图像转换】积木指令之后,放置下列积木指令:<br>
+10.	逻辑:【逻辑判断】<br>
+11.	AI模组|AI模型:【物体识别】<br>
+12.	循环:【For循环】<br>
+13.	AI模组|AI模型:【物体识别】<br>
+14.	AI模组|图像处理:【萤幕文字】,并修改座标的X值及Y值,使「物体名称」显示在萤幕左上角的适宜位置<br>
+15.	文字:【建立字串使用】<br>
+16.	AI模组|模型:【获取物体参数】选择「物体名称」<br>
+17.	AI模组|图像处理:【萤幕文字】并输入「Nothing Detected.」,并修改座标的X值及Y值<br>
+
+</td>
+</tr>
+<tr >
+<td colspan=2><img src="/media/ai/AI_t6.png" width="300"/></td>
+</tr>
+<tr >
+<td colspan=2><img src="/media/ai/AI_t7.png" width="300"/></td>
+</tr>
+</table>
+
+###### 第四步:在萤幕上显示影像
+<table style="margin-top:20px;">
+<tr>
+  <td colspan=2>在步骤10【逻辑判断】积木指令之后,放置下列积木指令:<br>
+18.	AI模组|萤幕:【设定起始点坐标】、【显示画布】(名称:img_display  起始座标X:8   Y值:36)
+</td>
+</tr>
+<tr >
+<td colspan=2><img src="/media/ai/AI_t8.png" width="300"/></td>
+</tr>
+</table>
+
+###### 完整程式:
+<table style="margin-top:20px;">
+<tr>
+ <td ><img src="/media/ai/AI_t9.png" width="300"/>
+</td>
+</tr>
+<tr >
+<td><img src="/media/ai/AI_t10.png" width="200"/></td>
+</tr>
+</table>
+
+---
+## H.	专题学习进阶
+将上面专题中的第三步改为以下内容:在萤幕中显示识别到的物体位置并以检测框的形式标注出来。
+<table style="margin-top:20px;">
+<tr>
+  <td >在【图像转换】积木指令之后,放置下列积木指令:<br>
+10. 逻辑:【逻辑判断】<br>
+11. AI模组|AI模型:【物体识别】<br>
+12. 循环:【For循环】<br>
+13. AI模组|AI模型:【物体识别】<br>
+14. AI模组|萤幕:【绘制矩形】(画布:img_display  矩形:空心  颜色:白色  厚度:2)
+起始座标:X值,Y值   尺寸:宽度,高度<br>
+a.	数学运算:【int】转换整数<br>
+b.	数学运算:【四则运算】,物体识别数值 / 1.42<br>
+c.	AI模组|AI模型:【物体识别属性】<br>
+18. AI模组|萤幕:【绘制实心圆形】放置在屏幕中间<br>
+</td>
+</tr>
+<tr >
+<td><img src="/media/ai/AI_u1.png" width="200"/></td>
+</tr>
+</table>
+
+###### 第四步:在萤幕上显示影像
+
+<table style="margin-top:20px;">
+<tr>
+  <td >在步骤10【逻辑判断】积木指令之后,放置下列积木指令:<br>
+19. AI模组|萤幕:【显示画布】(名称:img_display  起始座标X:8   Y值:36)<br>
+</td>
+</tr>
+<tr >
+<td> <img src="/media/ai/AI_u2.png" width="200"/></td>
+</tr>
+<tr >
+<td> 完整Python代码:<img src="/media/ai/AI_u3.png" width="200"/></td>
+</tr>
+<tr >
+<td> 完整程式:<img src="/media/ai/AI_u4.png" width="200"/></td>
+</tr>
+<tr >
+<td> 运行结果:<img src="/media/ai/AI_u5.png" width="200"/><img src="/media/ai/AI_u6.png" width="200"/></td>
+</tr>
+</table>

+ 1 - 0
aikit/overview.md

@@ -0,0 +1 @@
+overview.md

+ 61 - 0
changelog.md

@@ -0,0 +1,61 @@
+## 版本日志 Changelog
+- - -
+
+### v1.0.8 (20201009)
+
+- 功能相关:
+  - 修复云端存储无法使用的问题
+  - 修改导航栏学习下的aihub跳转链接为最新
+  - 修复实验室无法使用的问题
+  - 更改二代上传插件最新链接
+  - 修复个人信息云端API key不会随着项目的切换而改变的问题
+  - 新增个人信息云端项目刷新的功能
+  - 导航栏学习选项新增原理、艺术
+  - 实验室语音识别点击开始录音录音后按钮文字变成结束录音
+- 积木相关:
+  - 调整IoT模块以及AI模块扩展模块栏目的顺序
+  - 输入/输出中设置引脚积木样式,内容以及生成代码的调整
+  - 修复IoT模块扩展模块电机转动选择C或者D无法转动的问题
+  - 删掉AI模块图形处理中的矢量转像素积木,并且修改与其相关的案例
+  - 修改积木显示上的按键为按钮
+  - 新增积木块鼠标悬浮在上面会显示代码注释
+  - 新增AI模块屏幕栏目下中文汉字显示积木
+  - 新增文字栏目下的注释积木
+  - 移除AI模块音频处理与AI模块下扩展模块中扬声器功能重复的相关积木
+  - 修改AI模块语音录制生成的界面,可使用简体中文以及繁体中文
+  - 新增IoT模块屏幕栏目下绘制条形以及折线统计图的积木
+- 界面相关:
+  - 新增IoT的屏幕相关案例到样例
+  - 修复“灯”字繁体下显示不为“燈”的问题
+  - 修复IoT模块下的某些案例放置位置错误的问题
+  - 新增IoT工作坊案例到样例
+  - 新增人工智能教材程序案例到样例
+  - 新增手写数字识别案例到样例中的AI模块机器学习案例
+
+---
+
+### v1.0.7 (20200810)
+
+- 功能相关
+  - 修复环境检测中点击开始检测一直在刷新的问题
+  - 修复上传插件下载链接出错的问题
+  - 修复页面右边工具栏最后一项文字不随语言的变化而变化,点击无反应的问题
+  - 新增页面右边工具栏最后一项文字点击添加对应的积木,中间会有加载提示
+  - 页面弹窗新增右上角关闭按钮
+  - 修复页面右边工具栏云端Python模式以及JavaScript模式跳转链接错误的问题
+  - 人脸辨识物体分类器路径修改
+- 积木相关:
+  - 新增IoT模组屏幕栏目以及相关积木,将其放入IoT模组扩展模块中
+  - 将IoT模组中的基础栏目,Wi-Fi栏目,Web栏目,物联网栏目的积木进行归类
+  - 将AI模组中的人工智能下基础栏目,音频处理栏目,AI模型栏目的积木进行归类
+  - 调整IoT模组中的基础栏目积木的颜色,使其与AI模组中的人工智能下基础栏目的积木颜色相同
+  - 将二代 blockly 中ai模组屏幕栏目的初始化积木中的 lcd.init(type=1 中的 1 改为 2)
+- 界面相关:
+  - 新增右上角个人信息过长,当超过元素宽度,只显示一部分字符,后面的字符以「...」替代
+  - 修复blockly编辑代码区域数字排序区域样式问题
+  - 修改版权信息
+
+---
+
+
+如有任何疑问,请邮件联系:support@cocorobo.cc 感谢。

+ 445 - 0
colorpicker.js

@@ -0,0 +1,445 @@
+/**
+ * ColorPicker - pure JavaScript color picker without using images, external CSS or 1px divs.
+ * Copyright © 2011 David Durman, All rights reserved.
+ */
+(function(window, document, undefined) {
+
+    var type = (window.SVGAngle || document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? "SVG" : "VML"),
+        picker, slide, hueOffset = 15, svgNS = 'http://www.w3.org/2000/svg';
+
+    // This HTML snippet is inserted into the innerHTML property of the passed color picker element
+    // when the no-hassle call to ColorPicker() is used, i.e. ColorPicker(function(hex, hsv, rgb) { ... });
+    
+    var colorpickerHTMLSnippet = [
+        
+        '<div class="picker-wrapper">',
+                '<div class="picker"></div>',
+                '<div class="picker-indicator"></div>',
+        '</div>',
+        '<div class="slide-wrapper">',
+                '<div class="slide"></div>',
+                '<div class="slide-indicator"></div>',
+        '</div>'
+        
+    ].join('');
+
+    /**
+     * Return mouse position relative to the element el.
+     */
+    function mousePosition(evt) {
+        // IE:
+        if (window.event && window.event.contentOverflow !== undefined) {
+            return { x: window.event.offsetX, y: window.event.offsetY };
+        }
+        // Webkit:
+        if (evt.offsetX !== undefined && evt.offsetY !== undefined) {
+            return { x: evt.offsetX, y: evt.offsetY };
+        }
+        // Firefox:
+        var wrapper = evt.target.parentNode.parentNode;
+        return { x: evt.layerX - wrapper.offsetLeft, y: evt.layerY - wrapper.offsetTop };
+    }
+
+    /**
+     * Create SVG element.
+     */
+    function $(el, attrs, children) {
+        el = document.createElementNS(svgNS, el);
+        for (var key in attrs)
+            el.setAttribute(key, attrs[key]);
+        if (Object.prototype.toString.call(children) != '[object Array]') children = [children];
+        var i = 0, len = (children[0] && children.length) || 0;
+        for (; i < len; i++)
+            el.appendChild(children[i]);
+        return el;
+    }
+
+    /**
+     * Create slide and picker markup depending on the supported technology.
+     */
+    if (type == 'SVG') {
+
+        slide = $('svg', { xmlns: 'http://www.w3.org/2000/svg', version: '1.1', width: '100%', height: '100%' },
+                  [
+                      $('defs', {},
+                        $('linearGradient', { id: 'gradient-hsv', x1: '0%', y1: '100%', x2: '0%', y2: '0%'},
+                          [
+                              $('stop', { offset: '0%', 'stop-color': '#FF0000', 'stop-opacity': '1' }),
+                              $('stop', { offset: '13%', 'stop-color': '#FF00FF', 'stop-opacity': '1' }),
+                              $('stop', { offset: '25%', 'stop-color': '#8000FF', 'stop-opacity': '1' }),
+                              $('stop', { offset: '38%', 'stop-color': '#0040FF', 'stop-opacity': '1' }),
+                              $('stop', { offset: '50%', 'stop-color': '#00FFFF', 'stop-opacity': '1' }),
+                              $('stop', { offset: '63%', 'stop-color': '#00FF40', 'stop-opacity': '1' }),
+                              $('stop', { offset: '75%', 'stop-color': '#0BED00', 'stop-opacity': '1' }),
+                              $('stop', { offset: '88%', 'stop-color': '#FFFF00', 'stop-opacity': '1' }),
+                              $('stop', { offset: '100%', 'stop-color': '#FF0000', 'stop-opacity': '1' })
+                          ]
+                         )
+                       ),
+                      $('rect', { x: '0', y: '0', width: '100%', height: '100%', fill: 'url(#gradient-hsv)'})
+                  ]
+                 );
+
+        picker = $('svg', { xmlns: 'http://www.w3.org/2000/svg', version: '1.1', width: '100%', height: '100%' },
+                   [
+                       $('defs', {},
+                         [
+                             $('linearGradient', { id: 'gradient-black', x1: '0%', y1: '100%', x2: '0%', y2: '0%'},
+                               [
+                                   $('stop', { offset: '0%', 'stop-color': '#000000', 'stop-opacity': '1' }),
+                                   $('stop', { offset: '100%', 'stop-color': '#CC9A81', 'stop-opacity': '0' })
+                               ]
+                              ),
+                             $('linearGradient', { id: 'gradient-white', x1: '0%', y1: '100%', x2: '100%', y2: '100%'},
+                               [
+                                   $('stop', { offset: '0%', 'stop-color': '#FFFFFF', 'stop-opacity': '1' }),
+                                   $('stop', { offset: '100%', 'stop-color': '#CC9A81', 'stop-opacity': '0' })
+                               ]
+                              )
+                         ]
+                        ),
+                       $('rect', { x: '0', y: '0', width: '100%', height: '100%', fill: 'url(#gradient-white)'}),
+                       $('rect', { x: '0', y: '0', width: '100%', height: '100%', fill: 'url(#gradient-black)'})
+                   ]
+                  );
+
+    } else if (type == 'VML') {
+        slide = [
+            '<DIV style="position: relative; width: 100%; height: 100%">',
+            '<v:rect style="position: absolute; top: 0; left: 0; width: 100%; height: 100%" stroked="f" filled="t">',
+            '<v:fill type="gradient" method="none" angle="0" color="red" color2="red" colors="8519f fuchsia;.25 #8000ff;24903f #0040ff;.5 aqua;41287f #00ff40;.75 #0bed00;57671f yellow"></v:fill>',
+            '</v:rect>',
+            '</DIV>'
+        ].join('');
+
+        picker = [
+            '<DIV style="position: relative; width: 100%; height: 100%">',
+            '<v:rect style="position: absolute; left: -1px; top: -1px; width: 101%; height: 101%" stroked="f" filled="t">',
+            '<v:fill type="gradient" method="none" angle="270" color="#FFFFFF" opacity="100%" color2="#CC9A81" o:opacity2="0%"></v:fill>',
+            '</v:rect>',
+            '<v:rect style="position: absolute; left: 0px; top: 0px; width: 100%; height: 101%" stroked="f" filled="t">',
+            '<v:fill type="gradient" method="none" angle="0" color="#000000" opacity="100%" color2="#CC9A81" o:opacity2="0%"></v:fill>',
+            '</v:rect>',
+            '</DIV>'
+        ].join('');
+        
+        if (!document.namespaces['v'])
+            document.namespaces.add('v', 'urn:schemas-microsoft-com:vml', '#default#VML');
+    }
+
+    /**
+     * Convert HSV representation to RGB HEX string.
+     * Credits to http://www.raphaeljs.com
+     */
+    function hsv2rgb(hsv) {
+        var R, G, B, X, C;
+        var h = (hsv.h % 360) / 60;
+        
+        C = hsv.v * hsv.s;
+        X = C * (1 - Math.abs(h % 2 - 1));
+        R = G = B = hsv.v - C;
+
+        h = ~~h;
+        R += [C, X, 0, 0, X, C][h];
+        G += [X, C, C, X, 0, 0][h];
+        B += [0, 0, X, C, C, X][h];
+
+        var r = Math.floor(R * 255);
+        var g = Math.floor(G * 255);
+        var b = Math.floor(B * 255);
+        return { r: r, g: g, b: b, hex: "#" + (16777216 | b | (g << 8) | (r << 16)).toString(16).slice(1) };
+    }
+
+    /**
+     * Convert RGB representation to HSV.
+     * r, g, b can be either in <0,1> range or <0,255> range.
+     * Credits to http://www.raphaeljs.com
+     */
+    function rgb2hsv(rgb) {
+
+        var r = rgb.r;
+        var g = rgb.g;
+        var b = rgb.b;
+        
+        if (rgb.r > 1 || rgb.g > 1 || rgb.b > 1) {
+            r /= 255;
+            g /= 255;
+            b /= 255;
+        }
+
+        var H, S, V, C;
+        V = Math.max(r, g, b);
+        C = V - Math.min(r, g, b);
+        H = (C == 0 ? null :
+             V == r ? (g - b) / C + (g < b ? 6 : 0) :
+             V == g ? (b - r) / C + 2 :
+                      (r - g) / C + 4);
+        H = (H % 6) * 60;
+        S = C == 0 ? 0 : C / V;
+        return { h: H, s: S, v: V };
+    }
+
+    /**
+     * Return click event handler for the slider.
+     * Sets picker background color and calls ctx.callback if provided.
+     */  
+    function slideListener(ctx, slideElement, pickerElement) {
+        return function(evt) {
+            evt = evt || window.event;
+            var mouse = mousePosition(evt);
+            ctx.h = mouse.y / slideElement.offsetHeight * 360 + hueOffset;
+            var pickerColor = hsv2rgb({ h: ctx.h, s: 1, v: 1 });
+            var c = hsv2rgb({ h: ctx.h, s: ctx.s, v: ctx.v });
+            pickerElement.style.backgroundColor = pickerColor.hex;
+            ctx.callback && ctx.callback(c.hex, { h: ctx.h - hueOffset, s: ctx.s, v: ctx.v }, { r: c.r, g: c.g, b: c.b }, undefined, mouse);
+        }
+    };
+
+    /**
+     * Return click event handler for the picker.
+     * Calls ctx.callback if provided.
+     */  
+    function pickerListener(ctx, pickerElement) {
+        return function(evt) {
+            evt = evt || window.event;
+            var mouse = mousePosition(evt),
+                width = pickerElement.offsetWidth,            
+                height = pickerElement.offsetHeight;
+
+            ctx.s = mouse.x / width;
+            ctx.v = (height - mouse.y) / height;
+            var c = hsv2rgb(ctx);
+            ctx.callback && ctx.callback(c.hex, { h: ctx.h - hueOffset, s: ctx.s, v: ctx.v }, { r: c.r, g: c.g, b: c.b }, mouse);
+        }
+    };
+
+    var uniqID = 0;
+    
+    /**
+     * ColorPicker.
+     * @param {DOMElement} slideElement HSV slide element.
+     * @param {DOMElement} pickerElement HSV picker element.
+     * @param {Function} callback Called whenever the color is changed provided chosen color in RGB HEX format as the only argument.
+     */
+    function ColorPicker(slideElement, pickerElement, callback) {
+        
+        if (!(this instanceof ColorPicker)) return new ColorPicker(slideElement, pickerElement, callback);
+
+        this.h = 0;
+        this.s = 1;
+        this.v = 1;
+
+        if (!callback) {
+            // call of the form ColorPicker(element, funtion(hex, hsv, rgb) { ... }), i.e. the no-hassle call.
+
+            var element = slideElement;
+            element.innerHTML = colorpickerHTMLSnippet;
+            
+            this.slideElement = element.getElementsByClassName('slide')[0];
+            this.pickerElement = element.getElementsByClassName('picker')[0];
+            var slideIndicator = element.getElementsByClassName('slide-indicator')[0];
+            var pickerIndicator = element.getElementsByClassName('picker-indicator')[0];
+            
+            ColorPicker.fixIndicators(slideIndicator, pickerIndicator);
+
+            this.callback = function(hex, hsv, rgb, pickerCoordinate, slideCoordinate) {
+
+                ColorPicker.positionIndicators(slideIndicator, pickerIndicator, slideCoordinate, pickerCoordinate);
+                
+                pickerElement(hex, hsv, rgb);
+            };
+            
+        } else {
+        
+            this.callback = callback;
+            this.pickerElement = pickerElement;
+            this.slideElement = slideElement;
+        }
+
+        if (type == 'SVG') {
+
+            // Generate uniq IDs for linearGradients so that we don't have the same IDs within one document.
+            // Then reference those gradients in the associated rectangles.
+
+            var slideClone = slide.cloneNode(true);
+            var pickerClone = picker.cloneNode(true);
+            
+            var hsvGradient = slideClone.getElementsByTagName('linearGradient')[0];
+            
+            var hsvRect = slideClone.getElementsByTagName('rect')[0];
+            
+            hsvGradient.id = 'gradient-hsv-' + uniqID;
+            hsvRect.setAttribute('fill', 'url(#' + hsvGradient.id + ')');
+
+            var blackAndWhiteGradients = [pickerClone.getElementsByTagName('linearGradient')[0], pickerClone.getElementsByTagName('linearGradient')[1]];
+            var whiteAndBlackRects = pickerClone.getElementsByTagName('rect');
+            
+            blackAndWhiteGradients[0].id = 'gradient-black-' + uniqID;
+            blackAndWhiteGradients[1].id = 'gradient-white-' + uniqID;
+            
+            whiteAndBlackRects[0].setAttribute('fill', 'url(#' + blackAndWhiteGradients[1].id + ')');
+            whiteAndBlackRects[1].setAttribute('fill', 'url(#' + blackAndWhiteGradients[0].id + ')');
+
+            this.slideElement.appendChild(slideClone);
+            this.pickerElement.appendChild(pickerClone);
+
+            uniqID++;
+            
+        } else {
+            
+            this.slideElement.innerHTML = slide;
+            this.pickerElement.innerHTML = picker;            
+        }
+
+        addEventListener(this.slideElement, 'click', slideListener(this, this.slideElement, this.pickerElement));
+        addEventListener(this.pickerElement, 'click', pickerListener(this, this.pickerElement));
+
+        enableDragging(this, this.slideElement, slideListener(this, this.slideElement, this.pickerElement));
+        enableDragging(this, this.pickerElement, pickerListener(this, this.pickerElement));
+    };
+
+    function addEventListener(element, event, listener) {
+
+        if (element.attachEvent) {
+            
+            element.attachEvent('on' + event, listener);
+            
+        } else if (element.addEventListener) {
+
+            element.addEventListener(event, listener, false);
+        }
+    }
+
+   /**
+    * Enable drag&drop color selection.
+    * @param {object} ctx ColorPicker instance.
+    * @param {DOMElement} element HSV slide element or HSV picker element.
+    * @param {Function} listener Function that will be called whenever mouse is dragged over the element with event object as argument.
+    */
+    function enableDragging(ctx, element, listener) {
+        
+        var mousedown = false;
+
+        addEventListener(element, 'mousedown', function(evt) { mousedown = true;  });
+        addEventListener(element, 'mouseup',   function(evt) { mousedown = false;  });
+        addEventListener(element, 'mouseout',  function(evt) { mousedown = false;  });
+        addEventListener(element, 'mousemove', function(evt) {
+
+            if (mousedown) {
+                
+                listener(evt);
+            }
+        });
+    }
+
+
+    ColorPicker.hsv2rgb = function(hsv) {
+        var rgbHex = hsv2rgb(hsv);
+        delete rgbHex.hex;
+        return rgbHex;
+    };
+    
+    ColorPicker.hsv2hex = function(hsv) {
+        return hsv2rgb(hsv).hex;
+    };
+    
+    ColorPicker.rgb2hsv = rgb2hsv;
+
+    ColorPicker.rgb2hex = function(rgb) {
+        return hsv2rgb(rgb2hsv(rgb)).hex;
+    };
+    
+    ColorPicker.hex2hsv = function(hex) {
+        return rgb2hsv(ColorPicker.hex2rgb(hex));
+    };
+    
+    ColorPicker.hex2rgb = function(hex) {
+        return { r: parseInt(hex.substr(1, 2), 16), g: parseInt(hex.substr(3, 2), 16), b: parseInt(hex.substr(5, 2), 16) };
+    };
+
+    /**
+     * Sets color of the picker in hsv/rgb/hex format.
+     * @param {object} ctx ColorPicker instance.
+     * @param {object} hsv Object of the form: { h: <hue>, s: <saturation>, v: <value> }.
+     * @param {object} rgb Object of the form: { r: <red>, g: <green>, b: <blue> }.
+     * @param {string} hex String of the form: #RRGGBB.
+     */
+     function setColor(ctx, hsv, rgb, hex) {
+         ctx.h = hsv.h % 360;
+         ctx.s = hsv.s;
+         ctx.v = hsv.v;
+         
+         var c = hsv2rgb(ctx);
+         
+         var mouseSlide = {
+             y: (ctx.h * ctx.slideElement.offsetHeight) / 360,
+             x: 0    // not important
+         };
+         
+         var pickerHeight = ctx.pickerElement.offsetHeight;
+         
+         var mousePicker = {
+             x: ctx.s * ctx.pickerElement.offsetWidth,
+             y: pickerHeight - ctx.v * pickerHeight
+         };
+         
+         ctx.pickerElement.style.backgroundColor = hsv2rgb({ h: ctx.h, s: 1, v: 1 }).hex;
+         ctx.callback && ctx.callback(hex || c.hex, { h: ctx.h, s: ctx.s, v: ctx.v }, rgb || { r: c.r, g: c.g, b: c.b }, mousePicker, mouseSlide);
+         
+         return ctx;
+    };
+
+    /**
+     * Sets color of the picker in hsv format.
+     * @param {object} hsv Object of the form: { h: <hue>, s: <saturation>, v: <value> }.
+     */
+    ColorPicker.prototype.setHsv = function(hsv) {
+        return setColor(this, hsv);
+    };
+    
+    /**
+     * Sets color of the picker in rgb format.
+     * @param {object} rgb Object of the form: { r: <red>, g: <green>, b: <blue> }.
+     */
+    ColorPicker.prototype.setRgb = function(rgb) {
+        return setColor(this, rgb2hsv(rgb), rgb);
+    };
+
+    /**
+     * Sets color of the picker in hex format.
+     * @param {string} hex Hex color format #RRGGBB.
+     */
+    ColorPicker.prototype.setHex = function(hex) {
+        return setColor(this, ColorPicker.hex2hsv(hex), undefined, hex);
+    };
+
+    /**
+     * Helper to position indicators.
+     * @param {HTMLElement} slideIndicator DOM element representing the indicator of the slide area.
+     * @param {HTMLElement} pickerIndicator DOM element representing the indicator of the picker area.
+     * @param {object} mouseSlide Coordinates of the mouse cursor in the slide area.
+     * @param {object} mousePicker Coordinates of the mouse cursor in the picker area.
+     */
+    ColorPicker.positionIndicators = function(slideIndicator, pickerIndicator, mouseSlide, mousePicker) {
+        
+        if (mouseSlide) {
+            slideIndicator.style.top = (mouseSlide.y - slideIndicator.offsetHeight/2) + 'px';
+        }
+        if (mousePicker) {
+            pickerIndicator.style.top = (mousePicker.y - pickerIndicator.offsetHeight/2) + 'px';
+            pickerIndicator.style.left = (mousePicker.x - pickerIndicator.offsetWidth/2) + 'px';
+        } 
+    };
+
+    /**
+     * Helper to fix indicators - this is recommended (and needed) for dragable color selection (see enabledDragging()).
+     */
+    ColorPicker.fixIndicators = function(slideIndicator, pickerIndicator) {
+
+        pickerIndicator.style.pointerEvents = 'none';
+        slideIndicator.style.pointerEvents = 'none';
+    };
+
+    window.ColorPicker = ColorPicker;
+
+})(window, window.document);

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 7 - 0
docsify-themeable


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
docsify.min.js


+ 69 - 0
extension/EX_01.md

@@ -0,0 +1,69 @@
+# <b>拓展转接模组 基础篇</b>
+
+## A. 认识拓展转接模组
+
+拓展转接模组上嵌有多组接口,包含AI 和 IoT两大类,分别配合 AI 模组和 IoT 模组使用,用于外接多种第三方感应器或电子元器件,如红外线感应器和超声波感应器等,通过「输入/输出」类积木指令编程控制。
+<table style="margin-top:20px;">
+ <tr>
+   <td width="50%"><img src="/media/ai/AI_tuozhan1.png" width="350"/></td>
+   <td width="50%"><img src="/media/ai/AI_tuozhan2.png" width="350"/></td>
+ </tr>
+ <tr>
+   <td>正面</td>
+   <td>反面</td>
+ </tr>
+</table>
+
+1. 每组接口由正极(+)、负极(-)、讯号接口(Digital和Analog均适用)组成;
+2. 每个讯号接口均对应一个数字编号;
+3. 可使用外接供电(锂电池、电池盒等),由切换开关控制,USB侧为模组供电, EXT侧为外接电源供电;
+4. 白色接口供连外接电源使用。
+
+
+## B.	使用拓展转接模组(配合AI模组)
+效果展示:使用按钮开关控制发光二极管亮和灭。<br><br>
+<img src="/media/EX/001.jpg" width="400"/><br>
+效果分析:获取按钮开关的状态(输入)以控制二极管的亮和灭(输出),按钮的按下与松开两种状态、二极管的亮和灭两种状态,分别与高电平、低电平或者0和1对应。
+
+所需材料:AI模组、拓展转接模组、杜邦线(母-母)、二极管、按钮开关。<br>
+<img src="/media/EX/002.jpg" width="400"/><br>
+
+### 步骤一:连接
+连接方式如下:<br>
+<img src="/media/EX/003.png" width="600"/><br>
+连接效果:<br>
+<img src="/media/EX/004.jpg" width="500"/><br>
+
+### 步骤二:编写程式并上传
+
+1. 所需拓展转接模组「输入/输出」类积木指令:
+
+ <img src="/media/EX/005.png" width="400"/><br>
+
+2. 编写程式示范:<br>
+
+<table style="margin-top:20px;">
+	<tr>
+		<td width="50%">在积木指令区点按以下指令,并依次放在积木编程区:<br>
+1.循环:「重复执行」<br>
+2.逻辑:「如果...执行」、「判断」<br>
+3.输入/输出:选择AI模组获取引脚、设定引脚<br>
+4.引脚编号务必与转接模组上实际连接的接口编号保持一致<br>
+5.数学运算:<img src="/media/EX/007.jpg"/>
+
+</td>
+		<td width="50%"><img src="/media/EX/006.jpg" width="350"/>
+	</tr>
+	<tr>
+		<td colspan=2>运行结果:
+当按下按钮时,二极管发光,当松开按钮时,二极管熄灭。
+</td>
+	</tr>
+</table>
+
+3. 补充<br>
+上面第2步「逻辑」积木指令的实现方式如下:<br>
+1)选择:<br><img src="/media/EX/008.jpg" /><br>
+2)点击左上角图标,显示如下:<br><img src="/media/EX/009.jpg" width="300"/><br>
+3)拖拽「否则」积木指令到右侧,放到「如果」下面,即可显示出「否则」部分:<br>
+<img src="/media/EX/010.jpg" width="300"/><br>

+ 131 - 0
extension/EX_02.md

@@ -0,0 +1,131 @@
+# <b>拓展转接模组 应用篇</b>
+
+## A. 感应器
+<b>感应器与拓展转接模组的连接方法:</b><br>
+<img src="/media/EX/011.png" width="500"/><br>
+
+⚠️注意:
+1. 若感应器同时有DO和AO接口,则说明此感应器支持数位讯号和类比讯号输入/输出;<br>
+若感应器仅有DO接口,则说明此感应器仅支持数位讯号输入/输出;<br>
+若感应器仅有AO接口,则说明此感应器仅支持类比讯号输入/输出。<br>
+2. 拓展转接模组上接口0、1为预留接口,供其他功能使用,建议连接感应器时,选择其他接口。
+
+<b>拓展转接模组可以配合多种感应器的使用,比如:</b>
+
+- ### 光照感应器
+探测光源処是一个光敏电阻,光敏电阻是用硫化镉或硒化镉等半导体材料制成的特殊电阻器,其工作原理是基于内光电效应。随著光照强度的升高,电阻值迅速降低,由于光照产生的载流子都参与导电,在外加电场的作用下作漂移运动,电子奔向电源的正极,空穴奔向电源的负极,从而使光敏电阻器的组织迅速下降。其在无光照时,几乎呈高阻状态,暗电阻很大。
+该光照感应器对环境光线最敏感,一般用来检测周围环境的光线的亮度,触发单片机或继电器模组等。
+<img src="/media/EX/012.jpg" width="500"/><br>
+<br>
+使用「序列埠互动窗」打印光照感应器「数码讯号数值」:<br><br>
+① 连接方法:<br>
+<img src="/media/EX/015.png" width="500"/><br>
+<img src="/media/EX/016.png" width="500"/><br>
+② 程式:<br>
+<img src="/media/EX/017.png" width="500"/><br>
+③ 效果:未遮挡感应器时显示“0”;遮挡感应器时显示“1”。<br>
+<img src="/media/EX/018.jpg" width="500"/><br>
+
+- ### 红外避障感应器
+红外避障感应器具有一对红外讯号发射与接收二极管,发射管发射一定频率的红外讯号,接收管接受这种频率的红外讯号,儅传感器的检测方向遇到障碍物(反射面)时,红外讯号反射回来被接收管接收,经过比较器电路处理之后,输出指示処的绿色指示灯将被点亮,同时数位端口持续输出低电平讯号。<br><br>
+<img src="/media/EX/056.jpg" width="300"/><br>
+<br>
+使用「序列埠互动窗」打印红外避障感应器「数码讯号数值」:<br><br>
+① 连接方法:<br>
+<img src="/media/EX/019.png" width="500"/><br>
+② 程式:<br>
+<img src="/media/EX/020.png" width="500"/><br>
+③ 效果:<br>
+<img src="/media/EX/019.jpg" width="500"/><br>
+
+- ### 雨滴感应器
+可用于不同天气状况的监测,并转换成数位讯号或类比讯号;使用时,感应板上没有水滴时,数位输出为高电平,开关指示灯灭,感应版越干燥,读取的模拟接口的数值越大,滴上一滴水,数位输出为低电平,开关指示灯亮,水滴越多,读取的模拟接口的数值越小。
+支持:数位讯号、类比讯号输入<br>
+参数:5.0*4.0cm<br><br>
+<img src="/media/EX/021.png" width="500"/><br><br>
+使用「序列埠互动窗」打印光照感应器「数码讯号数值」:<br><br>
+① 连接方法:<br>
+<img src="/media/EX/015.png" width="500"/><br>
+② 程式:<br>
+<img src="/media/EX/017.png" width="500"/><br>
+③ 效果:无雨时显示“1”;有雨时显示“0”。<br>
+<img src="/media/EX/022.png" width="500"/><br>
+提示:此处使用湿纸巾模拟雨滴效果。
+
+
+- ### 土壤湿度感应器
+土壤湿度感应器采用FDR频域反射原理。FDR(Frequency Domain Reflectometry)频域反射仪是一种用于测量土壤水分的仪器,它利用电磁脉冲原理、根据电磁波在介质中传播频率来测量土壤的表现介电常数,从而得到土壤相对含水量。
+将感应器插入土壤中,通过类比/数位转换电压讯号,即可检测土壤水分,土壤越干燥,输出电压越小,读取的模拟接口的数值则越大,相反,越湿润输出电压越大(数值越小),读取的模拟接口的数值则越小。<br>
+支持:数位讯号、类比讯号<br>
+注意:高电平数位输出为1,低电平数位输出为0;<br><br>
+<img src="/media/EX/023.png" width="500"/><br><br>
+使用「序列埠互动窗」打印光照感应器「数码讯号数值」:<br><br>
+① 连接方法:<br>
+<img src="/media/EX/024.png" width="500"/><br>
+② 程式:<br>
+<img src="/media/EX/025.png" width="500"/><br>
+③ 效果:无雨时显示“1”;有雨时显示“0”。<br>
+<img src="/media/EX/026.jpg" width="500"/><br>
+
+
+- ### 烟雾感应器
+当感应器所处环境中存在可燃性气体时,感应器的电导率随空气中可燃性气体浓度的增加而增大,类比讯号对应的输出电压随浓度越高电压越高。<br><br>
+<img src="/media/EX/027.png" width="500"/><br><br>
+使用「序列埠互动窗」打印烟雾感应器「数码讯号数值」:<br><br>
+① 连接方法:<br>
+<img src="/media/EX/047.png" width="500"/><br>
+② 程式:<br>
+<img src="/media/EX/048.png" width="500"/><br>
+③ 效果:<br>
+<img src="/media/EX/049.jpg" width="500"/><br>
+
+- ### 火焰感应器
+火焰是由各种燃烧生成物、中间物、高温气体、碳氢物质以及无机物质为主题的高温固体微粒构成的。火焰的热辐射具有离散光谱的气体辐射和连续光谱的固体辐射。不同燃烧物的火焰辐射强度、波长分布有所差异,但总体来说,其对应火焰温度的近红外波长域及紫外光域具有很大的辐射强度,根据这种特性可制成火焰传感器。<br>
+可监测火焰或者波长在 760nm-1100nm 范围内的光源,打火机测试火焰距离为80cm,与火焰的距离越大,测试距离越远。<br><br>
+<img src="/media/EX/028.png" width="500"/><br>
+使用「序列埠互动窗」打印火焰感应器「数码讯号数值」:<br><br>
+① 连接方法:<br>
+<img src="/media/EX/050.png" width="500"/><br>
+② 程式:<br>
+<img src="/media/EX/051.png" width="500"/><br>
+③ 效果:<br>
+<img src="/media/EX/052.jpg" width="500"/><br>
+
+- ### 震动感应器
+震动感应器的作用主要是将机械量接收下来,并转换为与之成比例的电量。它并不是直接将原始要测的机械量转变为电量,而是将原始要测的机械量作为震动感应器的输入量,然后由机械接收部分加以接收,形成另一个适合于变换的机械量,最后由机电变换部分再变换为电量。因此一个感应器的工作性能是由机械接收部分和机电变换部分的工作性能来决定的。<br>
+震动感应器用于各种震动触发作用,不震动时,震动开关呈闭合导通状态,输出端输出低电平讯号,绿色指示灯亮。<br><br>
+<img src="/media/EX/029.png" width="500"/><br>
+使用「序列埠互动窗」打印火焰感应器「数码讯号数值」:<br><br>
+① 连接方法:<br>
+<img src="/media/EX/053.png" width="500"/><br>
+② 程式:<br>
+<img src="/media/EX/054.png" width="500"/><br>
+③ 效果:晃动震动感应器时,显示“1”;保持静止时,显示“0”。 <br>
+<img src="/media/EX/055.png" width="600"/><br>
+
+## B. 伺服马达
+伺服马达(Servomotor)是对用于使用伺服机构的马达总称。指依照命令动作的意义。所谓伺服系统,就是依照指示命令动作所构成的控制装置,应用于马达的伺服控制,将感测器装在马达与控制对象机器上,侦测结果会返回伺服放大器与指令值做比较。<br><br>
+<img src="/media/EX/030.png" width="400"/><br><br>
+设定伺服马达转动<br><br>
+① 连接方法:<br>
+<img src="/media/EX/031.png" width="500"/><br>
+<img src="/media/EX/032.png" width="400"/><br>
+② 程式:<br>
+<img src="/media/EX/033.png" width="500"/><br>
+
+<table style="margin-top:20px;">
+	<tr>
+		<td width="50%">在积木指令区点按以下指令,并依次放在积木编程区:<br>
+1. 伺服马达:「初始化」<br>
+2. 循环:「一直重复执行」<br>
+3. 伺服马达:设定伺服马达转动角度<br>
+4. 引脚编号务必与转接模组上实际连接的接口编号保持一致<br>
+5. 时间:「等待」<br>
+</td>
+		<td width="50%"><img src="/media/EX/034.png" width="350"/>
+	</tr>
+	<tr>
+		<td colspan=2>运行效果:伺服马达的舵臂会先转动至90度,再返回起始位置,一直重复
+</td>
+	</tr>
+</table>

+ 46 - 0
extension/EX_03.md

@@ -0,0 +1,46 @@
+# <b>拓展转接模组 通讯篇</b>
+
+## A. Micro:bit
+Micro:bit是由英国BBC公司推出的面向青少年编程教育的微型计算机,别看它身材不大,但麻雀虽小五脏俱全,一块小板子上集成了加速度传感器,磁力传感器,两个可编程按钮,25个单色LED,蓝牙等常用感测器设备,采用Micro usb口供电,可外接电池盒,在底部还有多个环孔连接器,可用于控制外接设备。<br>
+学习使用Micro:bit请参阅:
+Micro:bit快速入门 https://archive.microbit.org/hk/guide/quick/<br>
+<img src="/media/EX/038.jpg" width="400"/><br><br>
+cocorobo的AI模组可以通过拓展版模组与Micro:bit通讯。<br>
+### 1. 拓展转接模组与Micro:bit通讯
+①  连接方法<br>
+Micro:bit与拓展转接模组的PIN口:<br>
+<img src="/media/EX/043.jpg" width="700"/><br><br>
+使用鳄鱼夹连接Micro:bit与拓展转接模组:<br>
+<img src="/media/EX/045.png" width="500"/><br><br>
+<img src="/media/EX/044.png" width="500"/><br><br>
+连接效果如下:<br>
+<img src="/media/EX/046.png" width="500"/><br><br>
+② :Micro:bit程式设计<br>
+程式设计平台:https://makecode.microbit.org/<br>
+编写下图程式接收序列埠通讯文字:<br>
+<img src="/media/EX/035.png" width="500"/><br><br>
+③:AI模组程式设计<br>
+程式设计平台:https://x.cocorobo.hk<br>
+<img src="/media/EX/039.png" width="500"/><br><br>
+④ 运行程式后查看Micro:bit的效果<br>
+<img src="/media/EX/040.gif" width="400"/><br><br>
+
+### 2. AI模组控制Micro:bit
+①  连接方法同上。<br>
+② :Micro:bit程式设计<br>
+编写下图程式接收序列埠通讯文字并做出不同指令:<br>
+<img src="/media/EX/037.png" width="500"/><br><br>
+③:AI模组程式设计<br>
+编写下图程式按下按键发送不同文字:<br>
+<img src="/media/EX/041.png" width="500"/><br><br>
+④ 运行程式后查看Micro:bit的效果<br>
+<img src="/media/EX/042.gif" width="400"/><br><br>
+
+## B. Arduino
+更多功能持续更新中。
+
+## C. mBot
+更多功能持续更新中。
+
+## D. LEGO
+更多功能持续更新中。

+ 1 - 0
extension/overview.md

@@ -0,0 +1 @@
+overview

+ 6 - 0
faq.md

@@ -0,0 +1,6 @@
+<div class="headerInProgress">
+	本部分内容仍在更新中,带来的不便,请您谅解。
+</div>
+
+# 常见问题解答 FAQ
+---

+ 1 - 0
getting-started.md

@@ -0,0 +1 @@
+to be edited.

+ 172 - 0
index.html

@@ -0,0 +1,172 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8">
+    <title>CocoBlockly X 帮助文档</title>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
+    <meta name="description" content="Description">
+    <meta name="viewport"
+        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
+    <!--<link rel="stylesheet" href="https://unpkg.com/docsify-themeable/dist/css/theme-simple.css">-->
+    <link rel="stylesheet" href="vue.css">
+    <meta name="theme-color" content="#2C4FCD">
+    <link rel="apple-touch-icon" sizes="57x57" href="http://cocorobo.hk/cocoblockly/dev/img/apple-icon-57x57.png">
+    <link rel="apple-touch-icon" sizes="60x60" href="http://cocorobo.hk/cocoblockly/dev/img/apple-icon-60x60.png">
+    <link rel="apple-touch-icon" sizes="72x72" href="http://cocorobo.hk/cocoblockly/dev/img/apple-icon-72x72.png">
+    <link rel="apple-touch-icon" sizes="76x76" href="http://cocorobo.hk/cocoblockly/dev/img/apple-icon-76x76.png">
+    <link rel="apple-touch-icon" sizes="114x114" href="http://cocorobo.hk/cocoblockly/dev/img/apple-icon-114x114.png">
+    <link rel="apple-touch-icon" sizes="120x120" href="http://cocorobo.hk/cocoblockly/dev/img/apple-icon-120x120.png">
+    <link rel="apple-touch-icon" sizes="144x144" href="http://cocorobo.hk/cocoblockly/dev/img/apple-icon-144x144.png">
+    <link rel="apple-touch-icon" sizes="152x152" href="http://cocorobo.hk/cocoblockly/dev/img/apple-icon-152x152.png">
+    <link rel="apple-touch-icon" sizes="180x180" href="http://cocorobo.hk/cocoblockly/dev/img/apple-icon-180x180.png">
+    <link rel="icon" type="image/png" sizes="192x192"
+        href="http://cocorobo.hk/cocoblockly/dev/img/android-icon-192x192.png">
+    <link rel="icon" type="image/png" sizes="32x32" href="http://cocorobo.hk/cocoblockly/dev/img/favicon-32x32.png">
+    <link rel="icon" type="image/png" sizes="96x96" href="http://cocorobo.hk/cocoblockly/dev/img/favicon-96x96.png">
+    <link rel="icon" type="image/png" sizes="16x16" href="http://cocorobo.hk/cocoblockly/dev/img/favicon-16x16.png">
+    <link rel="manifest" href="http://cocorobo.hk/cocoblockly/dev/img/manifest.json">
+    <meta name="msapplication-TileColor" content="#ffffff">
+    <meta name="msapplication-TileImage" content="http://cocorobo.hk/cocoblockly/dev/img/ms-icon-144x144.png">
+    <script type="text/javascript" src="colorpicker.js"></script>
+    <link href="./lightbox.min.css" rel="stylesheet" />
+    <style type="text/css">
+        #picker {
+            width: 200px;
+            height: 200px
+        }
+
+        #slide {
+            width: 30px;
+            height: 200px
+        }
+
+        .headerInProgress {
+            font-weight: bold;
+            background-color: rgba(247, 114, 16, .9);
+            color: white;
+            padding: 16px 18px;
+            margin-bottom: 40px;
+            border-radius: 10px;
+            border-left: 5px solid rgba(238, 91, 10, 1.0);
+        }
+    </style>
+</head>
+
+<body>
+    <nav class="body-nav">
+        <a href="#/" id="hk">繁</a>
+        <a href="#/" id="cn" class="active">简</a>
+        <!-- <a href="#/" id="aa">EN</a> -->
+    </nav>
+    <div id="app">Please wait...</div>
+    <script>
+        window.$docsify = {
+            name: 'CocoBlockly X Help',
+            // repo: '',
+            logo: '/media/help-logo.png',
+            themeColor: '#225dd5',
+            homepage: 'index.md',
+            auto2top: true,
+
+            loadSidebar: true,
+            loadSidebar: 'summary.md',
+            maxLevel: 1,
+            subMaxLevel: 1,
+
+            // Search feature
+
+            search: 'auto', // default
+            search: [
+                '/index.md',
+                '/EX_01.md',
+                '/EX_02.md',
+                '/EX_03.md',
+            ],
+
+            // complete configuration parameters
+            search: {
+                maxAge: 86400000, // Expiration time, the default one day
+                paths: 'auto', // or 'auto'
+                placeholder: '点击此处搜寻内容',
+
+                // Localization
+                placeholder: {
+                    '/': '点此处搜寻内容'
+                },
+
+                noData: '沒有搜寻到结果',
+
+                // Localization
+                noData: {
+                    '/': '沒有搜寻到结果'
+                },
+
+                // Headline depth, 1 - 6
+                depth: 6
+            },
+
+            ga: 'UA-110081781-1'
+        }
+    </script>
+    <script>
+        var hash = window.location.hash;
+        if (window.addEventListener) {
+            window.addEventListener("hashchange", myFunction, false);
+        } else if (window.attachEvent) {
+            window.attachEvent("hashchange", myFunction);
+        }
+        // window.onhashchange(function () {
+
+        // console.log(myFunction())
+        // })
+        function myFunction() {
+            hash = window.location.hash;
+            setTimeout(() => { imgload(); }, 500)
+        }
+        document.getElementById('hk').onclick = function () {
+            window.location.href = `http://x-help.cocorobo.hk/${hash}`
+        }
+        // document.getElementById('aa').onclick = function () {
+        //     window.location.href = `http://x-help.cocorobo.hk/${hash}`
+        // }
+    </script>
+    <!-- docsify -->
+    <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/docsify/4.9.4/docsify.min.js"></script>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/docsify/4.9.4/plugins/search.min.js"></script> -->
+    <script src="docsify.min.js"></script>
+    <script src="search.min.js"></script>
+    <!-- docsify-themeable -->
+    <!-- <script src="//unpkg.com/docsify-themeable"></script>-->
+    <script type="text/javascript" src="lightbox-plus-jquery.min.js"></script>
+    <script>
+        window.onload = imgload = function () {
+            let imgs = document.getElementsByTagName('img')
+            for (let i = 0; i < imgs.length - 1; i++) {
+                imgs[i].onclick = function () {
+                    let parent = imgs[i].parentNode;
+                    let num = 0
+                    for (let j = 0; j < parent.children.length; j++) {
+                        let parentStr = decodeURI(parent.children[j] && parent.children[j].src) || '';
+                        let imgSrc = imgs[i].src
+                        if ((parentStr && parentStr.slice(parentStr.lastIndexOf('/') + 1, parentStr.lastIndexOf('.'))) === imgSrc.slice(imgSrc.lastIndexOf('/') + 1, imgSrc.lastIndexOf('.'))) {
+                            num = j;
+                            console.log(num)
+                        }
+                    }
+                    if (parent.tagName !== "A") {
+                        imgs[i].style.marginRight = 5 + 'px';
+                        let A = document.createElement('a')
+                        A.href = imgs[i].src;
+                        A.setAttribute('data-lightbox', imgs[i].src);
+                        A.appendChild(imgs[i]);
+                        parent.insertBefore(A, parent.children[num]);
+                        A.addEventListener('click', function () { })
+                    }
+                }
+            }
+        }
+    </script>
+</body>
+
+</html>

+ 18 - 0
index.md

@@ -0,0 +1,18 @@
+# CocoBlockly X 在线帮助文档
+<img src="/media/blockly.png" width="650"/>
+
+## AI Kit
+
+* [认识CocoBlockly X编程环境](/aikit/AI_1.md)
+* [认识屏幕模组](/aikit/AI_2.md)
+* [认识摄影镜头模组](/aikit/AI_3.md)
+* [认识物体识别](/aikit/AI_4.md)
+
+## 拓展轉接模組
+
+* [基础篇](/extension/EX_01.md)
+* [应用篇](/extension/EX_02.md)
+* [通讯篇](/extension/EX_03.md)
+
+## [Uploader常见错误处理](/aikit/A0.md)
+<!-- ## [版本更新日志](changelog) -->

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 13 - 0
lightbox-plus-jquery.min.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
lightbox.min.css


BIN=BIN
media/EX/001.jpg


BIN=BIN
media/EX/002.jpg


BIN=BIN
media/EX/003.jpg


BIN=BIN
media/EX/003.png


BIN=BIN
media/EX/004.jpg


BIN=BIN
media/EX/005.jpg


BIN=BIN
media/EX/005.png


BIN=BIN
media/EX/006.jpg


BIN=BIN
media/EX/007.jpg


BIN=BIN
media/EX/008.jpg


BIN=BIN
media/EX/009.jpg


BIN=BIN
media/EX/010.jpg


BIN=BIN
media/EX/011.png


BIN=BIN
media/EX/012.jpg


BIN=BIN
media/EX/015.png


BIN=BIN
media/EX/016.png


BIN=BIN
media/EX/017.png


BIN=BIN
media/EX/018.jpg


BIN=BIN
media/EX/019.jpg


BIN=BIN
media/EX/019.png


BIN=BIN
media/EX/020.png


BIN=BIN
media/EX/021.png


BIN=BIN
media/EX/022.png


BIN=BIN
media/EX/023.png


BIN=BIN
media/EX/024.png


BIN=BIN
media/EX/025.png


BIN=BIN
media/EX/026.jpg


BIN=BIN
media/EX/027.png


BIN=BIN
media/EX/028.png


BIN=BIN
media/EX/029.png


BIN=BIN
media/EX/030.png


BIN=BIN
media/EX/031.png


BIN=BIN
media/EX/032.png


BIN=BIN
media/EX/033.png


BIN=BIN
media/EX/034.png


BIN=BIN
media/EX/035.png


BIN=BIN
media/EX/036.jpg


BIN=BIN
media/EX/037.png


BIN=BIN
media/EX/038.jpg


BIN=BIN
media/EX/039.png


BIN=BIN
media/EX/040.gif


BIN=BIN
media/EX/041.gif


BIN=BIN
media/EX/041.png


BIN=BIN
media/EX/042.gif


BIN=BIN
media/EX/043.jpg


BIN=BIN
media/EX/044.png


BIN=BIN
media/EX/045.png


BIN=BIN
media/EX/046.png


BIN=BIN
media/EX/047.png


BIN=BIN
media/EX/048.png


BIN=BIN
media/EX/049.jpg


BIN=BIN
media/EX/050.png


BIN=BIN
media/EX/051.png


BIN=BIN
media/EX/052.jpg


BIN=BIN
media/EX/053.png


BIN=BIN
media/EX/054.png


BIN=BIN
media/EX/055.png


BIN=BIN
media/EX/056.jpg


BIN=BIN
media/EX/w1.png


BIN=BIN
media/EX/w2.png


BIN=BIN
media/EX/w3.png


BIN=BIN
media/ai/AI_E1.png


BIN=BIN
media/ai/AI_E2.png


BIN=BIN
media/ai/AI_E3.png


BIN=BIN
media/ai/AI_I1.png


BIN=BIN
media/ai/AI_I10.png


BIN=BIN
media/ai/AI_I11.png


BIN=BIN
media/ai/AI_I12.png


BIN=BIN
media/ai/AI_I13.png


BIN=BIN
media/ai/AI_I14.png


BIN=BIN
media/ai/AI_I15.png


BIN=BIN
media/ai/AI_I17.png


BIN=BIN
media/ai/AI_I18.png


BIN=BIN
media/ai/AI_I19.png


BIN=BIN
media/ai/AI_I2.png


BIN=BIN
media/ai/AI_I20.png


BIN=BIN
media/ai/AI_I21.png.png


BIN=BIN
media/ai/AI_I3.png


Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio