Arduino应用技术 课件 第三章 Arduino基本示例_第1页
Arduino应用技术 课件 第三章 Arduino基本示例_第2页
Arduino应用技术 课件 第三章 Arduino基本示例_第3页
Arduino应用技术 课件 第三章 Arduino基本示例_第4页
Arduino应用技术 课件 第三章 Arduino基本示例_第5页
已阅读5页,还剩45页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第三章Arduino基本示例传感器感知世界,Arduino让创意动起来《Arduino应用技术(第二版)》·温湿度·红外·液晶·超声波·声音·电机·数码管·键盘·多任务高职电子信息类专业教学用本章学习目标学完本章,你将能利用Arduino驱动传感器与执行器,完成一个个可运行的电子小实验。1掌握温湿度传感器及其使用2掌握人体运动红外传感器及其使用3掌握液晶显示器及其使用4掌握超声波传感器及其使用5掌握声音播放6了解电机驱动与控制7了解数码管驱动与显示8了解矩阵键盘的使用9了解多任务处理方法本章共10节:从温湿度检测、红外感应到液晶显示、超声波测距、声音控制、电机驱动、数码管、矩阵键盘,最后掌握多任务处理技巧。3本章地图:从"感知"到"行动"的十个实验每一节都按"认识模块→连接电路→编写程序→观察现象"四步完成一个小实验3.1温湿度检测DHT11数字

LM35模拟3.2人体红外PIR传感器

继电器输出3.3液晶显示LCD1602

I2C接口3.4超声波测距HC-SR04

声速测距3.5

声音电子琴

音乐播放3.6舵机驱动SG90伺服

角度控制3.7步进电机28BYJ-48

步进控制3.8数码管显示七段码

动态扫描3.9矩阵键盘键值读取

密码锁3.10

多任务millis

中断前五节以"传感器"为主,后五节以"执行器与系统"为主,最终回归多任务处理这一进阶主题。3.1.1DHT11温湿度传感器DHT11是一款具备已校准数字信号输出的温湿度传感器:内部集成电阻式感湿元件+NTC测温元件+高性能8位单片机。校准系数以程序形式存放在OTP内存中,检测信号时自动调用,因此可靠性高、长期稳定。单总线(单线制)串行接口,系统集成简单快捷4针单排引脚封装,体积超小、功耗低性价比极高,是入门温湿度检测的首选注意:避免安装在强风、强光直射或化学气体浓度过高的环境中主要性能指标湿度量程20%~90%RH湿度精度±5%RH温度量程0~50℃温度精度±2℃工作电压3.3V~5.5V工作电流平均约1mA响应时间湿度约25s,温度1~2s3.1.1DHT11电路连接DHT11为4针单排封装:第1脚VCC、第2脚DATA、第3脚悬空、第4脚GND图3-2DHT11与Arduino的连接第1脚接电源,第4脚接地VCC与数据脚间接4.7kΩ~10kΩ上拉电阻,保证空闲时数据线为高电平第2脚(数据)接Arduino的D3可加100nF去耦电容滤除电源噪声小提示:也可直接选购已封装好外围电路(含上拉电阻)的DHT11模块,接线更简单。3.1.1DHT11程序编写DHT11通信协议较复杂,可直接使用网络上成熟的dht库:把库文件放入IDE的libraries目录,再通过#include调用。dht11.ino·温湿度检测#include<dht.h>#defineDHT11_PIN3dhtDHT;voidsetup(){Serial.begin(9600);Serial.println("TherealtimeTemperature");Serial.println("andHumidityis:");}voidloop(){intchk=DHT.read11(DHT11_PIN);//读入数据Serial.print("Humidity:");Serial.print(DHT.humidity,1);Serial.println('%');Serial.print("Temparature");Serial.print(DHT.temperature,1);Serial.println('C');delay(2000);}运行结果(串口监视器)图3-3温湿度程序运行结果上传完成后打开串口监视器,选择正确端口与波特率9600,即可看到每秒刷新的温度与湿度。3.1.2LM35温度传感器图3-4LM35温度传感器(TO-92封装)线性输出:每升高1℃输出电压增加10mV25℃时约250mV,100℃时约1000mV工作电压4~30V;典型精度±0.25℃常用型号与测温范围LM35DH0℃~70℃LM35DZ0℃~100℃LM35CZ-40℃~110℃LM35AH-55℃~150℃一般精度越高,价格也稍高免校准:负载1mA时输出阻抗低至0.1Ω低功耗、自热效应极低(静止时约0.08℃),适合电池供电正负双电源供电可测量负温度3.1.2LM35电路连接与程序图3-5LM35电路连接接线建议:电源两端加0.1μF瓷片电容退耦;信号线尽量短,采用模拟接地,避免与数字地共用。

