搜索代码

第22/31课:使用Arduino和电子骰子驱动七段数码管 | SunFounder Robojax

第22/31课:使用Arduino和电子骰子驱动七段数码管 | SunFounder Robojax

在本课中,我们将探索如何用Arduino控制七段数码管。我们不是用十几个或更多的I/O引脚直接驱动每个LED段,而是采用一个巧妙的技巧:移位寄存器。这颗小巧且廉价的芯片让我们只需使用Arduino的三根线就能控制所有七个段(加上小数点)。这是电子学中的一项基础技术,它允许你扩展微控制器上可用的输出数量,从而无需升级开发板就能构建更复杂的项目。

视频中的面包板接线

除了基本的计数器之外,我们还将构建一个电子骰子。这个项目不仅强化了显示控制,还通过按钮引入了用户输入以及中断的概念,打造出一个响应迅速且交互性强的设备。本指南基于Robojax Arduino课程中的一课,该课程使用SunFounder三合一Arduino套件。

以下是一些你可以利用这些知识构建的实用创意:

  • 创建简易记分牌,用于乒乓球或篮球等游戏。
  • 构建数字计时器,用于桌游或厨房倒计时。
  • 制作随机数生成器,用于游戏或决策。
  • 构建基础数字温度计,只需添加一个温度传感器。

硬件与组件

在开始之前,让我们准备好所需组件。这个项目的核心是74HC595移位寄存器,它是最大限度减少所需引脚数的关键。我们不是将七个段中的每一个直接连接到Arduino,而是将它们连接到移位寄存器。Arduino随后将数字数据串行(一次一位)发送到芯片,芯片再输出正确的模式来点亮各段。

  • Arduino Uno(或兼容开发板)
  • 七段数码管(型号5161AS,共阴极)
  • 74HC595移位寄存器IC
  • 按钮
  • 电阻(220Ω - 330Ω)
  • 跳线
  • 面包板

5161AS数码管是共阴极类型。这意味着内部所有LED的阴极(负极)都连接到一个公共接地引脚。要点亮某段,你需要向其特定的阳极引脚提供正电压。74HC595充当桥梁,接收来自Arduino的串行数据,并输出驱动这些阳极所需的并行信号。

接线指南

电路_6.5_段_原理图
段_接线_sundounder_三合一套件

连接移位寄存器和数码管看似棘手,但按图逐步操作至关重要。视频(04:48处)提供了这一过程的详细讲解。74HC595芯片一端有一个缺口,用于识别引脚1。引脚从缺口处逆时针编号(一侧为1-8,另一侧为9-16)。

以下是视频中的接线摘要:

  • 电源与接地:将74HC595的引脚8和引脚13连接到接地轨。将引脚10和引脚16连接到5V轨。
  • 数据线:将Arduino的数字引脚连接到移位寄存器的数据引脚:引脚12(STcp)连接到芯片引脚12,引脚8(SHcp)连接到芯片引脚11,引脚11(DS)连接到芯片引脚14。
  • 数码管到移位寄存器:这是最复杂的部分。视频(07:18处)详细说明了每个连接。例如,数码管上的段'a'连接到芯片引脚6,段'b'连接到引脚5,依此类推。数码管的共阴极引脚通过电阻连接到地。

如需直观且精确的指南,请参考官方接线图:

确切的引脚连接至关重要,而且很容易出错。请花时间对照图表逐一检查每根线。视频是很好的跟随学习资源。

骰子

代码解释

本课提供了两个代码示例。第一个是简单的计数器,第二个在其基础上构建电子骰子。两者共享相同的控制显示的核心逻辑。

以下是基本计数器的代码:

const int STcp = 12;//连接到74HC595的ST_CP的引脚
const int SHcp = 8;//连接到74HC595的SH_CP的引脚 
const int DS = 11; //连接到74HC595的DS的引脚 

