Arduino程序设计教程

PPT
  • 阅读 84 次
  • 下载 0 次
  • 页数 599 页
  • 大小 46.512 MB
  • 2022-11-12 上传
  • 收藏
  • 违规举报
  • © 版权认领
下载文档50.00 元 加入VIP免费下载
此文档由【小橙橙】提供上传,收益归文档提供者,本网站只提供存储服务。若此文档侵犯了您的版权,欢迎进行违规举报版权认领
在线阅读已结束,您可下载此文档阅读剩下的599 已有0人下载 下载文档50.00 元
/ 599
  • 收藏
  • 违规举报
  • © 版权认领
下载文档50.00 元 加入VIP免费下载
文本内容

【文档说明】Arduino程序设计教程.pptx,共(599)页,46.512 MB,由小橙橙上传

转载请保留链接:https://www.ichengzhen.cn/view-2212.html

以下为本文档部分文字说明:

目录1.1Arduino简介1.2ArduinoUno简介一.什么是ArduinoArduino的产生是为了满足创意创新的需求!Arduino是一款便捷灵活、方便上手的开源电子原型平台,包含硬件(各种型号的Arduino板)和软件(ArduinoIDE)。它适用于爱好者、艺术家、设计师和

对于“互动”有兴趣的朋友们。Arduino能通过各种各样的传感器来感知环境,通过控制灯光、电动机和其他的装置来反馈、影响环境。二.为什么使用Arduino做开发用Arduino制作作品或者进行产品开发的优势是很明显的。①跨平台ArduinoIDE可以在Wi

ndows、MacintoshOSX、Linux三大主流操作系统上运行,而其他的大多数控制器只能在Windows上开发。②简单清晰的开发ArduinoIDE基于processingIDE开发。对于初学者来说,极易掌握,同时有着足够的灵活性。Arduino

语言基于wiring语言开发,是对AVRGCC库的二次封装,不需要太多的单片机基础、编程基础,简单学习后,你也可以快速的进行开发。三.Arduino的优势Arduino不仅仅是全球最流行的开源硬件,也是一个优秀的硬件开发平台,更是硬件开发的趋势。Arduino简单的开发方式使得开发者更关注创意与

实现,更快的完成自己的项目开发,大大节约了学习的成本,缩短了开发的周期。因为Arduino的种种优势,越来越多的专业硬件开发者已经或开始使用Arduino来开发他们的项目、产品;越来越多的软件开发者使用Arduino进入硬件、物联网等开发领域;大学里,自动化、软件,甚至艺术专业,也

纷纷开展了Arduino相关课程。2.Arduino的历史这个最经典的开源硬件项目,诞生于意大利的一间设计学校。Arduino的核心开发团队成员包括:MassimoBanzi,DavidCuartielles

,TomIgoe,GianlucaMartino,DavidMellis和NicholasZambetti。四.Arduino的历史据说MassimoBanzi的学生们经常抱怨找不到便宜好用的微控制器,2005年冬天,MassimoBanzi

跟朋友DavidCuartielles讨论了这个问题,DavidCuartielles是一个西班牙籍晶片工程师,当时在这所学校做访问学者。两人决定设计自己的电路板,并引入了Banzi的学生DavidMellis为电路板设计编程语言。两天以后,DavidMellis就写出了程式码。又过了三天,电路板

就完工了。这块电路板被命名为Arduino。几乎任何人,即使不懂电脑编程,也能用Arduino做出很酷的东西,比如对感测器作出回应,闪烁灯光,还能控制马达。四.Arduino的历史意大利北部一个如诗如画的小镇「Ivrea」,横跨过蓝绿色DoraBaltea河,它最著名的事迹是关

于一位受压迫的国王。公元1002年,国王Arduin成为国家的统治者,不幸的是两年后即被德国亨利二世国王给废掉了。今日,在这位无法成为新国王的出生地,cobblestone街上有家叫「diReArduino」的酒吧纪念了这位国王。MassimoBanzi经常光临这家酒吧,而他将这个电子产

品计划命名为Aruino以纪念这个地方。四.ArduinO的历史随后Banzi,Cuartielles,和Mellis把设计图放到了网上。保持设计的开放源码理念,因为版权法可以监管开源软体,却很难用在硬体上,他们决定采用CreativeCommons许可。CreativeC

ommons(CC)是为保护开放版权行为而出现的类似GPL的一种许可(license)。在CreativeCommons许可下,任何人都被允许生产电路板的复制品,还能重新设计,甚至销售原设计的复制品。你不需要付版税,甚至不用

取得Arduino团队的许可。唯一被保留的只有Arduino这个名字。它被注册成了商标。如果有人想用这个名字卖电路板,那他们可能必须付一点商标费用给Arduino的核心开发团队成员。五.Arduino的优点

1.跨平台ArduinoIDE可以在Windows、MacintoshOSX、Linux三大主流操作系统上运行,而其他的大多数控制器只能在Windows上开发。2.简单清晰的开发ArduinoIDE基于processingIDE开发。对

于初学者来说,极易掌握,同时有着足够的灵活性。Arduino语言基于wiring语言开发,是对AVRGCC库的二次封装,不需要太多的单片机基础、编程基础,简单学习后,你也可以快速的进行开发。五.Arduino的优点3.开放性Arduino的硬件原理图、电路图

、IDE软件及核心库文件都是开源的,在开源协议范围内里可以任意修改原始设计及相应代码。4.社区与第三方支持Arduino有着众多的开发者和用户,你可以找到他们提供的众多开源的示例代码、硬件设计。例如,可以在Github.com、Ard

uino.cc、Openjumper.com等网站找到Arduino第三方硬件、外设、类库等支持,更快更简单的扩展你的Arduino项目。五.Arduino的优点5.硬件开发的趋势Arduino不仅仅是全球最流行的开源硬件,也是一个优秀的硬件开发平台,更是硬件开发的趋势。Arduino简

单的开发方式使得开发者更关注创意与实现,更快的完成自己的项目开发,大大节约了学习的成本,缩短了开发的周期。六.Arduino系列控制器特色1.开放源代码的电路图设计,程序开发接口免费下载,也可依需求自己修改;2.可以采用USB接口

供电,也可以外部供电,双向选择;3.Arduino支持ISP在线烧写,可以通过USB更新程序;4.可依据官方提供的Eagel格式PCB和SCH电路图,简化Arduino模组,完成独立运作的微处理控制。可简

单地与传感器,各式各样的电子元件连接(红外线、超音波、热敏电阻、光敏电阻、伺服舵机…等);5.支持多种互动程序,如:Flash、Max/Msp、VVVV、C、Processing等;6.应用方面,利用Arduino,突破以往只能使用鼠标、键盘,CC

D等输入的装置的互动内容,可以更简单地达成单人或多人游戏互动。七.Arduino作品——首款完整机器人平台Arduino宣布向机器人领域进发,发布了名为ArduinoRobot的首款完整机器人。这款机器人尺寸为178x102mm,将两个

圆形Arduino板叠一起。上部的Arduino板名为“ControlBoard”,主要读取主板传感器的各种数据并且内置处理器进行相应的计算处理。在机器人身上装备了一些常见的传感器设备,比如数字罗盘,红外感应器,彩色液晶屏,扬声

器,地面传感器,可活动的LED指示灯等等。这款机器人还能进行各种编程,能够通过USB连接到电脑上连接。机器人通过四节可充电AA镍氢电池提供能量。WillO'Brien最近利用自己手头的老iPhone和一个Arduino(可开发电路板)自行研制了

一个通过iPhone短信发动汽车的组合,短信也能发动汽车,听起来是不是很神奇?基于Arduino的智能家居方案将你需要互相控制灯光的每个房间,换上智能开关,配对后就能通过无线在一个房间对另一个房间的灯光进行控制

和监视。简答的说,就是你只需要更换掉你卧室和厕所里的普通照明开关,就可以在卧室里看到厕所的灯是否关闭了,能通过卧室的面板来关闭厕所的灯光。用ArduinoUNO去显示图像全彩RGBLED阵列屏Arduino驱动板Colorduino

“tiltradio”倾斜收音机是以色列设计师lukaor的作品,他利用Arduino来研究交互设计中的极简主义。设计师将收音机和使用者体验等元素全都剥离,仅留下必要部分——收音机的AM/FM调幅/调频系统,设计师甚至把物理上

的调节按钮也去掉了。使用者通过将收音机左右倾斜来实现波段和频道调节,省去了传统的调频按钮。在用户体验方面,收音机倾斜的位置还反映了使用者的收听频率和习惯。ArduinoMoistureSensor土壤湿度传器自动浇花这款阿迪达斯帆布胶底运动鞋内置有Ardui

no控制板,板上连接有陀螺仪、加速度传感器、压力传感器、喇叭和蓝牙等,它判断穿戴者的活动与行走路径,时不时的用英国男人忠告式的腔调说一些鼓励的话或不耐烦的话。当你坐着不动,它会说:“超级无聊。”而当你运动跳跃

时,它会说:“我喜欢鞋带上有风的感觉”。你也可以设置鞋子的个性,这样它也会说脏话。会说话的运动鞋,还有什么不能?利用Arduino玩出来的各种各样发烧级玩具基于Arduino编程捷克学生发明智能照明灯一名

捷克学生通过Arduino编程,设计了这台能够自动寻找黑暗角落并将其照亮的机器人灯。这款灯采用了S型仿生外观设计,由底部的轮子、配重块、主体程序和头部聚光灯组成。设计者还赋予了它“生命”——当它发现黑暗或者光线不足的角落,就会停下来在原地

做出前后俯仰的动作,如同在兴奋地炫耀它的劳动成果。用Arduino在彩色显示屏上显示Google天气信息看到街边停车场的自动栏杆随轿车的进出自动升降,于是前去观察,一上一下的,蛮有意思,想想,是否可以做个原型产品娱乐下,所以我就制作了这个Ar

duino与LEGO结合下的自动栏杆。这个作品的工作过程是:当红外传感器(图中黄色圆柱状器件)检测到小车到达栏杆前方,栏杆自动升起打开,并保持打开状态一小会,小车通过栏杆处后,栏杆会放下关闭。Arduino与LEGO结合下的自动栏杆推荐网站http://www.

Arduino.cn/1.ArduinoDuemilanove这是一款基本的Arduino产品,控制器采用Atmega168或Atmega328,支持直流电源供电和USB口供电,如图所示。后续很多产品都是这款产品的基础上发展而来的。八.Arduino的种类2.ArduinoNanoArdu

inoNano在设计中去掉了直流电源接口,采用Mini-B标准的USB接口来连接电脑,除了外观变了,其他接口及功能保持不变,控制器同样采用Atmega168或Atmega328,是一款缩小版的ArduinoDuem

ilanove,如图所示。八.Arduino的种类3.Arduinomini考虑到存在一些空间要求十分严格的使用者,Arduinomini在设计中甚至去掉了USB接口和复位开关,这样能够减小Arduino的尺寸。唯一的问题是连接电脑或烧写程序时需要一个USB或RS

232转换成TTL,Arduino官方也有相应的适配座——MiniUSBAdapter。八.Arduino的种类4.ArduinoBTArduinoBT本身包含了一个BluegigaWT11蓝牙模块,支持蓝牙无线串行通信,但不支持蓝牙音频设备。若没有USB接口,连接电脑或

烧写程序可以通过蓝牙适配器与ArduinoBT连接实现无线程序下载与控制。八.Arduino的种类5.LilyPadArduino这是一款真正有艺术气质的产品,面向的主要使用者是从事服装设计之类工作的设计师,他

可以使用导电线和或普通线缝在衣服或不料上,LilyPadArduino每个引脚上的小东大到足够缝纫针可以轻松穿过,如图。如果用导电线缝纫的话,即可以起到固定作用,又可以起到传导作用。比起普通的Arduino板

,LilyPadArduino相对比较脆弱,比较容易损坏,但是他的基本功能都保留了下来,除了一点,它没有USB接口,所以LilyPadArduino连接电脑或烧写程序时需要一个USB或RS232转换成TTL的适配座。八.Arduin

o的种类6.Arduinopro和ArduinoproMINI设计ArduinoPro的目的是为了那些便利性和低成本的高级用户。为了降低成本,它省去了USB接口、直流电源接口和引脚排针,连接电脑或烧写程序时需要一个USB或RS232转换成TTL的适配座

。ArduinoPro更像是一个大号的Arduinomini,如图。需要注意的是,ArduinoPro有3.3V/8MHz和5V/16MHz两个版本,使用的时候要留意。另外ArduinoPro同样有一个Ard

uinoProMini的版本。八.Arduino的种类八.Arduino的种类7.ArduinofioArduinoFio的工作电压是3.3V,控制器的工作频率是8MHz,采用Mini-B标准的USB接口,提供一个锂聚合物电池接口,底部预留一个Xbee模块插座,Xbee模块可使

Arduino方便的应用于无线网络。八.Arduino的种类8.ArduinoUnoArduinoUno是最新的Arduino产品系列,如图所示,它与之前的Arduino板最大的区别在于它不是使用FTDIUSB-to-serial串行驱动器芯片,而是采用Atmega8U2芯片

进行USB到串行数据转换。目前ArduinoUno已成为Arduino的主推产品。八.Arduino的种类9.Arduinomega2560ArduinoMega2560的控制器采用ATMega2560,他的资源要比之前的Arduino产品丰富很多,用于满足需使用较多资源进行产

品设计与开发的用户需求,同时ArduinoMega2560也兼容之前基于ArdinoDuemilanove1.2ArduinoUno简介ArduinoUno开发板——以ATmega328MCU控制器为基础.14路数字输入/输出引脚(其中6路可用于PWM输出)、6路模

拟输入、一个16MHz晶体震荡器、一个USB接口、一个电源插座、一个ICSP接头和一个复位按钮。它采用Atmega16U2芯片进行USB到串行数据的转换。UnoPCB的最大长度和宽度分别为2.7和2.1英寸,USB连接器和电

源插座超出了以前的尺寸。4个螺丝孔让电路板能够附着在表面或外壳上。1.2ArduinoUno简介1.ATmega328具有32KB闪存(其中0.5KB被启动加载器占用)。它还具有2KBSRAM和1KBEEPROM(可以利用EEP

ROM库读取和写入)。2.ArduinoUno可通过USB连接或者外部电源供电。外部(非USB)电源可以是AC-DC适配器,也可以是电池。通过将2.1mm中心正极插头插入电路板的电源插座即可连接适配器。电池的引线可插入电源连接器的Gnd和Vi

n排针。电路板可由6~20V外部电源供电。然而,如果电源电压低于7V,那么5V引脚可能会提供低于5V的电压,电路板也许会不稳定。如果电源电压超过12V,稳压器可能会过热,从而损坏电路板。电压范围建议为7~12V。电源引脚如下:1.2ArduinoUno简介VIN.使用外部电源

时Arduino板的输入电压(与通过USB连接或其它稳压电源提供的5V电压相对)。可以通过该引脚提供电压,或者如果通过电源插座提供电压,则可通过该引脚使用它。5V.该引脚通过电路板上的稳压器输出5V电压。电路板可由DC电源插座(7-12V)、USB连接器(5V)或电路

板的VIN引脚(7-12V)供电。通过5V或3.3V引脚供电会旁路稳压器,从而损坏电路板。我们不建议如此。3V3.板载稳压器产生的3.3V电源。最大电流消耗为50mA。1.2ArduinoUno简介GND.接地引脚。IOREF.Arduino板上的该

引脚提供微控制器的工作电压参考。配置得当的盾板可以读取IOREF引脚电压,选择合适的电源或者启动输出上的电压转换器以便在5V或3.3V电压下运行。1.2ArduinoUno简介1.2ArduinoUno简介利用pinMode()、digita

lWrite()和digitalRead()功能,Uno上的14个数字引脚都可用作输入或输出。它们的工作电压为5V。每个引脚都可以提供或接受最高40mA的电流,都有1个20-50kΩ的内部上拉电阻器(默认情况下断开)。此外,某些引脚还具有特殊功能:·串口:0

(RX)和1(TX)。用于接收(RX)和发送(TX)TTL串口数据。这些引脚与ATmega8U2USB转TTL串口芯片的相应引脚相连。1.2ArduinoUno简介3.外部中断:2和3。这些引脚可以配置成在低值、上升或下降沿或者数值变化时触发中断。详情请参照

attachInterrupt()功能。4.PWM:3、5、6、9、10和11。为8位PWM输出提供analogWrite()功能。5.SPI:10(SS)、11(MOSI)、12(MISO)、13(SCK)。这些引脚支持利用SPI库进行SPI通信。1.2ArduinoUno简介5.

LED:13。有1个内置式LED连至数字引脚13。在引脚为高值时,LED打开;引脚为低值时,LED关闭。Uno有6个模拟输入,编号为A0至A5,每个模拟输入都提供10位的分辨率(即1024个不同的数值)。默认情况下,它们的电压为0~5V,虽然可以利用AREF引脚和

analogReference()功能改变其范围的上限值。此外,某些引脚还具有特殊功能:6.TWI:A4或SDA引脚和A5或SCL引脚。支持通过线库实现TWI通信。电路板上还有另外2个引脚:1.2Ar

duinoUno简介7.AREF.模拟输入的参考电压。与analogReference()一起使用。8.Reset.降低线路值以复位微控制器。通常用于为盾板添加复位按钮。目录2.1Arduino开发环境2.2Arduino语言概述2.3Ardui

no基本函数2.1Arduino开发环境2.1.1IDE安装ArduinoIDE是Arduino的开放源代码的集成开发环境,其界面友好,语法简单,并能方便地下载程序,使得Arduino的程序开发变得非常便捷。作为一款开放源代码的软件,ArduinoIDE也是由Java、

Processing、avr-gcc等开放源码的软件写成。ArduinoIDE的另一个最大特点是跨平台的兼容性,其适用于Windows、MaxOSX以及Linux。2011年11月30日,Arduino官方正式

发布了Arduino1.0版本,可以下载不同系统下的压缩包,也可以在github上下载源码重新编译自己的IDE。到目前为止,ArduinoIDE已经更新到1.8版本,安装过程如下。2.1.1IDE安装(1)从Arduin

o官网下载最新版本IDE。选择适合自己计算机系统的安装包,这里以Windows7的64位系统安装过程为例。首先运行安装程序。2.1.1IDE安装(2)安装选项,一般保持默认安装。2.1.1IDE安装(3)选择安装位置。2.1Arduino开发环境(4)安装过程。2.1

.1IDE安装(5)安装完成。2.1.1IDE安装(6)IDE的主界面。2.1.2使用IDE使用ArduinoIDE,需要将Arduino开发板通过USB线连接到计算机。这样,计算机会为Arduino开发板安装驱动程序,并分配相应的COM端口,如COM1、

COM2等。计算机和系统分配的COM端口是不一样的。在菜单栏中打开“工具”“端口”,进行端口设置,设置为计算机硬件管理中分配的端口;然后,在菜单栏打开“工具”“开发板”,选择Arduino开发板的类型,如Uno、DUE、YUN等各种上面介绍的开发板。这样计算机就可以与开发板进行

通信了。2.1.2使用IDEvoidsetup()里面的代码在导通电源时会被执行一次,而voidloop()里面的代码会不断执行。由于在一般的Arduino开发板上,第13脚上都有一个LED灯,所以定义

整形变量led=13,用于函数的控制。另外,程序中用了一些函数,pinMode()是设置引脚的输入或者输出;delay()设置延迟的时间,单位为ms;digitalWrite()是向led变量写入相关的

值,使得13脚的LED灯的电平发生变化——HIGH或者LOW。这样LED灯就会根据延迟的时间交替地亮灭。2.2Arduino语言概述2.2.1标识符标识符是用来标识源程序中某个对象的名字。这些对象可以是语句、数字类型、函数、变量

、常量和数量等。标识符长度不要超过32个字符,C语言对于大小写字符敏感,所以在编写长程序的时候要注意大小写字符的区分。2.2.2关键字C语言的关键字共有32个,根据关键字的作用,可将其分为数据类型关键字、控制语句关键字、储存类型关键字和其他关键字等4类。1.数

据类型关键字12个①char:声明字符型变量或函数。②double:声明双精度变量或函数。③enum:声明枚举类型。④float:声明浮点型变量或函数。2.2.2关键字⑤int:声明整型变量或函数。⑥long:声明

长整型变量或函数。⑦short:声明短整型变量或函数。⑧signed:声明有符号类型变量或函数。⑨struct:声明结构体变量或函数。⑩union:声明共用体(联合)数据类型。⑪unsigned:声明无符号类型变量或函数。⑫void:声明函数无返回值或无参数,声明无类型指针

。2.2.2关键字2.控制语句关键字12个①循环语句(5个):for,是一种循环语句;do,循环语句的循环体;while,循环语句的循环条件;break,跳出当前循环;continue结束当前循环,开始下一个循环。②条件语句(3个):if,条件语句

;else,条件语句否定分支(与if连用);goto,无条件跳转语句。③开关语句(3个):switch用于开关语句;case开关语句分支;default,开关语句中的“其他”分支。2.2.2关键字④语句(1个):return,子程序返回语句(可以带

参数,也可以不带参数)3.储存类型关键字4个①auto:声明自动变量,一般不使用。②extern:声明变量是在其他文件中声明(也可以看作是引用变量)。③register:声明寄存器变量④static:声明静态变量。2.2.2关键字4.其他关键字4个①const:声明只读变量。②size

of:计算机数据类型长度。③typedef:用以给数据类型取别名。④volatile:说明变量在程序执行中可被隐含地改变。2.2.3运算符运算符是告诉编译程序执行特定算术或逻辑操作的符号。C语言的运算范围很宽,把除了控制语句和输入∕输出以外几乎所

有的基本操作都作为运算符处理。运算符主要分为三大类:算术运算符、关系运算符与逻辑运算符。除此之外,还有一些用于完成特殊任务的运算符。2.2.3运算符1.赋值运算符赋值语句的作用是把某个常量、变量或表达式的值赋给另一个变量。C语言中,符号为“

=”这里并不是等于的意思,只是赋值,等于用“==”表示。注意:赋值语句左边的变量在程序的其他地方必须声明。2.2.3运算符2.算术运算符在C语言中,有两个单目和五个双目运算符,分别为:+正、-负、*乘法、/除法、%取模、+加法、-减法。3.逻辑运算符逻辑运算符是根据表达式的值来返回真值或是假

值。其实,在C语言中没有所谓的真值和假值,只是认为非0为真值,0为假值。符号功能:&&(逻辑与)||(逻辑或)、!(逻辑非)。2.2.3运算符4.关系运算符关系运算符是对两个表达式进行比较,各关系返回一个真/假值。2.2A

rduino语言概述5.自增自减运算符自增自减运算符是一类特殊的运算符,其中,自增运算符(++)和自减运算符(--)对变量的操作结果是增加1和减少1。6.复合赋值运算符2.2.3运算符7.条件运算符条件运算符(:)是C语言中唯一的一个三目运算符。它是对第一个表达式作真/假检测,然后根

据结果返回另外两个表达式中的一个,语法格式如下:<表达式1>?<表达式2>:<表达式3>8.逗号运算符在C语言中,多个表达式可以用逗号分开,其中用逗号分开的表达式的值分别结算,但整个表达式的值是最后一个表达式的值。2.2.4语言控制语句控制语句用于控制程序的流程,以实现程序的各种结构方

式。它们由特定的语句定义符组成。C语言有9种控制语句,可分为以下3类。1.条件判断语句C语言支持两种选择语句:if语句和switch语句。这些语句允许你在程序运行时并知道其状态的情况下,控制程序的执行过程。首先看一下if语句的用法:

if(condition)statement1;elsestatement2;2.2.4语言控制语句(1)if语句If语句的执行过程如下:如果条件为真,就执行if的对象statement1;否则,执行else的对象statement2。任何时候两条语句都不可能同时执行。inta,b;if(

a<b)a=0;elseb=0;2.2.4语言控制语句(2)switch语句C语言又提供了一个专门用于处理多分支结构的条件选择语句,称为switch语句,又称开关语句。使用switch语句可直接处理多个分支(当然包括两个分支),其一般形式如下。2.2.4语言控制语句switc

h(表达式){case常量表达式1;语句1;break;case常量表达式2;语句2;break;…case常量表达式n;语句n;break;…default:语句n+1;break;}2.2.4语言控制语句2.循环执行语句(1)while语句while语句实现

“当型”循环,其一般格式如下。while(termination){body;}当布尔表达式(termination)的值为true时,循环执行大括号中的语句,并且初始化部分和迭代部分是任选的。2.2.4语言控制语句(2)do-while语句do-while语句实现“直到型”循环,其一般格式如

下。do{body;}while(termination);do-while语句首先执行循环体,然后计算终止条件:若结果为true,则循环执行大括号中的语句,直到布尔表达式的结果为false。2.2.4语言控制语句(3)for语句for语句也用来实现“当型”循环,其一般格式如下。for

(initialization;termination;iteration){body;}2.2.4语言控制语句3.转向语句转向语句包括break语句、continue语句、return语句及goto语句。此类语句尽量少用,因为这不利于结构化程序设计,

滥用它会使程序流程无规律、可读性差。2.2.4语言控制语句(1)break语句break语句中断当前循环,和label一起使用,中断相关联的语句。一般格式如下。break[label];上述语句中,可选的label参数指定断点处语句

的标签。2.2.4语言控制语句(2)continue语句continue语句是跳过循环体中剩余的语句而强制执行下一次循环,其作用为结束本次循环,即跳过循环体中下面尚未执行的语句,接着进行下一次是否执行循环的判定。格式如下。While(表达式1){语句组

1if(表达式2)continue;语句组2}2.2.4语言控制语句(3)return语句return表示从被调函数返回到主调函数继续执行,返回时可附带一个返回值,由return后面的参数指定。return通常是必要的,因为函数调用的时候计算结果通常是通过返回值带出的,如

果函数执行不需要返回计算结果,也经常需要返回一个状态码来表示函数执行得顺利与否(-1和0就是最常用的状态码),主调函数可以通过返回值判断被调函数的执行情况。2.2.4语言控制语句(4)goto语句goto语句也称为无条件转移语句,其一般格式如下。goto语句标号;其中,

语句标号是按标识符规定书写的符号,放在某一语句行的前面,标号后加冒号(:)。语句标号起标识语句的作用,与goto语句配合使用。实例如下。label:i++;loop:while(x<7);2.2.5语法结构1.顺序结构顺序结构的程序设计是最简单的,只要按照解决问题的

顺序写出相应的语句就行。它的执行顺序是自上而下,依次执行。2.2.5语法结构2.选择结构按照给定的条件有选择地执行程序中的语句。(1)if单分支结构该结构的格式如下。if(表达式)语句功能:判断表达式的值,若为true(真)则执行语句;若为false(假),则不执行语句。

2.2.5语法结构①表达式可以是任意合法的C++表达式,一般为逻辑表达式或关系表达式,当表达式为赋值表达式时,可以含对变量的定义。实例如下。if(inti=3)语句//等价于inti;if(i=3)语句②若表达式的值为

数值,则0被视为假,一切非0被视为真。③当表达式的表达式为真,要执行多条语句时,应将这些语句用花括号括起来以复合语句的形式出现。2.2.5语法结构④程序是将整个if控制结构看成一条语句处理的。该语句称为if语句,也称为条件语句。⑤语句可以是另一个if语

句或其他控制语句(嵌套)2.2.5语法结构(2)if双分支结构该结构的格式如下。if(表达式)语句1else语句2功能:判断表达式的值,若为true(真)则执行语句1;若为false(假)则执行语句If-false语句。2.2.5语法结构•①

语句1和语句2可以是另一个if语句或其他控制语句(嵌套)。此时else总是与它前面最近且未配对的if配对。•②程序是将整个if-false控制结构看成一条语句处理的。else是if语句中的子句,不能作为独立

的语句单独使用。•③可以用条件运算符“:”来实现简单的双分支结构。2.2.5语法结构(3)if多分支结构该结构的格式如下。if(表达式1)语句1elseif(表达式2)语句2elseif(表达式3)语句

3[else语句n]2.2.5语法结构•①if多分支结构实际上是一种规范化的if嵌套结构。在这种结构中,if语句嵌套在else之后,即符合以下格式。•if(表达式1)语句1elseif(表达式2)语句2elseif(表达式3)语句3else…[else语句n]2.2.

5语法结构②从逻辑上看,各个表达式条件都应当是相互排斥的,任意时刻最多有一个条件得以满足,不应出现既满足这个条件又满足那个条件的情况。2.2.5语法结构(4)switch多分支结构该结构的格式如下。switch(表达式){case常量表达式1:[语句序列1]case常量表达式2:[语

句序列2]case常量表达式3:[语句序列3]case常量表达式4:[语句序列4]case常量表达式5:[语句序列5]case常量表达式6:[语句序列6]...[default:语句序列n]}2.2.5语法结构①表达式和

各个常量表达式的类型一般为整型、字符型、逻辑型和枚举型。各个常量表达式的类型要与表达式的类型相同或相容,所有常量表达式的值必须互不相同。②case子句为若干个(包括0个),default子句最多只能有一个。从语法上讲,default子句可以放在任何

一个case子句的前面,此时还是先判断各个case常量表达式的值与表达式值的匹配(相等)情况,如果所有常量表达式的值均不匹配,这才将default子句作为程序的执行入口点。2.2.5语法结构③语句序列由若干条单语句组成,这些单语句可以不写成复合语句的形式。必要时,case语句标号后的语句

