Arduino学习笔记


注意:本网站所有内容为自己学习期间记录的笔记,很多都是原作者那边摘抄过来的,不作商业用途也不插播广告。(如有侵权,请联系我删除,15909440083)

如果有不理解的推荐去看他们的视频,讲的特别详细。参考:

【太极创客】零基础入门学用Arduino 第一部分

一、认识Arduino

1.1 认识硬件

我初学用的板子是uno

2d8ddd66fc8f68dc15868f6466964a3ec9dfebfa.png@1256w_956h_!web-article-pic

bfd0cc63a885d12164224b343594afc44c1820e1.png@1256w_578h_!web-article-pic

UNO引脚说明图(中文)

6ff76acfdc12356d52aa7af91a2f170c13b2cbdb.png@1256w_816h_!web-article-pic

71cdd5940c8677f5f4579ffe0420ce533c0571d2.png@1256w_572h_!web-article-pic

1.2 Arduino.exe开发软件

4038c8415cd67ee8ed5a9f79bbfea8f10ea6db88.png@1256w_920h_!web-article-pic

写完程序记得验证上传

二、简单编程

如有不懂的可以进这个网站查询:http://www.taichi-maker.com/homepage/reference-index/arduino-code-reference/

2.1 程序认识hello world

2.1.1 基础知识

void setup(); 						//这个函数是最开始的时候运行一次,(初始化函数)。
void loop();						//这个函数是执行函数,会不断循环工作,(死循环函数)。
void pinMode (pin,mode);			 //将 数字IO口 指定为输入或输出。(mode=OUTPUT,INOUP)
void digitalWrite(pin,Value);		 //将 数字IO口 输出高电平或低电平 (Value=HIGH,lOW)
void delay(ms);						//延时多少时间后执行下一句

Serial.bengin();	//这个函数对串口定义波特率
Serial.read();   // 这个函数读串口并返回收到参数读取1byte的序列资料(读取串口的输入)
Serial.printnl();  //在串口端打印输出数据(在串口打印输出)

2.1.2 实验实操

首先先来练习一个不需要其他辅助元件,只需要一块Arduino 和一根下载线的简单实验,让我们的Arduino 说出“Hello World!”,这是一个让Arduino 和PC 机通信的实验,这也是一个入门试验,希望可以带领大家进入Arduino 的世界。

这个实验我们需要用到的实验硬件有:

  1. Arduino 控制器

img

  1. USB 下载线

img

我们按照上面所讲的将Arduino 的驱动安装好后,我们打开Arduino 的软件,编写一段程序让Arduino 接受到我们发的指令就显示“Hello World!”字符串,当然您也可以让Arduino 不用接受任何指令就直接不断回显“Hello World!”,其实很简单,一条if语句就可以让你的Arduino 听从你的指令了,我们再借用一下Arduino 自带的数字13口LED,让Arduino 接受到指令时LED 闪烁一下,再显示“Hello World!”

下面给大家一段参考程序。

int val;		//定义变量val
int ledpin=13;	//定义数字接口13

void setup(){
    Serial.begin(9600);		//定义与计算机通讯的波特率,这里要跟软件设置相一致。当接入特定设备(如:蓝牙)时,我们也要跟其他设备的波特率达到一致。
    pinMode(ledpin,OUTPUT);	//设置数字13 口为输出接口,Arduino 上我们用到的I/O 口都要进行类似这样的定义。
}

void loop(){
	val=Serial.read();//读取PC 机发送给Arduino 的指令或字符,并将该指令或字符赋给val
    if(val=='R')//判断接收到的指令或字符是否是“R”。
    {//如果接收到的是“R”字符
        digitalWrite(ledpin,HIGH);	//输出高电平灯亮  点亮数字13 口LED。
        delay(500);
        digitalWrite(ledpin,LOW);	//输出低电平灯灭  熄灭数字13 口LED
        delay(500);
        Serial.println("Hello World!");//显示“Hello World!”字符串
    }
    dealy(1);//防死循环卡死
}

2.2 LED闪烁实验

2.2.1 基础知识

image-20240111210321369

image-20240111210413119image-20240111210419792

void digitalWrite();
//将数字引脚写 [HIGH](高电平)或 [LOW](低电平)
//如果该引脚通过 pinMode() 设置为输出模式(OUTPUT),您可以通过digitalWrite()语句将该引脚设置为HIGH(对ArduinoNUO来说是5伏特)或LOW(0伏特/GND)。

面包板的使用方法(上下的两排是正负极,全部连接的,其他的每一列的五个孔是连接的。)

image-20240111210910453

2.2.2 实验操作

LED 小灯实验是比较基础的实验之一,上一个“ Hello World!”实验里已经利用到了Arduino 自带的LED,这次我们利用其他I/O 口和外接直插LED 灯来完成这个实验,我们需要的实验器材除了每个实验都必须的Arduino 控制器和USB 下载线以外的

其它器件如下:

  • 红色M5 直插LED*1
  • 220Ω直插电阻*1,或者200Ω的电阻
  • 面包板*1
  • 面包板跳线*1 扎

下一步我们按照下面的小灯实验原理图链接实物图,这里我们使用数字10 接口。使用发光二极管LED 时,要连接限流电阻,这里为220Ω电阻,否则电流过大会烧毁发光二极管

小灯实验原理图

img

实物图

img

按照上图链接好电路后,就可以开始编写程序了,我们还是让LED 小灯闪烁,点亮1 秒熄灭1 秒。这个程序很简单与Arduino 自带的例程里的Blink 相似只是将13 数字接口换做10 数字接口。

参考程序如下:

int ledPin = 10; //定义数字10 接口
void setup(){
	pinMode(ledPin, OUTPUT);//定义小灯接口为输出接口
}

void loop(){
    digitalWrite(ledPin, HIGH); //点亮小灯
    delay(1000); //延时1 秒
    digitalWrite(ledPin, LOW); //熄灭小灯
    delay(1000); // 延时1 秒
}

下载完程序就可以看到我们的10 口外接小灯在闪烁了,这样我们的小灯闪烁实验就完成了。

2.3 按键开关实验

2.3.1 基础知识

pinMode()说明

通过pinMode()函数,你可以将Arduino的引脚配置为以下三种模式:

  • 输出(OUTPUT)模式
  • 输入(INPUT)模式
  • 输入上拉(INPUT_PULLUP)模式 (仅支持Arduino 1.0.1以后版本)

输入上拉(INPUT_PULLUP)模式中,Arduino将开启引脚的内部上拉电阻,实现上拉输入功能。一旦将引脚设置为输入(INPUT)模式,Arduino内部上拉电阻将被禁用。

  • 设置Arduino引脚为输出(OUTPUT)模式

    • 当引脚设置为输出(OUTPUT)模式时,引脚为低阻抗状态。这意味着Arduino可以向其它电路元器件提供电流。也就是说,Arduino引脚在输出(OUTPUT)模式下可以点亮LED或者驱动电机。(如果被驱动的电机需要超过40mA的电流,Arduino将需要三极管或其它辅助元件来驱动他们。)
  • 设置引脚为输入(INPUT)模式

    • 当引脚设置为输入(INPUT)模式时,引脚为高阻抗状态(100兆欧,100MΩ)。此时该引脚可用于读取传感器信号或开关信号。
  • 设置引脚为输入上拉(INPUT_PULLUP)模式

    • Arduino 微控制器自带内部上拉电阻。如果你需要使用该内部上拉电阻,可以通过pinMode()将引脚设置为输入上拉(INPUT_PULLUP)模式

注意:当Arduino引脚设置为输入(INPUT)模式或者输入上拉(INPUT_PULLUP)模式,请勿将该引脚与负压或者高于5V的电压相连,否则可能会损坏Arduino控制器。

2.3.2 实验操作

image-20240111215946515

image-20240111220004781

image-20240111220036928

对应上一副图的上拉电阻实验

void digitalRead(pin);
// 读取数字引脚的 HIGH(高电平)或 LOW(低电平)。
// pin:被读取的引脚号码      返回值:HIGH 或 LOW
//读取引脚2的数字输入,将结果显示在串口监视器中
//引脚2连接有按键开关,给它一个名字:
int pushButton = 2;
 
//当你按下复位按钮后,setup流程运行一次:
void setup() {
  //串口通讯初始化,每秒9600位
  Serial.begin(9600);
  //设置按键引脚为输入
  pinMode(pushButton, INPUT);
}
 
// loop 流程会永远的反复运行
void loop() {
  //读取输入引脚:
  int buttonState = digitalRead(pushButton);
  // 显示按键状态,开关断开的时候是高电平(1),闭合的时候是低电平(0)
  Serial.println(buttonState);
  delay(1);        // 为确保程序稳定运行进行短暂停止
}

2.3.3 按键控制LED的开关示例

I/O 口的意思即为INPUT 接口和OUTPUT 接口,到目前为止我们设计的小灯实验都还只是应用到Arduino 的I/O 口的输出功能,这个实验我们来尝试一下使用Arduino的I/O 口的输入功能即为读取外接设备的输出值,我们用一个按键和一个LED 小灯完成一个输入输出结合使用的实验,让大家能简单了解I/O 的作用。按键开关大家都应该比较了解,属于开关量(数字量)元件,按下时为闭合(导通)状态。完成本实验要

