本网页已闲置超过3分钟,按键盘任意键或点击空白处,即可回到网页
最热资讯


亲,“电路城”已合并升级到更全、更大、更强的「新与非网」。点击查看「新与非网」
你有没有想过开发一个项目并能够将机械、电子、传感器和编程结合起来?
在本文中,我们将教您如何使用Arduino创建电梯项目以及如何使用屏蔽板连接和控制项目中的所有设备。
您想知道如何创建上述所有结构并开发自己的电梯制造商吗?看过这篇文章,相信你可以学习到如何使用 Arduino 完成完整的电梯时间表。
为什么要使用 Arduino 开发电梯?
在许多地方,电梯用于允许建筑物的用户在不同楼层之间移动。
电梯是通过在其结构中使用多个传感器而具有高度安全性的设备。
除了用于运送人员之外,一些地方还使用电梯作为建筑工地、餐厅、接收产品交付等的货物处理平台。
学习如何建造自己的电梯将帮助您了解:
电梯是如何工作的
有很多经验可以帮助您构建自己的电梯结构。
此外,您将开发编程逻辑,这是任何电子和自动化专业人士的基本点。
Arduino电梯结构
下图显示了项目的完整结构。电梯由4层楼和一个控制接口组成。
控制界面由 4 个按钮和一个 20x4 的 LCD 组成。用户将能够通过每个按钮控制电梯位置,并在结构的显示屏上接收系统信息。
控制箱连接到电梯的后部。见下图。
电线进入这个背面区域并与负责处理编程逻辑的 Arduino 连接。
此外,电梯结构的创建是为了方便其编程,并允许用户在编程过程中不要移除 Arduino。
下面是电梯结构中 Arduino 的图像。如您所见,可以访问 Arduino 的 USB 端口和用于电源的插孔连接器。
所有电子设备都通过使用此扩展板连接到 Arduino。如下图所示。
为什么在 Arduino UNO 上使用 Shield
如果您在项目中不使用屏蔽,将会出现两个大问题:焊料连接错误以及缺少传感器和其他设备的电源端子。
让我们了解如何解决这两个问题?
例如,看看项目的传感器。我们有 4 个传感器来检测电梯的位置。见下图。
总共有 4 个 GND 和 4 根电线用于 +5V 连接。不幸的是,我们知道 Arduino 只有 2 个 GND 端子和 1 个 +5V 的连接引脚。
这迫使我们将这些电线焊接在一起并连接到这些端子。
但是,在某些情况下,会出现焊接连接问题,并且项目中的设备无法正常工作。这需要时间并阻止您继续前进。
为了防止出现此问题并扩展电源引脚以更轻松地连接所有设备,我们为 Arduino UNO 创建了 Shield。
您可以使用 Arduino UNO 将其应用于任何项目。
接下来,我们将找出项目中的哪些电子设备将连接到 Arduino 的 Shield 电路板。
项目电子设备与 Shield Arduino 的连接
该项目由几个电子设备组成。其中,我们重点介绍了 L293D 驱动器和直流电机。
L293D 驱动器和直流电机
Arduino 将发送命令来激活 L293D 驱动器并转动直流电机以移动电梯箱。
我们将在电机轴和电梯箱上放置一条尼龙线以进行牵引。
在旋转过程中,线会缠绕在电机轴架上。见下图。
这样我们就可以上下移动电梯。但是,我们有一个问题:我们怎么知道电梯是否到达了4层的每个位置?
这就是为什么我们应该使用簧片开关传感器。它们将使我们能够在电梯移动时检测到它的位置。
用于检测电梯位置的簧片开关传感器
在下图中,我们展示了 4 个簧片开关传感器。
它们在检测到附近存在磁场时触发,并将向 Arduino 的数字引脚发送高逻辑电平信号。
我们将使用连接到电梯井后部的磁铁在每个传感器移动时触发它。
在下图中,我们有一层电梯井的结构。
可以看出,在电梯结构中实现了直线导轨。它们旨在提高电梯运动的稳定性并防止其运动过程中的振动。
因此,这改进了传感器对电梯位置的检测。
下面我们有另一个线性导轨结构的图像。
电梯位置由项目控制界面上的按钮选择。接下来,我们将介绍控制界面的结构。
Arduino电梯控制接口
这种结构是为了方便电梯控制而开发的。它由一个 20x4 的 LCD 和 4 个按钮组成。
按钮用于请求电梯到所需位置。
LCD 旨在允许系统和用户之间交换数据。通过它,我们将能够呈现各种信息:
所使用的 LCD 具有 SERIAL-I2C 转换器,以减少导线数量和与屏蔽板电气连接的复杂性。
现在,我们将看看如何创建编程逻辑来控制我们的 JLCPCB Arduino 电梯的运动。
Arduino电梯控制逻辑
现在您了解了电梯结构是如何构建的,让我们了解如何使用编程逻辑来控制它。
有多种方法可以创建编程逻辑来控制电梯的运动。我们的逻辑将如下所示工作。
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//Inicializa o display no endereco 0x27
LiquidCrystal_I2C lcd(0x27,20,4);
//Variavel para controlar a entrada no loop
bool controle = 0;
bool not_pos = 0;
//Variaveis de controle para iteracao nos lacos for
int i = 0, j = 0;
//Variaveis utilizadas para armazenar a atual posicao do elevador e a posicao desejada pelo usuario
int actual_pos = 0, des_pos = 0;
//Vetores para armazenar as posicoes do elevador (sensor) e a posicao desejada pelo usuario (pedido)
int sensor[4];
int pedido[4];
//Inicio da funcao void setup
void setup()
{
// Initialization of 20x4 LCD
lcd.begin (20,4); //Inicializa o Display de LCD
// Initializing the 20x4 LCD
lcd.init();
//LCD Backlight Activation
lcd.backlight();
// Activating the cursor to the 0.0 position of the 20x4 LCD
lcd.setCursor(0,0);
//Configurando os pinos dos botoes como entrada e pull up
for(int i = 2; i <= 5; i++)
{
pinMode(i, INPUT_PULLUP);
}
//Configurando os pinos dos botoes como entrada e pull up
for(int i = 6; i <= 10; i++)
{
pinMode(i, INPUT);
}
for(int i = 0; i<4; i++)
{
pedido[i] = 1;
}
//Configuracao dos pinos de controle dos motores como saidas digitais
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
//Comandos para que o motor fique parado
digitalWrite(10, LOW);
digitalWrite(11, LOW);
}
void loop()
{
//Leitura dos botoes selecionados pelo usuario do elevador
for(int botao = 2; botao < 6; botao++)
{
//Armazena o estado de cada botao no vetor pedido
pedido[botao-2] = digitalRead(botao);
//Verifica qual o andar desejado para o elevador subir
if(pedido[botao-2] == 0)
{
des_pos = botao - 1;
controle = 0;
}
}
//Verifica se um dos botoes foi pressionado e se a variavel de controle possui valor igual a 0
if((pedido[0] == 0 || pedido[1] == 0 || pedido[2] == 0 || pedido[3] == 0) && controle == 0)
{
//Set a value of 1 to the control variable to allow the code stream to enter the condition only once
controle = 1;
//Execute the loop commands while the control variable is equal to 1
//Reading of all sensors to determine the current position of the elevator
for(int sens = 6; sens < 10; sens++)
{
sensor[sens-6] = digitalRead(sens);
}
//Comparing the current elevator position with the desired position
for(i = 0; i<4; i++)
{
if(sensor[i] == 1)
{
break;
}
}
for(j = 0; j<4; j++)
{
if(pedido[j] == 0)
{
break;
}
}
if(j == i)
{
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
}
if(j < i)
{
digitalWrite(10, LOW);
digitalWrite(11, HIGH);
}
if(j > i) //2 > 0
{
digitalWrite(10, HIGH);
digitalWrite(11, LOW);
}
controle = 0;
not_pos = 0;
while(not_pos != 1)
{
//Determinando a posicao atual do elevador
for(int sens = 6; sens < 10; sens++)
{
bool s = digitalRead(sens);
if(s == 1)
{
actual_pos = sens - 5;
}
}
if(actual_pos == des_pos)
{
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
not_pos = 1;
for(int i = 0; i<4; i++)
{
pedido[i] = 1;
sensor[i] = 0;
}
break;
}
}
}
}
接下来,我们将解释该项目的编程逻辑。
最初,我们插入了库来处理 LCD 功能、I2C 通信,并创建了 LCD 对象。
LCD 已配置为 20x4,I2C 通信地址为 0x27。
声明项目中使用的所有变量和向量。
之后,我们有设置功能。执行设置功能以初始化 LCD 并将数字引脚配置为输入和输出以控制项目的设备。
例如,在这些设备中,我们有直流电机、簧片开关传感器和控制按钮。
//Start of void setup function
void setup()
{
// Initialization of 20x4 LCD
lcd.begin (20,4); //Inicializa o Display de LCD
// Initializing the 20x4 LCD
lcd.init();
//LCD Backlight Activation
lcd.backlight();
// Activating the cursor to the 0.0 position of the 20x4 LCD
lcd.setCursor(0,0);
//Configuring button pins as input and pull up for the buttons
for(int i = 2; i <= 5; i++)
{
pinMode(i, INPUT_PULLUP);
}
//Configuring button pins as input for the sensors
for(int i = 6; i <= 10; i++)
{
pinMode(i, INPUT);
}
for(int i = 0; i<4; i++)
{
pedido[i] = 1;
}
//Configuration of motor control pins as digital outputs
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
//Commands for the engine to stop
digitalWrite(10, LOW);
digitalWrite(11, LOW);
}
现在让我们讨论循环函数。我们实现了电梯控制的完整逻辑。
void loop()
{
//Leitura dos botoes selecionados pelo usuario do elevador
for(int botao = 2; botao < 6; botao++)
{
//Armazena o estado de cada botao no vetor pedido
pedido[botao-2] = digitalRead(botao);
//Verifica qual o andar desejado para o elevador subir
if(pedido[botao-2] == 0)
{
des_pos = botao - 1;
controle = 0;
}
}
//Verifica se um dos botoes foi pressionado e se a variavel de controle possui valor igual a 0
if((pedido[0] == 0 || pedido[1] == 0 || pedido[2] == 0 || pedido[3] == 0) && controle == 0)
{
//Set a value of 1 to the control variable to allow the code stream to enter the condition only once
controle = 1;
//Reading of all sensors to determine the current position of the elevator
for(int sens = 6; sens < 10; sens++)
{
sensor[sens-6] = digitalRead(sens);
}
//Comparing the current elevator position with the desired position
for(i = 0; i<4; i++)
{
if(sensor[i] == 1)
{
break;
}
}
for(j = 0; j<4; j++)
{
if(pedido[j] == 0)
{
break;
}
}
if(j == i)
{
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
}
if(j < i)
{
digitalWrite(10, LOW);
digitalWrite(11, HIGH);
}
if(j > i) //2 > 0
{
digitalWrite(10, HIGH);
digitalWrite(11, LOW);
}
controle = 0;
not_pos = 0;
while(not_pos != 1)
{
//Determinando a posicao atual do elevador
for(int sens = 6; sens < 10; sens++)
{
bool s = digitalRead(sens);
if(s == 1)
{
actual_pos = sens - 5;
}
}
if(actual_pos == des_pos)
{
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
not_pos = 1;
for(int i = 0; i<4; i++)
{
pedido[i] = 1;
sensor[i] = 0;
}
break;
}
}
}
}
第一个活动是读取 4 个按钮并将它们的状态存储在“pedido”向量中。
在循环内部,我们通过按下的按钮检查需要哪个楼层。
以下条件检查是否按下了其中一个按钮以及控制变量是否等于 1。
“controle”变量用于允许在按下其中一个按钮时执行一次条件代码。
当电梯到达用户选择的位置时,码流会重新进入该状态。
以下循环用于读取当前的电梯位置和用户所需的楼层。
这两条信息将用于确定电机向上或向下到所需楼层的旋转方向。
我们有3个条件。请参阅下面的代码块。它们将在下面解释。
当 j 等于 i 时,表示电梯已经在用户请求的楼层上。在这种情况下,发动机必须保持停止状态。
当 j 小于 I 时,表示电梯位于用户请求的上方位置。在这种情况下,电机必须旋转才能降低电梯。
最后,我们有最后一个条件,即 j 大于 i。在这种情况下,电梯位于用户请求的位置下方。
因此,电机必须转动才能使电梯上升。
下一步是监控电梯的位置,并在到达用户选择的楼层时停止电机。
这个过程是通过读取传感器来完成的。请参阅下面的代码块。
只要 not_pos 变量不等于 1,代码就会执行。当电梯到达所需位置时,该变量的值将从 0 变为 1。
下面的条件用于读取电梯的当前位置。
如果为真,则直流电机必须进入和退出回路。
之后,它会退出while,返回到void loop函数的开头,等待用户选择一个新的位置。
这是设计用于控制 Arduino 电梯的整个结构。
您可以测试其他逻辑编程并在您的项目中实现新功能。
如果您对此项目有任何想法、意见或问题,请在下方留言。
基于 Arduino Uno 的太阳能充电电池供电
2021-11-20
基于 Arduino UNO 的倒数计时器
2021-10-28
基于 Arduino 的DIY自动喂鱼器
2021-10-31
基于 Arduino Uno 对 ATtiny85进行编程
2021-11-08
基于Arduino的两个创意产品diy-机器人小车以及红外激光安全系统
2019-11-04
讨论 (1)
dragon6663 · 2022-03-13
挺好的,就是变量名设置的有点迷
回复 展开