序列可以省略不写。④若语句序列中含有break语句,则执行到此就立即跳出switch语句体。当所有case子句和default子句都带有break子句时,它们出现的顺序可以任意。⑤当需要针对表达式的不同取值范围进行不同处理时,使用if多分支结构比较方便,因为switch

语句只能对相等关系进行测试,而if语句却可以用关系表达式对一个较大范围内的值进行测试。2.2.5语法结构3.循环结构(1)while循环(当型循环)该结构的格式如下。while(表达式)语句①表达式就是给定的循环条件,语句构成循环体,在

循环体中一般应用使循环趋于结束的语句。②先判断表达式,后执行语句。当一开始表达式的值就为false时,程序1次也不循环。③While语句一般用于不知道具体循环次数的情况。2.2.5语法结构(2)do-while循环(直到型循环)该结构的格式如下。do语句w

hlie(表达式);①先执行语句,后判断表达式。程序至少要循环1次。②do-while与while循环的不同之处在于:do-while循环的循环体在前,循环条件在后,因此do-while循环时在任何情况下都至少被执行一次;而while循环的循环

条件在前,循环体在后,当循环条件一开始就不成立时,循环体一次也不执行。这一点正是在构造循环结构时决定使用do-while语句还是while语句的重要依据。2.2.5语法结构(3)for循环(次数循环)该结构的格式如下。for([表达式1];[表

达式2];[表达式3])语句①表达式1为for循环的初始化部分,一般用来设置循环控制变量的初始值,当表达式为一赋值表达式时,可包含对变量的定义;表达式2为for循环的条件部分,是用来判定循环是否继续进

行的依据;表达式3为for循环的增量部分,一般用来修改循环控制变量的值。②省略表达式1时应在for语句之前给循环变量赋初值;省略表达式2时可认为循环的条件始终为真。2.2.5语法结构4.跳转语句(1)break语句(跳出语句)该语句的格式如下。break;跳转语句用在sw

itch结构中,break语句使执行流程跳出所在switch语句。用在循环结构中,break语句使执行流程无条件地跳出本层循环体。2.2.5语法结构①break语句经常用于使执行流程跳出死循环。②若break语句位于多重循环的内层循环体中,则只能跳出内层循环(本层循环),而不能跳出其他外

层循环。2.2.5语法结构(2)continue语句(继续语句)该语句的格式如下。continue;用于在循环结构中,结束本次循环,即跳过循环体中尚未执行的语句,接着进行下一次循环判断。2.2.5语法

结构(3)goto语句(转向语句)该语句有两种格式,具体如下。•①格式一•goto语句标号;•[语句序列]•语句标号:语句2.2.5语法结构②格式二语句标号:语句[语句序列]goto语句标号;goto语句强制中止执行goto语句之后的语

句,无条件地跳转到语句标号对应的语句继续执行2.3Arduino基本函数2.3.1I/O操作函数1.pinMode(pin,mode)描述:将制定的针脚配置成输出或输入。语法:pinMode(pin,mode)。参数:pin,要设置模式的针脚;mode,INPUT或OUTPU

T。2.3.1I/O操作函数2.digitalWrite(pin,value)语法:digitaiWrite(pin,value)。参数:pin,针脚编号(如1,5,10,A0,A3);value,HIGH或LOW。注意:模拟针脚也可以当作数字引脚使用。2.3.1I/O操

作函数3.intdigitalRead(pin)描述:读取指定针脚的值,HIGH或LOW。语法:digitalRead(pin)。参数:pin,要读取的针脚号(int)。返回:HIGH或LOW。注意:如果脚悬空,digitalRead()会返回HIGH

或LOW(随机变化),模拟输入脚能当作数字脚使用。2.3.2模拟I/O操作函数1.analogReference(type)描述:设定用于模拟输入的基准电压(输入范围的最大值)。type可以取如下值。①DEFAULT:默

认值5V(Arduino板为5V)或3V(Arduino板为3.3V)为基准电压。②INTERNAL:在Atmega168和Atmega328上以1.1V为基准电压,在Atmega8上以2.56V为基准电压(A

rduinoMega无此选项)。2.3.2模拟I/O操作函数③INTERAL1V1:1.1V为基准电压(此选项劲针对ArduinoMega)。④INTERNAL2V56:2.56V为基准电压(此选项仅针对ArduinoMega)。⑤EXTERNAL:以AREF引脚(0~5V)的电压作为基

准电压。注意事项:改变基准电压后,之前从analogRead()读取的数据可能不准确。2.3.2模拟I/O操作函数2.analongRead()描述:从指定的模拟引脚读取数值。Arduino板包含一个6通道(Mini和Na有8个通道

,Mega有16个通道)、10位模拟/数字转换器。这标识它将0~5V的输入电压映像到0~1023的整数值,即每个读数对应电压值为5V/1024,每单位0.0049V(4.6mV)。输入范围和精度可以通过analogReference()改变,其大约需要100µ

s(0.0001s)来读取模拟输入,所以最大的阅读速度是每秒1000次。2.3.2模拟I/O操作函数语法:analogRead的整数值。数值的读取:从输入引脚(大部分板子从0~5,Mini和Nano从

0~7,Mega从0~15)读取数值。返回:从0~1023的整数值。注意事项:如果模拟输入引脚没有连入电路,由analogRead()返回的值将根据很多项因素(例如其他模拟输入引脚,手靠近板子等)产生波动。2.3.2模拟I/O

操作函数3.analogWrite()描述:从一个针脚输出模拟值(脉冲宽度调整,PulseWidthModulation,PWM),让LED以不同的亮度点亮或驱动电机以不同速度旋转。analogWrite()输出结束后,该针脚将

产生一个稳定的特定占空比的PWM。PWM输出持续到下次调用analogWrite(),或在同一针脚调用digitalRead()或digitalWrite()。语法:analogWrite(pin,va

lue)。参数:pin,用于输入的针脚;value,占空比,取值范围为0(完美关闭)~255(完美打开)。2.3.3高级I/O1.tone()描述:在一个针脚上产生一个特定频率的方波(50%占空比)。持续时间可以设定,波形会一直产生直到调用noT

one()函数。该针脚可以连接压电峰鸣器或其他喇叭播放声音。注意:如果要在多个针脚是产生不同的音调,则要在对下一个针脚使用tone()函数前,先使用noTone()函数。语法:tone(pin,frequency)或tone(pi,frequency,duration)。2.3.3高级I/

O2.noTone()语法:noTone(pin)参数:pin,所要停止产生声音的引脚。2.3.3高级I/O3.ShiftOut()描述:将数据的一个字节一位一位地移出。从最高有效位(最左边)或最低有效位(最右边)开始,依次向数据脚(DataPin)写入每一位,之后时钟脚被拉高或拉低,指示之前的数

据有效。注意:如果所连接的设备时钟类型为上升沿(RisingEdges),则要确定在调用shiftOut()前时钟针脚为低电平,如调用digitalWrite(clockPin,LOW)。语法:shiftOut(dataPin,clockPin,bitOrder,value)。2.3.3

高级I/O4.shiftIn()描述:将数据的一个字节一位一位地移入。从最高有效位(最左边)或最低位有效位(最右边)开始,对于每个位,先拉高时钟电位,再从数据传输线中读取一位,再将时钟线拉低。注意:这是一个软件实现,也可以参考硬件

实现的SPI链接库,其速度更快,但只对特定脚有效。语法:byteincoming=shiftIn(dataPin,clockPi,bitOrder)。2.3.3高级I/O5.pulseIn()描述:读取一个针脚的脉冲(HIGH或LOW)。语法:

pulseIn(pin,value)或pulseIn(pin,value,timeout)。参数:pin,要进行脉冲计时的针脚号(int);value,要读取的脉冲类型,H或LOW(int);timeout(可选

),指定脉冲计数的等待时间返回0(unsignedlong)。2.3.4shiftOut(dataPin,clockPin,bitOrder,val)shiftOut函数能够将数据通过串行的方式在引脚上进行输出,相当于一般意义上的同步串行通信。这是控制器与控制器、控制器与传感器之间

常用的一种通信方式。①dataPin:数据输出引脚,数据的每一位将逐次输出。引脚模式需要设置输出。②clockPin:时钟输出引脚,为数据输出提供时钟,引脚模式需要设置成输出。③bitOrder:数据位移顺序选择位,该参数为byt

e类型,有两种类型可选择,分别是高位先入MSBFIRST和低位先入LSBFIRST。④value:所要输出的数值。2.3.5pulseIn(pin,state,timeout)pulseIn函数用于读取引脚脉冲的时间长度,而脉冲可以是HIGH或LOW。如果是HIGH,函数将先等引脚变为高电平,

然后开始计时,一直到变为低电平为止。返回脉冲持续的时间使用的,单位为ms。如果超时还没有读到的话,将返回0。2.3.6时间函数1.Millis()描述:返回Arduino开发板运行当前程序开始的毫秒数。这

个数字将在约50天后溢出(归零)。返回:返回从运行当前程序开始的毫秒数(无符号长整数unsignedlong)。2.3.6时间函数2.micros()描述:返回Arduino开发板从运行当前程序开始的微秒数,这个数字将在约70分钟后溢出(归零)。在1

6MHz的Arduino开发板上(比如Duemilanove和Nano),这个函数的分辨率为4μs(即返回值总是4的倍数);在8MHz的Arduino开发板上(比如LilyPad),这个函数的分辨率为8μs。返回:返回从当前程序开始的微秒数(无符号长整数)。2.3.6时间函数3.

delay()描述:是程序设定的暂停时间(单位毫秒)。语法:delay(ms)。参数:ms,暂停的毫秒数(unsignedlong)。2.3.6时间函数4.delayMicroseconds()描述:使程序

暂停指定的一段时间(单位ms)。目前,能够产生的最大延时准确值是16383。这可能会在未来的Arduino版本中有所改变。对于超过几千μs的延时,应该使用delay()代替。语法:delayMicroseconds(us)。参数:µs,

暂停的时间,单位微秒(unsignedint)。2.3.7中断函数1.外部中断函数(1)attachInterrupt(interrupt,function,mode)描述:当发生外部中断时,调用一个指定的函数

。这会用新的函数取代之前指定给中断的函数。大多数的Arduino板有两个外部中断:0号中断(引脚2)和1号中断(引脚3)。部分不同类型Arduino板的中断及引脚关系,表中的int是interrupt的缩写,而不是代表整数的int。A

rduinoDue有更强大的中断能力,其允许在所有的引脚上触发中断程序,可以直接使用attachInterrupt指定引脚号码。2.3.7中断函数语法:attachInterrupt(interrup

t,function,mode)、attachInterrupt(pin,function,mode)。参数:interrupt,中断的编号;pin,引脚号码(Due专用);function,中断发生时调用的函数,此函数必须不带参数和不返回任何值;m

ode,定义何种情况发生中断,以下四个常数为mode的有效值。①LOW:当引脚为低电位时,触发中断。②CHANGE:当引脚电位发生改变时,触发中断。③RISING:当引脚由低电位变为高电位时,触发中断。

④FALLING:当引脚由高电位变为低电位时,触发中断。2.3.7中断函数2.中断使能函数(1)interrupts(中断)描述:重新启用中断(使用noInterrupts()命令后将被禁用)。中断允许一些要任务在后台运行。禁用中断后一些函数可能无法工作,传入信息可能会被忽

略。中断会稍微打乱代码的时间,可以在程序关键部分禁用中断。2.3.7中断函数(2)noInterrupts()描述:禁止中断。中断允许后在后台运行一些重要任务,默认使能中断。禁止中断时部分函数会无法工作,通信中接收到的信息也可能

会丢失,中断会影响计时代码,在某些特定的代码中也会失效。2.3.8串口收发函数1.Serial.begin(speed)描述:将串行数据传输速率设置为bit/s(波特)。与计算机进行通信时,可以使用这些波特率:

300、1200、2400、4800、9600、14400、19200、28800、38400、57600或115200。当然,也可以指定其他波特率,例如,针脚0、1和一个组件进行通信,它需要一个特定的波特率。语法:S

erial.begin(speed)仅适用于ArduinoMega、Seriall。begin(speed)、Serial2.begin(speed)、Serial3.begin(speed)、Serial.begin(speed,config)、Serial2.begin(s

peed,config)、Serial3.begin(speed,config)。2.3.8串口收发函数2.intSerial.available()描述:从串口读取有效的字节数(字符)。这是已经传输到并存储在串行接收缓冲区(能够存储64个字节)的

数据。Available()继承了Stream类。语法:Serial.available()。此外,仅适用于ArduimoMage的还有3个,分别是Serial1.available()、Serial2.available()和Serial3.ava

ilable()。2.3.8串口收发函数3.intSerial.read()描述:读取传入的串口的数据,read()继承自Stream类。语法:Serial.read()。此外,仅适用于ArduimoMage的还有3个

,分别为Serial1.read()、Serial2.read()和Serial3.read()。返回:传入串口数据的第一个字节(或‐1,如果没有可用的数据,int)。2.3.8串口收发函数4.Serial.flush()描述:等待

超出的串行数据完成传输(在1.0及以上的版本中,flush()语句的功能不再是丢弃所有进入缓存器的串行数据)。flush()继承自Stream类。语法:Serial.flush()。此外,仅适用于ArduinoMega的有3个,分别为Serial1.f

lush()、Serial2.flush()和Serial3.flush()。2.3.8串口收发函数5.Serial.print(data)描述:以ASCII文本形式打印数据到串口输出。此命令可以采取多种形式。若要发送一个字节,则使用Se

rial.write()。语法:Serial.println(val)或Serial.print(val,格式)。参数:val,打印输出的值,可以为所有数据类型;格式,指定进制(整数数据类型)或小数位数(

浮点类型)。返回:字节print()将返回写入的字节数,但是否使用(或读出)是可以设定的。2.3.8串口收发函数6.Serial.println(data)描述:打印数据到串行端口,输出人们可识别的ASCII码文本并回车(ASCII13,或”\r

”)及换行(ASCII10,或”\n”)。此命令采用的形式与Serial.print()相同。语法:Serial.println(val)或Serial.println(val,format)。参数:val,打印的内容,可以为所有数据类型;format,指定基数(整数数据类型)或

小数位数(浮点类型)。返回:字节(byte),printfln()将返回写入的字节数,但可以选择是否使用它。目录3.1SPI通信3.2红外通信3.3WiFi通信3.4蓝牙通信3.1SPI通信3.1.1工作原理SPI的英文全称是SerialPeripheral

Interface,翻译成中文的意思是串口通信外围设备接口技术。也就是把数据用串口传输方式进行交换。它有一个主控制器,一般采用微处理器,如常用的单片机,以及一些其他的外围设置,如数码管、液晶显示屏、SD卡等外围设备。它一般是由5根线组成的,分别

是MOSI、MISO、SCK、SS以及地线、电源线。MISO即MasterInSlaveOut,主设备数据输入,从设备数据输出,一般是由主机向设备发出数据的。MOSI即MasterOutSlaveIn,主设备数据输出,从设备数据输入,一般是由设备向主机发送数据的。SCK即SerialClock

,串行时钟,数据传输的时钟基于主处理器产生的时钟脉冲,起到一个控制数据传输的校准,根据Arduino官方说明,具备有对数据全能的控制作用。3.1.2电路图及应用1.SPI串口读取大气压传感器SCP1000型的大气压传感

器可以读出气压和温度。电路原理如图3-1所示。由于篇幅有限,说明文件不再讲述,请读者动手查阅。图3-1SPI串口与大气压传感器电路连接图(2)安装选项,一2.SPI串口控制数字分压计在这个实验中需要使用到AD5206数字分压计,它是一个6通道的数字分压计。这意味着它内置六个可变电阻以便于独立的

电子控制。它具体的使用方法不再讲述,请读者查阅相关的说明文件。关于AD5206的连接:所有的A引脚连接到+5V;CS连接到数字引脚到地;将W引脚通过一个LED串联一个220Ω的电阻连接倒地;CS连接到数字

引脚10(SS);SDI连接到数字引脚11(MOSI);CLK连接至数字引脚13(SCK)。电路连接如图3-2所示,电路原理如图3-3所示。般保持默认安装。图3-2SPI串口与AD5206电路连接图AREFGNDD13D12D11/PW

MD10/PWMD9/PWMD8D7D6/PWMD5/PWMD4D3/PWMD2DigitaK1/TXDigitaK1/RXA6W6B6GndCSVddSDICLKV55B6W5A5B4W4A4B2W2A2A1W1B1A3W3B3+5V+5V图3-3SPI串口与

AD5206电路原理图3.1.3工作代码1.SPI串口控制大气压传感器的示例代码下面的代码是使用SPI串口控制大气压传感器SCP1000,获取大气压强的示例。SPI串口控制大气压传感器SCP1000使用引脚

6、7、11~13,引脚分配为DRDY(pin6)、CSB(pin7)、MOSI(pin12)、SCK(pin13)、传感器使用了SPI串口,所以要使用库文件。#include<SPI.h>constintPRESSURE=0x1F;//记录传感器

注册的地址,记录3位气压最重要的比特constintPRESSURE_LSB=0x20;//记录16位气压比特constintTEMPERATURE=0x21;//读取16比特温度constbyteREAD=0b11111100;//SCP1000的读取命令cons

tbyteWRITE=0b00000010;//SCP1000的写入命令//定义用与传感器连接的引脚,并且初始化其库:constintdataReadyPin=6;constintchipSelectPin=7;voidse

tup(){Serial.begin(9600);//启动SPI库SPI.begin();//初始化数据准备和芯片选择引脚pinMode(dataReadyPin,INPUT);pinMode(chipSelectPin,OUTPUT);//配置SCP1000为低

噪声设置writeRegister(0x02,0x2D);writeRegister(0x01,0x03);writeRegister(0x03,0x02);//给传感器时间进行设置delay(100);}vo

idloop(){//选择高分变率模式writeRegister(0x03,0x0A);//在数据准备引脚为高之前不要做任何事if(digitalRead(dataReadyPin)==HIGH){//读取数据温度inttempDat

a=readRegister(0x21,2);//把温度转换成摄氏并显示floatrealTemp=(float)tempData/20.0;Serial.print("Temp[C]=");//显示温度Serial.

print(realTemp);//读取最高三位的压力数据bytepressure_data_high=readRegister(0x1F,1);pressure_data_high&=0b00000111;//只需要比特2~0位//读

取低16位压力数据unsignedintpressure_data_low=readRegister(0x20,2);longpressure=((pressure_data_high<<16)|pressure_data_low)/4;Seria

l.println("\tPressure[Pa]="+String(pressure));}}//从SCP1000读取或写人unsignedintreadRegister(bytethisRegister,int

bytesToRead){byteinByte=0;//从SPI的输入数据unsignedintresult=0;//返回结果Serial.print(thisRegister,BIN);Serial.print("\t");//存储器高6位读取注册名称,向左移动两比特thisRegister=t

hisRegister<<2;//将地址和命令整合进一个字节中bytedataToSend=thisRegister&READ;Serial.println(thisRegister,BIN);//将芯片置低去选择设备digitalWrite(

chipSelectPin,LOW);//向存储器发送所需要读取的设备SPI.transfer(dataToSend);//发送值0以读取返回的第一个字节result=SPI.transfer(0x00);//缩减字节数目以读取//如果还要读取另一

个数据if(bytesToRead>0){//将第一个字节向左替换,获取第二个字节数据result=result<<8;inByte=SPI.transfer(0x00);//发送值0以读取返回的第一个字节result=result|inByt

e;//缩减字节数目以读取bytesToRead--;}//将芯片选择置高位以反选digitalWrite(chipSelectPin,HIGH);//返回结果return(result);}//向SCP1000发送写命令voidwriteRegister(bytethisRegis

ter,bytethisValue){thisRegister=thisRegister<<2;bytedataToSend=thisRegister|WRITE;digitalWrite(chipSelectPin,LOW);SPI.tran

sfer(dataToSend);//发送存储器位置SPI.transfer(thisValue);//向存储器发送值digitalWrite(chipSelectPin,HIGH);}2.SPI串口控制数字分

压计的示例代码下面的代码是使用SPI串口控制AD5206数字分压计的示例。数字端口控制AD5206数字分压计。AD5206有六个分压通道。每一个通道引脚都被标注了如下分类:A一连接至电源;W一擦除器,每当设置的时候就会改变;B一连接至

地,AD5206是SPI串口适配的,若要控制它,需要发送两字节的信号,一个是通道信号(0~5),另一个为通道所赋的值(0~255)。例程要包含所需的库文件。#include<SPI.h>constintslavSelectPin=10;/

/将10引脚设置为数字引脚的选择项voidsetup(){pinMode(slaveSelectPin,OUTPUT);//将slaveSelectPin设为输出SPI.begin();//初始化SPI}voidloop(){for(intchannel=0;channel<6;channel+

+){//遍历所有6个通道的数字接口for(intlevel=0;level<255;level++){//将赋值从最小到最大依次改变digitalPotWrite(channel,level);delay

(10);}}}voiddigitalPotWrite(intaddress,intvalue){digitalWrite(slaveSelecPin,LOW);//将SS引脚置低电平以选择芯片SPI.t

ransfer(address);//通过SPI发送地址和值SPI.transfer(value);digitalWrite(slaveSelecPin,HIGH);//将SS引脚置高电平以反选芯片3.2红外通信3.2.1工作原理红外线遥控是目前使用最广泛的一种通信

和遥控手段。由于红外线遥控装置具有体积小、功耗低、功能强、成本低等特点,因而,继彩电、录像机之后,在录音机、音响设备、空调机以及玩具等其他小型电器装置上也纷纷采用红外线遥控。工业设备中,在高压、辐射、有毒气体、粉尘等环境下,采用红外线遥控不仅完全可靠而且能有效地隔离电气干扰。通用红外遥

控系统由发射和接收两大部分组成。发射部分包括键盘矩阵,编码调制,LED红外发送器;接收部分包括光/电转换放大器、解调/解码电路。红外接收的接收电路是一种集成红外线接收和放大一体的红外接收器模块,能够完成从红外接收到输出与TTL电平信号兼容的所有工作,适用于红外线遥控和红外线数据传输。接收器做成的

红外接收模块只有三个引脚:信号线、Vcc、GND,与Arduino和其他单片机连接通信非常方便。红外通信原理图如图3-4所示。图3-4红外通信原理图3.2.2元件选型本例程完成两个功能,其一接收红外信号,并显示红外编码如图所示,连接使用220Ω电阻。打开Accessport串口助手软件

并启用监控,手持红外线遥控器,依序按键,记录红外编码。其二,接收红外信号,控制LED灯。电路图与功能一相同,使用红外线遥控器,按1点亮LED,按键2关闭LED。3.2.3连接示意图红外线接收器连接原理图如图3

-5所示,红外线接收器电路连接图如图3-6所示。P1.1P1.2P1.3P1.4P1.5P1.6P1.7P3.38050+5v5140106C40106D10K+5vTXDP1.040106A40106B89c205

1图3-5红外线接收器连接原理图图3-6红外线接收器电路连接图3.2.4调试代码下面例子是使用红外线接收模块接收信号,并在PC端的控制串口显示接收信息(既红外遥控器的编码)。本例来自于红外接收模块的IRremote的自带范例。#include<IRremote.h>intRECV_PIN=11

;//定义红外接收器的引脚为11IRrecvirrecv(RECV_PIN);decode_resultsresults;voidsetup(){Serial.begin(9600);Irrecv.enableIRIn()

;//初始化红外接收器}voidloop(){if(irrecv.decode(&results)){Serialprintln(results.value,HEX);//以十六进制换行输出接收代码Serialprintln();//为了便于观看输出结果增加一个空行irrecv.resume();

//接收下一个值}}//使用红外线控制LED灯的示例代码//下面示例通过红外线控制LED灯的亮灭,本例来自于红外接收模块的IRremote自带范例,已经作出了修改,电路连接,按键1点亮LED,按键2关闭

LED。#include<IRremote.h>intRECV_PIN=11;//定义红外接收器的引脚为11intLED_PIN=3;//定义led的引脚为3IRrecvirrecv(RECV_PIN);decode_res

ultsresults;voidsetup(){Serial.begin(9600);irrecv.enableIRIn();//初始化红外接收器}voidloop(){if(irrecv.decode(&results)){i

f(results.value,HEX);Serial.println(results.value,HEX);Serial.println();//以十六进制换行输出接收代码digitalWrite(LED_PIN,HIGH);//LED点亮Seria

l.println("点亮发光二极管tunonLED:");//串口显示开灯}elseif(results.value==16718055);//接收到按键2的编码{digitalWrite(LED_PIN,LOW);//LED熄灭Serial.println(resu

lts.value,HEX);//以十六进制换行输出接收代码Serial.println();//为了便于观看输出结果增加一个空行Serial.println("关发光二极管tunoffLED:");//串口显示关灯}irrecv.resume();//

接收下一个值}}3.3WiFi通信3.3.1工作原理无线网络,是一种可以将个人计算机,手持设备(如PDA、手机)等终端以无线方式互相连接的技术,事实上它是一个高频无线信号。无线保真是一个无线网络通信技术的品牌,由WiFi联盟所持有。目的是改善基于IEEE802.11标准的无线网络产品之间的互通性

,经常有人把WiFi及IEEE802.11混为一谈,二者还是有区别的。当前,WiFi已经成为我们工作与生活中使用最频繁的网络接入方式,在进行Arduino实验时,难免需要接入互联网来实现功能,而前面介绍的以太网盾的接入方式又需要插入网线,具有

局限性。所以,本节介绍扩展的ArduinoWiFi插板,实物图如图3-7所示。图3-7WiFiShield实物图3.3.2元件选型WiFiSHield的使用方法和有线的EthernetShield插板类似,是按引脚方向插在Arduino

UNO板上,它的配置及使用方式与EthernetShield接入互联网也非常相似。WiFi插板使用10号、11号、12号、13号引脚把WiFi模块通过SPI串口连接,同时使用数字4号引脚作为芯片选择引脚提供SD卡的选择。需要注意的是在连接

之前,要保证能接入一个802.11b/g的无线网络。在特定的网络SSID下面,需要改变网络设置。3.3.3连接示意图连接示意图如图3-8所示。图3-8连接示意图3.3.4调试代码1.没有密码的无线网连接通过wifi

shield连接一个没有密码的无线网,程序如下:#include<WiFi.h>charssid[]="yourNetwork";//网络的名称intstatus=WL_IDLE_STATUS;//WiFi状态voidsetup(){Ser

ial.begin(9600);//初始化串口并且等待端口打开while(!Serial){;//等待串口连接}if(WiFi.status()==WL_NO_SHIELD){//检测插板的连接Serial,p

rintln("WiFishieldnotpresent");while(true);//插板没连接时不能继续}while(status!=WL_CONNECTED){//尝试连接WiFi网络Serial.print("AttemptingtoconnecttoopenSSID:

");Serial.println(ssid);delay(10000);//等待10s连接}Serial.print("you'reconnectedtothenetwork");//已连接上,所以打印出数据printCurrentNet();p

rintWifiData();}voidloop(){//当超过10s时检查网络连接delay(10000);printCurrentNet();}voidprintWifiData(){//打印wifi插板的IP地址IPAddressip=WiFi.LocalIP();Serial.pri

nt("IPAddress:");Serial.println(ip);Serial.println(ip);bytemac[6];//打印MAC地址WiFi.macAddress(mac);Serial,print("MACaddress:");Serial,print(mac

[5],HEX);Serial,print(":");Serial,print(mac[4],HEX);Serial,print(":");Serial,print(mac[2],HEX);Serial,print(":");Serial,prin

t(mac[1],HEX);Serial,print(":");Serial,println(mac[0],HEX);IPAddresssubnet=WiFi,subnetMask();//打印子网掩码Serial,print("NetMask");Serial,println(subnet);I

PAddressgateway=WiFi,gatewayIP();//打印网关地址Serial,print("Gateway");Serial,println(gateway);}voidprintCurrentN

et(){Serial,print("ssid:");//打印所连接的无线网络的SSIDSerial,println(WiFi,SSID());bytebssid[6];//打印所连接的硬件的MAC地址WiFi.BSSID(bassi

d);Serialprint("BSSID:");Serialprint(bssid[5],HEX);Serialprint(":");Serialprint(bssid[4],HEX);Serialp

rint(":");Serialprint(bssid[3],HEX);Serialprint(":");Serialprint(bssid[2],HEX);Serialprint(":")Serialprint(bssid[1]

,HEX);Serialprint(":")Serialprintln(bssid[0],HEX);Longrssi=WiFi.RSSI();//打印信号强度Serialprint("signalstrength(RSSI):");Seria

l.println(rssi);byteencryption=WiFi.encryptionType();//打印秘钥类型Serial.print("EncryptionType:");Serial.println(encryption,HEX);}3.3.5实验背景随着互联网越来越深如地走进人

们的生活,用户对能够随时随地上网的需求越来越迫切,WiFi无线通信技术也得到了迅速发展。WiFi的主要技术优点是无线接入、高速传输以及传输距离较远。其中,802.11n可以将WLAN的传输速率由目前802.11a及

802.11g提供的54Mbps提高到300Mbps甚至高达600Mbps。在开放性区域通信距离可达305m,在封闭性区域通信距离为76~122m,方便与现有的有线以太网整合,组网的成本较低。WiFi设备的频段为

2.4~2.4835GHz的ISM频段,在频率资源上不存在限制,因此使用成本低廉也成为WiFi技术的又一优势。有没有遇见这些情况:在上班时想起忘了关自家的电灯;想在回家前半小时打开家里的热水器;想知道自家的温度有多高,湿度是多