用到的元件如下:

  • 按键开关*1 *
  • 红色M5 直插LED1
  • 220Ω电阻1
  • 10KΩ电阻1
  • 面包板1
  • 面包板跳线1 扎

我们将按键接到数字7 接口,红色小灯接到数字11 接口(Arduino 控制器0-13 数字I/O 接口都可以用来接按键和小灯,但是尽量不选择0 和1 接口,0 和1 接口为接口功能复用,除I/O 口功能外也是串口通信接口,下载程序时属于与PC 机通信故应保持0 和1 接口悬空,所以为避免插拔线的麻烦尽量不选用0 和1 接口),按下面的原理图连接好电路。

img

img

下面开始编写程序,我们就让按键按下时小灯亮起,根据前面的学习相信这个程序很容易就能编写出来,相对于前面几个实验这个实验的程序中多加了一条条件判断语句,这里我们使用if 语句,Arduino 的程序便写语句是基于C 语言的,所以C 的条件判断语句自然也适用于Arduino,像while、swich 等等。这里根据个人喜好我们习惯

于使用简单易于理解的if 语句给大家做演示例程。

我们分析电路可知当按键按下时,数字7 接口可读出为高电平,这时我们使数字11 口输出高电平可使小灯亮起,程序中我们判断数字7 口是否为低电平,要为低电平使数字11 口输出也为低电平小灯不亮,原理同上。

参考源程序:

int ledpin=11;//定义数字11 接口
int inpin=7;//定义数字7 接口
int val;//定义变量val
void setup(){
    pinMode(ledpin,OUTPUT);//定义小灯接口为输出接口
    pinMode(inpin,INPUT);//定义按键接口为输入接口
}

void loop(){
    val=digitalRead(inpin);//读取数字7 口电平值赋给val  断开时是低电平,按下时是高电平
    if(val==LOW){ //检测按键是否按下,按键按下时小灯亮起,  
    	digitalWrite(ledpin,LOW);
    }
    else { 
        digitalWrite(ledpin,HIGH);
    }
}

2.3.4 输入上拉模式示例程序

在本示例中,我们将通过**pinMode()**语句将Arduino引脚2配置为输入模式。在此示例中,

  • 当开关断开,引脚2获得高电平开关信号,
  • 当开关闭合后,引脚2将获得低电平开关信号,引脚13旁的LED(如下照片红圈所示)将被点亮。反之,该LED为熄灭状态。
learn_arduino_uno_r3_L_circled-1024x614

本示例程序Arduino Uno连接说明(如下图)

inputPullupButton

 /*
本示例展示如何使用pinMode(INPUT_PULLUP)。通过本程序,Arduino将读取引脚2的数字输入并将结果显示在串口监视器中。
 电路:
 * 引脚2连接轻触开关,开关另一端接地
 * 引脚13上安装有开发板内置LED
 
 与使用pinMode(INPUT)不同,我们在使用pinMode(INPUT_PULLUP)时不需要外接上拉或下拉电阻。
开发板内置一个20K欧姆电阻,该电阻将引脚上拉到5V。开关在打开时,引脚读取到高电平。开关闭合后,引脚读取到低电平。
 */

void setup() {
  Serial.begin(9600);//开始串口通讯
  pinMode(2, INPUT_PULLUP);//将引脚2设置为输入上拉模式
  pinMode(13, OUTPUT);
}
 
void loop() {
  int sensorVal = digitalRead(2);//将开关状态数值读取到变量中
  Serial.println(sensorVal);	//输出开关状态数值
 
  //请留意在上拉模式下,按钮的逻辑状态是反的。
  //即:开关断开时引脚读取到高电平。开关被按下后引脚读取到低电平。
  //按钮被按下后,引脚13连接的LED将被点亮。按钮没有按下时,LED熄灭。
   
  //如果按钮没有按下,熄灭LED。否则,点亮LED
     
  if (sensorVal == HIGH) {  //按钮没有按下
    digitalWrite(13, LOW);  //熄灭LED
  } else {                  //否则
    digitalWrite(13, HIGH); //点亮LED
  }
}

2.4布尔运算

2.4.1 简单布尔运算

电路和上面的一样

boolean pushButton; // 创建布尔型变量
 
void setup() {
  pinMode(2, INPUT_PULLUP); //将引脚2设置为输入上拉模式
  pinMode(13, OUTPUT);      //将引脚13设置为输出模式
}
 
void loop() {
  pushButton = digitalRead(2); //读取引脚2电平状态并将其赋值给布尔变量
   
  if (pushButton){          //根据布尔变量数值点亮或者熄灭LED,(开关断开是高电平——亮灯)   
    digitalWrite(13, HIGH); //布尔变量数值为真(true)时点亮LED
  } else {											//(开关闭合:按下是低电平——关灯)
    digitalWrite(13, LOW);  //布尔变量数值为假(false)时熄灭LED
  }
}

2.4.1 与或非

电路如下:

image-20240115201825994

/*布尔运算
 * 本示例程序演示逻辑与布尔运算。通过本程序,Arduino将对引脚2和引脚8的电平状态
 * 进行逻辑与布尔运算,并根据运算结果点亮或熄灭引脚13上连接的LED。
 * 
 * 电路:
 * 引脚2连接按键开关1,开关1另一端接地
 * 引脚8连接按键开关2,开关2另一端接地
 * 引脚13上安装有开发板内置LED
*/
 
boolean pushButton1; // 创建布尔型变量用来存储按键开关1的电平状态
boolean pushButton2; // 创建布尔型变量用来存储按键开关2的电平状态
 
void setup() {
  pinMode(2, INPUT_PULLUP); //将引脚2设置为输入上拉模式
  pinMode(8, INPUT_PULLUP); //将引脚8设置为输入上拉模式
  pinMode(13, OUTPUT);      //将引脚13设置为输出模式
}
 
void loop() {
  pushButton1 = digitalRead(2); //读取引脚2电平状态并将其赋值给布尔变量
  pushButton2 = digitalRead(8); //读取引脚8电平状态并将其赋值给布尔变量
  //开关断开是高电平,两个按键都按下时才会亮
  if (!pushButton1 && !pushButton2){  //根据逻辑与运算结果点亮或者熄灭LED
    digitalWrite(13, HIGH);           //两个布尔变量数值都为假(false)时点亮LED
  } else {
    digitalWrite(13, LOW);            //否则熄灭LED
  }
}

//或
void loop() {
  pushButton1 = digitalRead(2); //读取引脚2电平状态并将其赋值给布尔变量
  pushButton2 = digitalRead(8); //读取引脚8电平状态并将其赋值给布尔变量
  //开关断开是高电平,只要有一个按键按下就会亮
  if (!pushButton1 || !pushButton2){    //根据逻辑或运算结果点亮或者熄灭LED
    digitalWrite(13, HIGH);             //两个布尔变量数值任何一个为假(false)时点亮LED
  } else {
    digitalWrite(13, LOW);              //否则熄灭LED
  }
}

2.5 猜数字小游戏(数码管)

2.5.1 基础知识

数码管是一种半导体发光器件,其基本单元是发光二极管。数码管按段数分为七段数码管八段数码管,八段数码管比七段数码管多一个发光二极管单元(多一个小数点显示),本实验所使用的是八段数码管。按发光二极管单元连接方式分为共阳极数码管共阴极数码管

  • 共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管。共阳数码管在应用时应将公共极COM 接到+5V,当某一字段发光二极管的阴极为低电平时,相应字段就点亮。当某一字段的阴极为高电平时,相应字段就不亮。
  • 共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管。共阴数码管在应用时应将公共极COM 接到地线GND 上,当某一字段发光二极管的阳极为高电平时,相应字段就点亮。当某一字段的阳极为低电平时,相应字段就不亮。

img

数码管的每一段是由发光二极管组成,所以在使用时跟发光二极管一样,也要连接限流电阻,否则电流过大会烧毁发光二极管的。本实验用的是共阴极的数码管,共阴数码管在应用时应将公共极接到GND,当某一字段发光二极管的阳极为低电平时,相应字段就点熄灭。当某一字段的阳极为高电平时,相应字段就点亮。介绍完原理,

我们开始准备实验用元器件。

LED数码管电路图:

image-20240115203250870

数码管实验是比较基础的实验之一,我们需要的实验器材除了每个实验都必须的Arduino 控制器和USB 下载线以外的

其它器件如下:

  • 杜邦线(公对公)×10
  • 面包板条线×10
  • 数码管
  • 200Ω-500Ω直插电阻*1,
  • 面包板*1
  • 按键开关×1

图片1

image-20240115220238843

image-20240521204504277

看上面这个要点亮数字1,就是让4、7引脚通电 digitalWrite(4, HIGH);digitalWrite(7, HIGH);

2.5.2 实验操作

/** MC猜数字 (Ver. 1.0)

 *  - LED数码管的原理和使用
 *  - if...else if的概念和应用
 *  - while循环的概念和应用
 *  - switch case控制语句
 *  - random函数的使用
 *  - 建立和使用自定义函数(三种形式:无参数无返回值,有参数无返回值,有参数有返回值)
 *  - 通过串口监视器观察调试程序运行状况
 *  
 *  电路连接:
 *  有关本制作的详细电路连接资料,请参阅太极创客网站的《零基础入门学用Arduino教程》相关网页。
*/

int thisResult;  //存储按键按下以后显示在数码管的数字。
int nextResult;  //存储作弊数字,也就是下一次按键按下后即将显示的数字。