int datArray[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

在代码顶部,你可以配置连接到移位寄存器的三个引脚。STcpSHcpDS分别分配给Arduino的引脚12、8和11。datArray[]是关键部分。它是一个查找表,包含数字0到9的十六进制值。每个值代表该特定数字要点亮的段模式。

loop()函数运行计数器。它使用一个for循环从0数到9。在循环内部,代码将当前数字的数据发送到移位寄存器。末尾的delay(1000)以毫秒为单位设置计数器的速度。将此值改为100可加快计数,改为500则可减慢计数。

电子骰子代码引入了一个新元素:通过按钮进行用户输入。关键的配置更改如下:

const int buttonPin = 2;
//...
pinMode(buttonPin, INPUT);
attachInterrupt(digitalPinToInterrupt(buttonPin), rollDice, FALLING);

这里,buttonPin被设置为数字引脚2。这个引脚很特殊,因为它可以用作中断。中断允许Arduino在按下按钮时立即停止当前操作,确保快速可靠的响应。FALLING模式在按钮被按下时(信号从高电平变为低电平)触发中断。

rollDice函数由中断调用。它在0和1之间切换state变量。当state为0时,骰子处于“滚动”状态,主loop()函数将随机显示数字。当再次按下按钮时,state变为1,停止循环并显示最终结果。showNumber()函数与计数器逻辑相同,但它接受一个数字作为参数来显示。

实际项目与演示

代码上传后,计数器将开始运行,以一秒的延迟显示从0到9的数字(视频中15:04处)。视频演示了更改延迟以使计数器运行得更快。

电子骰子演示(视频中20:15处)展示了按钮的实际操作。当你按下一次按钮时,显示屏开始快速循环显示数字。再次按下按钮则停止循环,留下一个1到6之间的随机数字显示,就像真正的骰子一样。

章节

  • [00:00] 七段显示屏项目介绍
  • [01:25] 了解七段显示屏
  • [03:51] 5161AS显示屏数据手册与规格
  • [04:48] 连接显示屏和移位寄存器
  • [12:24] 0-9计数器的Arduino代码
  • [15:04] 计数器演示与速度调整
  • [16:27] 构建电子骰子项目
  • [20:15] 电子骰子演示与去抖动

图像

Wiring on breadboard from video
Wiring on breadboard from video
Circuit 6.5 segment schematic
Circuit 6.5 segment schematic
Dice
Dice
Segment wiring for Sunfounder 3-in-1 kit
Segment wiring for Sunfounder 3-in-1 kit
Segments of segment display
Segments of segment display
Seven segment pins - common cathode
Seven segment pins - common cathode
Seven segment pins - DP decimal pin
Seven segment pins - DP decimal pin
Seven segment pins - common cathode
Seven segment pins - common cathode
902-Lesson 23/31: Arduino code Using Seven Segment Display
语言: C++
/*
Lesson 23/31: Using Seven Segment Display 
Get this code and watch video Download and resource page https://robojax.com/RJT605
YouTube video https://www.youtube.com/watch?v=3qoGAYh0lbc

*/
const int STcp = 12;//Pin connected to ST_CP of 74HC595
const int SHcp = 8;//Pin connected to SH_CP of 74HC595 
const int DS = 11; //Pin connected to DS of 74HC595 

int datArray[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

void setup ()
{
  //set pins to output
  pinMode(STcp,OUTPUT);
  pinMode(SHcp,OUTPUT);
  pinMode(DS,OUTPUT);
}
void loop()
{
  for(int num = 0; num <10; num++)
  {
    digitalWrite(STcp,LOW); //ground ST_CP and hold low for as long as you are transmitting
    shiftOut(DS,SHcp,MSBFIRST,datArray[num]);
    digitalWrite(STcp,HIGH); //pull the ST_CPST_CP to save the data
    delay(1000);
  }
}
903-Lesson 23/31: Electronic dice
语言: C++
/*
Lesson 23/31: Electronic Dice
Get this code and watch video Download and resource page https://robojax.com/RJT605
YouTube video https://www.youtube.com/watch?v=3qoGAYh0lbc

*/
const int STcp = 12;//Pin connected to ST_CP of 74HC595
const int SHcp = 8;//Pin connected to SH_CP of 74HC595
const int DS = 11; //Pin connected to DS of 74HC595
const int buttonPin = 2;
int datArray[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f,  0x6f};
int number = 0;
int state = 0;

void setup ()
{
  //set pins to output
  pinMode(STcp, OUTPUT);
  pinMode(SHcp, OUTPUT);
  pinMode(DS, OUTPUT);
  pinMode(buttonPin, INPUT);

  attachInterrupt(digitalPinToInterrupt(buttonPin), rollDice, FALLING);
}

void loop()
{
  if (state == 0) {
    showNumber((int)random(1, 7));
    delay(50);
  }
}

void showNumber(int num) {
  digitalWrite(STcp, LOW); //ground ST_CP and hold low for as long as you are transmitting
  shiftOut(DS, SHcp, MSBFIRST, datArray[num]);
  //return the latch pin high to signal chip that it
  //no longer needs to listen for information
  digitalWrite(STcp, HIGH); //pull the ST_CPST_CP to save the data
}


void rollDice() {
  state = !state;
}

文件📁

Arduino 库(zip 格式)