少。下面这个实验将一一解决。3.3.6材料清单及数据手册1.材料清单本实验所用到的材料清单如表3-1所示。表3-1材料清单元件名称型号参数规格数量参考实物图Arduino开发板UnoR31串口WIFI模块TLN13UA601面包板专用插线若干2.WiFi模块数据手

册本实验中采用串口WiFi模块,型号为TLN13UA60,该模块体积小,单3.3V供电,功耗较低,支持硬件RTS/CTS流控,支持快速联网、无线漫游以及节能模式,支持自动和命令两种工作模式,详细的技术性能指标如下所示:·双排(2x4)插针式接口·支持波特率范围:1200bps~115200bps

·支持硬件RTS/CTS流控·单3.3V供电·支持IEEE802.11b/g无线标准·支持频率范围:2.412~2.484GHz·支持3种无线网络类型:基础网(STA或AP)、自组网(Ad-hoc)·支持多种安全加密及认证机制:·WEP64/WEP128/TKIP/CCMP(AES)·OPEN/

WPA-PSK/WPA2-PSK·支持快速联网·支持无线漫游·支持节能模式·支持多种网络协议:TCP/UDP/ICMP/DHCP/DNS/HTTP·支持DHCPServer、DNSServer·支持自动和命令两种工作模式·支持串口透明传输模式·支持AT+控制指令集·支持多种参数配置方式:串口

/WEB服务器/无线适配器3.3.7电路连接及通信初始化WiFi无线通信实验的硬件连接如图3-9所示。Arduino板与TLN13UA60WiFi模块通过串口相连接,采用Andriod手机的WiFi功能与TLN13UA60模块进行WiFi通信,已验证WiFi无线通信功能。串口Wi

Fi模块与Arduino的连接原理如图3-10所示,图中左侧器件即为串口WiFi模块。具体连接方法为:串口WiFi模块的RXD连接Arduino的TX;串口WiFi模块的TXD连接Arduino的RX;串口WiFi模块的3V3连接Arduino的3.3V;串口WiFi模

块的GND连接Arduino的GND。本实验要测试的事WiFi无线通信功能。在硬件电路连接好后,首先要配置无线网络基本参数,完成设备的初始化工作,模块及网络初始化步骤如下。第一步:给模块供电。模块上电之后,就会出现一个名为wifi-socket的网络,用

手机可搜索到网络。单击wifi-socket按钮(出厂设置不需要用户名和密码),可直接接入。第二步:打开Android平台的网络调试。选择udpclient,然后选择“添加”选项,并正确填写相关参数,如图3-11所示。第三步:单击“增加”按钮,完成添加网络连接,网络参数初始

化结束。图3-9WiFi无线通信实验的硬件连接实物图图3-10串口有WiFi模块与Arduino的连接原理图图3-11通信软件初始化3.3.8程序设计WiFi无线通信实验参考程序的源代码为:voidsetup(){Serial.begin(9600);}vo

idloop(){Serial.println("helloworld");delay(1000);}3.3.9程序调试程序下载至Arduino板子之后,Andriod手机已按前一节的操作连接上了WiFi模

块,此时就可以在Andriod手机看到Arduino通过WiFi传回来的“helloworld!”字符。3.3.10技术小贴士(1)WiFi概括WiFi是IEEE定义的无线网技术,在1999年IEEE官方定义802.11标准的时候,选择并认定了CSIRO发明的无线网技术是世界

上最好的无线网技术,因此,CSIRO的无线网技术标准,就成为2010年WiFi的核心技术标准。WiFi技术由澳大利亚政府的研究机构CSIRO在20世纪90年代发明并于1996年在美国成功申请了无线网技术专利(USPatentNumber5487069)。发明人是悉尼大学工程系毕业生DrJohn

O’Sullivan领导的由毕业生组成的研究小组。IEEE曾请求澳大利亚政府放弃其WiFi专利,让世界免费使用WiFi技术,但遭到拒绝。澳大利亚政府随后在美国通过官司胜诉或庭外和解,收取了世界上几乎所有电器电信公司(包括苹果、因特尔、联想、戴尔、AT&T、索尼、东芝、微软、宏基、华硕等)的专

利使用费。2010年每购买一台含有WiFi技术的电子设备,所付的价钱就包含了交给澳大利亚政府的WiFi专利使用费。2010年全球每天估计会有30亿台电子设备使用WiFi技术,而到2013年底CSIRO的无线网专利过期之后,这个数字预计会增加到50亿。WiFi被澳大利亚媒体誉为澳大利亚媒体誉为

澳大利亚有史以来最重要的科技发明,其发明人JohnO‘Sullivan被澳大利亚媒体称为“WiFi之父”并获得了澳大利亚的国家最高科学奖和全世界的众多赞誉,其中包括欧盟机构、欧洲专利局(EPO)频发的Europr

anInventorAward2012,即2010年欧洲发明者大奖。(2)WiFi网络组建一般架设无线网络的基本配备就是无线网卡及一台AP,如此便能以无线的模式,配合既有的有线架构来分享网络资源,架设费用和复杂程度远远低于传统的有线网络。如果只是几台计算机的对等网,也可不要A

P,只需要每台计算机配备无线网卡。AP为AccessPoint的简称,一般翻译为“无线访问接入点”或“桥接器”,主要在媒体存取控制层MAC中扮演无线工作站及有线局域网的桥梁。有了AP,就像一般有线网络的Hub一般,无线工作站可以快速且

容易地与网络连接。特别对于宽带的使用,WiFi更具有优势。有线宽带网络(ADSL、小区LAN等)到户后,连接到一个AP,然后在计算机中安装一块无线网卡即可、普通的家庭有一个AP已经足够,甚至用户从邻居得到授权后,也无需增加端口,就能以共享的方式上网。(

3)WiFi应用由于WiFi的频段在世界范围内是无需任何电信运营执照的,因此WLAN无线设备提供一个世界范围内可以使用的,费用及其低廉且数据带宽极高的无线空中接口。用户可以在WiFi覆盖区域内快速浏览网页,随时随地接听拨打电话。而其他一些基于WLAN的宽带数据应用,如流媒体,网络游戏等功

能更是值得用户期待。有了WiFi功能打长途电话、浏览网页、收发电子邮件、音乐下载、数码照片传递等,再无需担心速度慢和花费高的问题。WiFi无线保真技术和蓝牙技术一样,同属于在办公室和家庭中使用的短距离无线技术。WiFi在掌上设备上的应用越来越广泛,

而智能手机首当其冲。与早前应用于手机上的蓝牙技术不同,WiFi具有更广的覆盖范围和更高的传输效率,因此WiFi手机成为了当前移动通信业界的流潮。WiFi的覆盖范围在国内越来越广泛,高级宾馆、豪华住宅区、飞机场以及咖啡厅等区域都有WiFi接口。当人们在旅游、办公时,就可以在

这些场所使用自己的掌上设备尽情网上冲浪了。厂商只要在机场、车站、咖啡店、图书馆等人员比较密集的地方设置“热点”,并通过高速线路将因特网接入上述场所,这样,由于热点所发射出的电波可以达到距接入点半径数十米至近百米的区域,用户只要将支持WiFi的笔记本计算机、PDA、手机、psp或ipadTouch等

接入、即可告诉接入因特网。在家也可以购买无线路由器设置局域网,然后就可以痛快的无线上网了,WiFi和3G技术的区别就是:3G在高速移动时传输质量较好,但静态的时候用WiFi上网就足够。3.4蓝牙通信3.4.1工作原理BlueTooth,蓝牙,是一种支持设备短距离通信(一般十几米)的无线电技

术,能在包括移动电话,PDA,无线耳机,笔记本电脑,相关外设等之间进行无线信息交换。利用蓝牙技术,能够有效得简化移动通信终端设备之间的通信,也能够简化设备与因特网Inernet之间的通信,从而数据传输变得更加迅

速高效。蓝牙采用分散式网络结构以及快跳频和短包技术,支持点对点及点对多点通信,工作在全球通用的2.4GHzISM(即工业、科学、医学)频段。其数据速率为1Mbps,采用时分双工传输方案是实现双全工传输。蓝牙技术使用高速跳频(FH,frequencyhoppin

g)和时分多址(TDMA,timedivesionmuli-access)等先进技术,在近距离内最廉价地将几台数字化设备(各种移动设备、固定通信设备、计算机及其终端设备、各种数字数据系统,如数字照相机、数字摄像机等,甚至各种家用电器、自动化设备

)呈网状链接起来。蓝牙技术将是网络中各种外围设备接口的统一桥梁,它消除了设备之间的连线,取而代之以无线连接3.4.2连接示意图图3-12为蓝牙模块与arduino的连接示意图。图3-12连接示意图3.4.3调试代码下面的代码是简单地

使用手机通过蓝牙模块控制Arduino实验板上的LED灯亮灯灭的示例,读者可以扩展出蓝牙通信的更多方法。charval;intledpin=13;voidsetup(){Serial.begin(9600);pinMode(ledpin,OUTPUT);}voidloop(){val=

Serial.read();if(val=='q'){digitalWrite(ledpin,HIGH);Serial.println("LEDON!");}elseif(val=='w'){digitalWrite(ledp

in,LOW);Serial.println("LEDOFF");}}3.4.4实验背景蓝牙技术是一项即时技术,它不要求固定的基础设施,且易于安装和设置,不需要电缆即可实现连接。新用户使用亦不费力——只需拥有蓝牙产品,检查可用的配置文件,将其连接至使用同一配置文件的另一蓝牙设备即可,后续

的PIN码流程如同在ATM机器上操作一样简单。本实验通过蓝牙实现Aedyino与手机之间的简单通信。3.4.5材料清单及数据手册1.材料清单本实验所用到的材料如表3-2所示。表3-2材料清单元件名称型号参数规格数量参考实物图Arduino

开发板UnoR31蓝牙模块HC—061面包板840孔无焊板1面包板专用线若干2.蓝牙模块数据手册本实验中用到的蓝牙模块为HC-06从模块,该模块的4个引脚分别为VCC、GND、TXD和RXD。预留LE

D状态输出脚,单片机可通过该引脚状态判断蓝牙是否已经连接。以下是该模块的其他性能参数。(1)用LED指示蓝牙连接状态,闪烁表示没有蓝牙连接,常亮表示蓝牙已连接并打开了端口。(2)底板3.3VLDO,输入电压3.6~6V,未配对时电流约30mA,配对后约100mA,编入

电压禁止超过7V。(3)接入电平3.3V,可以直接连接各种单片机(51、AVR、PIC、ARM、MSP430等),5V单片机也可直接连接,无需MAX232,也不能经过MAX232进行电平转换。(4)空旷地有效距离10m,超过10m也可能传输但必须保证连接质量。、(5)配对以后

可作为全双工串口使用,无需了解任何蓝牙协议,但仅支持“8位数据位,1位停止位、无奇偶校验”的通信格式,这也是常用的通信格式,不支持其他格式。(6)未建立蓝牙连接时,支持通过AT指令设置波特率、名称、配对密码,设置参数掉电保存,蓝牙连接以后自动切换到透视模式。(7)HC-06

模块为从机模块,从机能与各种带蓝牙功能的计算机、蓝牙主机、大部分带蓝牙的手机、PDA、PSP等智能终端配对,从机之间不能配对。(8)TXD为发送端,一般表示为自己的发送端,正常通信必须接另一个设备的RXD;RXD为接收端,一般表示为自己的接收端,正常通信必须接另一个设备

的TXD;正常通信时,本身的TXD永远接设备的RXD。(9)自收自发。正常通信时RXD接其他设备的TXD,因此,如果要接收自己发送的数据,则自身的TXD直接连接到RXD,这用来测试本身的发送和接收是否正常,是最快最简单的测试方法。当出现问题时首先应测试是否为产品故障,该

测试方法也称回环测试。3.4.6硬件连接Arduino与蓝牙模块的连接原理图如图3-13所示,Arduino与蓝牙模块连接方法为:(1)蓝牙模块的VCC连接Arduino的5V;(2)蓝牙模块的GND连接Arduino的GND;(3)蓝牙

模块的TXD发送端连接Arduino的RX;(4)蓝牙模块的RXD接收端连接Arduino的TX。图3-13Arduino与蓝牙模块连接原理图硬件连接好后,将Arduino上电,如果蓝牙的指示灯闪烁,则表。明没有连接上设备。如图3-14所示,如果LED常亮,表明Ardui

no上的蓝牙模块已经和Arduino上的蓝牙模块已经和Android手机实现连接图3-14Android手机与Arduino上的蓝牙模块正常连接3.4.7程序设计voidsetup(){Serial.begin(9600);}voidloop()

{while(Serial.available());{charc=Serial.read();if(c=='A'){Serial.println("HelloIamamarino");}}}3.4.8调试及实验现象首先下载Android的蓝牙管理软件Amarin

o,在计算机上安装后,启动Android的蓝牙,打开Amarino的客户端,如图3-15所示,左右下角AddBTDevice中就能找到蓝牙和名字,图3-16所示。图3-15Amarino客户端图3-16客户端中显示的

蓝牙名字单击connect按钮后,会弹出输入PIN的对话框,蓝牙默认PIN为1234,图3-17为连接成功后的界面。单击Monitoring按钮可以看到蓝牙的连接信息,如图3-18所示。图3-17连接

成功后的界面图3-18蓝牙连接信息连接成功之后,就要看数据发送是否正常。这里直接单击send按钮就可以实现发送,如图3-19所示。当Arduino连接到A符号时,就会在COM口输出对应内容,表明蓝牙通信正常,实验结果如图3-20所示。图3-20通信正常示意图3.4.9技术小贴士(1)蓝牙版本(2

)截止2014年7月,蓝牙共有六个版本,V1.1/1.2/2.0/2.1/3.0/4.0。从通信距离来看,不同版本可分为ClassA(1)/ClassB(2)。V1.1为最早期版本,传输速率为748~81

0kbps,早期设计容易受到同频率产品的干扰,从而影响通信质量。V1.2的传输速率也为748~810kbps,但采用软件方法改善了抗干扰跳频功能。ClassA用在大功率、远距离的蓝牙产品上,但因成本高、耗电量大,不适合于个人通信产品

,故多用在部分商业特殊用途上,通信距离大约为80~100m。ClassB是最流行的制式,通信距离大约为8~30m,多用于手机、蓝牙耳机、蓝牙Dongle等个人通信产品,耗电量小,体积小,方便携带。V1.1/1.2版本的蓝牙产

品,基本上可以支持Stereo音效的传输,但只能工作在单工模式,加上音频响应不够宽,不能算是最好的Stereo传输工具。版本2.0是1.2的改良提升版,传输速率约为1.8Mps~2.1Mps,开始支持双工模式——一方面用于语音通信,另一方面传输档

案、高像素图片,2.0版本当然也支持Stereo传输。应用最广泛的是Bluetooth2.0+EDR标准,该标准在2004年已经推出,支持Bluetooth2.0+EDR标准的产品也于2006年大量出现,虽然Bluetooth2.0+EDR标准在技术上作了大量的改进,但从

1.X标准延续下来的配置流程复杂和设备功耗较低的问题依然存在·。为了改善蓝牙技术存在的问题,蓝牙SIG组织推出了Bluetooth2.1+EDR版本的蓝牙技术。2009年4月21日,蓝牙技术联盟正式颁布了新一代标准规

范BluetoothCoreSpecificationVersion3.0HighSpeed。蓝牙3.0的核心是GenericAlternateMAC/PHY(AMP),这是一种交替射频技术,允许蓝牙

协议栈针对任一任务动态地选择正确的射频。最初被期望用于规范的技术包括802.11以及UMB,但是规范中取消了UMB的应用。蓝牙3.0的传输速度更高,而秘密就在802.11无线协议上。通过集成802.11PAL(协议适应层),蓝牙3.0的数据传输速率提高到了大约24Mps

。在传输速度上,蓝牙3.0是蓝牙2.0的12倍,可以轻松用于录像机至高清电视、PC至PMP、UMPC至打印之间的资料传输。在功耗方面,通过蓝牙3.0高速传送大量数据自然会消耗更多能量,但由于引入了增强电源控制(EPC)

机制,再辅以802.11实际空闲功耗会明显降低,蓝牙设备的待机耗电问题已得到初步解决。(2)蓝牙V4.0蓝牙4.0包括三个自规范,即传统蓝牙技术、高速蓝牙技术和新的蓝牙功耗技术,蓝牙4.0的改进之处主要体现在三方面:电池续航时间、节能和设备种类,具有成本低、跨厂商互操作性、3m

s低延时、100m以上超长传输距离。AES-128加密等诸多特色。(3)蓝牙的应用居家通过使用蓝牙技术产品,人们可以免除居家办公电缆缠绕的苦恼。鼠标。键盘、打印机、膝上型计算机、耳机和扬声器等均可以在PC环境中无线使用,这不但增加了办公区域的美感,

还为室内装饰提供了更多创意和自由。此外,通过在移动设备和家用PC之间同步联系人和日历信息,用户可以随时随地存取更新的信息。工作过去的办公室因各种电线纠缠不清而导致非常混乱。从为设备供电的电线到连接计算机至键盘、打印机、鼠标和PDA的电缆,无不导致一个杂乱无

序的工作环境。在某些情况下,这回增加办公室的危险,如员工可能会被电线绊倒会被电缆缠绕。通过蓝牙无线技术,办公室里再也看不到凌乱的电线,,整个办公室也像一台机器一样有条不紊地高效运作。PDA可与计算机同步以共享日历和联系人列表,外围设备可以直接与计算机通信,员工可通过蓝牙耳机在整个办公室

区域内行走时接听电话,所有这些都无需电线连接。娱乐玩游戏、听音乐、结交新朋友、与朋友共享照片——越来越多的消费者希望能够方便及时地享受各种娱乐活动,而又不愿再忍受电线的束缚。蓝牙无线技术是一种能够真正实现无线娱乐的技术。内置蓝牙技术的游戏设备,让用户能够在任何地方

与朋友展开游戏竞技,如在地下通道、在飞机场或在起居室中。由于不需要任何电线,玩家能够轻松地发现对方,甚至可以匿名查找,然后开始令人愉快的游戏。目录4.1LED灯实验4.2开关按键实验4.3电机控制实验4.4LCD显示实验4.5设计游戏Jum

pingPong4.1Arduino开发环境4.1.1材料清单4.1.2调试代码图4-1为实验的原理图图4-1原理图4.1.2调试代码按照右图连接好电路后,就可以开始编写程序了。程序需要让LED小灯闪烁,实现点亮1秒熄灭1秒。这个程序很简单,与

Arduino自带的例程里的Blink相似,只是将13数字接口换做10数字接口。图4-2实物图4.1.3调试代码编好后,单机下载到Arduino,Arduino的编程界面就会出现下列代码。voidsetup(){pinMode(10,OUTPUT);}voidloop(){dig

italWrite(10,!(HIGH));delay(1000);digitalWrite(10,!(LOW));delay(1000);}紧接着就可以看到接到I/O口10脚上的高亮LED灯模块在闪烁了,小灯闪烁实验就完成了。注意:Arduino开发软件

的选择工具栏板卡的选项是Uno,通信端口要选择初次安装出现的串口,两项缺一不可,否则不能下载程序。图4-3Arduino的编程界面4.1.4拓展训练流水灯,用八个LED,呈现多种流水效果。图4-4实物图4.2开关按键实验4.2.1材料清单4.2.2实验原

理图4-5按键开关4.2.3硬件调试图4-6连接图按照单键控制LED连接原理图连接好电路。按键开关的一端连接5V,另一端接模拟输入的0号端口;LED阳极串联220Ω限流电阻后连接数字13号端口,阴极连接到地。连接图如图4-6所示。4.2.4程序设计2.

程序源码pinMode(LED,OUTPUT);//设置数字I/0引脚为输出模式}voidloop(){inti;while(1){i=analogRead(A0);//读取模拟0口电压值if(i>1000)//如果电压值大于1000(即4.88V)

digitalWrite(LED,HIGH);//设置第13引脚为高电平,点亮LED灯elsedigitalWrite(LED,LOW);//设置第13引脚为低电平,熄灭LED灯}3.调试及实验现象图4-8单键控

制LED实物连接图4.2.5拓展训练完成上述实验后,会发现一个问题,要想LED一直亮着就必须一直按着按键不放,很显然这是一个不切实际的做法,所以现在要实现的功能就是当按下按键并放开后,LED仍然会一直亮着。要想达到这个目的,在不修

改硬件连接的情况下,只需要对程序进行适当的修改即可(定义了state变量用来保存按键按下的状态)。下面为修改后的参考程序源代码:#defineLED13#definesw7intval=0;intold_val=0;

intstate=0;//定义状态位voidsetup(){pinMode(LED,OUTPUT);pinMode(sw,INPUT);}voidloop(){val=digitalRead(sw);if((val==HIGH)&&(old_val==LOW)){state=1-state;//状

态位取反delay(10);}old_val=val;if(state==1){digitalWrite(LED,HIGH);}else{digitalWrite(LED,LOW);}将上述代码下载到开发板上后,可以发现,当按下按键并松开后,LED灯不会熄灭,而是一直亮着。该功能的实现主要归功于上

述参考程序中定义的state变量保存了按键按下的状态。4.3电机控制实验4.3.1材料清单4.3.2实验原理随着数字化技术的发展,数字控制技术得到了广泛而深入的应用。步进电机是一种将数字信号直接转换成角位移或线位移的控制驱动元件,具有快速启动和停止的特

点。因为步进电动机的控制系统结构简单,价格低廉,性能上满足工业控制的基本要求,所以广泛地应用于手工业自动控制,数控机床,组合机床,机器人,计算机外围设备,照相机,投影仪,数码摄像机,大型望远镜,卫星天线定位系统,医疗器件

以及各种可控机械工具等。直流电机广泛应用于计算机外围设备(如磁盘,软盘和光盘存储器),家电产品,医疗器械和电动车上,无刷直流电机的转子普遍使用永磁材料组成的磁钢,在航空,航天,汽车,精密电子等行业被广泛应用。在电工设备中的应用,除了直流电磁铁(直流继电器,直流接触器等)外,最重要的就是在直

流旋转电机中的应用。在发电场里,同步发电机的励磁机,蓄电池的充电机等,都是直流发电机;锅炉给粉机的原动机-是直流电动机。此外,在许多工业应用场合,列如大型轧钢设备,大型精密机床,矿井卷扬机,市内电车,电缆设备等严格要求线速度一致的地方,通常都采用直流电动

机作为原动机来拖动工作机械。直流发电机通常作为直流电源,向负载输出电能;直流电动机则作为原动机带动各种生产机械工作,向负载输出机械能。在控制系统中,直流电机还有其他的用途,例如测速电机,伺服电机等,它们都是利用电和磁的相互作用来实现向机械能的转换。步进电机是将电脉冲信号转变

为角位移或线位移的开环控制元件。在非超载的情况下,电机的转速,停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,即给电机加一个脉冲信号,电机就转过一个步距角。由于这一线性关系的存在,加上步进电机具有只有周期性

的误差而无累计误差等特点,所以步进电机在速度,位置控制等领域应用广泛,使用步进电机后使很多原本复杂的控制变得非常简单。一般采用软件延时的方法来对步进电机的运行速度,步数及方向进行控制。根据计算机所发出脉冲的频率和数量所需的时间来设计一个字程序,该子程序包含一定的指令,设计者通常要对这些指

令的执行时间进行严密的计算或者精确的测试,以便确定延长时时间是否符合要求,每当子程序结束后,可以执行下面的操作。采用软件延时方式时,cpu一般被占用,cpu利用率低,这些许多场合是非常不利的。因此需要重新设计步进电机的控制程序

,采用pcl-812PG数据采集卡,利用812PG卡中自带的可编程计数/定时器8254及其他逻辑电路器件,设计一种步进电机控制方式,仅需要几条简单的指令就可以产生具有一定频率和数目的脉冲信号。可编程的硬件定时器直接对系统时脉冲或某一固定频率的时钟脉冲进行计数,计数值

则由编程决定。当计数到预定的脉冲数时,给出定时时间到的信号,得到所需的延时时间或定时间隔,由于计数的初始值由编程决定,因此在不改动硬件的情况下,只通过程序的变化即可满足不同的定时和计数要求,使用很方便。4.3.3硬件调试4.3.4程序设计1.步进电机实验软件流程自增自减运

算符是一类特殊的运算符,其中,自增运算符(++)和自减运算符(--)对变量的操作结果是增加1和减少1。图4-10步进电机试验软件流程图2.步进电机实验程序#include<Stepper.h>//这里设置步进电机旋转一圈是多少步#define

STEPS100//设置步进电机的步数和引脚Stepperstepper(STEPS,8,9,10,11);//定义变量用来存储历史读数intprevious=0;voidsetup(){//设置电机每分钟的转速为90步stepper.setSpeed(90);}void