void setup() {
  pinMode(2, INPUT_PULLUP); //2号引脚上连接有按键开关,将2号引脚设置为输入上拉模式
  int pinNumber = 3;        //设置3-9号引脚为输出模式
  while(pinNumber <= 9){
    pinMode(pinNumber, OUTPUT);
    pinNumber = pinNumber + 1;
  }
  randomSeed(analogRead(A0)); //为了每一次复位或断电后产生不同顺序的随机数字
}

void loop() {
  if (!digitalRead(2)){      //读取2号引脚电平状态
    getRandomNumber(0,10);   //用户按下按键后,开始新一次猜数字游戏
  }
  displayNumber(thisResult); //将猜数字游戏"结果"显示在数码管中
}

/*
用户在每一次按下按键后,随机产生的数字将存储于nextResult变量中。
而实际显示在数码管上的数字是thisResult变量。
当thisResult即将显示在数码管前,程序会将下一次显示的数字通过
图形暗示的形式显示在数码管上。具体程序如何显示暗示图形,
请参阅displayCheat()函数说明。
*/
void getRandomNumber(int minNumber, int maxNumber){
  thisResult = nextResult; 
  int i; 
  while(i < 15){
    i = i + 1;
    nextResult = random(0, 10);
    displayRandom();         //显示随机图案,混淆注意力
    delay(50 + i * 10);      //让随机图案显示时间由快到慢,增加混淆
    displayClear();
  }
  displayCheat(nextResult);  //显示作弊图案,用户可通过此函数所显示的图案
                             //获知下次按键后将要出现在LED数码管上的数字。  
                             //此图案是在用户每次按下按键后显示新的数字
                             //前的最后一次图案显示
  delay(500);
  displayClear();
}

//根据参数数值在LED数码管上显示数字
void displayNumber(int ledNumber){     
  switch(ledNumber){
    case 1:  //显示1
      digitalWrite(4, HIGH);
      digitalWrite(7, HIGH); 
      break;   
    case 2:  //显示2
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH); 
      digitalWrite(5, HIGH); 
      digitalWrite(8, HIGH); 
      digitalWrite(9, HIGH); 
      break;   
    case 3:   //显示3
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH); 
      digitalWrite(5, HIGH); 
      digitalWrite(7, HIGH); 
      digitalWrite(8, HIGH); 
      break;   
    case 4:  //显示4
      digitalWrite(4, HIGH); 
      digitalWrite(5, HIGH); 
      digitalWrite(6, HIGH); 
      digitalWrite(7, HIGH); 
      break;  
    case 5:  //显示5
      digitalWrite(3, HIGH);
      digitalWrite(5, HIGH); 
      digitalWrite(6, HIGH); 
      digitalWrite(7, HIGH); 
      digitalWrite(8, HIGH); 
      break;
    case 6:  //显示6
      digitalWrite(3, HIGH);
      digitalWrite(5, HIGH); 
      digitalWrite(6, HIGH); 
      digitalWrite(7, HIGH); 
      digitalWrite(8, HIGH); 
      digitalWrite(9, HIGH); 
      break;    
    case 7:  //显示7
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH); 
      digitalWrite(7, HIGH);  
      break;
    case 8:  //显示8
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      digitalWrite(5, HIGH); 
      digitalWrite(6, HIGH); 
      digitalWrite(7, HIGH); 
      digitalWrite(8, HIGH); 
      digitalWrite(9, HIGH); 
      break;
    case 9:  //显示9
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      digitalWrite(5, HIGH); 
      digitalWrite(6, HIGH); 
      digitalWrite(7, HIGH); 
      digitalWrite(8, HIGH); 
      break;
    case 0:  //显示默认
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      digitalWrite(6, HIGH); 
      digitalWrite(7, HIGH); 
      digitalWrite(8, HIGH); 
      digitalWrite(9, HIGH); 
      break;
    default:
        digitalWrite(4, HIGH); 
        digitalWrite(5, HIGH); 
        digitalWrite(7, HIGH); 
        digitalWrite(8, HIGH);  
        digitalWrite(9, HIGH);   
    }
}

//清理显示内容
void displayClear(){
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW); 
  digitalWrite(6, LOW); 
  digitalWrite(7, LOW); 
  digitalWrite(8, LOW); 
  digitalWrite(9, LOW); 
}

//显示随机图案以混淆注意力
//使作弊图案显示时不易察觉。
void displayRandom(){
  int randomPin = random(3,9);
  digitalWrite(randomPin, HIGH);  
}

//显示作弊图案。
void displayCheat(int number){
  switch(number){
    case 1:  // 显示数字1作弊图案
      digitalWrite(3, HIGH);
      break;   
    case 2:  // 显示数字2作弊图案
      digitalWrite(6, HIGH); 
      break;   
    case 3:  // 显示数字3作弊图案
      digitalWrite(4, HIGH); ;
      break;   
    case 4:  // 显示数字4作弊图案
      digitalWrite(5, HIGH); 
      break;  
    case 5:  // 显示数字5作弊图案
      digitalWrite(9, HIGH); 
      break;
    case 6:  // 显示数字6作弊图案
      digitalWrite(7, HIGH);   
      break;    
    case 7: // 显示数字7作弊图案
      digitalWrite(8, HIGH);
      break;
    case 8: // 显示数字8作弊图案
      digitalWrite(6, HIGH);
      digitalWrite(4, HIGH);
      break;
    case 9: // 显示数字9作弊图案
      digitalWrite(9, HIGH);
      digitalWrite(7, HIGH);
      break;
    case 0: // 显示数字0作弊图案
      digitalWrite(3, HIGH);
      digitalWrite(8, HIGH); 
      break;
    }
}

2.6 模拟输出

2.6.1 analogWrite()基础知识

要调节他的亮度,阳极就是高电平的那个引脚要接到带~的引脚。

image-20240521205320063

image-20240521210745086

2.6.2 PWM知识

Pulse Width Modulation 就是通常所说的PWM,译为脉冲宽度调制,简称脉宽调制。脉冲宽度调制(PWM)是一种对模拟信号电平进行数字编码的方法,由于计算机不能输出模拟电压,只能输出0 或5V 的的数字电压值,我们就通过使用高分辨率计数器,利用方波的占空比被调制的方法来对一个具体模拟信号的电平进行编码。PWM 信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么是5V(ON),要么是0V(OFF)。电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。只要带宽足够,任何模拟值都可以使用PWM 进行编码。输出的电压值是通过通和断的时间进行计算的。输出电压=(接通时间/脉冲时间)*最大电压值

img

PWM 被用在许多地方,调光灯具、电机调速、声音的制作等等。

下面介绍一下PWM 的三个基本参数:

img

  • 1、脉冲宽度变化幅度(最小值/最大值)
  • 2、脉冲周期(1 秒内脉冲频率个数的倒数)
  • 3、电压高度(例如:0V-5V)

2.6.2 实验操作

/*
25 模拟输出1 - analogWrite
演示如何通过两个按键开关通过analogWrite指令
进行模拟输出操作。具体电路和其它信息请参考
太极创客网站本教程相关页面。
2017-04-28
*/
boolean pushButton1;   // 创建布尔型变量用来存储按键开关1的电平状态
boolean pushButton2;   // 创建布尔型变量用来存储按键开关2的电平状态
int ledPin = 9;        //LED引脚号
int brightness = 128;  //LED亮度参数

void setup() {
  // put your setup code here, to run once:
  pinMode(2, INPUT_PULLUP); //将引脚2设置为输入上拉模式(断开状态就是高电平,闭合开关读的就是低电平)
  pinMode(8, INPUT_PULLUP); //将引脚8设置为输入上拉模式
  pinMode(ledPin, OUTPUT);  //将LED引脚设置为输出模式
  Serial.begin(9600);      //启动串口通讯
}

void loop() {
  // put your main code here, to run repeatedly:
  pushButton1 = digitalRead(2); //读取引脚2电平状态并将其赋值给布尔变量
  pushButton2 = digitalRead(8); //读取引脚8电平状态并将其赋值给布尔变量
  
  if (!pushButton1 && brightness > 0){     // 当按下按键开关1并且LED亮度参数大于0
    brightness--;                          // 减低LED亮度参数
                                           //(brightness-- 相当于  brightness = brightness - 1;)
  } else if (!pushButton2 && brightness < 255) {  //当按下按键开关2并且LED亮度参数小于255
    brightness++;                                 //增加LED亮度参数
                                                  //(brightness++ 相当于  brightness = brightness + 1;)
  }
  analogWrite(ledPin, brightness);         //模拟输出控制LED亮度
  Serial.println(brightness);              //将LED亮度参数显示在串口监视器上
  delay(10);
}

2.6.3 模拟输出-for循环

image-20240522202821877

/*2
演示如何通过for循环语句实现LED明暗交替(呼吸灯)效果。
2017-04-28
*/
void setup() {
  pinMode(9, OUTPUT);      //设置9号引脚为输出模式
  Serial.begin(9600);     //启动串口通讯
}

void loop() {
  // LED由暗到明
  for (int brightness = 0; brightness <= 255; brightness++){
    analogWrite(9, brightness);   
    Serial.println(brightness);
    delay(10);
  }
  
  // LED由明到暗  
  for (int brightness = 255; brightness >=0 ; brightness--){
    analogWrite(9, brightness);
    Serial.println(brightness);
    delay(10);
  }
}