lm35.ino·串口每1秒刷新一次温度voidsetup(){Serial.begin(9600);}voidloop(){Serial.print((0.488*analogRead(A0)));Serial.println("C");delay(1000);}软件上可用多次取平均等算法,减少数据大幅波动。3.1温湿度传感器实物与原理补充DHT11传感器实物与LM35原理图,完善“认识模块”环节图3-1DHT11温湿度传感器图3-6LM35原理图小结:DHT11输出数字信号(单总线),LM35输出模拟电压(10mV/℃),是数字与模拟温度传感器的典型代表。3.2人体运动红外检测·PIR传感器运动传感器把"人或物体的运动"转化为电信号。按工作方式分为两类:主动式(AIR):主动发射辐射,检测其反射变化。被动式(PIR):不发射辐射,只接收人体体温发出的红外线(约10μm),应用最广泛。图3-7PIR模块工作电压4.5~20V;输出电压高3.3V/低0V;探测角度约120°,探测范围最大7m。工作原理(被动热释电)人体约10μm红外线→菲涅耳透镜增强→聚焦到热释电元件→温度变化使元件电荷失衡→电路检测处理后输出信号。图3-9PIR检测原理图3.2PIR传感器内部结构认识PIR的热电传感器与菲涅耳透镜,了解电路板各功能区图3-8PIR内部结构图3-10PIR电路板结构组成:热电传感器接收人体红外,菲涅耳透镜负责聚焦;电路板带3V稳压器、单次/重复触发选择及两个可调电位器。3.2PIR敏感度与延时调节电路板上的两个电位器分别调节感应距离与高电平保持时间图3-11敏感度调节图3-12延时时间调节调节:敏感度旋钮逆时针/往左增加感应距离(最左可达7m),顺时针/往右减小;延时旋钮决定高电平保持5s~5min。3.2PIR电路连接与继电器图3-14PIR与Arduino硬件电路连接图PIR信号输出端→ArduinoD2继电器信号端→ArduinoD3分别接通电源(VCC)与地线(GND)继电器常开/常闭输出端可连接大电流负载继电器引脚说明地连接0V信号低电平有效,输入低于约2V时继电器开启电源连接5VPIR电路板功能调节(表3-1)延时时间高电平停留5s~5min可调敏感度检测范围3~7m可调数字输出检测到运动输出高电平(3.3V)电源4~20V直流供电3.2继电器结构与连接实物了解继电器引脚(常开/常闭/公共),并查看PIR与Arduino的实物连接图3-13继电器结构示意图图3-15运动传感器与Arduino连接实物图接线:继电器三针接口分别接地、电源与信号(低电平有效),常开/常闭输出端可连接大电流负载。3.2PIR运动检测程序检测到人体运动→LED点亮、继电器动作→延时10s后自动关闭;无人时LED熄灭pir.ino·变量定义与setup()intledPin=13;//LED输出13脚intrelayInput=3;//继电器输出3脚intinputPin=2;//PIR输入2脚intpirState=LOW;//初始未侦测到动作intval=0;//读入引脚状态voidsetup(){pinMode(ledPin,OUTPUT);pinMode(inputPin,INPUT);pinMode(relayInput,OUTPUT);digitalWrite(relayInput,HIGH);Serial.begin(9600);}pir.ino·loop()主循环voidloop(){val=digitalRead(inputPin);if(val==HIGH){//检测到高电平digitalWrite(ledPin,HIGH);if(pirState==LOW){Serial.println("Motiondetected!");pirState=HIGH;digitalWrite(relayInput,LOW);Serial.println("TurnontheLamp!");delay(10000);//等待10sdigitalWrite(relayInput,HIGH);Serial.println("TurnofftheLamp!");}}else{digitalWrite(ledPin,LOW);if(pirState==HIGH){Serial.println("Motionended!");pirState=LOW;}}}要点:pirState用于记录状态变化,只在状态跳变时打印与动作,避免重复触发继电器。3.3液晶显示器(LCD1602)认识LCD1602液晶显示器的外观,2行×16字符点阵图3-16液晶显示器要点:本教材采用带PCF8574TI2C模块的LCD1602,仅用SDA、SCL两条数据线即可驱动,对比度由背面蓝色电位器调节。3.3液晶显示·LCD1602(I2C接口)传统LCD会占满几乎所有I/O口;本教材采用带PCF8574T/PCA8574I2C模块的LCD1602,仅用两条数据线即可驱动。I2C串行总线:SDA数据线+SCL时钟线,需上拉电阻,支持5V/3.3V。对比度由背面蓝色电位器调节;移除背光跳线帽即关背光。ArduinoLCD1602GNDGND5VVCCA4SDAA5SCL表3-2Arduino与LCD的接线注意:LCD1602默认I2C地址通常是0x27,也可能是0x37/0x3E/0x24,使用前需确认。图3-17Arduino与LCD电路连接图只用4根线(GND、VCC、SDA、SCL)即可点亮LCD,为其他外设省下大量I/O口。3.3安装液晶I2C库文件在ArduinoIDE库管理器中搜索并安装LiquidCrystal_I2C库图3-19安装液晶I2C库文件(一)图3-19安装液晶I2C库文件(二)安装:库管理器搜索LiquidCrystal_I2C→选择版本点击“安装”;也可用ZIP方式手动导入库文件夹。3.3寻找I2C地址与安装库i2c_scanner.ino·扫描总线上的设备地址#include<Wire.h>voidsetup(){Wire.begin();Serial.begin(9600);}voidloop(){byteerror,address;Serial.println("Scanning...");for(address=1;address<127;address++){Wire.beginTransmission(address);error=Wire.endTransmission();if(error==0){Serial.print("Foundat0x");if(address<16)Serial.print("0");Serial.println(address,HEX);}}delay(5000);}图3-18寻找I2C液晶地址(串口显示0x27)安装LiquidCrystal_I2C库(三选一)下载ZIP解压到libraries目录项目→加载库→添加.ZIP库…库管理器搜索安装3.3LCD显示程序lcd_display.ino·显示"Hello!world"#include<Wire.h>#include<LiquidCrystal_I2C.h>LiquidCrystal_I2Clcd(0x27,16,2);voidsetup(){lcd.init();//初始化LCD}voidloop(){lcd.setCursor(0,0);//光标第一行lcd.backlight();//打开背光lcd.print("Hello!");lcd.setCursor(0,1);//光标第二行lcd.print("world");}lcd(0x27,16,2)表示地址0x27、16列、2行;setCursor(列,行)定位光标。图3-20LCD实物显示效果拓展:两行文字向左滚动显示chara1[]="Helloall!";chara2[]="WelcometoNJCIT";voidloop(){lcd.setCursor(15,0);for(intp=0;p<26;p++){lcd.scrollDisplayLeft();lcd.print(a1[p]);delay(500);}lcd.clear();lcd.setCursor(15,1);}3.4超声波测距·HC-SR04图3-21超声波传感器HC-SR044引脚:VCC(5V)、GND、Trig(触发)、Echo(回响)工作过程1.Trig引脚触发测距:发送至少10μs高电平2.模块自动发射8个40kHz方波,并检测回波3.检测到回波后,Echo引脚输出高电平,其持续时间即超声波往返时间