loop(){intval=analogRead(0);//移动步数为当前读数减去历史读数stepper.step(val-previous);//保存历史读数previous=val;}4.3.5拓展训练1.直流电机的工作原理直流电机是指能将直流电能转换成机械能的机械设备,因其良好的调速性

能而在电力拖动中得到广泛应用。直流电动机按励磁方式分为永磁,它励和自励三类,其中自励又分为并励,串励和复励3种。本文不对直流电机原理进行深入研究,只是大概介绍一下。其实在本实验主要是关注直流电机是有刷电机还是无刷电机,因为有刷电机干扰很大,会对A

rduino以及其他外围芯片造成干扰,甚至会导致芯片复位,所以只从有刷和无刷这两类大致进行介绍。(1)有刷直流电动机。有刷电动机的2个刷(铜刷或者钢刷)是通过绝缘座固定在电动机后盖上,直接将电源的正负极引入到转子的换相器上,而换相器连通了转子的线圈,

3个线圈极性不断地交替交换与外壳上固定的2块磁铁形成作用力而转动起来。由于换相器与转子固定在一起,而刷与外壳(定子)固定在一起,电动机转动时刷与换相器不断地发生摩擦产生大量的阻力与热量。所以,有刷电机效率较低。

但是,它具有制造简单,成本低廉的优点。(2)无刷直流电动机无刷直流电动机是将普通直流电动机的定子与转子进行了互换。其转子为永久磁铁,产生气隙磁通;定子为电枢,由多相绕组组成。在结构上,它与永磁同步电动机类似。无刷直流电动机定子的结构与普通的同步电动机或感应电动机相同,在铁芯

中嵌入多相绕组(三相,四相,五相不等),绕组可接成星行或三角形,并分别与逆变器的各种率管相连,以便进行合理换相。转子多采用钐钴或钕铁硼等高娇顽力,高剩磁密度的稀土料,由磁极中磁性材料所放位置的不同,可以分为表

面式磁极,嵌入式磁极和环形磁极。由于电动机本机为永磁电机,所以习惯上把无刷直流电动机也叫做永磁无刷电动机。2.驱动芯片驱动步进电机用的是ULN2003。由于只用了4个引脚,ULN2013还有3个空闲的驱动引脚。另外,为

了使电路简单,就直接用ULN2003剩余的一个引脚来驱动了。因此,也只能驱动电机朝一个方向转动。3.驱动电路由于使用的是直流电机,干扰较大,驱动电路就要多作一些消除干扰的设计,常见的有在电机两端串联手感,加电容等方法

。这里只加了续流二极管和电容,如图4-11所示,其中Arduino的12脚接ULN2003的第7脚。图4-11电路图4.4LCD显示实验4.4.1材料清单4.4.2实验原理液晶显示器简称LED(liquidcrystal

display),其结构是在两片平行的玻璃基板当中放置液晶盒,下基板玻璃上设置TFT(薄膜晶体管),上基板玻璃上设置彩色滤光片,通过TFT上的信号与电压改变来控制液晶分子的转动方向,从而达到每个像素带点偏振光出射的目的。现在LED已经替代CRT成为主流,价格已经下降了很多,其普及速度

相当快。1602液晶也叫1602字符型液晶,是指显示的内容为16*2(即可以显示两行),每行16个字符的液晶模块(显示字符和数字),是一种专门来显示字母,数字,符号等的点阵型液晶模块。它由若干个5*7或者5*11等点阵字符位组成,每个

点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到字符间距和行间距的作用。因此。1502型液晶不能很好地显示图形(用自定义CGRAM,显示效果也不好),但非常适合便携式及低功耗测试设备。市

面上的字符型液晶大多数是基于HD44780液晶芯片的,控制原理完全相同,因此基于HD44780所编写的控制程序可以很方便地应用于市面上大部分的字符型液晶。本实验是驱动1602液晶显示文字。4.4.3硬件调

试4.4.4程序设计4.5JUMPINGPONG4.5.1功能构思Jumpingpong.主要功能包括以下几个方面的内容:(1)8乘8点阵的应用(6)光敏电阻实现光控开关。(2)红外遥控的接收与发射。

(7)模块连接。(3)语音模块的使用。(4)1602LCD显示屏显示分数。(5)游戏摇杆模块实现球拍移动。4.5.2设计原理1.设计思路将游戏代码封装在一个函数game中,改变gane中控制球速的代码将游戏分为不同等级和单双人模式,在游

戏开始前,先判断周围环境的光照强度,当光强大于一定值时再继续执行紧接着的功能。之后,判断是否接到红外信号,当接收到特定值得信号时,调用game函数,游戏开始。每当球碰到一次拍子,分数就自动加1,实现计分功能。当一方未接到球时,游戏结束,

显示分数及下一步功能选择。如此反复,在游戏进行中,不断刷新光敏电阻的值,判断是否符合光强条件,以保证游戏功能正常运行。2.各模块电路连接所需材料:Arduino主板和扩展板(各1个),8×8点阵(1个),MAX7219驱动芯片(1个),面包

板(2块),LCD显示屏(1个),语音模块(1个),导线若干,游戏摇杆模块(2个),小喇叭(1个),红外线遥控和光敏电阻(各1个)。电路连接分为8×8点阵部分,红外线遥控都分,光敏电阻部分,1602LCD显示屏部分及总体电路,分别如图4-14、

4-15、4-16、4-17所示。图4-148*8点阵连接ArduinoUNO图4-15红外遥控部分图4-16光敏电阻部分图4-17LCD显示屏部分4.6打地鼠游戏机设计一个打地鼠游戏机,该设计中4个LED灯,对应4

个按键,每秒生成一个1~4的随机数,对应点亮相应的LED灯,在下次随机数生成之前判断相应的按键是否按机数频率变为0.8s一次,完成10次操作后频率变为0.4s一次,以此类推,0.2s的情况下完成10次操作游戏结束。蜂鸣器鸣叫5声,频率5Hz。在游戏过程中,错误

3次也游戏结束,蜂鸣器鸣叫3声,频率5Hz。4.6.1功能构思4.6.2设计原理利用Arduino主板及其相应的一系列配件实现具有“打地鼠”功能的一个简易游戏机。打地鼠游戏的本质,即人要根据不同的信号提示做出不同的行为。利用不同的光信号的视觉刺激,即人眼在看见不同的灯发光时按下

相应的按键。电路连接如图4-18所示。图4-18电路连接图目录5.1制作智能小车5.2采用驱动模块进行控制5.3材料清单5.4机械零件设计5.5实物拼装5.6成品实物图5.7项目拓展-智能巡线避障小车5.1制作智能小车大部分同学小的时候都梦想有一台属于自己的四驱车,并且好奇为什么通电四驱车就会跑起

来,接下来的章节将介绍四驱车的工作原理以及带领同学们了解电机的类型并且让同学们制作出属于自己的智能小车。5.1.1直流电机直流电机(directcurrentmachine)是指能将直流电能转换成机械能(直流电动机)或将机械能转换成直流电能(直流发电机)的旋转电机。它是能实现直流

电能和机械能互相转换的电机。当它作电动机运行时是直流电动机,将电能转换为机械能;作发电机运行时是直流发电机,将机械能转换为电能。直流电机示意图如图5-1所示。图5-1常见的直流电机5.1.2直流无刷电机的控制原理直流无刷电机的控制原理,要让电机转动起来,首先控制部就必须根据ha

ll-sensor感应到的电机转子所在位置,然后依照定子绕线决定开启(或关闭)换流器(inverter)中功率晶体管的顺序,inverter中之AH、BH、CH(这些称为上臂功率晶体管)及AL、BL、CL(这些称为下臂功率晶体管),

使电流依序流经电机线圈产生顺向(或逆向)旋转磁场,并与转子的磁铁相互作用,如此就能使电机顺时/逆时转动。当电机转子转动到hall-sensor感应出另一组信号的位置时,控制部又再开启下一组功率晶体管,如此循环电机就可以依同一方向继续转动直到控制部决定要电机转子停止则关闭功率晶体管(或只开下臂功

率晶体管);要电机转子反向则功率晶体管开启顺序相反。基本上功率晶体管的开法可举例如下:AH、BL一组→AH、CL一组→BH、CL一组→BH、AL一组→CH、AL一组→CH、BL一组,但绝不能开成AH、AL或BH、BL或CH、CL。此外因为电

子零件总有开关的响应时间,所以功率晶体管在关与开的交错时间要将零件的响应时间考虑进去,否则当上臂(或下臂)尚未完全关闭,下臂(或上臂)就已开启,结果就造成上、下臂短路而使功率晶体管烧毁。当电机转动起来,控制部会再根据驱动器设定的速度及加/减速率所组成的命令

(Command)与hall-sensor信号变化的速度加以比对(或由软件运算)再来决定由下一组(AH、BL或AH、CL或BH、CL或……)开关导通,以及导通时间长短。速度不够则开长,速度过头则减短,此部份工作就由PWM来完成。PWM是决定电机转速快或慢的方式,如何产生这样的P

WM才是要达到较精准速度控制的核心。高转速的速度控制必须考虑到系统的CLOCK分辨率是否足以掌握处理软件指令的时间,另外对于hall-sensor信号变化的资料存取方式也影响到处理器效能与判定正确性、实时性。至于低转

速的速度控制尤其是低速起动则因为回传的hall-sensor信号变化变得更慢,怎样撷取信号方式、处理时机以及根据电机特性适当配置控制参数值就显得非常重要。或者速度回传改变以encoder变化为参考,使信号分辨率增加以期得到更佳的控制

。电机能够运转顺畅而且响应良好,P.I.D.控制的恰当与否也无法忽视。之前提到直流无刷电机是闭回路控制,因此回授信号就等于是告诉控制部电机转速距离目标速度还差多少,这就是误差(Error)。知道了误差自然就要补偿,方式有传统的工程控制如P.I.D.控制。但控制的状态及环

境其实是复杂多变的,若要控制的坚固耐用则要考虑的因素恐怕不是传统的工程控制能完全掌握,所以模糊控制、专家系统及神经网络也将被纳入成为智能型P.I.D.控制的重要理论。5.1.3直流电机的控制直流电机控制方法较为简单,可以采用Arduinouno直接控制,具体控制

连接原理图如图5-2所示。控制代码也相对简单,具体如下文所示。图5-2直流电机控制连接图简单控制的示例:voidsetup(){pinMode(3,OUTPUT);}voidloop(){digitalWrite(3,HIGH);delay(2000);pinMode(3,OUTPUT);}in

tmotorpin=3;voidsetup(){}voidloop(){for(intfadeValue=0;fadeValue<=255;fadeValue+=50){analogWrite(motorpin,fadeValue);delay(2000);}f

or(intfadeValue=255;fadeValue>=0;fadeValue-=50){analogWrite(motorpin,fadeValue);delay(2000);}}5.2采用驱动模块进行控制驱动模块根据功能、性能分为很多种类,本节根据实

际需求将介绍L298N驱动模块。L298N是一种高电压、大电流电机驱动芯片。该芯片采用15脚封装。内含两个H桥的高电压大电流全桥式驱动器,可以用来驱动直流电动机和步进电动机、继电器线圈等感性负载;采用标准逻辑电平信号控制;具有两个使能控制端,在不受输入信号影响的情况下允许或禁止器件工作有一

个逻辑电源输入端,使内部逻辑电路部分在低电压下工作;可以外接检测电阻,将变化量反馈给控制电路。使用L298N芯片驱动电机,该芯片可以驱动一台两相步进电机或四相步进电机,也可以驱动两台直流电机。接口定义如图5-3所示,Arduino+L298N驱动直流电机接线方式

如图5-4所示,接线方法如图5-5所示。图5-3接口定义(1)简单示例图5-4Arduino+L298N驱动直流电机接线方式*当ENA使能IN1IN2控制OUT1OUT2*当ENB使能IN3IN4控制OUT3OUT4由于本模块是2路的H桥驱动,所以可以同

时驱动两个电机,使能ENAENB之后,*可以分别从IN1IN2输入PWM信号驱动电机1的转速和方向*可以分别从IN3IN4输入PWM信号驱动电机2的转速和方向图5-5接线方法(2)接线方式IN1-4分别接Arduinomega2560的PIN4-7,将L298N

上的ENA、ENB插口上的插销拔掉,随后,将ENA与Arduinomega2560的PIN11脚相连,ENB与Arduinomega2560的PIN8相连。连线示意图如图5-6所示。IN1接PIN4;IN2接PIN5;IN3接PIN6;IN4接PIN7;ENA接PIN11;ENB接PIN

8;图5-6连线示意图示例:#definemotor1pin14//定义IN1引脚#definemotor1pin25//定义IN2引脚#definemotor1pwm11//定义ENA引脚(我的是Mega2560的板子)#definemotor2pin16//定义I

N3引脚#definemotor2pin27//定义IN4引脚#definemotor2pwm8//定义ENB引脚voidmotor(intmotorpin1,intmotorpin2,intmotorpwm,

intval){pinMode(motorpin1,OUTPUT);//输出第一个引脚pinMode(motorpin2,OUTPUT);//输出第二个引脚digitalWrite(motorpin2,0);//将第二个引脚置低digitalWrite(motorpin

1,1);//将第一个引脚抬高analogWrite(motorpwm,val);//给EN引脚设定模拟值,设定转速}voidsetup(){}voidloop(){inti;for(i=100;i<=2

55;i++)//让电机的转速从100到255转动,A,B转速不一样,完成转向{motor(motor2pin1,motor2pin2,motor2pwm,255);//电机B保持255匀速转动motor(motor1pin1,motor1pin2

,motor1pwm,i);//电机A从100到255转动delay(500);//间隔500ms}for(i=100;i<=255;i++)//让电机从100到255转动,功能同上{motor(motor1pin1,motor1pin2,motor1pwm,255);motor

(motor2pin1,motor2pin2,motor2pwm,i);delay(500);}motor(motor1pin1,motor1pin2,motor1pwm,255);//电机A以最大转速转动delay(5000);motor(motor1pin2,motor1pin

1,motor1pwm,255);//电机A反向转动delay(5000);}程序效果:直流电机B电机匀速转动,A电机从100加速到255转动.5.3材料清单材料清单序号元器件名称型号参数规格数量参考实物图1ArduinoMega25601个2万向轮1寸全局从动转向轮1个3语言模

块非特定人声语音识别模块1个4铜柱M3*64个5螺丝M3*8126螺母M3127杜邦线20cm公对母18电池盒四节电池盒19小车底盘网购(有条件可自己3d打印,或者使用洞洞板代替)110橡胶车轮直径65mm轴孔长5.3mm211电机DC3V-6V直流减速电机212开关小型开关113驱动板L298N

114蓝牙串口模块HC-051个2.上述清单中的材料中有几处需要特别注意:(1)第11项直流减速电机,一定要按照要求购买减速电机,否则将会像市面上的玩具赛车一样一经上电就具有很高的速度。这样及其容易烧毁电路。(2)第3项是本项目的语音识别、对话功能实现的

模块。之所以选择这个型号是因为其内置了较大的存储空间,用户可以自行定义2000句的对话。可以实现人和机器人的对话交流,也能实现用户对机器人的语音控制功能。该语音模块有三个版本,分别是核心板、升级版和完全版。核心板的价钱相对较低,本

项目建议使用该版本。如果有同学想额外增加语音方面的功能和有这方面需求,可以选择后面两个版本。(3)项目2中万向轮亦可以用牛眼轮来替代。(4)项目14中需购买HC-05种类的蓝牙串口模块,HC-05主从端一体

,可以进行信号的转化。比较出色的完成遥控任务5.4机械零件设计下车底板零件图如图5-7所示,立体图如图5-8所示。图5-7小车底板零件图图5-8小车地板立体图本节所提供的零件都是3D建模,自行打印完成的,在打印时需要注意小车地板上的螺丝口以及细小的口,以免后期因为当时的马

虎而造成不必要的损失。5.5实物拼装底板拼装实物图如图5-9所示。图5-9底板拼装实物图5.5.1电路设计智能声控小车主要由转向机构、驱动机构、驱动控制模块(Mega2560)、语音控制模块四大部分组成小车为轮式结构,机械部分分为转向机构和驱动机构(Mega2560)转向机构主要由转

向电机、转向架和万向轮轮组成驱动机构采用玩具小车常用的双电机驱动方案,包括两个减速电机和Mega2560,其原理为:转向时由控制语音者向小车发出转向信号,语音控制模块向Mega2560发送指令信息,Mega2560再发送信号给转向电机,转向电机根据转向信号正向或反向旋转一定角度,电机通过齿

轮、齿条系统带动转向架摆动一定角度,最终带动与转向架固定在一起的前轮偏摆一定角度小车在转向时由于内、外侧的车轮的转弯半径不同,所以内外侧车轮的转速也不相同前轮为从动轮,会根据转弯角度的大小自动调节内、外侧车轮的转速;而后

轮为主动轮,其转速分别由两个电机独立驱动,不会根据转弯半径自动调节转速因此小车转弯时,控制系统在控制转向电机的同时还需要根据转向角度的大小向两个驱动电机发出控制信号。连接图如图5-10所示。图5-10连接图5.5.2语音识别模块连接1.本项目语言识别

模块使用了WEGASUN-M6核心板。该模块一款集语音识别、语音合成、语音(MP3)点播、RF(射频)功能、红外功能于一体的多功能模块。目前主要应用在智能家居、对话机器人、车载调度终端、高端智能语音交互玩具、楼宇智能化

、教育机器人等方面。主打傻瓜式的简易操作、优越的语音识别和语音合成性能,应用领域十分广泛。2.模块连接方法语音识别模块与Arduino2560接线方法:语音模块TXD---2560RX1语音模块RXD---2560TX1语音模块GND---2560GN

D语音模块3V3---25603.3V同时,注意语音识别模块的供电。如果发现语音识别模块的3.3V电压从2560的3.3V引脚取电无法进行语音识别或者播放语音,那请将语音识别模块的5V电源输入端接到UNO的VIN引脚端,并且选择外部9V的电源适配器给2560供电,这样就有充足

的电流和电压了。实物连接图如图5-11所示。图5-11实物连接图3.程序代码1.核心板代码@KeyWordBuf02#前进001|后退002|$@KeyWordBuf04#左转003|右转004|$@KeyWordBuf04#停止005|$@WriteKeyWord

Buf#$@WriteFlashText#|001!|002!|003!|004!|005!|$2.ArduinoMega2560代码voidsk(){val=Serial2.read();if(-1!=val){if(1==val){digitalWrite(4,HIGH);digital

Write(7,HIGH);analogWrite(5,250);analogWrite(6,250);}if(2==val){digitalWrite(4,LOW);digitalWrite(7,LOW);analogWrite(5,250);analogWrite(6,250);

}if(3==val){digitalWrite(4,LOW);digitalWrite(7,HIGH);analogWrite(5,240);analogWrite(6,240);}if(4==val){digitalWrite(4,H

IGH);digitalWrite(7,LOW);analogWrite(5,240);analogWrite(6,240);}if(5==val){analogWrite(5,0);analogWr

ite(6,0);}}}4.蓝牙控制蓝牙小车原理:app设定编码-->通过手机蓝牙发送编码-->HC05收到编码,发送到Arduino2560板子-->板子解析编码-->控制电机。下图5-12为蓝牙控制手机控制端截图。图5-12蓝牙控制手机控

制端截图点击打开app之后,首先会自动弹出提示要求打开手机蓝牙,可以看到四个方向箭头以及中间停止,用来控制小车前进后退左转右转,做这些操作前提是要连接上蓝牙小车的蓝牙模块HC05.所以需要首先点击右下角很像螺母的图标弹出下图5-13蓝牙设备连接示意图。图

5-13蓝牙设备连接示意图如果没有图5-13所示,请点击搜索蓝牙设备,不出意外应该会看到一个HC06,没有的话请确保你的蓝牙模块电源连接正确。看到HC06,点击一下,如果是第一次配对,是需要输入密码:默认是0000或者

1234.如果配对过,点击就自动连接了。蓝牙小车前进后退左转右转停止,都是一种状态,所以我们用编码去区分。在我的app里,我默认设置为:前进3后退4左转1右转2停止0。当然,也可以自定义编码,点击左下角进入设置页面、如图5-14、5-15所示

。图5-14设置界面编码只能是0-9数字以及大小写26个字母,足够使用。图5-15设置自定义说完app端,要说一下怎么测试编码是否正确。把下面代码烧入Arduino2560板子:voidsetup(){//putyourset

upcodehere,torunonce:Serial.begin(9600);}voidloop(){//putyourmaincodehere,torunrepeatedly:if(Serial.available()>0){charch=Serial.read();i

f(ch=='1’){//前进Serial.println("up");}elseif(ch=='2’){//后退Serial.println("back");}elseif(ch=='3’){//左转S

erial.println("left");}elseif(ch=='4’){//右转Serial.println("right");}elseif(ch=='0’){//停车Serial.println(

"stop");}else{//其他编码Serial.println(ch);}}}然后就可以用ArduinoIDE自带的串口调试器来查看,不出意外应该可以看到类似下面的打印,如图5-16所示。图5-16打印结果5.6成品实

物图电路细节图如图5-17所示,侧视图如图5-18所示,主视图如图5-19所示图5-17电路细节图图5-18侧视图图5-19主视图1.材料准备材料清单如表5-2所示,底板实物图如图5-20所示,电路连接图如图5-21所示,车前实物图如图5-22所示,小车与遥控器的电路连接图如图5-23

所示。5.7项目拓展-智能巡线避障小车元器件名称参数规格数量参考实物图巡线传感器SEN1595-1D7超声波SRF-041图5-20实物图图5-21电路连接图图5-22实物图图5-23小车与超声波的电路连接图#include<

Servo.h>//#definesendServomyservo;intEcho=A1;//Echo回声脚(P2.0)intTrig=A0;//Trig触发脚(P2.1)intin1=5;intin2=4;intin3=3;intin4=2;intrightDistanc

e=0,leftDistance=0,middleDistance=0;voidforward(){digitalWrite(in1,HIGH);digitalWrite(in2,LOW);digitalWrite(in3,HIGH);digitalW

rite(in4,LOW);}voidback(){digitalWrite(in1,LOW);digitalWrite(in2,HIGH);digitalWrite(in3,LOW);digitalWrite(in4,HIGH);}voidturnleft(){digital

Write(in1,HIGH);digitalWrite(in2,LOW);digitalWrite(in3,LOW);digitalWrite(in4,HIGH);}voidturnright(){digitalWrite(in1,LOW);digitalWrite(in2

,HIGH);digitalWrite(in3,HIGH);digitalWrite(in4,LOW);}voidstop(){digitalWrite(in1,LOW);digitalWrite(in2,LOW);digitalWrite(in3,LOW);digital

Write(in4,LOW);}intDistance_test()//量出前方距离{digitalWrite(Trig,LOW);//给触发脚低电平2μsdelayMicroseconds(2);digitalWr

ite(Trig,HIGH);//给触发脚高电平10μs,这里至少是10μsdelayMicroseconds(20);digitalWrite(Trig,LOW);//持续给触发脚低电floatFdistance=pulseIn(Echo,HIGH);//读取高电平时间(单位:微秒)Fdist

ance=Fdistance/58;//为什么除以58等于厘米,Y米=(X秒*344)/2//X秒=(2*Y米)/344==》X秒=0.0058*Y米==》厘米=微秒/58return(int)Fdistance;}voidsetup(){myservo.attach(9);Serial.be

gin(9600);//初始化串口pinMode(Echo,INPUT);//定义超声波输入脚pinMode(Trig,OUTPUT);//定义超声波输出脚pinMode(in1,OUTPUT);pinMode(in2,OUTPUT);pinMode(in

3,OUTPUT);pinMode(in4,OUTPUT);stop();}voidloop(){myservo.write(90);delay(500);middleDistance=Distance_test();#ifdefsendSerial.print("middleDi

stance=");Serial.println(middleDistance);#endifif(middleDistance<=20){stop();delay(500);myservo.write(5);delay(1000);rightDistance=Distance_test();#i

fdefsendSerial.print("rightDistance=");Serial.println(rightDistance);#endifdelay(500);myservo.write(90);delay(1000);myservo.

write(175);delay(1000);leftDistance=Distance_test();#ifdefsendSerial.print("leftDistance=");Serial.println(leftDistance);#endif

delay(500);myservo.write(90);delay(1000);if(rightDistance>leftDistance){turnright();delay(450);}elseif(rightDistance<leftDistance){turnleft();del

ay(450);}else{forward();}}elseforward();}目录6.1设计思想6.2材料清单6.3机械零件设计6.4组装流程6.5电路设计6.6步态设计6.7红外控制设计6.8成品实物图6.1设计思想六足仿生机器人俗称蜘蛛机器人,因其运动方式有着其他机器人不具有的能力优势流动

性良好,能适应各种崎岖路面,且能耗较少,主要用于军事侦察、太空探索、救灾、抢险救灾等方面,还可应用于家庭娱乐、机器人教育等领域,有着较为广阔的应用前景。本项目的仿生蜘蛛机器人主要由控制板,18个舵机(六条腿),稳压器

,无线模块和一些数据采集传感器(温度传感器等)组成。本项目的蜘蛛机器人有丰富的扩展接口,后期可根据各种应用领域的需要扩充相应的传感器和功能模块,完全能够胜任视觉定位、自主规划判断路径、多传感器组合扩展等功能,具有语音控制、人机对话等多种功能,应用领域广泛、市场前景良好。6.2材料清单材料清

单如表6-1所示。材料清单序号元器件名称型号参数规格数量参考实物图1固定板上自行打印1块详见6.32固定板下自行打印1块详见6.33膝关节自行打印12个详见6.34胫关节自行打印12个详见6.35踝关节自行打印6个详见6.36脚部支撑自行打印6个详见6.37ArduinoMega2560

1个8舵机控制器32路1个9语音模块非特定人声语音识别模块核心版1个10红外避障C7A4611超声波传感器HC-SR04超声波测距模块112openmvCamM4-OV77251个13云台支架自行打印1套14数字舵机MRS-D2009SP1915电池1200mA/7.4v一个16杜邦线30cm公

对母一捆17杜邦线20cm公对母2捆18红外接收器VS1838B通用一体化红外接收头一个19遥控器ps2无线手柄一个20螺丝M1.6*5144个21螺丝M1.6*2072个22螺丝M3*836个23螺母M312个上述清单中的材料中有几处需要特别注意:1.第8项舵机控制器之所以选用了32路

是为了日后扩展其他功能所预留的通道,如果没有其他特殊需求,实际上24路舵机控制器就可以满足需要,本项目至少需要使用12路以上舵机控制器,各位同学制作的时候可以根据自己的实际需求选定。此外,六足仿生机器人和四足仿生机器人、八足仿生机器人的控制原理

基本相同,舵机控制调用方式相同,传感器连接设计方法相同,这些内容后面会陆续介绍,唯一不同的是步态姿势不同。各位有兴趣的同学可以在本项目设计完成之后,自行设计其他足数的仿生机器人。2.第9项是本项目的语音识别、对话功能实现的模块。之所以选择这个型号是因为其内置了较大的存储空间,用

户可以自行定义2000句的对话。可以实现人和机器人的对话交流,也能实现用户对机器人的语音控制功能。该语音模块有三个版本,分别是核心板、升级版和完全版。核心板的价钱相对较低,本项目建议使用该版本。如果有同学想额外增加语音方面的功能和有这方面需求,可以选择后面两个

版本。3.第12项OPENMV模块是本项目的视觉模块,因其与Arduino兼容性较好,功能调用较为容易而选用。本模块用两个版本,分别为M4和M7。M4版本固件版本较低,芯片处理速度低于M7,但是其价格

便宜,实现的功能基本相同,没有特别需求的同学可以选择M4版本。第13项云台支架本项目使用的是自行建模3D打印的零件,主要目的是降低开发成本。如果有同学想要性能更好的云台或者完成某些测绘、监控任务的需求,可自行选装市

面上的各种二轴、三轴无刷云台,提高性能的同时不影响本项目机器人的其他功能实现。第14项中的数字舵机,各位同学也可以根据实际需求选择市面上的数字舵机,根据需要可以选用180度或者270度的数字舵机。舵机的扭矩规格可以根据实际情况选用15KG-20kg之间。但是不建议同学们

选用模拟舵机,因为模拟舵机需要不断的接受舵机控制器发送的PWM信号才能保持锁定角度,完成相应的操作,并且精度较差,线性度很难达标。而数字舵机仅需接受一次舵机控制器传递的PWM信号就可以锁定角度不变,控制精度较高、线性度良好、相应速度快,能够完成本项目的

各项功能需要。特别值得注意的是,并不是舵机的转动角度越大越好,同学们不要选用360度舵机,因为目前市面的无死角舵机绝大部分无法接受PWM信号控制,不能锁定角度不变,一经上电会不停旋转。6.第18项和第19项的红外接收模块和红

外手柄(遥控器)是配套使用的。因成本低廉,本项目选用了红外控制方式。但是同学们需要注意的是,红外接收控制有较多的限制,控制距离较近,不能有明显的遮挡物,并且在电子设备较多的复杂情况容易造成信号丢失,从而导致对机器人失去控制。有条件的同学可以根据本书前几章的内

容,选用蓝牙、WiFi、2.4G技术等控制方式,不影响机器人的其他功能实现。6.3机械零件设计机械零件包括机身固定板上下两部分、12个膝关节、12个胫关节、6个踝关节和6个脚步支撑部件组成,这些零件的设计图和装配图都在下文中给出。本项目的机

械零件采用SolidWorks建模生成。该软件功能强大,能够胜任大部分的工程制图,最重要的是其操作简单、易学易用,特别适合新手使用。各零件图如下图6-1、6-2、6-3、6-4、6-5、6-6、6-7所示。图6-1底板零件图图6-2踝关节零件图图6-3上板零件图图6-4

膝关节零件图图6-5足零件图图6-6云台零件图图6-7踝关节零件图本节所提供的零件都是3D建模,自行打印完成的,上述所有模型的尺寸单位都是mm。虽然作者使用的建模软件是SolidWorks,同学们也可以根据自己平时的喜好和习惯选

用其他的建模软件操作,只要按照上图所给出的尺寸设计就可以,但是输出文件一定要选择.stl格式的才可以,因为目前市面上常用的桌面级3D打印机和准工业级3D打印机仅支持这种文件格式。另外,3D打印机原则上是选用精度越高的越好,但是同学们往往接触到的都是入门级别的设备,所以上

述零件图各插口没有做的特别细小,一般的打印机都可以完成。上述零件打印的最低要求标准是机器打印精度0.2mm,打印层高0.4mm6.4组装流程6.4.1六足组装步骤一:把两个膝部关节固定在一起,示意图如图6-8、6-9所示图6-8固定示意图(1)图6-9固定示意图(2)步骤

二:把膝部舵机和上一步的零件一起固定,固定过程分解图如图6-10、6-11、6-12所示。图6-10固定示意图(1)图6-11固定示意图(2)图6-12固定示意图(1)步骤三:将上一步完成的内容与胫部关节连接件固定,示意图如下图6-13、6-14所示。图6-

13固定示意图(1)2.2.3运算符1.赋值运算符赋值语句的作用是把某个常量、变量或表达式的值赋给另一个变量。C语言中,符号为“=”这里并不是等于的意思,只是赋值,等于用“==”表示。注意:赋值语句左边的变量在程序的其他地方必须声明。图6-14固定示意图(2)步骤四:

完成胫部和踝部的连接,连接示意图如图6-15、6-16所示。图6-15连接示意图(1)图6-16连接示意图(2)步骤五:将踝部、胫部、膝部所有零件固定,固定示意图如图6-17、6-18所示。图6-17固定示意图(1)图6-18固定示意图(2)步骤六:重复前面五个步

骤,完成其他五条腿的组合。6.4.2身体部分组装步骤一:安装云台,示意图如下6-19、6-20.图6-19安装示意图(1)图6-20安装示意图(2)步骤二:将上板,底板,云台与6只腿拼装起来,拼装示意图如图6-21、6-22、6-23.图6-21拼装示意图(

1)图6-22拼装示意图(2)图6-23拼装示意图(3)组装过程中,如果各别零件因为打印的原因无法按进螺丝或者打印件有抽丝,可以有刻刀将孔洞适当的钻一下,但是一定要注意力度,不要将孔钻的过大。上螺丝的时候不易将螺丝拧的过紧,因为PL

A素材相对较脆,打印机崩的太紧极易造成碎裂。此外,机身上板不要提早上螺丝,要按系统硬件连接图将主控板和传感器固定后再安装机身上盖。机身整体布线要尽量简洁工整,不要让舵机线裸露在外面。尽量将所有传感器调试好后,确定布线没问题了再固定,避免重复工作。6.5电路设

计6.5.1机器人硬件系统框图如下图6-24所示,通过机器人模式的选择,语音控制模块、是视觉模块或者其他传感器将采集到的数据传输给主控板ArduinoMega2560,主控板将收到的数据进行处理编译,并将执行命令传输给舵机控制器,

舵机控制器根据主控板发送的命令进行操作,驱动相对应的舵机完成指定命令,最终实现对六足机器人的控制。图6-24系统框架图6.5.2主板连接1.ArduinoMega2560原理图原理图如图6-25所示。

图6-25ArduinoMega2560原理图本系统之所以使用ArduinoMEGA2560作为控制板是因为2560具有较高的性价比,具有14路数字输入输出口,4路串口信号,6路外部中断,14路脉冲宽度调制,具有丰富的扩展功能。实际

上本设计的基本功能,ArduinoLeonardo也能够实现,但是从后期开发和扩展等方面原因考虑,选择2560无疑为本项目提供了不断升级的可能。2.系统硬件连接图6-26系统硬件连接图图6-26是系统的主要部件连接图,Arduino在这里起到

了一个中间协调的作用,视觉模块将采集的信息传输给2560,2560接收到信息并进行处理后发出指令到舵机控制器,舵机控制器转出相应的命令对舵机进行控制。同理其他的传感器也是这个工作原理。6.5.3视觉模块连接1.视觉模块本项目采用了OPENMV视觉模块。Openmv搭载Micr