2.7 模拟输入

2.7.1 电位器

我们实验的电位器是1000Ω,当这个旋钮转到中间是每个分到一般的电阻,13之前都是1000Ω。

  • 小小电位器
  • 旋钮可调节
  • 旋钮向哪转
  • 哪边电阻减

image-20240522203558462image-20240522203629389image-20240522203700366

通常电位器用于分压电路,

image-20240522203940748image-20240522204003663

按这个习惯,往右旋转中间的电压就会变大,符合我们使用习惯。

2.7.2 analogRead()基础知识

moin = analogRead(A0);      //本指令用于从Arduino的模拟输入引脚读取数值。Arduno控制器有多个10位数模转换通道。这意味着Arduino可以将0-5伏特的电压输入信号映射到数值o-1023。
image-20240522204121017 image-20240522204229697

模拟输入是接到A0引脚,LED灯是接到9号引脚(PWM的一个) 保护电阻是:220Ω直插电阻*1,或者200Ω的电阻。

image-20240522205140181

image-20240522205515315

2.7.2 程序示例

/*
  电位器模拟输出
 读取模拟输入引脚,并将读取到的数值映射到0 - 255之间。然后用该映射结果设置
 引脚9的LED亮度,同时通过串口监视器显示这一映射结果。
 
 电路连接:
     电位器中间引脚连接到模拟输入A0引脚
     电位器两端引脚分别连接在Arduino +5V和接地引脚
   * LED正极通过 限流电阻连接在Arduino的9号引脚
     LED负极接地
 */
 
void setup() {
   
  Serial.begin(9600);  // 串口通讯初始化(9600 bps)
  pinMode(9, OUTPUT);  // 设置9号引脚为输出模式
}
 
void loop() {
  int analogInputVal = analogRead(A0);  // 读取模拟输入值 
  int brightness = map(analogInputVal, 0, 1023, 0, 255); //将模拟输入数值(0 - 1023)等比映射到模拟输出数值区间(0-255)内   
  analogWrite(9, brightness);  //根据模拟输入值调节LED亮度
 
  // 将结果通过串口监视器显示:
  Serial.print("analogInputVal = ");
  Serial.println(analogInputVal);
   
  Serial.print("brightness = ");
  Serial.println(brightness);
    
  Serial.println("");
}

2.8 其他知识

2.8.1 示例:电位器呼吸灯

/*
3引脚作为小灯泡(LED灯)的正极,记得连接一个保护的220Ω电阻,
模拟输入的引脚用A0引脚,就是电位器中间的引脚连接这个,一般电位器右边连接5V,左边接地;
呼吸灯闪烁延迟的时间就是电位器的旋转的大小,x = map(y,0,1023,1,9);把他映射到1-9秒
*/
int y = 0int x = 0;
void setup(){
    pinMode(3,OUTPUT); 
}

viod loop(){
    y = analogRead(0);
    x = map(y,0,1023,1,9);
    for(int i = 0;i < 255; i++){
        analogWrite(3,i);
        delay(x);
    }
    for(int i = 255;i > 0; i--) {
        analogWrite(3,i);
        delay(x);
    }
    delay(1);
}

2.8.2 子函数

void hexideng(int m){}  //void 表示函数不返回任何的值. hexideng 是自定义函数名    
//int m  是形参,int表示数据类型   ,  {}  中的语言为函数体
//在主函数中填写函数名就可以调用子函数 hexideng(x) x是实参

示例:子函数

int y = 0;
int x = 0;
void hexideng(int m)//子函数:当主程序执行到hexideng这个函数名时就会跳转到这执行循环
{
    analogWrite(3,m);//字母代替参数,相当于一个模板,让模拟电压的高低决定3引脚输出电平的高低
    dealy(n);
}

void setup(){
    pinMode(3,OUTPUT);//初始化3号引脚为高
}

void loop()
{
    y = analogRead(0);//读取A0号引脚输入电压的模拟值
    x = map(y,0,1023,1,9); //将模拟值转成1-9代替
    for(int i=0;i<255;i++) 
    {
        hexideng(i,x); //调用子函数,让3号引脚输出电平的高低决定呼吸的快慢
    }
      for(int i=255;i>0;i--)
    {
        hexideng(i,x);
    }
}

2.8.3 PWM频率计算

delayMicroseconds() 函数是暂停多少微秒,一百万分之一秒

millis() 函数是返回时间函数,回传晶片开始执行到目前的毫秒,该参数溢出大概需要50天时间。

示例:PWM频率计算

void setup()
{
  pinMode(2,OUTPUT);
  Serial.begin(9600);
}
 
void loop()
{
  unsigned long time1 = 0;
  unsigned long time2 = 0;
  time2 = millis();
  for (unsigned long i = 0;i < 1000000; i++)
  {
    digitalWrite(2,HIGH);
    delayMicroseconds(1);
    digitalWrite(2,LOW);
    delayMicroseconds(1); 
  }
  time2 = millis() -time1;
  Serial.println(time2);
  while (1)
  {
    delay(1);
  }
}

示例:PWM控制

void setup()
{
  pinMode(2,OUTPUT);
 
}
 
void PWM(int m)
{
  digitalWrite(2,HIGH);
  delayMicroseconds(m);
  digitalWrite(2,LOW);
  delayMicroseconds(1023 - m);
}
void loop()
{
  PWM(analogRead(0));
}

2.8.4 光敏电阻控制灯的开关

int y = 0;
void setup()
{
    pinMode(12,OUTPUT);
    Serial.begin(9600);
}
void loop()
{
    y = analogRead(0);
    Serial.printlan(y);
    if(y > 600)
    {
         digitalWrite(12,1)}
    else
    {
        digitalWrite (12,0);
    }
    delay(1);
}

2.8.5 库函数的调用(舵机控制)

#include <Servo.h>
Servo duoji;
void setup()
{
    duiji.attavh(9);
}
 
void loop()
{
    for (int i =0; i<180;i++)
    {
        duoji.write(i);
        delay(10);
    }
    for (int i = 180; i > 0;i--)
    {
        duoji.write(i)
        delay(10);
    }
}

示例:自定义舵机函数实现电位器控制舵机角度

int sck =2;
int jiaodu;
int PWM;
int dwp;
 
 void duji(int sck, int jiaodu)
 {
    PWM = (jiaodu * 11)+ 500;
    digitalWrite(sck,HIGH);
    delayMicroseconds(PWM);
    digitalWrite(sck,LOW);
    delayMicroseconds(2000-PWM);
 } 
 
 void setup()
 {
  pinMode(sck,OUTPUT);
 }
 void loop()
 {
  dwp = map(analogRead(A0),0,1023,0,180);
  duji(sck,dwp);
  delay(5);
 }

三 、Arduino套装的课件练习

3.1-Hello World

首先先来练习一个不需要其他辅助元件,只需要一块Arduino 和一根下载线的简单实验,让我们的Arduino 说出“Hello World!”,这是一个让Arduino 和PC 机通信的实验,这也是一个入门试验,希望可以带领大家进入Arduino 的世界。

这个实验我们需要用到的实验硬件有:

  • Arduino 控制器(UNo开发板)
  • USB 下载线

我们按照上面所讲的将Arduino 的驱动安装好后,我们打开Arduino 的软件,编写一段程序让Arduino 接受到我们发的指令就显示“Hello World!”字符串,当然您也可以让Arduino 不用接受任何指令就直接不断回显“Hello World!”,其实很简单,一条

if()语句就可以让你的Arduino 听从你的指令了,我们再借用一下Arduino 自带的数字13 口LED,让Arduino 接受到指令时LED 闪烁一下,再显示“Hello World!”

//下面给大家一段参考程序。

int val;//定义变量val
int ledpin=13;//定义数字接口13

void setup(){
	Serial.begin(9600);//设置波特率为9600,这里要跟软件设置相一致。当接入特定设备(如:蓝牙)时,我们也要跟其他设备的波特率						达到一致。
	pinMode(ledpin,OUTPUT);//设置数字13 口为输出接口,Arduino 上我们用到的I/O 口都要进行类似这样的定义。
}

void loop(){
    val=Serial.read();//读取PC 机发送给Arduino 的指令或字符,并将该指令或字符赋给val(在开发板中这个函数非阻塞)
    if(val=='R')//判断接收到的指令或字符是否是“R”。
    {//如果接收到的是“R”字符
        digitalWrite(ledpin,HIGH);//点亮数字13 口LED。
        delay(500);
        digitalWrite(ledpin,LOW);//熄灭数字13 口LED
        delay(500);
        Serial.println("Hello World!");//显示“Hello World!”字符串
    }
}

image-20240523194732444

3.2 LED闪烁实验

LED 小灯实验是比较基础的实验之一,上一个“ Hello World!”实验里已经利用到了Arduino 自带的LED,这次我们利用其他I/O 口和外接直插LED 灯来完成这个实验,我们需要的实验器材除了每个实验都必须的Arduino 控制器和USB 下载线以外的

其它器件如下:

  • 红色M5 直插LED*1 *
  • 220Ω直插电阻1
  • 面包板1
  • 面包板跳线1 扎

下一步我们按照下面的小灯实验原理图链接实物图,这里我们使用数字10 接口。使用发光二极管LED 时,要连接限流电阻,这里为220Ω电阻,否则电流过大会烧毁发光二极管。