图3-22超声波工作原理图3.4HC-SR04电路连接图3-23HC-SR04与Arduino连接图Echo→D2(回响信号输入)Trig→D3(触发信号输出)VCC→5V

GND→GND图3-25串口实时显示测量距离实验过程中通过串口实时查看距离;超出2~400cm量程时显示"Outofrange"。3.4HC-SR04连接实物图超声波模块与Arduino的实际接线效果,以及串口实时显示距离图3-24HC-SR04与Arduino连接实物图图3-27HC-SR04与Arduino显示连接实物图接线:Echo→D2、Trig→D3、VCC→5V、GND→GND;串口每1秒刷新一次距离值。3.4连接Arduino板到电脑用USB数据线将Arduino板连接到电脑,选择端口并下载程序图3-26连接Arduino板到电脑步骤:连接USB→IDE选择开发板Arduino/GenuinoUno→选择对应COM端口→点击上传。3.4超声波测距程序Trig发10μs高电平触发→pulseIn()测得Echo高电平宽度(往返时间)→换算成距离ultrasonic.ino·引脚与setup()#defineechoPin2//回声引脚#definetrigPin3//触发引脚voidsetup(){Serial.begin(9600);pinMode(trigPin,OUTPUT);pinMode(echoPin,INPUT);}ultrasonic.ino·loop()测距与输出voidloop(){floatduration,distance;digitalWrite(trigPin,LOW);delayMicroseconds(2);digitalWrite(trigPin,HIGH);delayMicroseconds(10);digitalWrite(trigPin,LOW);duration=pulseIn(echoPin,HIGH);distance=(duration/2)*0.0344;if(distance>=400||distance<=2){Serial.println("Outofrange");}else{Serial.print("Distance=");Serial.print(distance);Serial.println("cm");}delay(500);}pulseIn(pin,HIGH)返回引脚高电平持续的时间(μs),是测距程序的核心。3.5声音控制·蜂鸣器与简易电子琴有源蜂鸣器内部集成振荡电路,施加直流电压即自动发出固定频率声音,无需外部音频信号。无源蜂鸣器无内置振荡电路,由压电陶瓷片+共鸣腔组成,需外部音频信号驱动,频率决定音高。tone(pin,频率)输出指定频率方波驱动无源蜂鸣器;noTone(pin)停止发声。图3-31蜂鸣器电路(模块,NPN三极管放大)电子琴原理:按下按钮,演奏对应频率的曲调。从中音C、D、E、F开始:C=262HzD=294HzE=330HzF=349Hz用数组存储频率,配合tone()演奏。3.5简易电子琴电路电子琴通过不同按键电阻分压产生不同模拟值,对应不同音阶频率图3-28简易电子琴电路连接实物图图3-29简易电子琴电路原理图原理:按键串联不同电阻分压到A0,程序读取模拟值判断按键,再通过tone()驱动无源蜂鸣器发声。3.5蜂鸣器频率与音阶不同音阶对应不同频率,用tone()输出指定频率方波驱动蜂鸣器图3-30Arduino蜂鸣器频率常用音阶频率对照(单位:Hz)C4=262D4=294E4=330F4=349G4=392A4=440B4=494C5=523D5=587E5=659G5=784C6=1047函数:tone(pin,频率)/noTone(pin)音频=每秒振动次数(Hz)。频率越高音调越高;无源蜂鸣器需外部方波驱动,频率决定音高。3.5.1简易电子琴程序不同按键通过电阻分压产生不同的A0模拟值,程序据此判断按键并演奏对应音阶piano.ino·按A0模拟值演奏C/D/E/Fintnotes[]={262,294,330,349};//演奏的频率voidsetup(){Serial.begin(9600);}voidloop(){intkeyVal=analogRead(A0);//存放A0输入Serial.println(keyVal);if(keyVal==1023){tone(8,notes[0]);//演奏C}elseif(keyVal>=990&&keyVal<=1010){tone(8,notes[1]);//演奏D}elseif(keyVal>=505&&keyVal<=515){tone(8,notes[2]);//演奏E}elseif(keyVal>=5&&keyVal<=10){tone(8,notes[3]);//演奏F}else{noTone(8);//不演奏}}要点:通过analogRead读按键分压值,用if-else判断并调用tone()播放不同频率。3.5.2音乐播放·音律与简谱节拍节拍是音乐中规律性的时间单位,犹如音乐的"心跳"。拍号如2/4拍,表示每小节2个四分音符节拍。音调音调由声音频率决定,全球统一用A~G表示。"1=C"即C调歌曲;标准音A每秒振动441个周期。图3-32《小星星》简谱简谱约定:数字无下划线=四分音符(1拍,500ms);带短横线=二分音符(2拍)。每个音符结束后加20ms无音停顿,增强音乐效果。3.5.2《小星星》播放程序twinkle.ino·三个全局数组inttonelist[]={0,262,294,330,350,393,441,495};intmusiclist[]={0,1,1,5,5,6,6,5,4,4,3,3,2,2,1,5,5,4,4,3,3,2,5,5,4,4,3,3,2,1,1,5,5,6,6,5,4,4,3,3,2,2,1};intrhythmlist[]={0,1,1,1,1,1,1,2,1,1,1,1,1,1,2,1,1,1,1,1,1,2,1,1,1,1,1,1,2,1,1,1,1,1,1,2,1,1,1,1,1,1,2};tonelist音调频率;musiclist简谱音符;rhythmlist音符时长(1=1拍,2=2拍)。twinkle.ino·play()与主程序voidplay(){inti;for(i=0;i<=42;i=i++){tone(8,tonelist[musiclist[i]]);delay(480*rhythmlist[i]);noTone(8);delay(20);}}voidsetup(){pinMode(8,OUTPUT);}voidloop(){play();delay(1000);//播完停1秒}3.6.1舵机的直接控制图3-33伺服电机(SG90)舵机(伺服电机Servo)能精准转动到指定角度,由直流电机、减速机构、传感器与反馈控制电路构成,常用于机器人关节、舵面控制。舵机仅用一个输入引脚接收类似PWM的脉冲信号,脉冲持续时间决定转动角度。基准信号周期20ms(低电平为主)1ms高电平→0°2ms高电平→180°两者之间对应0°~180°的角度图3-34舵机工作原理图舵机保持角度需持续接收脉冲,稳定性受最大扭力限制。3.6.1舵机电路连接与程序图3-35舵机电路连接图红色→5V;黑/棕→GND;橙/黄(控制)→PWM引脚9。抖动时可GND与5V间加470μF以上大电容;大扭矩舵机应外接电源。servo.ino·舵机逐步旋转0°~180°#include<Servo.h>Servomyservo;//舵机对象intpos=0;//位置变量voidsetup(){myservo.attach(9);//接9脚}voidloop(){for(pos=0;pos<=180;pos+=1){myservo.write(pos);delay(15);//等待到位}for(pos=180;pos>=0;pos-=1){myservo.write(pos);delay(15);}}3.6.2舵机的自动控制(电位器)自动控制思路在电路中增加一个10kΩ电位器,转动电位器即可实时改变舵机角度,实现传感器与执行器的结合(自动控制)。map()映射函数map(值,原下限,原上限,新下限,新上限)把模拟量0~1023等比映射为角度0°~180°:val=map(val,0,1023,0,180);servo_pot.ino·电位器控制舵机#include<Servo.h>Servomyservo;//舵机对象intpotpin=0;//电位器接A0intval;voidsetup(){myservo.attach(9);}voidloop(){val=analogRead(potpin);//0~1023val=map(val,0,1023,0,180);myservo.write(val);delay(15);}本质:电位器模拟信号→舵机执行动作,是闭环自动控制的入门。3.7.1步进电机简介(28BYJ-48)图3-38步进电机及其驱动器步进电机依据电磁铁原理,将电脉冲信号转换为角位移:每接收一个脉冲,输出轴转动一个"步距角"。它以分步方式旋转,适合低速高精度定位(如3D打印机、电动移门)。28BYJ-48为4相5线永磁式单极减速步进电机,常配ULN2003驱动器。工作电压5~12V;电流约200mA;减速比1:64步距角5.625°/64;四相绕组A、B、C、DULN2003:达林顿管阵列,耐压50V,单通道输出500mA内轴转一圈需64×64=4096个脉冲(步距角5.625°÷64,减速比1:64),即输出轴每圈4096步。3.7.1通电方式与电路连接图3-39电机与ULN2003连接图28BYJ-48与ULN2003模块防反插直连;IN1~IN4接数字脚8、9、10、11;改变脉冲顺序即可改变转动方向。三种通电方式单四拍:A→B→C→D→A双四拍:AB→BC→CD→DA八拍:A→AB→B→BC→C→CD→D→DA图3-41单极四相步进电机通电方式“单/双”指同时通电绕组数;“拍”指完成一次通电循环的步数。八拍同一步数下仅转半圈。3.7.1步进电机直接驱动(单四拍)用switch-case按单四拍顺序给四相绕组通电,配合micros()定时每1ms走一步stepper_direct.ino·主循环#defineIN18#defineIN29#defineIN310#defineIN411intSteps=0;//当前步boolDirection=true;//方向unsignedlonglast_time=0;intsteps_left=4095;//总步数voidsetup(){pinMode(IN1,OUTPUT);pinMode(IN2,OUTPUT);pinMode(IN3,OUTPUT);pinMode(IN4,OUTPUT);}voidloop(){while(steps_left>0){if(micros()-last_time>=1000){stepper(1);//每1ms走一步last_time=micros();steps_left--;}}Direction=!Direction;//换向steps_left=4095;}stepper_direct.ino·通电与方向voidstepper(intxw){//单四拍for(intx=0;x<xw;x++){switch(Steps){case0://A相通电digitalWrite(IN1,HIGH);digitalWrite(IN2,LOW);digitalWrite(IN3,LOW);digitalWrite(IN4,LOW);break;case1://B相通电digitalWrite(IN1,LOW);digitalWrite(IN2,HIGH);digitalWrite(IN3,LOW);digitalWrite(IN4,LOW);break;case2://C相通电digitalWrite(IN1,LOW);digitalWrite(IN2,LOW);digitalWrite(IN3,HIGH);digitalWrite(IN4,LOW);break;case3://D相通电digitalWrite(IN1,LOW);digitalWrite(IN2,LOW);digitalWrite(IN3,LOW);digitalWrite(IN4,HIGH);break;}SetDirection();}}voidSetDirection(){if(Direction)Steps++;elseSteps--;if(Steps>3)Steps=0;if(Steps<0)Steps=3;}3.7.2步进电机库函数驱动(Stepper)ArduinoIDE内置Stepper库(项目→导入库→Stepper),仅需3个函数Stepper(steps,pin1,pin2,pin3,pin4):创建电机对象,steps为每圈步数。例:Stepperstepper(4096,8,9,10,11);setSpeed(rpm):设置转速(转/分钟),仅设速不控步数。例:stepper.setSpeed(60);step(steps):按指定步数旋转,正数正向、负数反向。例:stepper.step(100);stepper_lib.ino·正反各一圈#include<Stepper.h>constintstepsPerRevolution=4096;SteppermyStepper(stepsPerRevolution,8,9,10,11);voidsetup(){myStepper.setSpeed(60);//60rpmSerial.begin(9600);}voidloop(){Serial.println("正向旋转");myStepper.step(stepsPerRevolution);delay(1000);Serial.println("反向旋转");myStepper.step(-stepsPerRevolution);delay(1000);}3.8.1单位数码管的驱动共阴极(CC)COM接负极,点亮段时对应引脚施加高电平,熄灭施加低电平。共阳极(CA)COM接正极,点亮段时对应引脚施加低电平,熄灭施加高电平。两种类型不可直接互换。段码duanma[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f},对应0~9(共阴,顺序dpgfedcba)。表3-3数码管接线表数码管ArduinoA4B5C6D7E8F9G10DP11ComGNDA~G各接220Ω限流电阻;COM接GND(共阴)。3.8.1单位数码管驱动程序用duanma段码数组配合bitRead()逐位驱动8个引脚,循环显示0~97seg.ino·段码与初始化constunsignedcharduanma[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0~9段码intLEDPins[]={4,5,6,7,8,9,10,11};intLEDCount=8;voidsetup(){for(intthisLED=0;thisLED<LEDCount;thisLED++)pinMode(LEDPins[thisLED],OUTPUT);}7seg.ino·驱动与主循环voiddeal(unsignedcharvalue){for(inti=0;i<8;i++)digitalWrite(LEDPins[i],bitRead(value,i));}voidloop(){for(inti=0;i<10;i++){deal(duanma[i]);delay(1000);}}bitRead(x,n):读取数字x的第n位(位序从右至左计,0起始)。deal()把段码逐位写到8个引脚上。3.8.24位七段数码管与动态扫描多路复用结构4位数码管共享段码A~G,每位有独立公共阳极(位码)。仅需12个引脚(8段+4位),替代独立显示所需的32个引脚。动态扫描与视觉暂留依次显示每一位并快速切换(约1ms)。因视觉暂留,人眼看到4位同时显示。例:显示"1234"时分时逐位点亮1、2、3、4。表3-44位数码管与Arduino连接段引脚位引脚A2D113B3D212C4D311D5D410E6——F7——G8——DP9——用四位数码管制作秒表,段码引脚2~9,位码引脚10~13(共阳)。核心思想:位选+段选分时切换,利用视觉暂留实现多位数显示。3.8.24位数码管秒表程序位选+段选动态扫描,millis()定时每秒计数一次并刷新显示stopwatch.ino·变量与缓冲intledCount=8;//段数intsegCount=4;//位数constunsignedcharduanma[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};intledPins[]={2,3,4,5,6,7,8,9};intsegPins[]={13,12,11,10};unsignedchardisplayTemp[4];//缓冲voidsetup(){for(inti=0;i<ledCount;i++)pinMode(ledPins[i],OUTPUT);for(inti=0;i<segCount;i++)pinMode(segPins[i],OUTPUT);}voiddeal(unsignedcharvalue){for(inti=0;i<8;i++)digitalWrite(ledPins[i],bitRead(value,i));}voidupdateDisplayBuffer(unsignedintnum){displayTemp[0]=duanma[num/1000];displayTemp[1]=duanma[(num%1000)/100];displayTemp[2]=duanma[(num%100)/10];displayTemp[3]=duanma[num%10];}stopwatch.ino·扫描与主循环voiddisplayDigits(){//动态扫描staticinti=0;deal(0);//清屏防鬼影for(inta=0;a<segCount;a++)digitalWrite(segPins[a],1);//关位digitalWrite(segPins[i],0);//选位deal(displayTemp[i]);//送段i++;if(i==segCount)i=0;}voidloop(){staticunsignedintnum=3467;staticunsignedlonglastTime=0;if(millis()-lastTime>=1000){lastTime=millis();num++;//每秒加1}updateDisplayBuffer(num);displayDigits();//持续刷新}3.9.1矩阵键盘简介与接线4×4矩阵键盘共16个按键,由4行×4列组合构成。每个按键一端接某行、另一端接某列,常用于输入密码、导航菜单、控制机器人。扫描原理单片机采用行扫描法或列扫描法检测按键:逐行输出低电平、读列电平,即可定位被按下的键位。相比直连,用8个引脚即可读16个键。表3-5电路连接表键盘引脚Arduino方向1/2/3/4D9/D8/D7/D6行5/6/7/8D5/D4/D3/D2列按下按键后,其值立即显示在串行监视器上。键面布局:123A/456B/789C/*0#D3.9.1键值读取程序(Keypad库)使用Keypad库:定义键位映射、行列引脚,getKey()读取按键并在串口显示keypad.ino·键位与引脚#include<Keypad.h>constbyteROWS=4;constbyteCOLS=4;charhexaKeys[ROWS][COLS]={{'1','2','3','A'},{'4','5','6','B'},{'7','8','9','C'},{'*','0','#','D'}};byterowPins[ROWS]={9,8,7,6};bytecolPins[COLS]={5,4,3,2};keypad.ino·读取与显示KeypadcustomKeypad=Keypad(makeKeymap(hexaKeys),rowPins,colPins,ROWS,COLS);voidsetup(){Serial.begin(9600);}voidloop(){charcustomKey=customKeypad.getKey();if(customKey){Serial.println(customKey);}}Keypad库通过"项目→导入库→管理库"安装加载。getKey()返回空表示无按键。3.9.2密码锁系统构成输入部件=矩阵键盘;输出部件=继电器控制的锁体。密码正确时改变继电器状态。工作流程①键盘输入密码存入Data[]②输入满7位后strcmp比较③正确→继电器开5s,LCD显示Correct④错误→显示Incorrect,清除重输password_lock.ino·核心逻辑charMaster[]="123A456";//密码intsignalPin=12;//继电器LiquidCrystal_I2Clcd(0x27,16,2);voidsetup(){lcd.init();lcd.backlight();pinMode(signalPin,OUTPUT);}voidloop(){lcd.print("EnterPassword:");customKey=customKeypad.getKey();if(customKey){Data[data_count]=customKey;lcd.setCursor(data_count,1);lcd.print(Data[data_count]);data_count++;}if(data_count==Password_Length-1){if(!strcmp(Data,Master)){lcd.print("Correct");digitalWrite(signalPin,HIGH);delay(5000);digitalWrite(signalPin,LOW);}else{lcd.print("Incorrect");delay(1000);}lcd.clear();clearData();}}strcmp(Data,Master)相等返回0,即密码匹配。3.10.1多任务处理简介单核与顺序执行ArduinoUNO采用ATmega328P,仅一个CPU核心,同一时刻只能执行一个任务;通常无操作系统,按预设流程顺序执行。问题根源:delay()阻塞延时期间CPU空转等待,任务响应不及时。流水灯+火焰报警并行时,可能错过持续时间很短的火焰信号。时间片轮转(OS)操作系统把CPU时间划分成时间片,按FIFO依次分配给任务,每个任务运行一个时间片后暂停换下一个。时间片极短,宏观上看似并行。本书的三种处理方法①millis()非阻塞延时②外部中断(硬件触发)③定时器中断(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论