oPython解释器,允许用户在嵌入式上使用Python来编程.Python使机器视觉算法的编程变得简单得多。比如,直接调用find_blobs()方法,就可以获得一个列表,包含所有色块的信息。使用python遍历每一个色块,就可以获取它们所有信息。并且,用户可以使用OpenMV专用的IDE,它有

自动提示,代码高亮,而且有一个图像窗口可以直接看到摄像头的图像,有终端可以debug,还有一个包含图像信息的直方图。OpenMV摄像头使用标准M12镜头,以更换不同焦距的镜头。而且,OpenMV采用可叠加的

设计,方便用户添加各种各样的shield。2.openmv与Arduino的通信OPENMV与Arduinomega2560连接通信方法如表6-1和图6-27所示。表6-1对应引脚关系图图6-27硬件连接示意图3.程序代码OPEN

MV上的代码(python)importsensor,image,timefrompybimportUARTyellow_threshold=(60,80,20,40,20,45)###########

########################################################################################_autosensor.reset()sensor.set_pixformat(sensor.RGB56

5)sensor.set_framesize(sensor.QQVGA)sensor.skip_frames(10)sensor.set_auto_whitebal(False)clock=time.clock()width=180#定义屏幕宽度height=120#

定义屏幕长度a=0c=0###################################################uart=UART(3,9600)while(True):clock.tick()img=sensor.snapshot()blobs=img.find_blobs([ye

llow_threshold])ifblobs:forbinblobs:img.draw_rectangle(b[0:4])#rectimg.draw_cross(b[5],b[6])#cx,cyprint(b[5]

,'',b[6])a=b[5]if(a>=width/3)and(a<=width/3*2):c='2'elifa<width/3:c='1'elifa>width/3*2:c='3'else:c='4'uart.write(c)print(c)t