小灯实验原理图

img

img

按照上图链接好电路后,就可以开始编写程序了,我们还是让LED 小灯闪烁,点亮1 秒熄灭1 秒。这个程序很简单与Arduino 自带的例程里的Blink 相似只是将13 数字接口换做10 数字接口。

参考程序如下:

int ledPin = 10; //定义数字10 接口

void setup(){
	pinMode(ledPin, OUTPUT);//定义小灯接口为输出接口
}

void loop(){
    digitalWrite(ledPin, HIGH); //点亮小灯
    delay(1000); //延时1 秒
    digitalWrite(ledPin, LOW); //熄灭小灯
    delay(1000); // 延时1 秒
}

下载完程序就可以看到我们的10 口外接小灯在闪烁了,这样我们的小灯闪烁实验就完成了。

3.3 PWM调控灯光亮度实验

Pulse Width Modulation 就是通常所说的PWM,译为脉冲宽度调制,简称脉宽调制。脉冲宽度调制(PWM)是一种对模拟信号电平进行数字编码的方法,由于计算机不能输出模拟电压,只能输出0 或5V 的的数字电压值,我们就通过使用高分辨率计数器,利用方波的占空比被调制的方法来对一个具体模拟信号的电平进行编码。PWM 信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么是5V(ON),要么是0V(OFF)。电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。只要带宽足够,任何模拟值都可以使用PWM 进行编码。输出的电压值是通过通和断的时间进行计算的。输出电压=(接通时间/脉冲时间)*最大电压值

img

PWM 被用在许多地方,调光灯具、电机调速、声音的制作等等。

下面介绍一下PWM 的三个基本参数:

img

  • 1、脉冲宽度变化幅度(最小值/最大值)
  • 2、脉冲周期(1 秒内脉冲频率个数的倒数)
  • 3、电压高度(例如:0V-5V)

Arduino 控制器有6 个PWM 接口分别是数字接口3、5、6、9、10、11,前面我们已经做了按键控制小灯的实验,那是数字信号控制数字接口的实验,我们也做过电位计的实验,这次我们就来完成一个用电位计控制小灯的实验。

需要的元器件有:

  • 电位计模块*1 *
  • 红色M5 直插LED1
  • 220Ω直插电阻
  • 面包板*1 *
  • 面包板跳线1 扎

电位计即为模拟值输入我们接到模拟口,小灯我们接到PWM 接口上,这样通过产生不同的PWM 信号就可以让小灯有亮度不同的变化。

我们先按照下面的原理图连接实物图。

image-20240523203047232

在编写程序的过程中,我们会用到模拟写入analogWrite(PWM 接口,模拟值)函数,对于模拟写入analogWrite()函数,此函数用法也很简单,我们在本实验中读取电位计的模拟值信号并将其赋给PWM 接口使小灯产生相应的亮度变化,再在屏幕上显示出读取的模拟值,大家可以理解为此程序是在模拟值读取的实验程序中多加了将模拟值赋给PWM 接口这一部分,下面给大家提供一段参考源程序。

参考源程序:

int potpin=0;//定义模拟接口0
int ledpin=11;//定义数字接口11(PWM 输出)
int val=0;// 暂存来自传感器的变量数值

void setup()
{
    pinMode(ledpin,OUTPUT);//定义数字接口11 为输出
    Serial.begin(9600);//设置波特率为9600
    //注意:模拟接口自动设置为输入
}

void loop()
{
    val=analogRead(potpin);// 读取传感器的模拟值并赋值给val
    Serial.println(val);//显示val 变量
    Serial.println("        ");//显示val 变量
    val =map(val,0,1023,0,255);
    Serial.println(val);//显示val 变量
    analogWrite(ledpin,val);// 打开LED 并设置亮度(PWM 输__________出最大值255)
    delay(10);//延时0.01 秒
}

下载完程序,我们旋转电位计的旋钮不但可以看到屏幕上数值的变化还也可以清楚的看到我们面包板上的LED 小灯的亮度也在随之变化。

3.4 广告灯效果实验

1)实验器件

  • Led灯:6个
  • 220Ω的电阻:6个
  • 多彩面包板实验跳线:若干

2)实验连线

按照二级管的接线方法,将六个LED灯依次接到数字2~7引脚上。如图:

广告灯实验的接线

3)实验原理

image-20240523214923490

在生活中我们经常会看到一些由各种颜色的led灯组成的广告牌,广告牌上各个位置上癿led灯不断的变话,形成各种效果。本节实验就是利用led灯编程模拟广告灯效果。

int BASE = 2 ;  //第一个LED灯的引脚
int NUM = 6;   //LED 的总数

void setup()
{
   for (int i = BASE; i < BASE + NUM; i ++) {
     pinMode(i, OUTPUT);   //设定这些引脚为输出模式
   }
}

void loop()
{
   for (int i = BASE; i < BASE + NUM; i ++) {
     digitalWrite(i, LOW);    //设置这些数字IO输出为低,即逐渐熄灭
     delay(200);        //延迟
   }
   for (int i = BASE; i < BASE + NUM; i ++) {
     digitalWrite(i, HIGH);    //设置这些数字IO输出为高,即逐渐点亮
     if(i>BASE){
        digitalWrite(i-1, LOW);    //设置这些数字IO输出为低,即逐渐熄灭
     }
     delay(200);        //延迟
   }  
}

3.5 交通灯设计实验

上面我们已经完成了单个小灯的控制实验,接下来我们就来做一个稍微复杂一点的交通灯实验,其实聪明的朋友们可以看出来这个实验就是将上面单个小灯的实验扩展成3 个颜色的小灯,就可以实现我们模拟交通灯的实验了。我们完成这个实验所需的元件除了Arduino 控制器和下载线还需要的硬件如下:

  • 红色M5 直插LED*1
  • 黄色M5 直插LED*1
  • 绿色M5 直插LED*1
  • 220Ω电阻*3
  • 面包板*1
  • 面包板跳线*1 扎

准备好上述元件我们就可以开工了,我们可以按照上面小灯闪烁的实验举一反三,下面是我们提供参考的原理图,我们使用的分别是数字10、7、4、接口.

img

img

既然是交通灯模拟实验,红黄绿三色小灯闪烁时间就要模拟真实的交通灯,我们使用Arduinodelay()函数来控制延时时间,相对于C 语言就要简单许多了。

下面是一段参考程序:

int redled =10; //定义数字10 接口
int yellowled =7; //定义数字7 接口
int greenled =4; //定义数字4 接口

void setup(){
    pinMode(redled, OUTPUT);//定义红色小灯接口为输出接口
    pinMode(yellowled, OUTPUT); //定义黄色小灯接口为输出接口
    pinMode(greenled, OUTPUT); //定义绿色小灯接口为输出接口
}

void loop(){
    digitalWrite(redled, HIGH);//点亮红色小灯
    delay(1000);//延时1 秒
    digitalWrite(redled, LOW); //熄灭红色小灯
    digitalWrite(yellowled, HIGH);//点亮黄色小灯
    delay(200);//延时0.2 秒
    digitalWrite(yellowled, LOW);//熄灭黄色小灯
    digitalWrite(greenled, HIGH);//点亮绿色小灯
    delay(1000);//延时1 秒
    digitalWrite(greenled, LOW);//熄灭绿色小灯
}

下载程序完成后就可以看到我们自己设计控制的交通灯了。

3.6按键控制LED实验

I/O 口的意思即为INPUT 接口和OUTPUT 接口,到目前为止我们设计的小灯实验都还只是应用到Arduino 的I/O 口的输出功能,这个实验我们来尝试一下使用Arduino的I/O 口的输入功能即为读取外接设备的输出值,我们用一个按键和一个LED 小灯完成一个输入输出结合使用的实验,让大家能简单了解I/O 的作用。按键开关大家都应该比较了解,属于开关量(数字量)元件,按下时为闭合(导通)状态。完成本实验要用到的元件如下:

  • 按键开关*1
  • 红色M5 直插LED*1
  • 220Ω电阻*1
  • 10KΩ电阻*1
  • 面包板*1
  • 面包板跳线*1 扎

我们将按键接到数字7 接口,红色小灯接到数字11 接口(Arduino 控制器0-13 数字I/O 接口都可以用来接按键和小灯,但是尽量不选择0 和1 接口,0 和1 接口为接口功能复用,除I/O 口功能外也是串口通信接口,下载程序时属于与PC 机通信故应保持0 和1 接口悬空,所以为避免插拔线的麻烦尽量不选用0 和1 接口),按下面的原理图连接好电路。

img

img

下面开始编写程序,我们就让按键按下时小灯亮起,根据前面的学习相信这个程序很容易就能编写出来,相对于前面几个实验这个实验的程序中多加了一条条件判断语句,这里我们使用if 语句,Arduino 的程序便写语句是基于C 语言的,所以C 的条件判断语句自然也适用于Arduino,像while、swich 等等。这里根据个人喜好我们习惯

于使用简单易于理解的if 语句给大家做演示例程。

我们分析电路可知当按键按下时,数字7 接口可读出为高电平,这时我们使数字11 口输出高电平可使小灯亮起,程序中我们判断数字7 口是否为低电平,要为低电平使数字11 口输出也为低电平小灯不亮,原理同上。

参考源程序:

int ledpin=11;//定义数字11 接口
int inpin=7;//定义数字7 接口
int val;//定义变量val

void setup(){
    pinMode(ledpin,OUTPUT);//定义小灯接口为输出接口
    pinMode(inpin,INPUT);//定义按键接口为输入接口
}
void loop()
{
    val=digitalRead(inpin);//读取数字7 口电平值赋给val
    if(val==LOW)//检测按键是否按下,按键按下时小灯亮起
    { 
        digitalWrite(ledpin,LOW);
    }
    else{ 
        digitalWrite(ledpin,HIGH);
    }
}

下载完程序我们本次的小灯配合按键的实验就完成了,本实验的原理很简单,广泛被用于各种电路和电器中,实际生活中大家也不难在各种设备上发现,例如大家的手机当按下任一按键时背光灯就会亮起,这就是典型应用了,下面一个实验就是一个最简单的生活中应用实例——抢答器。

3.7 抢答器设计实验

完成上面的实验以后相信已经有很多朋友可以独立完成这个实验了,本实验就是将上面的按键控制小灯的实验扩展成3 个按键对应3 个小灯,占用6 个数字I/O 接口。

原理这里就不多说了同上面实验,下面附上参考原理图和实物连接图。

img

img

参考源程序如下:
int redled=10;
int yellowled=9;
int greenled=8;

int redpin=7;
int yellowpin=6;
int greenpin=5;

int red;
int yellow;
int green;

void setup(){
    pinMode(redled,OUTPUT);
    pinMode(yellowled,OUTPUT);
    pinMode(greenled,OUTPUT);
    pinMode(redpin,INPUT);
    pinMode(yellowpin,INPUT);
    pinMode(greenpin,INPUT);
}

void loop(){
    red=digitalRead(redpin);
    if(red==LOW) { 
        digitalWrite(redled,LOW);
    }
    else{ 
        digitalWrite(redled,HIGH);
    }
    
    yellow=digitalRead(yellowpin);
    if(yellow==LOW){ 
        digitalWrite(yellowled,LOW);
    }
    else{ 
        digitalWrite(yellowled,HIGH);
    }
    
    green=digitalRead(greenpin);
    if(green==LOW){ 
        digitalWrite(greenled,LOW);
    }
    else{ 
        digitalWrite(greenled,HIGH);
	}
}

此程序与前面程序除接口增多以外并无异处,因此不做程序注解分析。

下载完程序,我们自己制作的简易抢答器就完成了。

3.8 按键膜测试

所需要的材料:

  • Arduino * 1
  • 线材 * 8
  • 按键膜 * 1

接线方式:

img

代码

#include <Keypad.h>

const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {13,12,11,10};		//第1、2、3、4行
byte colPins[COLS] = {7,6,5,4};			//第1、2、3、4列

//键盘类的初始化  键盘的字符数组,键盘的行引脚,键盘的列引脚,行数,列数;
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS );
byte ledPin = 13; 	//用自带的灯

boolean blink = false;

void setup(){
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);
  keypad.addEventListener(keypadEvent);		//调用键盘的类方法(应该是监听键盘事件的行为)
}
  
void loop(){
  char key = keypad.getKey();
  
  if (key != NO_KEY) {
    Serial.println(key);
  }
  if (blink){
    digitalWrite(ledPin,!digitalRead(ledPin));
    delay(100);
  }
}

//take care of some special events
void keypadEvent(KeypadEvent key){
  switch (keypad.getState()){
    case PRESSED:
      switch (key){
        case '#': digitalWrite(ledPin,!digitalRead(ledPin)); break;
        case '*': 
          digitalWrite(ledPin,!digitalRead(ledPin));
        break;
      }
    break;
    case RELEASED:
      switch (key){
        case '*': 
          digitalWrite(ledPin,!digitalRead(ledPin));
          blink = false;
        break;
      }
    break;
    case HOLD:
      switch (key){
        case '*': blink = true; break;
      }
    break;
  }
}

3.9 模拟值读取实验

本个实验我们就来开始学习一下模拟I/O 接口的使用,Arduino 有模拟0—模拟5 共计6 个模拟接口,这6 个接口也可以算作为接口功能复用,除模拟接口功能以外,这6 个接口可作为数字接口使用,编号为数字14—数字19,简单了解以后,下面就来开始我们的实验。电位计是大家比较熟悉的典型的模拟值输出元件,本实验就用它来完成。

所需元器件有:

  • 电位计*1
  • 面包板*1
  • 面包板跳线*1 扎

本实验我们将电位计的阻值转化为模拟值读取出来,然后显示到屏幕上,这也是我们以后完成自己所需的实验功能所必须掌握的实例应用。我们先要按照以下电路图连接实物图

img

img

我们使用的是模拟0 接口。

程序的编写也很简单,一个analogRead();语句就可以读出模拟口的值,Arduino 32810 位的A/D 采集,所以读取的模拟值范围是0-1023,本个实验的程序里还有一个难点就是显示数值在屏幕这一问题,学习起来也是很简单的。首先我们要在voidsetup()里面设置波特率,显示数值属于Arduino 与PC 机通信,所以Arduino 的波特率应与PC 机软件设置的相同才能显示出正确的数值,否则将会显示乱码或是不显示,在Arduino 软件的监视窗口右下角有一个可以设置波特率的按钮,这里设置的波特率需要跟程序里void setup()里面设置波特率相同,程序设置波特率的语句为Serial.begin();括号中为波特率的值。其次就是显示数值的语句了,Serial.print();或者Serial.println();都可以,不同的是后者显示完数值后自动回车,前者不是,更多的关于语句的讲解前面有介绍这里就不再多说了。

下面是参考源程序:

int potpin=0;//定义模拟接口0
int ledpin=13;//定义数字接口13
int val=0;//将定义变量val,并赋初值0

void setup(){
    pinMode(ledpin,OUTPUT);//定义数字接口为输出接口
    Serial.begin(9600);//设置波特率为9600
}

void loop(){
    digitalWrite(ledpin,HIGH);//点亮数字接口13 的LED
    delay(50);//延时0.05 秒
    digitalWrite(ledpin,LOW);//熄灭数字接口13 的LED
    delay(50);//延时0.05 秒
    val=analogRead(potpin);//读取模拟接口0 的值,并将其赋给val
    Serial.println(val);//显示出val 的值
}

参考程序借用了Arduino 数字13 口自带的LED 小灯,每读一次值小灯就会闪烁一下。

本实验到这里就完成了,当您旋转电位计旋钮的时候就可以看到屏幕上数值的变化了,读取模拟值这个方法将一直陪伴我们,模拟值读取是我们很常用的功能,因为很多传感器都是模拟值输出,我们读出模拟值后再进行相应的算法处理,就可以应用到我们需要实现的功能里了。

3.10 光控声音实验

1、实验器件

  • 光敏电阻:1个
  • 蜂鸣器:1个
  • 多彩面包板实验跳线:若干

2、实验连线

img

按照Arduino教程将控制板、prototype板子、面包板连接好,下载线接好。光敏电阻的一端接在数字6口,另一端与蜂名器正极相连,蜂明器的负极和GND相连。

3、实验原理

本程序应用前面几节读取模拟口电压值的方法,直接将光敏电阻接在数字口。程序类似第二节蜂鸣器发声的程序,没有光照时,正常发出声音,但声音特别的小;当有光照时,光敏电阻的阻值减小,所以蜂鸣器两端的电压就会增大,蜂鸣器声音发大光照越强,电阻越小,蜂鸣器越响。

程序说明:

void setup() { 
	pinMode(6,OUTPUT); 	
} 
void loop() { 
    while(1) { 
        char i,j; 
        while(1){ 
            for(i=0;i<80;i++){  //发出一个频率的声音 
                digitalWrite(6,HIGH); 
                delay(1); 
                digitalWrite(6,LOW); 
                delay(1); 
            } 
            for(i=0;i<100;i++){ //发出另一个频率的声音 
                digitalWrite(6,HIGH); 
                delay(2); 
                digitalWrite(6,LOW); 
                delay(2); 
            } 
        } 
    } 
} 

将程序下载到实验板后,可以用手电筒或其他収光物体照射光敏电阻,可以听到有光照时蜂鸣器声音更大。

掌握本程序后,大家可以自己动手设计实验,也可以用光敏电阻控制led灯亮度。

3.11 感光灯实验

完成以上的各种实验后,我们对Arduino 的应用也应该有一些认识和了解了,在基本的数字量输入输出和模拟量输入以及PWM 的产生都掌握以后,我们就可以开始进行一些传感器的应用了。

光敏电阻器(photovaristor)又叫光感电阻,是利用半导体的光电效应制成的一种电阻值随入射光的强弱而改变的电阻器;入射光强,电阻减小,入射光弱,电阻增大。光敏电阻器一般用于光的测量、光的控制和光电转换(将光的变化转换为电的变化)。

光敏电阻可广泛应用于各种光控电路,如对灯光的控制、调节等场合,也可用于光控开关。

本次实验我们先进行一个较为简单的光敏电阻的使用实验。光敏电阻既然是可以根据光强改变阻值的元件,自然也需要模拟口读取模拟值了,本实验可以借鉴PWM 接口实验,将电位计换做光敏电阻实现当光强不同时LED 小灯的亮度也会有相应的变化。