ime.sleep(800)1.ArduinoMega2560上的代码voidsj(){intshijue=Serial1.read();//读取串口接收到的值if(-1!=shijue)//(没接收到数据时是等于-1的,Arduino串口基础,不多说。){if(1==s

hijue){//前进Serial.print("G4F1\r\n");delay(100);}if(2==shijue){//向左转60度Serial.print("G2F1\r\n");delay(100);}if(3==shijue

){//向右转60度Serial.print("G5F1\r\n");delay(100);}if(4==shijue){//向后转Serial.print("G5F3\r\n");delay(100);}}}6.5.4语音识别模块连接1.本项目语言识别模块使用了WEG

ASUN-M6核心板。该模块一款集语音识别、语音合成、语音(MP3)点播、RF(射频)功能、红外功能于一体的多功能模块。目前主要应用在智能家居、对话机器人、车载调度终端、高端智能语音交互玩具、楼宇智能化、教育机器人等方面。主打傻瓜式的简易操作、优越的语音识别和语音合成

性能,应用领域十分广泛。2.模块连接方法语音识别模块与Arduino2560接线方法:语音模块TXD---2560RX1语音模块RXD---2560TX1语音模块GND---2560GND语音模块3V3---25603.3V同时,注意语音识别模块的供电。如

果发现语音识别模块的3.3V电压从2560的3.3V引脚取电无法进行语音识别或者播放语音,那请将语音识别模块的5V电源输入端接到UNO的VIN引脚端,并且选择外部9V的电源适配器给2560供电,这样就有充足的电流和电压了。实物连接图如图6-28所示。图6-28实物连

接图3.程序代码(1)核心板代码@KeyWordBuf01#开机001|关机002|$@KeyWordBuf02#前进003|后退004|$@KeyWordBuf03#快跑005|快退006|$@KeyWordBuf04#左转007|右转008|$@KeyWordBuf05#左走009|右走010

|$@KeyWordBuf06#蹲下011|起来012|$@KeyWordBuf07#攻击姿态013|攻击014|$@KeyWordBuf08#警戒015|复位016|$@KeyWordBuf09#睡017|醒018|$@KeyWordBu

f10#开启遥控模式019|关闭遥控模式020|$@KeyWordBuf11#开启自由活动021|关闭自由活动022|$@KeyWordBuf12#开启声音模块023|关闭声音模块024|$@KeyW

ordBuf13#开启感光模式025|关闭感光模式026|$@KeyWordBuf14#开启震动模块027|关闭震动模块028|$@KeyWordBuf15#开启触摸模块029|关闭触摸模块030|$

@WriteKeyWordBuf#$@WriteFlashText#|001!|002!|003!|004!|005!|006!|007!|008!|009!|010!|011!|012!|013!|014!|015!|016!|017!|018!|019!|020!|021

!|022!|023!|024!|025!|026!|027!|028!|029!|030!|$(2)ArduinoMega2560代码voidsk(){intval=Serial2.read();if(-1!=val){i

f(1==val){//站立Serial.print("G0F1\r\n");}if(2==val){//蹲下Serial.print("G10F1\r\n");}if(3==val){//前进for(inti=0;i<50;i++){Serial.print("G2F1\r\n

");delay(500);}}if(4==val){//后退for(inti=0;i<50;i++){Serial.print("G3F1\r\n");delay(500);}}if(5==val){

//左转Serial.print("G4F1\r\n");delay(500);}if(6==val){//右转Serial.print("G5F1\r\n");delay(500);}if(7==val){//左走for(inti=0;i<50;i++){

Serial.print("G6F1\r\n");delay(2000);}}if(8==val){//右走for(inti=0;i<50;i++){Serial.print("G7F1\r\n");delay(2000);}}}}6.6步态设计1.步态设计原理六足机器人根据仿生学原理,行走方式采

用三角步态。六条腿的昆虫行走时,一般不是六足同时直线前进,是把三对足分成两组,以三角形支架结构,互相交替前行。目前,大部分仿生蜘蛛机器人采用了仿昆虫的结构,六条腿分布在身体的两侧,身体左面的前、后足及右面的

中足为一组,右面的前、后足和左面的中足为另一组,分别组成两个三角形支架,靠大腿前后划动来实现支撑以及摆动过程,这就是最典型的三角步态行走方式。主要有身体重心比较低,容易稳定的优点。如下图6-29所示。图6-29三

角步态行走方式2.步态实现六足机器人的行走移动依靠32路舵机控制器实现,该控制器原理图如图6-30所示:图6-30控制器原理图3.控制代码上位机截图如图6-31所示。前进:#5P1700#11P1300#17P1300T300#3

P1500#6P1700#9P1500#10P1300#13P1500#16P1300T300#5P1500#11P1500#17P1500T300#2P1700#8P1700#13P1500#14P1300T300#3

P1700#6P1500#9P1700#10P1500#13P1300#16P1500T300#1P1500#2P1500#3P1700#4P1500#5P1500#6P1500#7P1500#8P1500#9P1700#10P1500#11P15

00#12P1500#13P1300#14P1500#15P1500#16P1500#17P1500#18P1500T300图6-31上位机截图后退:#2P1700#8P1700#14P1300T300#3P1300#6P1500#9P1300#10P1500#1

3P1700#16P1500T300#2P1500#8P1500#14P1500T300#5P1700#11P1300#17P1300T300#3P1500#6P1300#9P1500#10P1700#13P1500#16P1700T300#5P15

00#11P1500#17P1500T300左转:#2P1700#8P1700#14P1300T300#6P1300#10P1300#16P1300T300#3P1500#9P1500#13P1500T300#2P1500#8P1500#14P1500T300#5P1700#11P1

300#17P1300T300#3P1300#9P1300#13P1300T300#6P1500#10P1500#16P1500T300#5P1500#11P1500#17P1500T300#1P1500#2P1500#3P1500#4P1500#5P1500#6P1500#7P1500#8P15

00#9P1500#10P1500#11P1500#12P1500#13P1500#14P1500#15P1500#16P1500#17P1500#18P1500T300右转:#5P1700#11P1300#17P1300T300#3P1700#9

P1700#13P1700T300#6P1500#10P1500#16P1500T300#5P1500#11P1500#17P1500T300#2P1700#8P1700#14P1300T300#6P170

0#10P1700#16P1700T300#3P1500#9P1500#13P1500T300#2P1500#8P1500#14P1500T300#1P1501#2P1501#3P1501#4P1501#5P1501#6P1501#7P1501#8P1501#9P1501

#10P1501#11P1501#12P1501#13P1501#14P1501#15P1501#16P1501#17P1501#18P1501T3006.7红外控制设计红外接收模块适用于红外线遥控和红外线数据传输。对于不同的遥控器,区别只是接到的数字不同。注意要买三脚的

红外接收头,而不是直接购买红外对管。当然也可以买电子积木的红外接收模块,它还多了一块小板和小灯,质量也相对好一些,容易固定,价钱稍贵。因为日光中有红外线,所以在室外使用可能受到影响。1.连接方法VCC接Arduino3.3V或5.5VGND接Arduino

GND\OUT接Digital11具体连接方式见下图6-32所示。图6-32连接方式1.控制代码------------------------第一部分---------------------#include<IRremote.h>intRECV_PIN=1

1;longCH1=0x00FFA25D;(不同遥控器不同码值)longCH=0x00FF629D;longCH2=0x00FFE21D;longPREV=0x00FF22DD;longNEXT=0x00FF02FD;

longPLAY=0x00FFC23D;longVOL1=0x00FFE01F;longVOL2=0x00FFA857;longEQ=0x00FF906F;longa0=0x00FF6897;longa100=0x00FF9867;longa200=0x00FFB04F;longa1=0x00

FF30CF;longa2=0x00FF18E7;longa3=0x00FF7A85;longa4=0x00FF10EF;longa5=0x00FF38C7;longa6=0x00FF5AA5;longa7=0x00FF

42BD;longa8=0x00FF4AB5;longa9=0x00FF52AD;IRrecvirrecv(RECV_PIN);decode_resultsresults;------------------------第二部分---------------------/

/********红外遥控***********pinMode(RECV_PIN,INPUT);irrecv.enableIRIn();//开始接收方------------------------第三部分--

-------------------//********红外遥控***********voidyaokon(){if(irrecv.decode(&results)){///////////////////////

//////////////////////////////////////if(results.value==a1){//左转Serial.print("G19F4\r\n");delay(9000);Serial.print("G0F1\r\n");

}////////////////if(results.value==a2){//前进Serial.print("G2F5\r\n");}//////////////////////if(results.value==a3){//右转Serial.pr

int("G20F4\r\n");delay(9000);Serial.print("G0F1\r\n");}///////////////if(results.value==a4){//左走Serial.

print("G5F4\r\n");}//////////////////////if(results.value==a5){//站姿Serial.print("G0F1\r\n");}///////////////////////if(res

ults.value==a6){//右走Serial.print("G6F4\r\n");}//////////////////////if(results.value==a7){//Serial.print("G19F8\r\n");Se

rial.print("G0F1\r\n");}///////////////if(results.value==a8){//后退Serial.print("G3F2\r\n");}//////////////////////if(results.value==a

9){//Serial.print("G20F8\r\n");Serial.print("G0F1\r\n");}//////////////////////if(results.value==a100){//蹲下Serial.print("G10\r\n");}////////

//////////////if(results.value==a200){//起立Serial.print("G11\r\n");}//////////////////////if(results.value==PLAY){//低姿态Serial.print("G12\r\n");}

//////////////////////if(results.value==PREV){//低前进Serial.print("G7F1\r\n");Serial.print("G8F2\r\n");}//////////

////////////if(results.value==NEXT){//低后退Serial.print("G7F1\r\n");Serial.print("G8F2\r\n");}///////////////////////////////////////

//////////////////////////////////////irrecv.resume();//Receivethenextvalue}}6.8成品实物图1.站立姿态如图6-33所示。图6-33站立姿态2.移动姿态如图6-34所示。图6-34移动姿态3.攻击姿态如图6-35

所示。图6-35攻击姿态4.俯视图如图6-36所示。图6-36俯视图目录7.1设计思想7.2材料清单7.3安装过程7.4固件详解7.5打印过程的注意事项7.1设计思想3D打印技术的出现,为各行各业乃至于这个世界

提供了无限可能。3D打印机让创造离人们生活从未来,它迅速的拉近了梦想构思和现实的距离,同时也快速推进了各行业的创新速度。3D打印机被誉为第三次工业革命重要标志,3D打印以其个性化、低消耗、小批量、高难度的制造新理念,正在颠覆传统的锻

造、切削加工制造模式,给大规模生产线的工业组织方式带来了重大变革。目前,3D打印已形成了从数据采集、材料、打印设备到应用服务的较为完整的产业链,被广泛应用于航空航天、汽车制造、医疗器械、个人消费、教育科研和军工生产等领域。7.2材料清单序号元器件名称型号参数规格数

量参考实物图1型材2020铝材246mm(X)2根2020铝材410mm(Z)2根2020铝材385mm(Y)2根2020铝材410mm(横梁)1根2020铝材230mm(横拉)2根2020铝材150mm(耗材架竖)1根2020铝材100mm(耗材架

横)1根2光杆6根3丝杆两根4电源+线12V/25ma1个5热床1套6Arduino主控板MEGA25601套7电机控制板ReprapRamps1.41套8电机驱动板HR-A498839打印件详见教材配套资料32个10角件15个11螺母5T1袋124T1袋13直线

轴承10个14燕尾夹4只15联轴器2只16限位开关ss-5g3只17T8铜螺母2个18轴承M52个19弹簧4只20张紧弹簧2只21同步轮2个22同步带2根23USB线1根24电源线12V1根25热缩管1根

26扎带若干27杜邦线3根28风扇2只29固体胶1支30喷嘴组件1套31螺丝M5*821个32M5*103个33M5*252个34M3*84个35M3*1011个36M3*143个37M3*1613个38M3*202个39M3*254个40M3*404个41M4*1022

个42包线管1卷43电机+线17HD40005-22B5个7.3安装过程首先将所有的型材进行分类,找出X型材(245mm)、Y型材(385mm)、M5螺丝、M5T螺母和角件,如图7-1所示。用螺丝和螺母穿过角件并固定好X、Y型材,安装图7-2的摆放方式进行固定安

装,安装的时候要注意不要将螺丝拧的特别紧,避免出现脱扣的情况出现。应该预留一定的松紧度,方便随时调整对其,确认角度没有问题后将螺丝拧紧,确保结构牢固。7.3.1机架安装图7-1分类图图7-2X、Y型材安装图找出横梁型材(410mm)1根、Z轴型材(31

0mm)2根,角件2个,M5螺丝2个,M5T螺母2个,M5扳手1个。将上一步的底座四角朝下,再长轴上找出255mm的位置上安装Z轴,安装的时候要注意两个Z轴型材的位置是一样的,如图7-3所示。图7-3X、Y、Z型材安装图固定

好两个Z轴型材后,开始安装横梁。横梁与Z轴固定的位置应该留有62mm的距离,并注意两边距离相同。安装如图7-4所示。图7-4横梁安装图上述步骤完成之后开始安装料架,料架安装在横梁上,应该距离横梁的一侧24

5mm,具体安装如图7-5所示。到这步为止铝型材框结构安装完毕。图7-5料架安装图7.3.2平台安装1.平台安装找出铝板、直线轴承3个、打印件4个、M3螺丝8个、M3T螺母8个、扎带6个。首先用扎带固定直线轴承在打印件

上,之后减掉多余的扎带。然后将三个直线轴承固定在铝板上。如图7-6所示。图7-6直线轴承固定示意图2.X平台安装准备直线轴承3个,打印件1个,扎带6个。与X轴安装方法类似,将直线轴承塞入打印件,然后用M3和M3T将其固定在打印件上。如图7-7所示。图7-7X平台安

装图(1)准备好电机1个,和与其配套的打印件、直线轴承2个、限位开关1个、同步轮1个、热缩管1段。用杜邦线连接限位开关,常开脚并用热缩管包住。如图7-8所示。图7-8X平台安装图(2)将电机用M3螺丝和M3T螺母固定在配套的打印件上,确定稳固后将同步轮固定在电机上。这时应

该特别注意,同步轮的齿轮一定要在打印件的空隙正中处,并能保证正常转动。上述步骤完成后将处理好的限位开关用扎带固定在打印件上,注意扎带要从打印件的空隙处穿过,完成的电机如7-9所示。图7-9X平台安装图(3)找出最短的两根光轴,与上一步的半成件进行

组装。此步骤完成后X轴平台安装完毕。完成图如7-10所示。图7-10X平台安装图(4)3.Z平台安装首先按照图7-11准备好想要材料。将联轴器和电机组装到一起,这个过程要注意因为联轴器顶丝打在电机D面内部两端的直径不同,需要插入直径小的部分中,如图7-12所示。完成之后贴近铝型材进

行固定,拼装后的完成图如7-13所示。图7-12联轴器和电机组装图图7-11材料图图7-13固定图找出剩余的两根光轴和丝杆,组装成图7-14的样式。安装过程中要特别注意,光杆要轻缓的穿过直线轴承。如果遇到阻塞,可以适当的调节期间的宽度,但是动作一定要轻缓。图7-14光轴与丝

杆组装图找出同步带、扎带、张紧弹簧,按图7-15的方法和Y轴同步带进行组装,一定要注意张紧弹簧的安装位置。图7-15与Y轴同步带组装图4.机械杂件的安装完成上述安装步骤之后是进行热床的安装,准备好将热板、4个弹簧、4个

M3自锁螺母、4个M3螺丝。如图7-16所示。用M3螺丝和螺母插入打印件,将热板固定在铁板上,拧紧4个角的螺丝。然后进行限位开关的安装,注意拧的过程不要太紧,因为打印时可能还需要进行调试。如7-17所示。图7-16材料图图7-17热板固定图接下来安装挤出机和电源,这两部分相对较为简

单,按照图7-18、7-19进行安装。图7-18挤出机安装图图7-19电源安装图7.3.3控制板安装及布线1.主控板安装本打印的核心控制单元是Arduinomega2560,mega2560板子在3d打印机中相当于大脑,控制这所有

的3d打印配件来完成复杂的打印工作,但mega2560不能直接使用,需要上传(upload)固件(firmware)才可以使用,本项目采用的固件是Marlin固件会在下节进行详细的介绍。此外mega2560需要和ReprapRam

ps1.4扩展板进行组合,通过扩展板完成对3D打印机的控制。mega2560和ReprapRamps1.4只需将后者的引脚插入2560即可,具体如图7-20所示。两者组合的时候要注意不要特别用力,如果某些引脚出现歪了的情况,只需将其掰正即可,不影响正常使用。图7-20引脚插入图组合完成之后需要进行

ReprapRamps1.4的相关电路连接,具体连接示意图如图7-21所示。图7-21连接示意图7.4固件详解7.4.1概述Sprinter固件是目前用的比较多的3D打印机固件,而Marlin固件和Repetier-firmware固件都是由其派生而

来。而且这两款固件的用户群非常活跃,而Sprinter固件已经没有人维护了。在这二者中,Marlin固件的使用更加广泛,很多打印机控制软件都兼容Marlin固件。一般用户在使用Marlin固件的时候只需要改变

一下Configuration.h文件中的一些参数即可,非常方便。本节主要介绍用户设置的基本信息、怎么运用这些设置、根据不同的需求制定特色功能。Marlin固件可在本书配套资源中找到。固件实际上是通过特定软件写入ArduinoMEGA2560内部的,实际上是通过ArduinoMEGA25

60发送各种控制指令对打印件进行三轴的控制。7.4.2MARLIN固件特点Marlin相对于Sprinter有很多优点,具体为以下几点:1.预加速功能(Look-ahead):Sprinter在每个角处必须使打印机先停下然后再加速继续运行,而预加速只会减速或加速到某一个速度值,从而速度的矢量变化不

会超过xy_jerk_velocity。要达到这样的效果,必须预先处理下一步的运动。这样一来加快了打印速度,而且在拐角处减少耗材的堆积,曲线打印更加平滑。2.支持圆弧(ArcSupport):Marlin固件可以自动调整分辨率去以接近恒定速度打印一段圆弧,得到最平滑的弧线。这样做的另一个优点是

减少串口通信量。因为通过1条G2/G3指令即可打印圆弧,而不用通过多条G1指令。3.温度多重采样(TemperatureOversampling):为了降低噪声的干扰,使PID温度控制更加有效,Marlin采样16次取平均值去计算温度。4.自动调节温度(AutoTemp):当打印任务要

求挤出速度有较大的变化时,或者实时改变打印速度,那么打印速度也需要随之改变。通常情况下,较高的打印速度要求较高的温度,Marlin可以使用M10SBF指令去自动控制温度。使用不带F参数的M109指令不会自动调节温度。否则,Marlin会计算缓存中所

有移指令中最大的挤出速度(单位是steps/sec),即所谓的“maxerate”。然后目标温度值通过公式T=tempmin+factor*maxerate,同时限制在最小温度(tempmin)和最大温度(tempmax)之间。如

果目标温度小于最小温度,那么自动调节将不起作用。最理想的情况下,用户可以不用去控制温度,只需要在开始使用M109SBF,并在结束时使用M109S0。5.非易失存储器(EEPROM):Marlin固件将一些常用的参数,比如加速度、最大速度、各轴运动单位等存储在EEPROM中,用

户可以在校准打印机的时候调整这些参数,然后存储到EEPROM中,这些改变在打印机重启之后生效而且永久保存。6.液晶显示器菜单(LCDMenu):如果硬件支持,用户可以构建一个脱机智能控制器(LCD屏+SD卡槽+编码器+按键)。用户可以通过液晶显示器菜单实时调整温度、加速度、速度、流量倍率,选择

并打印SD卡中的G-Code文件,预加热,禁用步进电机和其他操作。比较常用的有LCD2004只能控制器和LCD12864只能控制器。7.SD卡内支持文件夹(SDcardfolders):Marlin固件可以读取SD卡中子文件夹内的G-Co

de文件,不必是根目录下的文件。8.SD卡自动打印(SDcardautoprint):若SD卡根目录中有文件名为auto[0-9].g的文件时,打印机会在开机后自动开始打印该文件。9.限位开关触发记录(Endstoptriggerr

eporting):如果打印机运行过程中碰到了限位开关,那么Marlin会将限位开关触发的位置发送到串口,并给出一个警告。这对于用户分析打印过程中遇到的问题是很有用的。10.编码规范(Codingparadigm):Marlin固件采用模块化编程方式,让用户可以

清晰地理解整个程序。这为以后将固件升级到ARM系统提供很大的方便。11.基于中断的温度测量(Interruptbasedtemperaturemeasurements):一路中断去处理ADC转换和检查温度变化,这样就减少了单片机资源

的使用。12.支持多种机械结构:普通的XYZ正交机械,CoreXY机械,Delta机械以及SCARA机械。7.4.3基本配置使用ArduinoIDE打开marlin.ino,切换到Configuration.h即可查看

并修改该文件。或者使用任何一款文本编辑器(notepad,notpad++等)直接打开Configuration.h也可以。Marlin固件的配置主要包含一下几个方面:1.通讯波特率2.主板类型,所使用的主板类型3.温度传感器类型,包括挤出头温度传感器和加热床的温度传感器4.温度

配置,包括喷头温度和加热床温度5.PID温控参数,包括喷头温度控制和加热床温度控制6.限位开关7.4个轴步进电机方向8.X/Y/Z三个坐标轴的初始位置9.打印机运动范围10.自动调平11.运动速度12.各轴运动分辨率13.脱机控制器根据经验来说,Ma

rlin固件中的Configuration.h将各个配置模块化,非常便于读及修改,而且注释非常详细,英文好的同学可以很容易地理解各参数的意义。注意到Marlin固件使用C语言编写,“//”后面的是注释语句,不会影响代码的作用。另外Marlin固件中大量使用#define,简单

来讲,就是定义的意思,包括定义某个参数的数值,定义某个参数否存在。最开始的两行非注释语句是定义固件的版本和作者。缺省的版本号就是编译时间,这可以不用修改,只需要把作者改为自己的名字即可,注意不能包含中文,不然会乱码。#defineSTRING_VERSION_CONFIG_H__DATE__

""__TIME__//builddateandtime#defineSTRING_CONFIG_H_AUTHOR"www.abaci3d.cn"//whomadethechanges.电脑和打印机通过串口进行通讯,要定义好端

口和波特率,在此定义的是3D打印主的端口和波特率,端口号使用默认的0就可以了。Marlin固件默认的波特率是250000,可以修改为其他值,比如115200,这是标准的ANSI波特率值。#define

SERIAL_PORT0#defineBAUDRATE250000下面定义主板类型,Marlin固件支持非常多种类的3D打印机主板,比如常见的RAMPS1.3/1.4、Melzi、Printrboard、Ultimainboa

rd、Sanguinololu等控制板。需要注意的是不同主板使用不同的脚口和数量,如果该定义和ArduinoIDE中使用的主板不一致,肯定会导致编译不通过。笔者使用的是RAMPS1.4并且D8、D9、D10控制的

是一个喷头加热、一个加热床加热和一个风扇输出,因此定义为33。#ifndefMOTHERBOARD#defineMOTHERBOARD3#endif接下来是定义挤出头的个数及电源类型,笔者使用的是单喷头

打印机,因此定义为1。电源有两种类型可以选择,1表示开关电源,2表示X-Box360203伏电源,一般都使用的是开关电源,因此定义为1。#defineEXTRUDERS1#definePOWER_SUPPLY1接下来定义温度传感器类型,包括每

个喷头使用的温度传感器(如果是多喷头)和加热床的温度传感器类型,常用的温度传感器有电热偶和热敏电阻两大类,热敏电阻又分为很多种。目前的3D打印机主要用的是热敏电阻,具体是哪种热敏电阻需要自己判断或询问卖家,不出意外的话,都是100kntc热敏电阻,即1。根据注释,1要求4.7k

的上拉电阻,而根据RepRapwiki,几乎所有的3D打印机都使用了4.7K的热敏电阻上拉电阻。笔者观察了几种电路板的电路图,发现都使用了4.7K的上拉电阻,如图7-22所示。//1is100kthermistor-bestchoiceforEPCOS100k(4.7kpu

llup)笔者的打印机为单喷头,因此第一个喷头的温度传感器配置为1,其他配置为0(0表示没有使用),加热床的温度传感器也配置为1。#defineTEMP_SENSOR_01#defineTEMP_SENSO

R_10#defineTEMP_SENSOR_20#defineTEMP_SENSOR_BED1器件连接原理图如图7-22所示。图7-22器件连接原理图接下来是温度检测的一些配置,包括双喷头温度差,M109检测配置,安全温度配置。下面进行一一解释。首先下面这一句配置双喷头温差最大值,如果

温度超过这个数值,那么打印机会终止工作,因此对于双喷头打印机玩家来说,这个参数需要注意。#defineMAX_REDUNDANT_TEMP_SENSOR_DIFF10下面这一段配置M109指令完成的指标,我们知道,M109指令设定喷头温度并等待,

那么等待到什么时候呢?下面这三个参数控制这个时间。第一个参数表示温度“接近”目标温度必须持续10秒才算加热完成,第二个参数表示和目标温度相差不超过3°为“接近”,第三个参数表示从温度与目标温度相差不超过1度开始计时,从此刻开始,温度和目标温度持续接近10秒钟,则完成加热。#

defineTEMP_RESIDENCY_TIME10#defineTEMP_HYSTERESIS3#defineTEMP_WINDOW1下面配置安全温度范围的下限和上限,包括各个喷头和加热床。如果温度超过下限,那么打印机会抛出MINTEMP的错误并终止工

作,如果超过上限,那么打印机抛出MAXTEMP的错误并终止工作。Marlin用这种方式保护3D打印机。下面的配置最小温度都是5°,喷头的最大温度为275°,热床的最大温度为150°。#defineHEATER_0_MINTEMP5#defin

eHEATER_1_MINTEMP5#defineHEATER_2_MINTEMP5#defineBED_MINTEMP5#defineHEATER_0_MAXTEMP2757.5打印过程的注意事项7.5.1翘边的处理

方法翘边可以说是3D打印最常见的问题了,没有之一。只要方法得当,也是可以有效减少翘边的,下面介绍5个方法解决翘边的问题。想要解决问题,首先得知道问题的根源,为什么在打印过程中总是会翘边呢?主要原因就是塑料的热胀冷缩,从喷嘴挤出来的塑料在冷却的过程中会收缩,导致模型边缘或者两头翘起来

,与平台分离。尤其是ABS,比PLA更易翘边。当模型底部面积不大时,收缩造成的影响并不明显。但面积较大时,每单位面积产生的收缩累积起来,向内产生的拉力就变得相当强大,造成边缘翘起。下面是经过测试的解决办法,同学们可以根据自己遇到的

实际情况选择不同的方法。1.加宽第一层线宽线宽越宽,从挤出孔挤出的料就越多,塑料和打印平台挤压的力量也会越强。这样可以增加模型与平台的黏合力,进而减少翘边的状况。2.首层不开风扇(适用于creator系列和Dreamer系列)风扇吹风可以让模型加速冷却,如果打印

的模型很小,来不及冷却就要开始印下一层,很容易就过热了,造成模型变形,所以一般都需要吹风来加速冷却。但是打印较大的模型时,风扇吹风会让塑料冷却过快而收缩,造成边缘翘起。所以,通常模型面积较大时,首层打印可以不开风扇,后面再开风扇。

因为首层的打印时间比较长,有足够的时间让塑料冷却,不开风扇也可以。3.减慢打印速度如果你发现自己的打印机总是出现翘边的情况,可以降低一下打印速度试试看。总结大量的打印经验,减慢速度的确有助于减少翘边。这种方法尤其适合三角洲打印机,降低标准速度百分之30左右

,处了大大的降低了翘边的可能性,打印质量也有明显的提升,精度明显高于高速打印。4.使用各种胶胶可以带来不错的附着力,降低翘边出现的概率。比如PVP固体胶、各种防翘边胶水、防翘边贴膜、美纹纸等等。涂胶也是有技巧的,一定

要均匀涂抹,选择那种粘度较强的胶。不要某一区域特别厚,某区域特别薄,这样反而会影响调平效果,造成打印失精等情况发生。5.改善模型修改下模型底部的形状,也是可以减少翘边的,比如模型底部加老鼠耳朵一样的边缘,增加附着力。改

善后的模型图如图7-23所示。图7-23改善模型图7.5.2打印时耗材无挤出对于刚接触到3D打印的同学来说,这是一个比较常见的问题。我们常见的挤出机不挤出耗材,一般来说是四种因素造成的。1.打印开始前,挤出机没有装填耗材2.喷嘴离平台太近3.线材在挤出齿轮上打滑(刨料)4.挤出机堵了7.5.3打

印时耗材无法粘到平台上打印的第一层,与平台紧密粘住,是很重要的。只有这样,接下来的层才能在此基础上,建构出来。如果第一层,没能粘平台上,那将导致后面的层出问题。例如:1.建构平台不水平2.喷嘴平台太远3.第一层打印太快4.温度或冷却设

置有问题5.平台表面处理(胶带,胶水,及材质)6.当以上方法都不行:溢边和底座7.5.4出料不足Simplify3D中包括一些设置,来决定3D打印机挤出多少塑料。然后3D打印机并没有反馈多少塑料实际已经流出了喷嘴。因此

,有可能实际挤出的塑料,与软件期望的要少(也即所谓的出料不足(under-extrusion))。如果出现这种情况,你可能会注意到,各相邻层之间,会有间隙。测试你的打印机,是否挤出足量的方法是,打印一个简单的20mm方的正方体,设置至少打印3层边线。检查一下,在方块的顶部的3条

边线,是否紧密地粘合在一起。如果3条连线之间有间隙,那么你就是遇到了出料不足的问题。如果这3条边线互相紧靠,并且没有间隙,那有可能你遇到是另一种问题。如果你确定,你遇到的是出料不足,那这儿有几个可行的方法,具体见下文。1.不正确的线材直径你需要确认的第一件事是,软件得知道你使

用的耗材的直径。点击“修改切片设置(EditProcessSettings)”,打开“其他”标签。确认设置的值,与你购买的线材直径是一致的。甚至,你需要用卡尺测试你的线材,以确定你在软件中设置的值,是正确的。最常见的线材直径是1.75和2.85。许多线材卷的包装上,也有正确的直径。2.增加

挤出倍率如果你的线材直径是正确的,但是你仍然看到出料不足的问题,那么你需要调整挤出倍率。这是Simplify3D中一个非常有用的设置,允许你轻松修改挤出机挤出量(也被称为流量倍率)。点击“修改切片设置(EditProcessSettings)”,打印“挤出机(Extruder)标签页”

。你打印机上的每个挤出机,都有一个单独的挤出倍率,所以,如果你想修改某一个挤出机的流量倍率,确保在列表上选择了与之对应的设置项。比如,如果你的挤出倍率原来是1.0,你修改它为1.05,这意味着将比以前多挤出5%的塑料

。比较典型的是,打PLA时设置挤出倍率为0.9左右,打印ABS时,设置接近1.0。尝试着增加5%,然后再打印测试方块,看边线上是否仍然有间隙。示意图如图7-25所示。图7-25挤出效果示意图7.5.5出料偏多软件与你的打印

机是一起工作的,请确认从喷嘴中挤出了准确数量的塑料。精确挤出是获得高质量打印件的重要因素。然而,大多数3D打印机,没有方法监测到底挤出了多少塑料。如果你的挤出机设置不正确,打印机有可能挤出超过软件预期的塑料。出

料偏多将导致打印件的外尺寸出问题。解决这个问题,在Simplify3D中,只需要进行很少的设置。请参考“出料不足”章节,以获得更详细的说明。虽然那个说明是关于出料不足的,但你可以修改相同的设置项,解决出料偏多的问题,只需要相反的设置。例如,增加挤出倍率可以解决出料不足的问题,你可以减少挤出倍率

,来解决出料偏多的问题。示意图如图7-26所示。图7-26出料偏多示意图7.5.6顶层出现孔洞或缝隙为了节省塑料,大多数3D打印件,都是由一层实心的壳和多孔中空的内芯构成。例如:打印件的内芯的填充率,只有30%,也即意味着,内芯只有30%的是塑料,其他部分是空气。虽然打印件的内芯是

部分中空的,但我们希望表面是实心的。为了达到这个目标,Simplify3D允许你设置,在你的打印件中,顶部和底部有多少实心的层。例如,你打印一个上下各有5层实心层的方块,软件将在上下各打印5层完全实心的层,但是其他中间的层,将部分中空。这个技术,可以节约大量的塑料和时间,但同时又能创造

出结实的打印件。当然,取决于你使用何种设置,你有可能注意到,打印件的顶层并不是完全实心的。在挤出机建构这些实心层时,你可能看到孔洞或间隙。如果你遇到这种问题,这儿有几个简单的设置,你可以对其进行调整,以解决问题。1.顶

部实心层数不足调整顶层实心填充层的数量,是最先被用到的。当在部分中空的填充的层上,打印100%的实心填充层时,实心层会跨越下层的空心部分。此时,实心层上挤出的塑料,会倾向下垂到空心中。因此,通常需要在顶部打印几层实心层,来获得平整完美的实心表面。好的作法是,顶层实

心部分打印的厚度至少为0.5mm。所以如果你使用0.25为层高,你需要打印2层顶部实心层。如果你打印层高更低,比如只有0.1mm,你需要在顶部,打印5个实心层来达到同样的效果。如果你在顶层发现挤出丝之间有间隙,第一件事,是尝试着增加顶部实心层的数量。例如,如果你发现这个问

题,而只打印了3个顶部实心层,那试试打印5个实心层,看看有没有改善。注意,增加实心层只会增加打印件里面塑料的体积,但不会增加外部尺寸。你可以点击“修改切片设置(EditProcessSettings)”,打印“层(La

yer)标签页”,来调整实心层的设置。2.填充率太低打印件内部的填充,会成为它上面层的基础。打印件顶部的实心层,需要在这个基础上打印。如果填充率非常低,那填充中将有大量空的间隙。比如,你只使用10%的填充率,那么打印件里面,剩下90%将是

中空的。这将会导致实心层,需要在非常大的中空间隙上打印如果你试过增加顶部实心层的数量,而你在顶部仍然能看到间隙,你或许可以尝试增加填充率,来看看是间隙是否会消失。比如,你的填充率,之前设置的是30%,试着用50%的填充率,因为这样,可以提供更好的基础,来打印顶部实心层。3.出料不足如果你已经尝

试增加填充率,和顶层实心层的数量,但在打印件的顶层,你的仍能看到间隙。那你可能遇到挤出不足的问题。这意味着,喷嘴没有挤出软件所预期数量的塑料。关于这个问题的完整解决办法,可以参考“出料不足”章节。效果示意图如图7-27所示。图7-27示意图7.5.7拉丝或垂料当打印件上残留细小的塑

料丝线,则发生了拉丝。通常,这是因为当喷嘴移到新的位置时,塑料从喷嘴中垂出来了。庆幸的是,在Simplify3D中,有几种设置,可能有助于解决这个问题。解决拉丝问题,最常用的是方法是“回抽”。如果回抽是开启的,那么当挤出机

完成模型一个区域的打印后,喷嘴中的线材会被回拉,这样再次打印时,塑料会被重新推入喷嘴,从喷嘴顶部挤出。要确认回抽已经开启了,可以点击“修改切片设置(EditProcessSettings)”,打开“挤出机(Extrud

er)标签页”,确认你的每个挤出机,都开启了回抽选项。在下面的几个章节中,我们将探讨这个重要的回抽设置,也会探讨其他几个处理拉丝问题的设置,例如,挤出机温度设置。1.回抽距离回抽最重要的设置,是回抽距离。它决定了多少塑料,会从喷嘴拉回。一般来说,从喷嘴中

拉回的塑料越多,喷嘴移动时,越不容易垂料。大多数直接驱动的挤出机,只需要0.5到2.0mm的回抽距离,然后一些波顿(Bowden)挤出机,可能需要高达15mm的回抽距离,因为挤出机驱动齿轮和热喷嘴之间的距离更大。如果你的打印件出现拉丝问题,试试增加回抽距离,每次增加1mm,观察改善情

况。2.回抽速度下一个回抽相关的设置,是回抽速度。它决定了线材从喷嘴抽离的快慢。如果回抽太慢,塑料将会从喷嘴中垂出来,进而在移动到新的位置之前,就开始泄漏了。如果回抽太快,线材可能与喷嘴中的塑料断开,甚至驱动齿轮的快速转

动,可能刨掉线材表面部分。有一个围,回抽效果比较好,介于1200-6000mm/min(20-100mm/s).庆幸的是,Simplify3D已经提供了一些内置的默认配置,使你有一个良好的起点,来确定多大的回抽速度,效果最好。但是,最理想的值,需根据实际你使用

的材料。所以,你需要做试验,来确定不同的速度,是否减少了拉丝量。3.温度太高如果你已经检查了回抽设置,下一个最常见的,导致拉丝问题的因素是挤出机温度。如果温度太高,喷嘴中的塑料,会变成非常粘稠,进而更容易从喷嘴中流

出来。然后,如果温度太低,塑料会保持较硬状态,而难以从喷嘴中挤出来。如果你觉得你的回抽设置是正确的,但是出现这个问题,试试降低挤出机温度,降5到10度。这将对最后的打印质量,有明显的影响。通过点击“修改切片设置(EditProcessSetting

s)”,打开“温度(Temperature)标签页”,你可以做调整。从列表中,选择相应的挤出机,在你想修改的温度值上双击。4.悬空移动距离太长如上面我们探讨的,拉丝发生在挤出机,在两个不同的位置间移动。在移动过程中,

塑料从喷嘴中垂下来。移动距离的大小,对拉丝的产生,有很大的影响。短程移动足够快,料没有时间从喷嘴中重落下来。然后,大距离的移动,更有可能导致拉丝。庆幸的是Simplify3D包含了一个非常有用的特性,来使移动路径尽可能小。软件非常智能,能自动调整移动路径,来保证喷嘴悬空移动

的距离非常小。事实上,在多数时候,软件都可以找到能合适的路径,来避免一口气悬空移动很远。这意味着,没有拉丝的可能性,因为喷嘴一直在实心的塑料上方,而且不会移动到打印件外部。要使用这个特性,点击“高级(Advanced)标签页”,开启“避免移动超出轮廓”的

选项。效果示意图如图7-28所示。图7-28示意图7.5.8过热从挤出机挤出的塑料,至少有190到240摄氏度。当塑料仍然是热的,它仍然是柔软的,可以轻易地塑造成不同的形状。然后,当它冷却后,它迅速变成固体,并

且定型。你需要在温度和冷却之间取得正常的平衡,进而塑料能顺利地从喷嘴中流出,但又能迅速凝固成,以获得打印件尺寸的精度。如果未能达到平衡,你会遇到一些打印质量问题,打印件的外型不精准,跟你期望的不一样。如图所示,金

字塔顶部挤出的线材,没能尽快冷却定型。下面的章节,将排查几种常见的导致过热的情况,及如何避免。1.散热不足最常见的导致过热的原因,是塑料能没及时冷却。冷却缓慢时,塑料很容易被改变形状。对于多塑料来说,快速冷却已经打印的层,来防止它们变形,是比较好的。如果你的打印上,有冷却风扇,试着增加风扇的风力来

使塑料冷却更快。点击“修改切片设置(EditProcessSettings)”,打开“冷却(Cooling)标签页”,你可以做相应设置。只需要简单地双你需要修改的风扇的控制点。这个额外的冷却,有助于塑料成型。

如果你的打印机,没有完整的冷却风扇,你可能需要试着安装一个自己配的风扇,或者使用手持风扇来加快层的冷却。2.打印温度太高如果你已经使用了冷却风扇,但仍然有问题,你可能需要试着降低打印温度。如果塑料以低一些的温度从喷嘴中挤出,它将可能更快地凝固成型。试着降低打印温度5到10度,来

看效果。你可以点击“修改切片设置(EditProcessSettings)”,打开“温度(Temperature)标签页”,做相应设置。只需要简单地双击你需要修改的温度的控制点。注意,不要降温太多,以致于塑料不够热,而无法从喷嘴细小的孔中挤出。3.打印太快如果你打印每个层都非常

快,可能导致没有足够的时间,让层正确地冷却,却又开始在它上面打印新的层了。在打印小模型时,这特别重要,因为每层只有很少的时间来打印。甚至有冷却风扇时,为这些很小的层,你仍然需要降低打印速度,来确保有足够的时间让层凝固。庆幸的事,Simplify3D有一个非常简单的选项,来处理这个问题。

如果你点击“修改切片设置(EditProcessSettings)”,打开“冷却(Cooling)标签页”,你会看到“速度重写(SpeedOverrides)”的设置项。这个设置项,是用来,在打印小的层时,自动降低速度,以确保在开始打印下一层时,它们有足够多的时间冷却和凝固

。例如,如果你允许,在打印时间少于15秒的层时,软件调整打印速度,程序会为这些小层,自动降低打印速度。对于解决高热问题,这是一个关键的特性。4.当以上这些办法都无效时,试试一次打印多个打印件如果你已经尝试了以上3个办法,但仍然在冷却方面有问题,有另一种办法,你可以

试一下。将你要打印的模型复制一份(编辑>复制/粘贴((Edit>Copy/Paste)),或者导入另一个可以同时打印的模型。通过同时打印两个模型,你能为每个模型,提供更多冷却时间。喷嘴将需要移动到不同的位置,去打印第二个模型,这就提供了一个机会,让第一个模型冷却。这很简

单,但却是一个很有效的策略,来解决过热的问题。过热现象效果图如图7-29所示。图7-29效果图7.5.9层错位多数3D打印机,使用开环控制系统。直白地说,它们没有关于喷头实际位置信息反馈。打印机只是简单地尝试移动喷头到某个位置,然后希望它能到达那儿。多数时候,这样是可行

的,因为驱动打印机的步进电机是非常有力的,不会有巨大的负载来阻止喷头移动。然后,如果出现了问题,打印机将没有办法发现它。例如,在打印的时候,你突然撞击你的打印机,你可能导致喷头移动到一个新的位置。机器没有反馈来识别这种情况。所以,它会继续打印,好像什么事也没发生一样。如果你发现打印

机中的层错位了,它可能是因为下面列出的原之一导致的1.喷头移动太快如果你以一个很高的速度打印,3D打印机的电机将尽力支持。如果你尝试以更快的速度打印,以至于超过了电机能承受的范围,你通常会听到咔咔的声音,电机没法转动到预的位置。此种情况下,接下来的打印的层,会与之前打印的所有层错位。

如果你觉得你的打印机打印太快了,试着降低50%的打印速度,来看是否有帮助。你可以点击“修改切片设置(EditProcessSettings)”,打开“其他(Other)标签页”,来设置。同时调整“默认

打印速度”和“X/Y轴移动速度”。默认打印速度,决定了挤出头挤出塑料时的速度。“X/Y轴移动速度”决定打印头空程时的移动速度。如果这些速度任意一个太快,都有可能导致错位。如果你愿意调整更多高级设置,你也可以考虑降低你打印机固件中的

加速度设置,使加速和减速更加平缓。2.机械或电子问题如果降低了速度,错位问题还一直出现,那就有可能你的打印机存在机械或电子问题。例如,多数3D打印机使用同步带来做电机传动,以控制喷头的位置。同步带一般是橡胶成,再加某种纤维来增强。使用时间一长,同步带可能会松弛,进而影响同步带带

位喷头的张力。如果张力不够,同步带可能在同步轮上打滑,这意味着同步轮转动了,但同步带没有动。如果同步带原本安装得太紧,也会导致问题。过度绷紧的同步带,会使轴承间产生过的摩擦力,从而阻碍电机转动。理想的情况是,皮带足够紧,防止打滑,

但又不太紧,以致阻碍系统运行。如果你在处理错位问题,你需要确认所有同步带的张力是合适的,没有太松或太紧。如果你觉得可能有问题,请与打印机提供商沟通,以便知道如何调整皮带张力。多数3D打印机,都包括一系列的同步带,驱动同步带的同步轮,使用一个止付螺丝(也称顶丝)来固定到

电机上。这种顶丝将同步轮锁紧在电机的轴上,这样二者可以同步旋转。因此,如果顶丝松动了,同步轮不再与电机轴一同旋转。这意味着,可能电机在旋转,而同步轮和同步带却没有运动。这种情况下,喷头也不会到达预期的位置,进而导致接下来的所有层错位。所以,如果层错位了的问题,重复出现,你需要确认

一下,所有电机上的紧固件都已经上紧了。还有另外一些常见的电子方面的问题,导致电机失步。例如,如果电机的电流不足,电机将没有足够的力矩转动。也可能是电机驱动板过热,这会导致电机间歇性地停止转动,直到电路冷却下来。然而这不是一个详尽的列表,

它只是提供一了些,当错位问题一直重现时,你可以需要检查的,常见的电子或机械方面的建议。效果图如图7-30所示。图7-30层错位效果图7.5.10层开裂或断开3D打印通过一次打印一层来构建模型。每个后续的层,都是打印在前一个层上,最后构建出想要的3D形状。然后,为了使最后的打印件

结实可靠,你需要确保每层充分地与它下面的层粘合。如果层与层之间不能很好地粘合,最后打印件可能开裂或断开。1.层高太高多数3D打印机喷嘴直径都在0.3到0.5mm之间。塑料从这个很小的孔中挤出,形成非常细的挤丝,进

而构建细节丰富的打印件。然而,这些小喷嘴,也导致层高的限制。当你在一层上打印另一层塑料,你需要确保新的层,被挤压到下面那层上,从而两层可以粘合在一起。一般来说,你需要确保你选择的层高比喷嘴直径小20%。例如,如果你的喷嘴直径是0.4mm,

你使用的层高不能超过0.32mm,否则每层上的塑料将无法正确地与它下面的层粘合。所以,如果你发现打印件开裂,层与层之间没能粘合在一起,首先你需要检查的是,层高与喷嘴直径是匹配的。2.打印温度太低相比冷的塑料,热的塑料,总是能更好地粘合在一起。

如果你发现,层与层之间不能很好粘合,并且你能确定层高设置没有太高,那么可能是你的线材,需要以更高的温度来打印,以便更好地粘合。例如,如果你尝试在190摄氏度时,打印ABS塑料,你可能会发现,层与层之间很容易分开。这是因为ABS一般需要在220到235摄氏度时打印,以便使层与层与有力地粘合。所以

如果你觉得可能是这个问题,确认是否对买到的线材,使用了正确的打印温度。尝试增加温度,每次增加10摄氏度,来看看粘合是否有所改善。你可以点击“修改切片设置(EditProcessSettings)”,打开“温度(Temperature)标签页”,来设置。只需要双击你想

修改的温度设置点。效果图如图7-31所示。图7-31层开裂货断开效果图7.5.11刨料多数3D打印机都是使用一个小齿轮与另一个轴承夹住线材,以使齿轮抓住线材。驱动齿轮有尖利的齿,可以咬进线材中,然后依靠齿轮的旋转方向,来推动线材前后运动。如果线材不能移动,但齿轮却在继续转动,这时齿轮可能会从线材上

刨掉部分塑料,以致齿轮没地方再抓住线材。许多人称这种情况叫“刨料”。因为太多塑料被刨掉了,导致挤出功能不正常。如果这种情况出现在你的打印机上,你一通常会看到许多塑料碎片散落一地。你也会看到,挤出机在转动,但线材却没有被推送到挤出机内部。在下面我们将介绍解决这个问的最简单的方法。示意图如图7-32所

示。1.提高挤出机温度如果你一直遇到刨料的问题,试着把挤出机的温度提高5到10度,这样塑料挤出易一些。你可以点击“修改切片设置(EditProcessSettings)”,打开“温度(Temperature)标签页”,来设置。从列表左边选择相应的挤出机,然后双击你想修改的温度定位点。塑料

在温度高时,总是更容易挤出,所以这是可以调整的一个非常有用的设置。2.打印速度太快在提高了温度后,如果你仍然遇到刨料的问题,下一个你需要做的是,降低打印速度。通过这样做,挤出机的电机,不必再那般高速转动,因为线材需要更长的时间来挤出。降挤出机的电机转速,有助于避免刨料问题。你可以

点击“修改切片设置(EditProcessSettings)”,打开“其他(Other)标签页”,来设置。调整“默认打印速度”,可以控挤出机挤出塑料时的运动速度。例如,你之前打印速度是3600mm/min(60mm/s),试试将3.检查喷嘴是否堵塞在降低的

温度和打印速度之后,如果你仍然有刨料的问题,那么可能是喷嘴堵塞了。请阅读“喷嘴堵塞”章节,来获知如何处理这个问题。图7-32示意图7.5.12喷头堵塞你的3D打印机,在它的生命周期里,需要熔化和挤出数公斤的塑料。所有的塑料都必须,通过一个大小只如沙子一般的孔中挤出,这使问题变复杂了。不可避免地

,在这个过程中,有时会现一些问题,挤出机不能再推动塑料通过喷嘴。这种堵塞经常是因为,有某些东西在喷嘴中,阻碍了塑料正常挤出。这种问题第一次出现时,有点让人不知所措,但接下来,我们会介绍几个简单的解决步骤,来修复被堵的喷嘴。效果图如图7-33所示。1.手工推送线材进入挤出机第一件事,你可能想做的是,

尝试手工推送线材进入挤出机。打开Simplify3D的设备控制面板,加热挤出机到塑料需要的温度。然后使用控制手柄,挤出少量塑料。例如,10mm。当挤出机电机旋转,用手轻轻地帮助推送线材进入挤出机。多数情况下,这

额外的力量,以使线材通过出问题的位置。2.重新安装线材如果线材仍然没有移动,接下来你要做的事,是拆下线材。确认挤出机温度正确,然后使用Simplify3D的控制面板,回抽线材,从挤出机中拔出。如前面,可能需要提供额外的力量,如果线材不移动。当线材被拔出后,使用剪刀剪

掉线材上熔化或损坏了的部分。然后重新安装线材,看这段新的,没有损坏的线材能不能挤出。3.清理喷嘴如果不能挤出这段新的塑料通过喷嘴,那么在继续操作前,可能你需要清理喷嘴。很多用户通过加热挤出机到100摄氏度,然

后手工挤出线材(希望没有东西堵在喷嘴中!)另外一些人,更喜欢用吉它上的E弦,将喷嘴中东西反向顶出来。有许多其他方法,不同的挤出机不一样,所以请联系你的打印机提供商,来获得可靠的指导。图7-33效果图7.5.13打印中途,挤出停止如果你的打印机,在开始的时候挤出正常,但后来突然停止

挤出,通常有一些因素,可能导致这个问题。我们将逐个探讨常见的原因,并提供建议解决问题。如果你的打印机,在刚开始的时候,挤出有问题,请参考“打印开始后,耗材无挤出”。效果图如图7-34所示。1.耗材耗尽这

种情况,显而易见。但是在检查其他问题时,首先确认一下,是否有耗材送入挤出机中。如果线材卷中线材耗尽,在开始打印前,你需要安装一卷新的耗材2.线材与驱动齿轮打滑在打印过程中,挤出机的电机会不停地转动,来推动线材进入喷嘴,

这样你的打印机能持续挤出塑料。如果你试图打印得太快,或你试图挤出太多塑料,可能会导致电机刨掉线材,直到驱动齿轮抓不住线材为止。如果挤出机电机在转动,但是线材没有移动,那么很可能是这个原因。请参考“刨料”章节,来获得解决该问题的更详细说明。3.挤出机堵塞如果不是面的任何

一种情况,那么很可能是挤出机堵塞了。如果这种情况发生在打印过程中,你可能需要检查并确认线材是干净的,并且线材卷上没有灰尘。线材上粘染上足够多灰尘后,可能导致打印过程中,堵住喷头。还有其他一些可能的原因,导致喷头堵塞,请参考“喷嘴

堵塞”章节,获取更多信息。4.挤出机电机驱动过热在打印过程中,挤出机的电机负载非常大。它持续地前后旋转,推拉线材向前向后。这些快速运动,需要很多电流。如果打印机的电路没能有效散热,可能导致电机驱动电路

过热。这种电机驱动通常有过热保护,当温度过高时,它会使电机停止工作。这种情况出现时,XY轴的电机,会旋转,移动喷头,但挤出机的电机却完全不动。解决这个问题的唯一办法是关闭打印机,使电路能冷却下来。如果问题持续出现,你也可以添加

额外的冷却风扇。图7-34效果图7.5.14填充不牢3D打印件中的填充部分,在增加模型强度方面,扮演着非常重要的角色。在3D打印中,填充负责连接外层的壳,同时,也支撑着将要打印其上的外表面。如果填充显得不牢或纤细,你需要在软件中,调整几个设置,来增

强这部分。效果图如图7-35所示。1.试试更换填充纹理首先你需要研究的设置,是你在打印中,使用的填充纹理。你可以点击“修改切片设置(EditProcessSettings)”,打开“填充(Infill)标签页”,来找到该设置。“内部填充纹理”决定了打印件内部,使

用什么纹理。有些纹理比其他更结实一些。比如,网格,三角和实心蜂巢都是结实的填充纹理。其他纹理,如线性,或快速蜂巢可能牺牲强度,以换取更快的打印速度。如果你在产生结实可靠的填充方面有问题,可以尝试不同的纹理,来看看是否会

不一样。2.降低打印速度3D打印过程上,填充速度通常比其他部分的打印速度要快。如果你试图让打印速度太快,挤出机将可能跟不上,在模型内部,会出现出料不足的问题。这种出料不足,将产生无力的,纤细的填充,因为喷嘴无法像软件期望的那样,挤出足够多的塑料。如果你尝试了几种填充纹理,但仍然填充不牢,

试试降低打印速度。点击“修改切片设置(EditProcessSettings)”,打开“其他(Other)标签页”,来设置。调整“默认打印速度”,这个参数直接决定填充时,所使用的速度。例如,你之前以3600mm/min(60mm/s

)的速度打印,试试将这个值减小一半,看是否填充开始变得更结实。3.增大填充挤出丝宽度Simplify3d中,另外一个非常有用的特性是,它能修改用于填充打印件的,挤出丝宽度。例如,你可以使用0.4mm的挤出丝宽度,打印外围,但可以使用0.8的挤出丝宽度,做充。这将

创造更厚,更结实的填充壁,这可能提高3D打印件的强度。修改该设置,可以击“修改切片设置(EditProcessSettings)”,打开“填充(Infill)标签页”。“填充挤出丝宽度”是以正常挤出丝宽度的百分比来设置的。例如,你输入200%,填充挤出线的宽度,将是外围的2倍。有一件事,

需要记住:调整这个设置时,软件也会维持你设置的填充率。所以如果你设置填充宽度是200%,每条填充线,将使用两倍的塑料。为了维持相同的填充率,填充线之间的距离将变远。因此,在增加了填充挤出丝宽度后,许多用户倾向于提高填充率。图7-35填充不牢效果

图7.5.15斑点和疤痕3D打印过程中,当挤出机移动到不同位置时,必须持续停止或开始挤出。多数挤出机在运行时,能产生一致的挤出线。然后每次挤出机关闭再开启后,它会产生明显的变化。例如,你观察你的3D打印件外壳,你会发现表现有一些细小的痕迹

,出现在挤出开始的区域。挤出机必须从你的3D模型的外壳的某个位置开始打印,当整个壳打印完后,喷头会返回那个位置。这通常被称作斑点或疤痕。你可以想象,在没有留下任何标记的情况下,很难将两片塑料连接在一起,但是Simplify3D提供了几个工作,可以尽量减小这种表面歇瑕疵。效果

图如图7-36所示。1.回抽和滑行如果你注意到打印件上的小瑕疵,找出是什么导致此现象的最好办法是,仔细观察打印件上的每条沿边。是否这些瑕疵出现在挤出机开始打印沿边时?或者它只出现在沿边完成之后,挤出机要停止时?如果小瑕疵正好出现在开始环开始的地方,那么很可能是你的回抽设置需要稍微调整一下。点

击“修改切片设置(EditProcessSettings)”,打开“挤出机(Extruders)标签页”.在回抽距离设置下方,会有一个名叫“额外重新开始距离”。这个选项决定了当挤出机停止时的回抽距离,与挤出重新开始装填时的距离之间的不同。如发现表现瑕疵正好在沿边打

印开始时,那么挤出机可能挤出了过多塑料。你可以通过在重新开始装填设置中,输入一个负值,来减少装填距离。例如,如果回抽距离是1.0mm,然后重新装填距离是-0.2mm(注意负号),那么每次挤出机停止,它会回抽0.1mm的塑料。然而,每次挤出机重新启动,它将只需推送0.8mm的塑料

回喷嘴。调整这个设置,直到挤机出开始打印沿边时的瑕疵不再出现。2.避免非必要的回抽上面说到的回抽和滑行设置,可以帮助避免每次喷嘴回抽产生的瑕疵,然后有些情况下,更好的办法是,完全避免回抽。这样挤出机不必反转方向,而能进行漂亮一致的挤出。对于使用Bowden挤

出机的机器,这点犹其重要,因为挤出机和喷嘴之间的大距离,使得回抽更麻烦。调整这个控制回抽发生的设置,可以打开高级标签页,寻找“渗出控制行为(OozeControlBehavior)”段落。这个段落包含很多有用的设置,可以修改你打印机的行为。就像我们在“拉丝”章节中提到的,回抽主要用于,当喷

嘴在打印件的不同打印部分之间移动时,防止喷嘴垂料。然而,如果喷嘴不移动到开放的区域,垂料会发生在模型内部,从外面无法看到。因为这个原因,很多打印机需要开启“只在移动到开放空间时才回抽”的设置,来避免不必要的回抽。另一个相关的设置,可以在“

移动行为”段落找到。如果你的打印机只在移动到放开空间时,才回抽,那么,尽量避免这样的开放空间,是更好的。Simplify3D中有一个非常有用的设置,可以使挤出机的移动路径转向,从而避免与轮廓外沿相交。如果通过修改挤

出机动路径,来避免与轮廓相交,那么回抽将是不需要的了。如需使用这个特性,只需简单地开启“避免移动路径与外轮廓相交”选项。3.非固定的回抽Simplify3D另外一个非常有用的特性,是能实现非固定回抽。这对波顿挤出机犹为有用,打印的时候,喷嘴中有非常大的压力。通

常这类机器停止挤出后,挤出机静置,由于内部的压力,它仍然会挤出一小坨。所以,Simplify3D增加了一个独特的选项,执行回抽动作时,允许你保持喷嘴一直运动。这意味着,你更不容易看到静止的小坨,因为在这个过程中,挤出机一直在运动。要撕开这个选项,我

们需要修改一些设置。首先,点击“修改切片设(EditProcessSettings)”,打开“挤出机(Extruders)标签页”.确保“擦嘴(WipeNozzle)选项是开启的。这将告诉打印机,在段打印结

束前,擦拭喷嘴。而“擦拭距离(WipeDistance)选项,设置为5mm,是一个比较好的起点。然后打开高级标签页,开启“在擦拭移动过程中执行回抽”选项。这将避免静止回抽,因为打印机已经被命令,在回抽时,擦拭喷嘴。这是一个非常强大而有用的特性,如

果你仍然面临打印件表面瑕疵的问题,可以试一试。4.选择起点位置如果你仍然在打印件表面看到瑕疵,Simplify3d也提供了另一个选项,可以控制这些点出现的位置。点击“修改切片设置(EditProcessS

ettings)”,打开“层(Layer)标签页”。多数情况下,这些位置的选择,是为了优化打印速度。然后,你也可以让这些位点随机化,或者设置它们到一个特定的位置。例如,你在打印一个雕像,你需要设置所有的起点,在模型的背面开始,这样它们就无法从前面被看到。要做这到个,开启“选

择以最靠近某个位置的地方为起点”的选项,然后输入你希望作为起点开始位置的XY坐标。图7-36效果图7.5.16填充与轮廓之间的间隙重组个打印件,都是由轮廓沿边和填充构成。轮廓的外沿边路径,构成了打印件结实而精准的外表面。填充打印在沿边的里面,用于填充层的剩余空间。通常填

充使用快速的往返纹理,这样打印速度更快。填充有不同的纹理,打印件的轮廓与填充这两部分结实粘合在一起很重要。1.轮廓重叠不够Simplify3D有一个设置,允许你调整外轮廓与填充之间的粘合强度。这个设置称作“轮廓重叠(OutlineOverlap)”,它决定了多少填充会重叠在

轮廓上,来使用这两部分连接起来。点击“修改切片设置(EditProcessSettings)”,打开“填充(Infill)标签页”,可以找到它。这个值是根据你的挤出丝宽度的百分比来定的,所以对于不同规格的喷嘴,它很容易扩展和调整。例如,

如果你设置20%的重叠,这意味着软件会命令打印机,填充会与最里面的外沿边重叠20%。这种重叠,有助于确保这两部分粘合有力。例如,你之前是使用20%的重叠,试着增加到30%,来看看是否沿边与填充之间的间隙消失了。2.打印太快你的打印件填充部分的速度,比轮廓快太多。如果填充打印得太快,会

导致它没有足够多的时间与外轮廓粘合。如果你试着增加轮廓重叠,但是仍然看到轮廓与填充之间的间隙,那么你需要降低打印速度。你可以点击“修改切片设置(EditProcessSettings)”,打开“其他(Other)标签页”,来设置。调整“默认打印速度”,这决定挤出机处于挤

出塑料状态时,所有移动的速度。例如,你之前设置打印速度是3600mm/min(60mm/s),试试打这个值减少到一半,看填充与轮廓间的间隙会不会消失。如果在低速时,间隙不再出现,逐步提高打印速度,直到你找到你打印

机的最佳速度。图7-37间隙效果图7.5.17边角卷曲和毛糙如果在打印后期,发现卷曲问题,通过意味着存在过热问题。塑料被以一个很高的温度,从喷嘴中挤出,它没能及时冷却,随着时间过去,它可能会变形。卷曲可以通过对每层快速的冷却来解决,这样它在凝固前,没有机会变形。请参考“过

热”章节来获得更详细的描述,及解决办法。如果你在打印开始没多久,就发现卷曲,可以参考“打印的耗材没有粘到平台上”。效果图如图7-38所示。图7-38边角卷曲和毛糙效果图7.5.18顶层表面疤痕D打印的好处是,每个打印件一次建构一

个层。这意味着每层是独立的,喷嘴可以自由移动到平台的任何位置,而此时打印件仍在下方建构中。这提供了很多机会,你可能看到喷嘴在前一层表面移动时,会留下痕迹。通过在打印件的上表面最容易看到。这种疤痕产生在,喷嘴移动到新的位置过程中,从之

前打印的塑料上拖曳而过。下面的章节将探讨几种可能的原因,并提供相应的建议,调整哪些设置,可以避免问题出现。效果图如图7-39所示。1.挤出塑料过多首先你需要确定的是,你的挤出机,没有挤出过多塑料。如果挤出过多塑料,每层将倾向于比预设的要厚。这意味着,当喷嘴从每层上移动通过时,它可能会拖拽

之前过度挤出的塑料。在你检查其他设置前,你需要确定你有没有挤出过多塑料。2.垂直抬升(Z抬升)如果你确定挤出机,挤出塑料量的正确的,但仍然遇到喷嘴在上表面拖拽的问题,那么你有必要看一下Simplify3D中的垂直抬升设置。开启这个选项,将导致喷嘴,在之前打印的层上面运动前,抬升一

段距离。当它到达目标位置,喷嘴将移回到原来高度,以备打印。通过向上移动一定的高度,可以避免喷嘴刮伤打印件的上表面。要开启这个功能,点击“修改切片设置(EditProcessSettings)”,打开“挤出机(Extruder)标

签页”。确定回抽开启,然后设置“回抽垂直抬升”的距离,看你想喷嘴抬升多高。例如,你输入0.5mm,在移动到一个新位置前,喷嘴将总是抬升0.5mm。请注意,抬升只会在回抽动作时发生。如果你想确保在打印机每一个移动发生前,都回抽,请点击“高级标签页”,然后确

保“只在通过开放区域时回抽”和“最小化回抽移动“,这两个选项是关闭的。图7-39疤痕效果图7.5.19底面边角上的孔洞和间隙3D打印时,每层在前一层基础上构建。然而,用于打印的塑料多少也是一个因素,因此,基础的强度与使用的塑料量之间,需要平衡。如果基础不够结实,在层与层之间,将会出现孔

洞和间隙。尤其在尺寸有变化的边角处容易出现(例如,你在一个40cm的广场上,打印一个20cm的方块)。当打印转换到更小的尺寸,你需要确保,有足够的基础来支撑20mm方块的边墙。导致基础不牢的原因,通常有几个。效果图如图7-40所示。1.边沿数量不足为打印件,增加更多轮

廓外沿,将明显增强基础。因为打印件里面,通常是部分中空的,外沿墙薄厚,将影响很大。点击“修改切片设置(EditProcessSettings)”,打开“层(Layer)标签页”,来调整。2.顶层实心层数不足另一个常见的,导致基础不牢的原因是,你的打印顶层实心填充层数量不足。太薄的上壁,无法充分

支撑在它上面打出来的结构。修改这个设置,可以“修改切片设置(EditProcessSettings)”,打开“层(Layer)标签页”。如果你之前使用2层顶层实心层,试试4层实心层,看看会不会有改善。3.填充率太低最后一个你需要检查的设置是填充率,它在“切片设置”下方或“填充”标签页下,通

过一个滑动条控制。顶层实心层是建构在顶层填充之上的,所以足够的填充以支撑这些层,是很重要的。例如,你之前设置的填充率是20%,试试增加这个值到40%,看看打印质量是否有改善。图7-40效果图7.5.20侧面线性纹理一个整体平滑的表面。然后,如果仅仅是某一层出现问题,在打印件的外表面,

它都能很清楚地被发现。这些不正确的层,会导致打印件的外表看起来像线性纹理。通常这种瑕疵会周期性出现,这意味着线条是有规律出现(例如,每15层出现一次)。效果图如图7-41所示。1.挤出不稳定这个问题,最可能的原因是线材质量不行。如果线材公差较大,你会在打印件的外壁会发现这种变化。例如,

你的整卷耗材直径只波动5%,从喷嘴中挤出的塑料线条宽度,将改变0.05mm。这种额外的挤出量,将导致相应层的比其他层更宽,最后在打印件的外壁将看到一条线。为了产生一个平滑的表面,你的打印机需要一个稳定的挤出条件,这

要求高质量2.温度波动大多数3D打印机,使用针脚来调节挤出机的温度。如果针脚调谐不正常,挤出机的温度,将会随着时间流逝而波动。鉴于针脚控制的原理,这种波动会频繁重现,这意味着,温度会像正弦波一样波动。当温度太高时,塑料的

挤出顺畅度,跟它更冷一些的时候相比,是不同的。这会导致打印机挤出的层不一样,导致打印件外表面出现纹理。一个正确调谐的打印机,应该可以将挤出机的温度,控制在正负2度之间。在你打印过程中,你可以使用Simplify3D的设备控制面板,来监控挤出机的温度。如果它的波动超过2度

,你需要重新校准针脚控制器。3.机械问题如果你确认,不稳定的挤出和温度波动不是罪魁祸首,那么有可能是机械故障,导致了打印件表面的线性纹理。例如,如果打印平台,在打印过程中晃动,会导致喷嘴位置波动。这意味着有的层会比其他层更厚。这些较厚的层,将在打印件外表产生线性纹理。另一个

常见的问题是,Z轴丝杆没有正确安装。图7-41纹理效果图目录8.1设计思想8.2材料清单8.3电路设计8.1设计思想智能机器人技术随着机器人学、计算机科学、计算机视觉等学科的发展,应用范围和使用价值得到了非常广泛的关注和提高,成为当今

世界高科技领域备受关注的热点课题。近年来智能机器人逐渐走进人类的日常生产和生活,而解魔方机器人因其无与伦比的趣味性和炫酷的交互性,正成为人工智能的研究热点。由于解魔方机器人融合了计算机视觉、图像处理、机器人控制技术、虚拟现实交互、魔方算法等多学科知识,因此实现一个快速、稳定的解魔

方机器人具有很大的挑战性。本项目的魔方机器人通过设计稳定的机械结构,采用当今世界上复原步数最少的Kociemba算法,优化传统的通过设定阈值的颜色识别策略,极大提高了整个系统工作的稳定性。通过优化魔方复原指令解析算法,进一步减少了魔方复原

指令解析得到的舵机执行步数。魔方机器人在复原魔方的快速性和稳定性两方面都达到了很好的效果,复原魔方平均不会超过70秒,达到了魔方机器人设计的预期。通过本项目的训练可以锻炼学生的电路连接、元器件搭载、程序调试、传感器运用、算法调

用及优化等多方面能力,能够将工科学生之前学到的相关课程进行一次梳理和整合,教会学生如何学以致用,并能够激发学生的学习兴趣和创新热情。8.2材料清单材料清单如表8-1所示表8-1材料清单上述清单中的材料中有几处需要特别注意:1.第2,3,4项本

项目使用的是自行建模3D打印的零件,主要目的是降低开发成本。如果有同学想追求更好的性能,可以联系淘宝进行定制,定制件具有精准性更高等优点。2.第7项中的数字舵机,各位同学也可以根据实际需求选择市面上的数字舵

机,推荐使用NG995,55g舵机,本舵机可以在同等电压下旋转180度的时间更短,极大地提升了魔方的还原速度。但是不建议同学们选用模拟舵机,因为模拟舵机需要不断的接受舵机控制器发送的PWM信号才能保持锁定角度,完成相应的操作,并且精度较差,线性度很难达标。而数字舵机仅需接受一次舵机控制器传

递的PWM信号就可以锁定角度不变,控制精度较高、线性度良好、相应速度快,能够完成本项目的各项功能需要。特别值得注意的是,并不是舵机的转动角度越大越好,同学们不要选用360度舵机,因为目前市面的无死角舵机绝大部分无法接受PWM信号控制,不能锁定角度不变,一经上电会不停旋转。3.本项目1和22项为

特殊定制件。需要同学们注意相关的细节问题,以免由于个人疏忽造成不必要的经济损失。4.第36项是STM32系统的专用仿真器,仿真器购买时需注意对应的型号和相应配置,如果型号和stm32开发板不匹配则无法进行数据的下载和导

入。8.3机械零件设计以下为亚克力定制工程图,因为考虑项目整体的可塑性和便携性,不建议用钢板、塑料等其他材料。选用亚克力板作为本设计的底盘是因其材料具有较好的透明性、易加工、不容易变形,表面光泽度较高,成本相对较低等优点。滑块增高块图如图8-1所示、机械手工程图如图8-2所示、基板工程

图如图8-3所示、基板工程图细节如图8-4所示。图8-1滑块增高块图图8-2机械手工程图图8-3基板工程图图8-4基板工程图细节图纸中所有单位均为MM,比例为1:1,透明亚克力材质。具体参数要求:1.滑块增高块厚度为30MM,数量4个

。2.机械手厚度为10MM,数量4个。3.基板厚度为8MM,数量1个。本项目的连接条和转魔方的机械手根据硬度和韧性的要求选择使用PLA材料。即通过自主建模,通过3D打印制作完成。以下为3D打印件工程图。连接条如图8-5所示,机械手如图8-6所示。图8-5连

接条图8-6机械手进行3D打印材料时,应该尽量选用质量好的PLA耗材,这样才能保证成品的质量。一般耗材选择1.75MM,公差不超过±0.02mm的材料。另外,3D打印机原则上是选用精度越高的越好,但是同学们往往接触到

的都是入门级别的设上述零件图各插口没有做的特别细小,一般的打印机都可以完成。上述零件打印的最低要求标准是机器打印精度0.2mm,打印层高0.4mm8.4电路设计8.4.1硬件框图1.魔方机器人设计方案主要的系统组成手机app主要功能是颜色识别过程中获取魔方六个面的六张图片,STM

32通过控制舵机让魔方旋转到特定的角度,ArduinoMega2560实现了STM32和各个传感模块之间的数据交换,其通过控制蓝牙模块实现了人对魔方机器人的各种控制,并利用蓝牙手机端APP来完成魔方复原的核心工作。魔方复原全过程如图8-8所示。图8-8魔方复原全

过程图8-9魔方机器人硬件电路框图设计硬件电路设计部分主要是STM32和Arduino进行数据交换,通过视觉模块将信息逐步传递,根据移植的相应算法进行计算,将具体的步骤以指令的形式转给主控器,主控器将具体命令通过蓝牙模块发出,驱动舵机运作,最终实现对魔方的转动。如图8-9所示。

7.4V的锂电池为整个STM32和2560硬件系统供电,经XL4015E1稳压电路降为6.0V为舵机供电,AMS1117稳压电路将锂电池电压降为3.3V为STM32和2560供电。蓝牙串口模块可以实现蓝牙协议和串口协议的转换,很方便地实现了STM3

2和2560进行数据传输。本项目用舵机两两一组构成曲柄滑块的机械结构作为复原魔方的机械手,8个舵机构成四组机械手。硬件系统实物图如图8-10所示。图8-10魔方机器人硬件系统实物图STM32和2560电路模块设计魔方机器人的电路设计较为简

单,本文只简要介绍XL4015E1稳压电路图8-11XL4015E1稳压电路本项目使用的舵机的驱动电流较大,每个舵机的驱动电流大约为500mA,8个舵机同时驱动需要至少4A的驱动电流,,舵机的驱动电压为4.

8V-6.5V。XL4015E1是一款输出电压可调的开关电源稳压器,最大输出电流为5A,输出电压为1.25V-32V,可以满足舵机的驱动电流和电压需求。XL4015E1开关频率为180KHZ,能量转换

效率高达96%,负载调整率<0.8%,电压调整率<0.8%。图8-11是XL4015E1稳压电路的原理图。输出电压的计算公式为:VOUT=1.25*(1+R1/R2)公式中1.25为参考电压,单位为V,R1的阻值为固定值10K,R2为

可调电阻,最大阻值为10K,当输出电压为6.0V时,R2的阻值约为2.6K。8.4.2魔方算法Kociemba算法及其优化本图是本文移植的Kociemba算法Java测试软件。按钮Scramble可以随机打乱一个

魔方,并在界面中显示出来,MoveLimit设定复原魔方公式的最大步数,TimeLimit设定复原的最大时间。按钮SolveCube运行Kociemba算法并生成复原公式,当超过设定的时间还没有解算出来或者设定的步数过短时,软件会有提示。图8-12测试软件主界面测试软件的主界面是魔方

六个面的展开图,如图8-12所示。魔方中心块上的字母代表这个面所处的方位:F(front)代表前面,B(back)代表后面,L(left)代表左面,R(right)代表右面,U(up)代表上面,D(down)代表下面。一个魔方共有6种颜色,某种颜色的颜色标号用中心块为该颜色的面所处的方位(F、B

、L、R、U、D)来表示。Kociemba算法的输入参数即为魔方54个颜色块的标号排列,颜色标号的排列按照一定的顺序,六个面的顺序依次为上、右、前、下、左、后,每个面的标号排列按照从上到下,从左到右的顺序。8.4.3KOCIEMBA算法的优化Kociemba魔方复原算法运行时,总会挑选近似最

优的解输出。据多次(大于15次)测试统计,单次运行算法时,输出的复原公式平均有21步,舵机执行此复原公式的平均步数为144步。算法运行一次输出是近似最优解,解算时间平均为10ms。为了取得最优的复原公式,系统在保证时间高效的同时,必须寻找出最优解。正常情况下,运行时

间越长,Kociemba魔方复原算法更有可能取得最优解。当运行Kociemba算法时间足够长时,一定会找出最优解,最优解能通过减少舵机执行步数来缩短魔方复原时间。但是减少的时间能不能抵消掉Kociemba算法多次运行带来的时间消耗,这个

还需要数据的测试。为了测试以取得最优模型,我们增加了“限时取解”的逻辑:让Kociemba算法连续运行t秒的时间,获取得到最优解,然后通过对比寻找最优解的时间消耗与最优解带来的的时间收益,来判断“限时取解”

是否是一种可行的方法。测试过程中,我们取限制时间t为0.4S和远大于0.4S的时间,如5S,同时我们统计出每次运行算法得到的复原公式对应的舵机步数。通过多次测试统计得出:1.Kociemba算法连续运行0.4秒或超过0.4秒的时,能获取到最优解,并且运行0.4秒与运行

超过0.4秒两种情形下取得的最优解执行效率相差不大。2.连续运行0.4秒时,Kociemba算法取得的最优解大大减少了舵机运行步数,舵机执行最优解时平均步数为116步,最优解带来的时间收益大于寻找最优解花

费的时间消耗。基于以上两个特点可以推断出:连续运行0.4秒的时间,足以使Kociemba算法找出魔方复原的最优解,所以“限时取解”模型是一种可行的方法。当限制时间t等于0.4S时,对“限时取解”模型的优化效果做了测试,从图

中可以看出,平均舵机步数优化比例为20%,优化效果较为可观。Kociemba算法限时取解测试数据如图8-13所示。图8-13Kociemba算法限时取解测试数据8.4.4魔方复原指令的优化魔方机器人有两套指令系统,第一套指令系统是现在世界各地的解魔方教程中所使用的一套复原指令系统,也就是K

ociemba算法得到的复原指令中使用的指令系统,第二套指令系统是我们的魔方机器人在执行魔方复原时用到的指令系统。其实对于复原指令优化程序来说,一方面是通过优化指令缩短魔方复原的时间,另一方面也是把第一套指令系统转变为第二套指令

系统,这样STM32才能在接收到指令后进行解析,复原魔方。所以第一套指令系统我们称为未优化指令系统,第二套指令系统我们称为优化后指令系统。未优化指令系统图表给出了魔方机器人的未优化指令系统,共有18种单指令。表中字母L(left)代表左面,R(r

ight)代表右面,F(front)代表前面,B(back)代表后面,U(up)代表上面,D(dowm)代表下面。字母后面加’代表逆时针旋转90度,例如F’表示将魔方的前面逆时针旋转90度,单独一个字母表示顺时针旋转90

度,字母后面有数字2表示将相应的面旋转180度,由于逆时针旋转180度和顺时针旋转180度的效果是一样的,所以不做区分。优化后指令系统此图表给出了魔方机器人优化后指令系统,共有16种单指令。指令系统中所有和未优化指令系统相同的指令表示的含义也相

同,优化后指令系统中字母后面加^和未优化指令系统中单字母表示的含义相同。两个字母相同的代表翻转指令,例如:LL代表把魔方向左翻转90度。8.4.5硬件系统连接1.下位机连接如下图8-14所示、图8-14下位机连接图此处同学们需要注意的是电源端的地线必须和stm32的GND相连舵机信

号线分别连接PA1到PA8Stm32单片机驱动舵机代码:编程环境为keil使用语言为c语言。作者使用的软件版本为Vision4,具体内容如下。#include"stm32f10x.h"#include"movement.h"#include"m

otor.h"#include"usart.h"#include"instruction.h“staticconstu16original_position[4]={1430,1440,1390,1500};staticc

onstu16clockwise90_position[4]={580,540,545,660};staticconstu16anticlockwise90_position[4]={2310,2440,2345,2470};staticc

onstu16clockwise180_position[4]={2270,2310,2340,2340};staticconstu16wrasp_position[4]={1940,1638,1780,1678};staticconstu16loosen

_position[4]={1410,1155,1230,1125};u16lines_num=0;u16initial_position[8];u16firpic_position[5][8];u16secpic_position[2]

[8];u16thirpic_position[5][8];u16fourpic_position[2][8];u16fifpic_position[5][8];u16sixpic_position[2][8];u16retuinit_position[5

][8];u16r_clockwise90[4][8];u16l_clockwise90[4][8];u16f_clockwise90[4][8];u16b_clockwise90[4][8];u16r_anticlockwise90[4][8];u16l

_anticlockwise90[4][8];u16f_anticlockwise90[4][8];u16b_anticlockwise90[4][8];u16r_clockwise180[4][8];u16l_clockwise180[4][8];u16f_clockwise1

80[4][8];u16b_clockwise180[4][8];u16overturnto_f[6][8];u16overturnto_b[6][8];u16overturnto_l[6][8];u16overturnto_r[6][8]voidInit_TotalArray(v

oid){Calcul_InitPosition();Calcul_FirPicPosition();Calcul_SecPicPosition();Calcul_ThirPicPosition();Calcul_FourPicPosition();Calcul_SixPicPosit

ion();RetuIni_AftPic();Calcul_Lclockwise90();Calcul_Rclockwise90();Calcul_Fclockwise90();Calcul_Bclockwise90();Calcul_Lanticlockwise90();Cal

cul_Ranticlockwise90();Calcul_Fanticlockwise90();Calcul_Banticlockwise90();Calcul_Lclockwise180();Calcul_Rclockwise180();Calcul_Fclockwise180();Cal

cul_Bclockwise180();Calcul_OverturntoB();Calcul_OverturntoF();Calcul_OverturntoL();Calcul_OverturntoR();voidCalcul_InitPosition(void){u8i,j;for(i=0;i

<4;i++){nitial_position[i]=original_position[i];}for(i=4,j=0;i<8;i++,j++){initial_position[i]=wrasp_position[j];}}voidInit_MotorMovement(void){u8i;f

or(i=0;i<8;i++){pos[0][i]=initial_position[i];}for(i=0;i<4;i++){pos[1][i]=initial_position[i];}for(i=0;i<4;i++){pos[1][i+4]=loose

n_position[i];}lines_num=1;}voidCalcul_FirPicPosition(void){u8i;for(i=0;i<8;i++){firpic_position[0][i]=initial_position[i];}for(i=0;i<8;i++)

{firpic_position[1][i]=initial_position[i];}firpic_position[1][5]=loosen_position[1];firpic_position[1][7]=loosen_position[3];for(i=0;i<8;i++){f

irpic_position[2][i]=initial_position[i];}for(i=0;i<8;i++){firpic_position[3][i]=firpic_position[2][i];}firpic_posi

tion[3][5]=loosen_position[1];firpic_position[3][7]=loosen_position[3];for(i=0;i<8;i++){firpic_position[4][i]=firpic_position[3][i];}firpic_p

osition[4][0]=clockwise90_position[0];firpic_position[4][2]=anticlockwise90_position[2];}voidCalcul_SecPicPosition(void){u8

i;for(i=0;i<8;i++){secpic_position[0][i]=firpic_position[4][i];}for(i=0;i<8;i++){secpic_position[1][i]=secpic_position[0][i];}secpic_posi

tion[1][0]=anticlockwise90_position[0];secpic_position[1][2]=clockwise90_position[2];}voidCalcul_ThirPicPosition(void){u8i;for(i=0;i<8;i++

){thirpic_position[0][i]=secpic_position[1][i];}for(i=0;i<8;i++){thirpic_position[1][i]=thirpic_position[0][i];}thirpic_position[1][5]=wrasp_

position[1];thirpic_position[1][7]=wrasp_position[3];for(i=0;i<8;i++){thirpic_position[2][i]=thirpic_position

[1][i];}thirpic_position[2][4]=loosen_position[0];thirpic_position[2][6]=loosen_position[2];for(i=0;i<8;i++){thirpic_position[3][i]=thirpic_positi

on[2][i];}thirpic_position[3][0]=original_position[0];thirpic_position[3][2]=original_position[2];for(i=0;i<8;i

++){thirpic_position[4][i]=thirpic_position[3][i];}thirpic_position[4][1]=clockwise90_position[1];thirpic_positio

n[4][3]=anticlockwise90_position[3];}voidCalcul_FourPicPosition(void){u8i;for(i=0;i<8;i++){fourpic_position[0][i]=thirpic_position[4

][i];}for(i=0;i<8;i++){fourpic_position[1][i]=fourpic_position[0][i];}fourpic_position[1][1]=anticlockwise90_position[1];

fourpic_position[1][3]=clockwise90_position[3];}voidCalcul_FifPicPosition(void){u8i;for(i=0;i<8;i++){fifpic_position[0

][i]=fourpic_position[1][i];}for(i=0;i<8;i++){fifpic_position[1][i]=fifpic_position[0][i];}fifpic_position[1][4]=wrasp_position[0

];fifpic_position[1][6]=wrasp_position[2];for(i=0;i<8;i++){fifpic_position[2][i]=fifpic_position[1][i];}fifpic_position[2][5]=loose

n_position[1];fifpic_position[2][7]=loosen_position[3];for(i=0;i<8;i++){fifpic_position[3][i]=fifpic_position[2][i

];}fifpic_position[3][1]=original_position[1];fifpic_position[3][3]=original_position[3];for(i=0;i<8;i++){fifpic_posi

tion[4][i]=fifpic_position[3][i];}fifpic_position[4][0]=clockwise90_position[0];fifpic_position[4][2]=anticlockwise90_positio

n[2];}voidCalcul_SixPicPosition(void){u8i;for(i=0;i<8;i++){sixpic_position[0][i]=fifpic_position[4][i];}for(i=0;i<8;i++){sixpic_position[1][i]=sixpi

c_position[0][i];}sixpic_position[1][0]=anticlockwise90_position[0]sixpic_position[1][2]=clockwise90_position[2];}voidRe

tuIni_AftPic(void){u8i;for(i=0;i<8;i++){retuinit_position[0][i]=sixpic_position[1][i];}for(i=0;i<8;i++){retuinit_position[1][i]=retuinit_positio

n[0][i];}retuinit_position[1][5]=wrasp_position[1];retuinit_position[1][7]=wrasp_position[3];for(i=0;i<8;i++){retui

nit_position[2][i]=retuinit_position[1][i];}retuinit_position[2][4]=loosen_position[0];retuinit_position[2][6]=l

oosen_position[2];for(i=0;i<8;i++){retuinit_position[3][i]=retuinit_position[2][i];}retuinit_position[3

][0]=original_position[0];retuinit_position[3][2]=original_position[2];for(i=0;i<8;i++){retuinit_position[4][i

]=retuinit_position[3][i];}retuinit_position[4][4]=wrasp_position[0];retuinit_position[4][6]=wrasp_position[2];}voidPicArray_ToBufferA

rray(u16(*array)[8],u16arrayline_num){u8i,j;lines_num=arrayline_num;for(j=0;j<=lines_num;j++){for(i=0;i<8;i++){pos[j][i]=*

(*(array+j)+i);}}}voidCalcul_Lclockwise90(void){u8i;for(i=0;i<8;i++){l_clockwise90[0][i]=initial_position[i];}l_clockwi

se90[0][1]=anticlockwise90_position[1];for(i=0;i<8;i++){l_clockwise90[1][i]=l_clockwise90[0][i];}l_clockwise90[1][5]=loos

en_position[1];for(i=0;i<8;i++){l_clockwise90[2][i]=l_clockwise90[1][i];}l_clockwise90[2][1]=original_position[1];for(i=0;i<8;i

++){l_clockwise90[3][i]=l_clockwise90[2][i];}l_clockwise90[3][5]=wrasp_position[1];}voidCalcul_Lanticlockwise90(void){u8i;for(i=0;i

<8;i++){l_anticlockwise90[0][i]=initial_position[i];}l_anticlockwise90[0][1]=clockwise90_position[1];for(i=0;i<8;i++){l_antic

lockwise90[1][i]=l_anticlockwise90[0][i];}l_anticlockwise90[1][5]=loosen_position[1];for(i=0;i<8;i++){l_anticlockwise90[2][i]=l_anticlockwise90[1]

[i];}l_anticlockwise90[2][1]=original_position[1];for(i=0;i<8;i++){l_anticlockwise90[3][i]=l_anticlockwise90[2][i];}l_anticlockwis

e90[3][5]=wrasp_position[1];}voidCalcul_Lclockwise180(void){u8i;for(i=0;i<8;i++){l_clockwise180[0][i]=initial_position[i];}l_clockwise180[0]

[1]=clockwise180_position[1];for(i=0;i<8;i++){l_clockwise180[1][i]=l_clockwise180[0][i];}l_clockwise90[1][5]=loosen_position[1];for(i=0;i<8

;i++){l_clockwise180[2][i]=l_clockwise180[1][i];}l_clockwise180[2][1]=original_position[1];for(i=0;i<8;i++){l_clockwise180[3][i]=l_clo

ckwise180[2][i];}l_clockwise180[3][5]=wrasp_position[1];}voidCalcul_OverturntoL(void){u8i;for(i=0;i<8;

i++){overturnto_l[0][i]=initial_position[i];}overturnto_l[0][5]=loosen_position[1];overturnto_l[0][7]=loosen_position[3];for(i

=0;i<8;i++){overturnto_l[1][i]=overturnto_l[0][i];}overturnto_l[1][0]=anticlockwise90_position[0];overturnto_l[1][2]=clockwise9

0_position[2];for(i=0;i<8;i++){overturnto_l[2][i]=overturnto_l[1][i];}overturnto_l[2][5]=wrasp_position[1];ove

rturnto_l[2][7]=wrasp_position[3];for(i=0;i<8;i++){overturnto_l[3][i]=overturnto_l[2][i];}overturnto_l

[3][4]=loosen_position[0];overturnto_l[3][6]=loosen_position[2];for(i=0;i<8;i++){overturnto_l[4][i]=overturnto_l[3][i];}ov

erturnto_l[4][0]=original_position[0];overturnto_l[4][2]=original_position[2];for(i=0;i<8;i++){overturnto_l[5]

[i]=overturnto_l[4][i];}overturnto_l[5][4]=wrasp_position[0];overturnto_l[5][6]=wrasp_position[2];}voidCalcul_Rclockwise90(v

oid){u8i;for(i=0;i<8;i++){r_clockwise90[0][i]=initial_position[i];}r_clockwise90[0][3]=anticlockwise90_position[3];for(i=0;i

<8;i++){r_clockwise90[1][i]=r_clockwise90[0][i];}r_clockwise90[1][7]=loosen_position[3];for(i=0;i<8;i++){r_clockw

ise90[2][i]=r_clockwise90[1][i];}r_clockwise90[2][3]=original_position[3];for(i=0;i<8;i++){r_clockwise90[3][i]=r_clockwise90[2][

i];}r_clockwise90[3][7]=wrasp_position[3];}voidCalcul_Ranticlockwise90(void){u8i;for(i=0;i<8;i++){r_anticlockwise90[0][i]=initial_position[i];}r

_anticlockwise90[0][3]=clockwise90_position[3];for(i=0;i<8;i++){r_anticlockwise90[1][i]=r_anticlockwise90[0][i];}r_anticlock

wise90[1][7]=loosen_position[3];for(i=0;i<8;i++){r_anticlockwise90[2][i]=r_anticlockwise90[1][i];}r_anticlockwise90[2][3]=original_position[3

];for(i=0;i<8;i++){r_anticlockwise90[3][i]=r_anticlockwise90[2][i];}r_anticlockwise90[3][7]=wrasp_position[3]

;}voidCalcul_Rclockwise180(void){u8i;for(i=0;i<8;i++){r_clockwise180[0][i]=initial_position[i];}r_clockwise180[0][3]=clockwise1

80_position[3];for(i=0;i<8;i++){r_clockwise180[1][i]=r_clockwise180[0][i];}r_clockwise180[1][7]=loosen_positi

on[3];}voidTIM4_Int_Init(u16arr,u16psc){TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;NVIC_InitTypeDe

fNVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);TIM_TimeBaseStructure.TIM_Per

iod=arr;TIM_TimeBaseStructure.TIM_Prescaler=psc;TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;TIM_TimeBaseStructure.TIM_CounterMode=TI

M_CounterMode_Up;TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);NVIC_InitStructure.NVIC_IRQChannel=T

IM4_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;NVIC_InitStructure.NV

IC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitStructure);TIM_Cmd(TIM4,DISABLE);}voidTIM3_Set_Time(u16arr){TIM_TimeBaseInitTypeDefTIM_TimeBaseS

tructure;arr--;TIM_TimeBaseStructure.TIM_Period=arr;TIM_TimeBaseStructure.TIM_Prescaler=71;TIM_TimeBaseInit(TIM3,

&TIM_TimeBaseStructure);}voidTIM4_Set_Time(u16arr){TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;arr--;TIM_TimeBaseStructu

re.TIM_Period=arr;voidTIM3_IRQHandler(void){staticu8i=1;if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET){flag

_vpwm=1;switch(i){case1:{PWM1=1;TIM3_Set_Time(pwm[0]);}break;case2:{PWM1=0;TIM3_Set_Time(2500-pwm[0]);flag_vpwm=1;}break;case3:{P

WM2=1;TIM3_Set_Time(pwm[1]);}break;case4:{PWM2=0;TIM3_Set_Time(2500-pwm[1]);flag_vpwm=1;}break;case5:{PWM3=1;TIM3_Set_Time(pwm[2]);}brea

k;case6:{PWM3=0;TIM3_Set_Time(2500-pwm[2]);flag_vpwm=1;}break;case7:{PWM4=1;TIM3_Set_Time(pwm[3]);}break;case8:{PWM4=0;TIM3_Set_Time(2500-pwm

[3]);flag_vpwm=1;}break;case9:{PWM5=1;TIM3_Set_Time(pwm[4]);}break;case10:{PWM5=0;TIM3_Set_Time(2500-pwm[4]);flag_vpwm=1;}break;case11:{PWM6=1;TIM3_

Set_Time(pwm[5]);}break;case12:{PWM6=0;TIM3_Set_Time(2500-pwm[5]);flag_vpwm=1;}break;case13:{PWM7=1;TIM3_Set

_Time(pwm[6]);}break;case14:{PWM7=0;TIM3_Set_Time(2500-pwm[6]);flag_vpwm=1;}break;case15:{PWM8=1;TIM3_Set_

Time(pwm[7]);}break;case16:{PWM8=0;TIM3_Set_Time(2500-pwm[7]);flag_vpwm=1;i=0;}break;default:break;}i++;}2.ARDUINOMEGA2560和STM32硬件连接图连接图如

图8-15所示。图8-15ArduinoMega2560和stm32通信图ArduinoMega2560的调试代码如下:intIntly=Serial1.read();Intabcd=Serial.read();voidsetup(){Serial.begin(9600);Serial1.begi

n(9600);}voidloop(){//putyourmaincodehere,torunrepeatedly:Serial.print(ly);//Serial1.print(abcd);}Stm32代码:#if1#pragmaimport(__use_no

_semihosting)struct__FILE{inthandle;};FILE__stdout;_sys_exit(intx){x=x;}intfputc(intch,FILE*f){while((USAR

T1->SR&0X40)==0);USART1->DR=(u8)ch;returnch;}#endifvoidUSART1_Config(void){GPIO_InitTypeDefGPIO_InitStructure;USART_InitTypeDefUSART_InitStructure

;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;GPIO_InitStructure.GPIO_

Mode=GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=GPIO

_Pin_10;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA,&GPIO_InitStructure);USART_InitStructure.USART_BaudRate=9600;USART_Init

Structure.USART_WordLength=USART_WordLength_8b;USART_InitStructure.USART_StopBits=USART_StopBits_1;USART_InitStructure.USART_

Parity=USART_Parity_No;USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;USART_InitStructure.USART_Hardw

areFlowControl=USART_HardwareFlowControl_None;USART_Init(USART1,&USART_InitStructure);USART_ITConfig(USART1,USART_IT_RXNE,ENABLE)

;/*EnablesUSART1interrupts,USART_IT_RXNE:ReceiveDataregisternotemptyinterrupt*/USART_Cmd(USART1,ENABLE);NVIC_USART1_Configuration();}

u8num_to_asc(u8num){u8asc;switch(num){case0:asc=0x30;break;case1:asc=0x31;break;case2:asc=0x32;break;case3:asc=0x33;break;case4:asc=0x34;b

reak;case5:asc=0x35;break;case6:asc=0x36;break;case7:asc=0x37;break;case8:asc=0x38;break;case9:asc=0x39;break;}ret

urnasc;}u8asc_to_num(u8asc){u8num;switch(asc){case0x30:num=0;break;case0x31:num=1;break;case0x32:num=2;break;

case0x33:num=3;break;case0x34:num=4;break;case0x35:num=5;break;case0x36:num=6;break;case0x37:num=7;break;case0x38:num=8;break;case0x39:num=9;br

eak;}returnnum;}{USART_SendData(USART1,asc_shi);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET)

;}USART_SendData(USART1,asc_ge);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);USART_SendChar8('');//USART_SendData(USART1,'\r