下面是所需要的元器件:

  • 光敏电阻*1
  • 红色M5 直插LED*1
  • 10KΩ直插电阻*1
  • 220Ω直插电阻*1
  • 面包板*1
  • 面包板跳线*1 扎

按照以下原理图连接电路。

img

img

连接好就可以编写程序了,本实验程序与PWM 实验程序相类似只是在PWM 值赋值时根据我们现在的电路稍有修改(修改部分见参考源程序)。

参考源程序:

int potpin=0;//定义模拟接口0 连接光敏电阻
int ledpin=11;//定义数字接口11 输出PWM 调节LED 亮度
int val=0;//定义变量val
void setup()
{
    pinMode(ledpin,OUTPUT);//定义数字接口11 为输出
    Serial.begin(9600);//设置波特率为9600
}
void loop()
{
    val=analogRead(potpin);//读取传感器的模拟值并赋值给val
    Serial.println(val);//显示val 变量数值
    //建议加这个   val=map(val,0,1023,0,255);
    analogWrite(ledpin,val);// 打开LED 并设置亮度(PWM 输出最大值255)
    delay(10);//延时0.01 秒
}

这里我们将传感器返回值除以4,原因是模拟输入analogRead()函数的返回值范围是0 到1023,而模拟输出analogWrite()函数的输出值范围是0 到255。下载完程序再试着改变光敏电阻所在的环境的光强度就可以看到我们的小灯有相应的变化了。在日常生活中光敏电阻的应用是很广泛的,用法也是很多,大家可以根据这个实验举一反三,做出更好的互动作品。

3.12 三色灯RGB LED 测试

所需要的材料:

  • 有四个引脚的LED * 1
  • 1KΩ的电阻 * 1
  • UNO开发板
  • 一些杜邦线

接线示意

img

img

程序示例

int redpin = 11; //select the pin for the red LED
int greenpin =10;// select the pin for the green LED
int bluepin =9; // select the pin for the  blue LED
int val;

void setup() {
  pinMode(redpin, OUTPUT);
  pinMode(bluepin, OUTPUT);
  pinMode(greenpin, OUTPUT);
  Serial.begin(9600);
}

void loop() 
{
    for(val=255; val>0; val--)
      {
       analogWrite(11, val);
       analogWrite(10, 255-val);
       analogWrite(9, 128-val);
       delay(1); 
      }
    for(val=0; val<255; val++)
      {
       analogWrite(11, val);
       analogWrite(10, 255-val);
       analogWrite(9, 128-val);
       delay(1); 
      }
}

3.13 倾斜开关实验

倾斜开关控制led灯的亮灭

image-20240527222105505

1. 实验器件

  • 滚珠开关(振动传感器):1个
  • Led灯:1个
  • 220Ω电阻:2个
  • 多彩面包板实验跳线:若干

2、实验连线

按照Arduino教程将控制板、扩展板子、面包板连接好,下载线接好。 然后将led灯连接到数字8引脚,滚珠开关连接到模拟5引脚。

20190717223506502

3、实验原理

当开关一端低于水平位置倾斜,开关寻通,模拟口电压值为5V左右 (数字二进制表示为1023),点亮led灯。当另一端低于水平位置倾斜 ,开关停止,模拟口电压值为0V左右(数字二进制表示为0),熄灭led 灯。在程序中模拟口电压值是否大于2.5V左右(数字二迕制表示为512) ,即可知道是否倾斜开关寻通了。

4、程序代码

程序代码如下:

void setup() { 
  Serial.begin(9600);
  pinMode(6,OUTPUT);//设置数字8引脚为输出模式 
} 
void loop() { 
  int i;//定义变量i 
  while(1) 
  { 
    i=analogRead(5);//读取模拟5口电压值 
    Serial.println(i);
    if(i>200)//如果大于512(2.5V) 
    { 
      digitalWrite(6,HIGH);//点亮led灯 
    } 
    else//否则 
    { 
      digitalWrite(6,LOW);//熄灭led灯 
    } 
  } 
}

3.14 火焰报警实验

一、火焰传感器介绍

1、认识火焰传感器

img

火焰传感器(即红外接收三极管)是机器人专门用来搜寻火源的传感器,本传感器对火焰特别灵敏。实物如图:

2、工作原理

火焰传感器利用红外线对火焰非常敏感的特点,使用特制的红外线接收管来检测火焰,然后把火焰的亮度转化为高低变化的电平信号,输入到中央处理器,中央处理器根据信号的变化做出相应的程序处理。

3、火焰传感器的连线

红外接收三极管的短引线端为负极,长引线端为正极。按照下图将负极接到5V接口中,然后将正极和10K电阻相连,电阻的另一端接到GND接口中,最后从火焰传感器的正极端所在列接入一根跳线,跳线的另一端接在模拟口中。如图

img

注意:传感器长脚为证,短为负。注意电源正负。

二、火焰报警实验

1、实验器件

  • 火焰传感器:1个
  • 蜂鸣器:1个
  • 10K电阻:1个
  • 多彩面包板实验跳线:若干

2、实验连线

1)蜂鸣器的连接

首先 按照Arduino教程将控制板、prototype板子、面包板连接好,下载线接好。从实验盒中取出蜂鸣器,按照第二节实验蜂鸣器的连接方法,将蜂鸣器连接到数字第八口。完成蜂鸣器的连接。

2)火焰传感器的连接

从实验盒中取出火焰传感器,按照本节所讲述的火焰传感器的接线方法,将火焰传感器接到模拟5口。完成整个实验的连线。

image-20240529203302411

3、实验原理

image-20240529203319395

在有火焰靠近和没有火焰靠近两种情况下,模拟口读到的电压值是有变化的。实际用万用表测量可知,在没有火焰靠近时,模拟口读到的电压值为0.3V左右;当有火焰靠近时,模拟口读到的电压值为1.0V左右,火焰靠近距离越近电压值越大。

所以在程序一开始,我仧可以先存储一个没有火焰时模拟口的电压值i。接着不断的循环读取模拟口电压值j、同存储的值做差值k=j-i、差值k不0.6v做比较。差值k如果大于0.6V(数字二迕制值为123),则判断有火焰靠近让蜂鸣器发出声音以作报警;如果差值小于0.6v则蜂鸣器不响。 (其实我用手电筒照射的时候也能发生反应,无光照时他的电阻可看成无穷大,有光照时电阻很小很小)

4、程序代码

int flame=A5;//定义火焰接口为模拟A5 接口
int Beep=8;//定义蜂鸣器接口为数字8 接口
int val=0;//定义数字变量
void setup() { 
    pinMode(Beep,OUTPUT);//定义BEEP 为输出接口
    pinMode(flame,INPUT);//定义火焰为输入接口
    Serial.begin(9600);//设定波特率为9600 
} 

void loop() { 
    val=analogRead(flame);	//读取火焰传感器的模拟值 
    Serial.println(val);	//输出模拟值,并将其打印出来
    if(val>=600){			//当模拟值大于600 时蜂鸣器鸣响
    	digitalWrite(Beep,HIGH); 
    }
    else { 
        digitalWrite(Beep,LOW); 
    } 
}

3.15 数码管显示实验(参考2.5 猜数字小游戏)

3.16 四位数码管

这次我们进行的实验是使用arduino驱动一块共阳四位数码管。驱动数码管限流电阻肯定是必不可少的,限流电阻有两种接法

一种是在d1-d4阳极接,总共接4颗。这种接法好处是需求电阻比较少,但是会产生每一位上显示不同数字亮度会不一样,1最亮,8最暗。

另外一种接法就是在其他8个引脚上接,这种接法亮度显示均匀,但是用电阻较多。本次实验使用8颗220Ω电阻(因为没有100Ω电阻,所以使用220Ω的代替,100欧姆亮度会比较高)。

image-20240529204553517

4位数码管总共有12个引脚,小数点朝下正放在面前时,左下角为1,其他管脚顺序为逆时针旋转。左上角为最大的12号管脚。

image-20240529211631402

下图为数码管的说明手册

image-20240529211651196

下面是硬件连接图

image-20240529211744291

image-20240529211752932

代码:
//设置阴极接口
int a = 1;
int b = 2;
int c = 3;
int d = 4;
int e = 5;
int f = 6;
int g = 7;
int p = 8;
//设置阳极接口
int d4 = 9;
int d3 = 10;
int d2 = 11;
int d1 = 12;
//设置变量
long n = 0;
int x = 100;
int del = 55;  //此处数值对时钟进行微调
 
void setup(){
    pinMode(d1, OUTPUT);
    pinMode(d2, OUTPUT);
    pinMode(d3, OUTPUT);
    pinMode(d4, OUTPUT);
    pinMode(a, OUTPUT);
    pinMode(b, OUTPUT);
    pinMode(c, OUTPUT);
    pinMode(d, OUTPUT);
    pinMode(e, OUTPUT);
    pinMode(f, OUTPUT);
    pinMode(g, OUTPUT);
    pinMode(p, OUTPUT);
}

void loop(){
    clearLEDs();
    pickDigit(1);
    pickNumber((n/x/1000)%10);
    delayMicroseconds(del);

    clearLEDs();
    pickDigit(2);
    pickNumber((n/x/100)%10);
    delayMicroseconds(del);

    clearLEDs();
    pickDigit(3);
    dispDec(3);
    pickNumber((n/x/10)%10);
    delayMicroseconds(del);

    clearLEDs();
    pickDigit(4);
    pickNumber(n/x%10);
    delayMicroseconds(del);
 
    n++;

    if (digitalRead(13) == HIGH){
    	n = 0;
    }
}
  
void pickDigit(int x)  //定义pickDigit(x),其作用是开启dx端口
{
    digitalWrite(d1, LOW);
    digitalWrite(d2, LOW);
    digitalWrite(d3, LOW);
    digitalWrite(d4, LOW);

    switch(x)
    {
        case 1: 
            digitalWrite(d1, HIGH); 
            break;
        case 2: 
            digitalWrite(d2, HIGH); 
            break;
        case 3: 
            digitalWrite(d3, HIGH); 
            break;
        default: 
            digitalWrite(d4, HIGH); 
            break;
    }
}
	 
void pickNumber(int x)   //定义pickNumber(x),其作用是显示数字x
{
	switch(x){
        default: 
            zero(); 
            break;
        case 1: 
            one(); 
            break;
        case 2: 
            two(); 
            break;
        case 3: 
            three(); 
            break;
        case 4: 
            four(); 
            break;
        case 5: 
            five(); 
            break;
        case 6: 
            six(); 
            break;
        case 7: 
            seven(); 
            break;
        case 8: 
            eight(); 
            break;
        case 9: 
            nine(); 
            break;
	}
}
 	 
void dispDec(int x)  //设定开启小数点
{
	digitalWrite(p, LOW);
}
	 
void clearLEDs()  //清屏
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
  digitalWrite(p, HIGH);
}
 
void zero()  //定义数字0时阴极那些管脚开关
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, HIGH);
}
	 
void one()  //定义数字1时阴极那些管脚开关
{
  digitalWrite(a, HIGH);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}
 
void two()  //定义数字2时阴极那些管脚开关
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, HIGH);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, HIGH);
  digitalWrite(g, LOW);
}
	 
void three()  //定义数字3时阴极那些管脚开关
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, LOW);
}
	 
void four()  //定义数字4时阴极那些管脚开关
{
     digitalWrite(a, HIGH);
     digitalWrite(b, LOW);
     digitalWrite(c, LOW);
     digitalWrite(d, HIGH);
     digitalWrite(e, HIGH);
     digitalWrite(f, LOW);
    digitalWrite(g, LOW);
}
 
void five()  //定义数字5时阴极那些管脚开关
{
     digitalWrite(a, LOW);
     digitalWrite(b, HIGH);
     digitalWrite(c, LOW);
     digitalWrite(d, LOW);
     digitalWrite(e, HIGH);
     digitalWrite(f, LOW);
     digitalWrite(g, LOW);
 }
 	 
 void six()  //定义数字6时阴极那些管脚开关
 {
     digitalWrite(a, LOW);
     digitalWrite(b, HIGH);
     digitalWrite(c, LOW);
     digitalWrite(d, LOW);
     digitalWrite(e, LOW);
     digitalWrite(f, LOW);
     digitalWrite(g, LOW);
 }
  
 void seven()  //定义数字7时阴极那些管脚开关
 {
     digitalWrite(a, LOW);
     digitalWrite(b, LOW);
     digitalWrite(c, LOW);
     digitalWrite(d, HIGH);
     digitalWrite(e, HIGH);
     digitalWrite(f, HIGH);
     digitalWrite(g, HIGH);
 }
  
 void eight()  //定义数字8时阴极那些管脚开关
 {
     digitalWrite(a, LOW);
     digitalWrite(b, LOW);
     digitalWrite(c, LOW);
     digitalWrite(d, LOW);
     digitalWrite(e, LOW);
     digitalWrite(f, LOW);
     digitalWrite(g, LOW);
}
	 
void nine()  //定义数字9时阴极那些管脚开关
{
    digitalWrite(a, LOW);
    digitalWrite(b, LOW);
    digitalWrite(c, LOW);
    digitalWrite(d, LOW);
    digitalWrite(e, HIGH);
    digitalWrite(f, LOW);
    digitalWrite(g, LOW);
}

3.17 小灯74HC595控制实验

74HC595 简单说来就是具有8 位移位寄存器和一个存储器,以及三态输出功能。 这里我们用它来控制8 个LED 小灯。我们为什么要用74HC595 来控制小灯呢?一定会有很多朋友会问这个问题,我想问的是我们要是单纯的用Arduino 控制8 个小灯的话要占用多少个I/O呢?答案是8 个,但是我们的Arduino 168 有几个I/O 口呢?加上模拟接口也就20 个吧,这8 个小灯占用了太多的资源了,我们用74HC595 的目的就是减少I/O 口的使用数量。用74HC595 以后我们可以用3 个数字I/O 口控制8 个LED 小灯岂不美哉。下面是我们要准备的元器件。

  • 74HC595 直插芯片*1
  • 红色M5 直插LED*4
  • 绿色M5 直插LED*4
  • 220Ω直插电阻*8
  • 面包板*1
  • 面包板跳线*1 扎

准备好元件我们就按下面的原理图连接电路。

img

img

此电路图看似复杂,我们仔细分析以后再结合参考实物就会发现很简单。

下面是参考源程序:
int data = 2;
int clock = 4;
int latch = 5;
int ledState = 0;
const int ON = HIGH;
const int OFF = LOW;
void setup(){
    pinMode(data, OUTPUT);
    pinMode(clock, OUTPUT);
    pinMode(latch, OUTPUT);
}

void loop(){
    int delayTime = 100;
    for(int i = 0; i < 256; i++) {
        updateLEDs(i);
        delay(delayTime);
    }
}

void updateLEDs(int value){
    digitalWrite(latch, LOW);
    shiftOut(data, clock, MSBFIRST, value);
    digitalWrite(latch, HIGH);
}

void updateLEDsLong(int value){
    digitalWrite(latch, LOW);
    for(int i = 0; i < 8; i++)    {
        int bit = value & B10000000;
        value = value << 1;
        if(bit == 128){digitalWrite(data, HIGH);}
        else{digitalWrite(data, LOW);}
        digitalWrite(clock, HIGH);
        delay(1);
        digitalWrite(clock, LOW);
    }
    digitalWrite(latch, HIGH);
}

int bits[]={B00000001, B00000010, B00000100, B00001000, B00010000, B00100000,B01000000, B10000000};
int masks[] ={B11111110, B11111101, B11111011, B11110111, B11101111, B11011111,B10111111, B01111111};
void changeLED(int led, int state){
    ledState = ledState & masks[led];
    if(state == ON){ledState = ledState | bits[led];}
    updateLEDs(ledState);
}

下载完程序大家就可以看到8 个小灯闪烁的美妙场景了。

3.18 步进电机

步进电机是一种将电脉冲转化为角位移的执行机构。通俗一点讲:当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(及步进角)。你可以通过控制脉冲个数来控制角位移量,从而达到准确定位的目的;同时你也可以通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的。

下面这个就是本次实验使用的步进电机

DSC03375.JPG

使用步进电机前一定要仔细查看说明书,确认是四相还是两相,各个线怎样连接,本次实验使用的步进电机是四相的,不同颜色的线定义如下图:

  • 减速步进电机
  • 直径:28mm
  • 电压:5V
  • 步进角度:5.625 × 1/64
  • 减速比:1/64
  • 5线4相 可以用普通uln2003芯片驱动,也可以接成2相使用

该步进电机空载耗电在50mA以下,带64倍减速器,输出力矩比较大,可以驱动重负载,极适合开发板使用。注意:此款步进电机带有64倍减速器,与不带减速器的步进电机相比,转速显得较慢,为方便观察,可在输出轴处粘上一片小纸板。

首先我们来看一下28BYJ-48步进电机名称的来历。

  • 28:步进电机的有效最大外径是28毫米
  • B:表示是步进电机
  • Y:表示是永磁式
  • J:表示是减速型(减速比1:64)
  • 48:表示四相八拍

换句话说,28BYJ-48的含义为外径28毫米四相八拍式永磁减速型步进电机

回头看一下电机参数表中的减速比这个参数吧——1:64,转子转64圈,最终输出轴才会转一圈,也就是需要64×64=4096个节拍输出轴才转过一圈。4096个节拍转动一圈,那么一个节拍转动的角度——步进角度就是360/4096,看一下表中的步进角度参数5.625/64,算一下就知道这两个值是相等的,一切都已吻合了。

DSC03376.JPG

步进电机(五线四相)驱动板(UL2003)试验板

步进电机驱动板(UL2003)试验板

DSC03386.JPG

外形尺寸:31×35mm

硬件连接图如下

Snap1.jpg

img

把代码下载到arduino控制板中看看效果

/*
* 步进电机跟随电位器旋转
* (或者其他传感器)使用0号模拟口输入
* 使用arduino IDE自带的Stepper.h库文件
*/

#include <Stepper.h>

// 这里设置步进电机旋转一圈是多少步
#define STEPS 100

// attached to设置步进电机的步数和引脚
Stepper stepper(STEPS, 8, 9, 10, 11);

// 定义变量用来存储历史读数
int previous = 0;

void setup()
{
  // 设置电机每分钟的转速为90步
  stepper.setSpeed(90);
}

void loop()
{
  // 获取传感器读数
  int val = analogRead(0);

  // 移动步数为当前读数减去历史读数
  stepper.step(val - previous);

  // 保存历史读数
  previous = val;
}

文章作者: 葛杨文
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 葛杨文 !
评论
  目录