');//while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);////USART_SendData(USART1,'\n');//while(USART_GetF

lagStatus(USART1,USART_FLAG_TC)!=SET);USART_ClearFlag(USART1,USART_FLAG_TC);}voidUSART_SendString(unsignedchar*s

tr){while(*str!='!'){USART_SendData(USART1,*str++);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);}}voidUSART

_SendChar(u8siglechar){USART_SendData(USART1,siglechar);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);U

SART_ClearFlag(USART1,USART_FLAG_TC);}voidNVIC_USART1_Configuration(void){NVIC_InitTypeDefNVIC_InitStructure;/*EnabletheUSARTyInterrupt*/NVIC_InitSt

ructure.NVIC_IRQChannel=USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;NVIC_InitStru

cture.NVIC_IRQChannelSubPriority=1;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitStructure);}voidUSART1_IRQHandler(void){static

u8i=0;if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)/*ReceiveDataregisternotemptyinterrupt*/{rece_stri

ng[i++]=USART1->DR;if(((rece_string[i-1]=='!')&&(rece_string[0]=='#')&&(rece_string[1]!='E'))||((rece_string[i

-1]=='!')&&(rece_string[0]=='@'))||((rece_string[i-1]=='!')&&(rece_string[0]=='%'))){i=0;rece_flag=1;USART

_ClearFlag(USART1,USART_IT_RXNE);/*clearReceivedataregisternotemptyflag*/}}}3.手机端设置上位机为手机app,其操作简单方便,便于使用,在此处就不作过多说明,具体如下图8-15所示:图8-15上位机

使用图片4.成品实物图成品实物图分别如图8-16、8-17、8-18所示。图8-16俯视图图8-17上位机魔方指令图图8-18解魔方过程图目录9.1ArduinoWiFi相关项目9.2Arduino与手机通讯调试项目9.

1ARDUINOWIFI相关项目9.1.1设计思想本节中我们将介绍如何基于Arduino控制板利用wifi模块上传周边的温度至服务器端,可以通过连接服务器的任一客户端获取。这样,就算甚至在大洋彼岸的任何国家,都能查阅到自己亲人身边的温度。同理,也可以利用

多种类型的传感器,查阅您需要的其他信息。9.1.2材料清单本实验所用到的材料清单如表9-1所示。表9-1材料清单利用ARDUINO和WIFI将温度传送至云端,如图9-1所示硬件实物图。图9-1硬件实物图1.工作

原理如图9-2所示。图9-2工作原理图2.实验分析(1)设计实验原理图:按照设计思路,画出实验原理图,如图9-3所示。这是从前面某一讲中抽取的一个图,为了读者查阅的方便,在这再次给出这个图。但这个原理图中,由

于画法的原因,还缺少Arduino的扩展板和wifi模板。但利用传感器LM35来采集数据的原理是一样的。图9-3实验原理图(2)实物连接:按照原理图,连接好电路,如图9-4所示。图9-4实验连接图(3)wifi网络连接:当连接

Arduino主板时,就已经可以收到wifi信号了,但是为了稳定,最好用专用充电器连接Arduino扩展板。你的电脑将会搜索到有wifi模块发出的wifi信号HI_LINK_0021(或者HI_LINK_XXXX可参考第2讲得内容)。双击连接HI_L

INK_0021wifi信号(默认密码12345678)。若不是第一次使用的,为了确保数据配置的正确性,需要将wifi模块恢复出厂默认设置(按住Arduino扩展板上的RST按钮6s,然后断电重启即可,具体也可参考第2讲的内容)。这一步相当于

咱们用打开手机的wifi信号上网一样。此时的wifi模块打开wifi信号,连接手机的wifi热点信号上网。(4)建立wifi热点:由于本次实验环境没有其他wifi,所以采用的是HTC手机建立wifi热点,用wifi路由器也是一样的。打开手机的“WLAN热点”,记住此时记得打开

手机的3G网络信号,以便由温度传感器LM35采集的数据上传至云端的服务器。本次实验WLAN热点名称“HTCtest”,密码“12345678”。也可以用手机默认的用户名和密码,不过,为了输入的方便,可以更

改手机默认的用户名和密码。5)网络数据配置:当成功连接wifiHI_LINK_0021网络后,打开浏览器,输入地址192.168.16.254,输入用户名和密码(均为admin)进入数据配置,如图9-5所示。图9-5网络数据配置注意红色框框标记部分,其他按默置即可。几点说明:

(1)此时的wifi模块相当于一个采集输送单元,将采集到的数据由wifi模块送至服务器端;(2)SSID和Password指的是手机(或wifi路由器)的SSID和Password;(3)RemoteServerDomian/IP:指的是咱们要将采集到的温度数据要

存放的服务器IP地址;(4)Locale/RemotePort:是访问服务器的地址。(5)配置完成后,点击“Apply”。这时,再检查手机的“WLAN热点界面”最下方的“管理用户处”,有“1连接的用户”。此时,表示wifi模块已经连接上了手机的热点,也即连接上了i

nternet。(6)编写Arduino代码:voidsetup(){Serial.begin(115200);//设置串口波特率}voidloop(){intn=analogRead(A0);//定义A0口为接收电压信号数据floatvol=n*(5.0/1023*100);//电压信

号数据温度转换upload_sensor(vol);//调用子函数delay(5000);}voidupload_sensor(floatvol){//sendtheHTTPPUTrequest:核心代码charbuf[200];memset(buf,0,200);intret;

ret=sprintf(buf,"GET/upload.php?uid=ycf&ps=ycf&sensor_name=Arduino&data=");//设置协议Serial.print(buf);//暂存至bufSerial.print(vol);

//调用温度数据volSerial.println("HTTP/1.1");//HTTP协议名称Serial.println("Host:api.cduino.com");//设置服务器地址Serial.println("Conn

ection:close");//数据传输完毕,连接关闭Serial.println();}将上述代码下载到Arduino主板上,注意,在Arduino的扩展板上有个开关,在下载数据时,请将拨至外侧(O)。这是因为连接串口时,有可能会影响数据的下载。同时打开串口,如图9-6注意红色的标记。此

时的环境温度为25.90。然后这个温度将通过wifi模块连接手机热点上的wifi信号上传至服务器端。图9-6Arduino串口监视器数据示(7)终端数据采集:若前面6步全部成功,恭喜你!成功啦,由温度传感器LM35采集到的温度数据已经通过wifi模块经由手机wifi联网成功,一

路过关斩将,历经千辛万苦,终于将温度传感器LM35采集到的温度数据上传至服务器端,如图9-7所示。图9-7服务端数据显示比较图图9-7服务器端数据显示比较图9-6(用Arduino自带的串口显示器)和图9-6(云端服务器),会发现,用Arduino自带串口监视器采集的温度数据

和云端服务器温度数据是一致的,说明数据传送成功。在下一讲的内容,咱们将接着下一步工作,将云端服务器的数据很好地展现给别人看。3.要点与总结(1)配置数据前,为确保数据能配置成功,请将wifi模块恢复出厂设置;(2)注意配置数据的

准确性,尤其是关于手机和服务器端的IP地址设置;9.2ARDUINO与手机通讯调试项目9.2.1设计思想想要通过Arduino实现与指定手机的通讯录进行信息交互有很多方法,nRF24L01的成本较低,但内部需通过SPI通信,略显复杂,而RF模块又过于专用,接入其他系统时需要转换,不方便。E

SP8266是乐鑫公司推出的廉价、但几乎全能的WIFI芯片,被各种智能硬件广泛使用,根据其datasheet,不但支持SPI,也可通过I2C、UART等方式进行通信,尤其是UART,直接支持AT指令,大大简化开发难度,相当便利。

本项目通过使用ESP8266无线wifi模块实现与手机进行通信,完成相应的任务。9.2.2材料清单本实验所用到的材料清单如表9-2所示。表9-2材料清单1.ESP8266-14简介ESP8266-14是一款低

成本WIFI-MCU通讯/控制模块,内置ESP8266WIFI通讯IC和STM8003单片机,拥有业内极富竞争力的封装尺寸和超低能耗技术,可广泛应用于智能家居和物联网网领域,用于将用户的物理设备连接到Wi-Fi无线网络上,进行互联网或局域网通信,实现联网控制功能。该模块内置了一个功能强大的

STM8003的芯片,所有管脚全部接出来,其串口与ESP8266的串口相连,用户可以编写STM8程序,通过AT指令控制ESP8266的实现绝大部分智能灯家居和WIFI物联网功能。ESP8266-14内

置ESP8266WIFI通讯IC和STM8003单片机,可以绕过单片机,直接通过串口使用ESP8266-14内置的8266模块,只是不能利用它的GPIO来作其他事情了,只能作为一个单纯的串口WiFi使用,不过对于目前的应用场景

,也差不多了。第一步调试,需要知道这模块从网上买来之后是否好用,那么一般需要用USB_TTL来接PC查看串口消息,不过Arduino可以使用软串口,不过更直接的,可以使用Arduino当作USBTTL来直连PC,是不是很

方便呢?这样就可以节省单独购买USBTTL串口调试板的费用了。是不是把Arduino的潜能开发出来了。代码很简单,就是把D0,D1端口中的内置上拉电阻使能。voidsetup(){//putyoursetupcodehere,tor

unonce:pinMode(0,INPUT_PULLUP);pinMode(1,INPUT_PULLUP);}voidloop(){//putyourmaincodehere,torunrepeatedly:}然后把其他设备的TX,RX,GND接到Arduin

o板子上和USBTTL方法一样。这样,其他设备就可以直接通过串口与PC相连了。PC可以通过串口直接操作它了。Arduino只是作为USB串口的模块存在。引脚图如图9-8所示。在进行USB_TTL上传的时候,不要把TX,RX插

到板子上。以免失败。图9-8Esp8266引脚图按此方式接线方式如图9-9,接入ArduinoMega2560(或UNO)图9-9接线方式8266TX(PD6)<->ArduinoTx08266RX(PD5)<->

ArduinoRx08266ESP_VDD<->Arduino3.3V8266GND<->ArduinoGNDArduinoVIN<->电池7.4V(为确保供电充足,不然USB口接电脑供电不足)ArduinoGND<->电池GND上面的插座是自己焊上去的,这个引脚不是标准的距离,比较费事,需

要把引脚掰弯之后焊接,如图9-10所示。上步完成后,如果通过串口能获取到信息,则证明芯片是好的。可以进行下一步.这里可以手动下一些AT命令对ESP8266进行控制测试第二步接线方式与第一步的区别是,TX,RX要反着接,以便Arduino给82

66发串口命令。图9-10接线方式8266RX(PD5)<->ArduinoTx18266TX(PD6)<->ArduinoRx18266ESP_VDD<->Arduino3.3V8266GND<->Arduin

oGNDArduinoVIN<->电池7.4V(为确保供电充足,不然USB口接电脑供电不足)ArduinoGND<->电池GND手机设置为便携热点,如图9-11所示(如果用8266作为热点,可能因为客户端没去连接它,而休眠,所以使用手机作

为热点)图9-11手机设置为便携热点手机上安装“网线调试助手”,安装成功之后,在tcpserver选项下,点击“配置”,弹出服务配置界面,默认5000端口,点击右边的“激活”,激活成功会显示手机的IP与端口,则在手机上创建了一个服务,我手机的IP是192.168.43.1:5

000.通过Arduino给8266发串口命令,使其连接手机#defineWIFISerialSerial1#define_cellSerial1charCMD_LEFT[]="LEFTOK";charCMD_RIGHT[]

="RIGHTOK";charCMD_BACK[]="BACKOK";charCMD_FORWARD[]="FORWARDOK";charCMD_STOP[]="STOPOK";intchlID;//clientid(0-4)intReceiveMessage(char

*buf){//+IPD,<len>:<data>//+IPD,<id>,<len>:<data>Stringdata="";if(_cell.available()>0){unsignedlongstart;start=millis();char

c0=_cell.read();if(c0=='+'){while(millis()-start<5000){if(_cell.available()>0){charc=_cell.read();data+=c;}if(data.indexOf("OK")!=-1){brea

k;}}//Serial.println(data);intsLen=strlen(data.c_str());inti,j;for(i=0;i<=sLen;i++){if(data==':'){break;}}booleanfound=false;for(j=4;j<=i;j++)

{if(data[j]==','){found=true;break;}}intiSize;//DBG(data);//DBG("\r\n");if(found==true){String_id=data.substrin

g(4,j);chlID=_id.toInt();String_size=data.substring(j+1,i);iSize=_size.toInt();//DBG(_size);Stringstr=data.substring(i+1,i+1+iSize);strcpy(buf,st

r.c_str());//DBG(str);}else{String_size=data.substring(4,i);iSize=_size.toInt();//DBG(iSize);//DBG("\r\n");Stringstr=data.sub

string(i+1,i+1+iSize);strcpy(buf,str.c_str());//DBG(str);}returniSize;}}return0;}booleanSend(Stringst

r){_cell.print("AT+CIPSEND=");//_cell.print("\"");_cell.println(str.length());//_cell.println("\"");u

nsignedlongstart;start=millis();boolfound;while(millis()-start<5000){if(_cell.find(">")==true){found=true;break;}}if(found)_cell.print(str);el

se{//closeMux();returnfalse;}Stringdata;start=millis();while(millis()-start<5000){if(_cell.available()>0){chara=_cell.read();d

ata=data+a;}if(data.indexOf("SENDOK")!=-1){returntrue;}}returnfalse;}voidsetup(){Serial.begin(115200);Serial.println("Goodnightmoon!");WIFIS

erial.begin(115200);delay(1000);WIFISerial.println("AT+RST");delay(6000);//WIFISerial.println("AT+CIPMUX=1");//delay(3000);/

/WIFISerial.println("AT+CIPSESVER=1,1001");WIFISerial.println("AT+CIPSTART=5000");//delay(2000);WIFISerial.println("AT+CIPMODE=0");////

delay(2000);//WIFISerial.println("AT+CIPSEND");//}voidloop(){charbuf[500];intiLen=ReceiveMessage(buf);if(iLen

>0){Serial.write(buf);if(!strcmp(buf,CMD_LEFT)){Serial.write("\r\nYesSirTurnLeft.");Send("left");//WIFISerial.write("\r\nYesSirTur

nLeft.");}elseif(!strcmp(buf,CMD_RIGHT)){Serial.write("\r\nYesSirTurnright.");WIFISerial.write("\r\nYe

sSirTurnright.");}elseif(!strcmp(buf,CMD_BACK)){Serial.write("\r\nYesSirback.");WIFISerial.write("\r\nYesSirTurnright.");}elseif(

!strcmp(buf,CMD_FORWARD)){Serial.write("\r\nYesSirforword.");WIFISerial.write("\r\nYesSirTurnright.");}WIFISer

ial.write("\r\nYesSirTurnright.");}elseif(!strcmp(buf,CMD_FORWARD)){Serial.write("\r\nYesSirforword.");WIFISerial.write("\r\nYesSir

Turnright.");}elseif(!strcmp(buf,CMD_STOP)){Serial.write("\r\nYesSirstop.");WIFISerial.write("\r\nYes

SirTurnright.");}}}手机上会显示已有设备连接上了,如图9-12所示。图9-12显示设备连接连接好之后,输入LEFTOK会收到Arduino通过8266传输回来的left.完整代码如下:#defineWIFISeria

lSerial1#define_cellSerial1charCMD_LEFT[]="LEFTOK";charCMD_RIGHT[]="RIGHTOK";charCMD_BACK[]="BACKOK";charCMD_FORWARD[]="FORWARDOK";charCMD_STOP[]="

STOPOK";intchlID;//clientid(0-4)intReceiveMessage(char*buf){//+IPD,<len>:<data>//+IPD,<id>,<len>:<data>Stringdat

a="";if(_cell.available()>0){unsignedlongstart;start=millis();charc0=_cell.read();if(c0=='+'){while(millis()-start<5000){if(_cell.

available()>0){charc=_cell.read();data+=c;}if(data.indexOf("OK")!=-1){break;}}//Serial.println(data);intsLen=strlen(data.c_str());inti,j;

for(i=0;i<=sLen;i++){if(data==':'){break;}}booleanfound=false;for(j=4;j<=i;j++){if(data[j]==','){found=true;break;}}inti

Size;//DBG(data);//DBG("\r\n");if(found==true){String_id=data.substring(4,j);chlID=_id.toInt();String_size=data.subs

tring(j+1,i);iSize=_size.toInt();//DBG(_size);Stringstr=data.substring(i+1,i+1+iSize);strcpy(buf,str.c_str());//DBG(str);}else{Str

ing_size=data.substring(4,i);iSize=_size.toInt();//DBG(iSize);//DBG("\r\n");Stringstr=data.substring(i+1,i+1+iSize);strcpy(buf,s

tr.c_str());//DBG(str);}returniSize;}}return0;}booleanSend(Stringstr){_cell.print("AT+CIPSEND=");//_cell.print("\"");_cell.println(str.length());/

/_cell.println("\"");unsignedlongstart;start=millis();boolfound;while(millis()-start<5000){if(_cell.find(">")==true){found=true;break;}}

if(found)_cell.print(str);else{//closeMux();returnfalse;}Stringdata;start=millis();while(millis()-start<5000){if(_cell.available()>0){chara=_

cell.read();data=data+a;}if(data.indexOf("SENDOK")!=-1){returntrue;}}returnfalse;}voidsetup(){Serial.

begin(115200);Serial.println("Goodnightmoon!");WIFISerial.begin(115200);delay(1000);WIFISerial.println("AT+RST");delay(60

00);//WIFISerial.println("AT+CIPMUX=1");//delay(3000);//WIFISerial.println("AT+CIPSESVER=1,1001");WIFISerial.println("AT+CIPSTART=\"

TCP\",\"192.168.43.1\",5000");//delay(2000);WIFISerial.println("AT+CIPMODE=0");////delay(2000);//WIFISerial.println("AT+CIPSEND");//}voidlo

op(){charbuf[500];intiLen=ReceiveMessage(buf);if(iLen>0){Serial.write(buf);if(!strcmp(buf,CMD_LEFT)){Serial.

write("\r\nYesSirTurnLeft.");Send("left");//WIFISerial.write("\r\nYesSirTurnLeft.");}elseif(!strcmp(buf,CMD_RIGHT)){Serial.write("\r\nYesSirTurnr

ight.");WIFISerial.write("\r\nYesSirTurnright.");}elseif(!strcmp(buf,CMD_BACK)){Serial.write("\r\nYesSirback.");WIFISerial.write("\r\nYesSirTur

nright.");}elseif(!strcmp(buf,CMD_FORWARD)){Serial.write("\r\nYesSirforword.");WIFISerial.write("\r\nYesSirTurnright.");}elseif(!strcmp(buf,CMD_S

TOP)){Serial.write("\r\nYesSirstop.");WIFISerial.write("\r\nYesSirTurnright.");}}}

小橙橙
小橙橙
文档分享,欢迎浏览!
  • 文档 25747
  • 被下载 7
  • 被收藏 0
相关资源
广告代码123
若发现您的权益受到侵害,请立即联系客服,我们会尽快为您处理。侵权客服QQ:395972555 (支持时间:9:00-21:00) 公众号
Powered by 太赞文库
×
确认删除?