亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

LEGO Wall-E with Arduino

组件和用品

LEGO Wall-E
不得不得到一只第二只手,因为他们不再制造它们了
× 1
Arduino Nano R3
× 1
直流电机(通用)
× 2
L298N 双电机控制器
× 1
双色 LED
带 3 个引脚
× 1
红外线传感器
× 1
蜂鸣器
可以播放不同音调的
× 1
9V 电池
× 1
电阻 330 ohm
× 3
跳线(通用)
× 20

必要的工具和机器

烙铁(通用)

应用和在线服务

Arduino IDE

关于这个项目

每个人都知道电影 Wall-E(如果你不知道,现在就去看吧!)和试图清理地球的黄色英雄。在这个项目中,我用了我们小伙伴的乐高版,教他如何避开障碍物。这是我的第一个项目,也是了解电子学基础知识的绝佳学习经历。

第 1 步 - 代码

作为一名软件开发人员,我考虑过我想让他做什么,然后从代码开始。

 // 这个程序是控制 Wall-E 乐高机器人。// Wall-E 正在开车。当他看到障碍物时,他会停下来环顾四周并选择另一条路径。// Arduino Nano 有 21 个引脚可用于数字读取和数字写入// PWM 引脚 3、5、6、9、10、11 可用于模拟写入//引脚0和1可用于TTL//引脚2和3可用于外部中断//引脚10、11、12、13支持SPI通信//引脚13可以是内部LED//引脚14到21 也是模拟引脚 A0 到 A7,可用于analogRead#define INFRA_RED 9 // 可以是任何引脚#define GREEN_LED 7 // 可以是任何引脚,但需要电阻,也许 220 欧姆 - 或者接地引脚得到 1 kOhm#定义 RED_LED 8 // 可以是任何引脚,但需要电阻,可能是 220 欧姆 - 或者接地引脚获得 1 kOhm#define BUZZER 10 // 需要是 PWM 引脚来设置频率,需要电阻,也许是 1 kOhm // MR 是右电机,ML 是左电机#define MR_1 A1 // 可以是任意引脚,所以让它们对应于 L289N 屏蔽上的引脚编号#define MR_2 A2 // 可以是任意引脚,所以让它们对应于p在 L289N 屏蔽上的数字#define MR_ENABLE 5 // 需要是用于速度控制的 PWM 引脚#define ML_1 A3 // 可以是任何引脚,所以让我们使它们对应于 L289N 屏蔽上的引脚编号#define ML_2 A4 //可以是任何引脚,所以让我们让它们对应于 L289N 屏蔽上的引脚编号#define ML_ENABLE 6 // 需要是用于速度控制的 PWM 引脚 // 将他的正常速度设置为maximumconst int NORMAL_SPEED =255;void setup() { // 在按下重置按钮后,稍等片刻,这样我们就可以通过电压尖峰延迟(2000)将他关闭而不会损坏任何组件; // 初始化 LED 和蜂鸣器 pinMode(GREEN_LED, OUTPUT); pinMode(RED_LED, OUTPUT);// pinMode(BUZZER, OUTPUT); // 没有必要 // 将 LED 重置为绿色 digitalWrite(RED_LED, LOW);数字写入(绿色 LED,高); // 设置直流电机引脚 pinMode(MR_ENABLE, OUTPUT); // 电机右侧 pinMode(MR_1, OUTPUT); pinMode(MR_2,输出); pinMode(ML_ENABLE,输出); // 电机左 pinMode(ML_1, OUTPUT); pinMode(ML_2,输出); // 初始化红外线 pinMode(INFRA_RED, INPUT); // 为随机轮次初始化随机数生成器 randomSeed(analogRead(0)); // 说你好 playHello();}void loop() { // 正常操作 driveForwards(NORMAL_SPEED); // 将 LED 设置为绿色 digitalWrite(RED_LED, LOW);数字写入(绿色 LED,高); // 检查障碍物 if (digitalRead(INFRA_RED) ==LOW) { //LOW 表示检测到障碍物 // 将 LED 更改为红色 digitalWrite(GREEN_LED, LOW);数字写入(RED_LED,高); // 停止电机 stopDriving(); // 播放哦哦的声音 playUhOh(); // 检查左转左(500);布尔障碍左 =假;如果(digitalRead(INFRA_RED)==低){障碍左=真; } // 回到中心延迟(100);右转(500); // 稍等,我们不想显得匆忙 delay(500); // 检查右转右(500);布尔障碍右 =假;如果(digitalRead(INFRA_RED)==低){障碍右=真; } // 回到中心延迟(100);左转(500); // 现在检查如何离开这里 if (obstacleLeft &&barrierRight) { driveBackwards(NORMAL_SPEED / 3); // 后退时发出哔哔声 5 秒 for (int i =0; i <5; i++) {tone(BUZZER, 1000, 500);延迟(1000); } // 为了避免卡在某个地方,在继续旅程之前随机转向一个方向 randomTurn(800, 1600); } else if (obstacleLeft) { turnRight(1000); } else if (obstacleRight) { turnLeft(1000); } else { randomTurn(1000, 1800); } } // 做一些随机的事情以获得更多的互动 int number =random(100); // 创建一个 0 到 99 之间的随机数 if (number ==0) { randomTurn(200,2000); }}void driveForwards(int speed) { // 设置电机朝同一个方向运行 digitalWrite(MR_1, LOW);数字写入(MR_2,高);数字写入(ML_1,高);数字写入(ML_2,低); setSpeed(speed);}void driveBackwards(int speed) { // 设置电机向相反方向运行 digitalWrite(MR_1, HIGH);数字写入(MR_2,低);数字写入(ML_1,低);数字写入(ML_2,高); setSpeed(speed);}void turnLeft(int duration) { // 向右转左转,用左轮向后转 digitalWrite(MR_1, HIGH);数字写入(MR_2,低);数字写入(ML_1,高);数字写入(ML_2,低); // 减速转向 setSpeed(NORMAL_SPEED / 2);延迟(持续时间); stopDriving();}void turnRight(int duration) { // 用右轮向后转右转,用左轮向前转 digitalWrite(MR_1, LOW);数字写入(MR_2,高);数字写入(ML_1,低);数字写入(ML_2,高); // 减速转向 setSpeed(NORMAL_SPEED / 2);延迟(持续时间); stopDriving();}void stopDriving() { // 关闭所有电机引脚 digitalWrite(MR_1, LOW);数字写入(MR_2,低);数字写入(ML_1,低);数字写入(ML_2,低); // 不确定如何处理 ENABLE 引脚,但关闭它们也无妨,我猜digitalWrite(MR_ENABLE, LOW); digitalWrite(ML_ENABLE, LOW);}void setSpeed(int speed) { // 速度必须在 0 到 255 之间 speed =constrain(speed, 0, 255); // 在模拟写入(MR_ENABLE,速度)上设置打开电机的速度;模拟写入(ML_ENABLE,速度);}void randomTurn(int 最小值,int 最大值){ 无符号长时间 =毫秒(); int 持续时间 =随机(最小值,最大值); if (time % 2) { turnRight(duration); } else { 左转(持续时间); }}无效播放你好(){音(蜂鸣器,262,250); // 播放 C4 延迟(300);音调(蜂鸣器, 330, 250); // 播放 E4 延迟(300);音调(蜂鸣器,392, 250); // 播放 G4 延迟(300);音调(蜂鸣器,523, 500); // 播放 C5 delay(550);}void playUhOh() {tone(BUZZER, 523, 250); // 播放 C5 延迟(300);音调(蜂鸣器,415, 500); // 播放 Gis4 delay(600);} 

当您断开正在运行的电机时,可能会出现电压尖峰并损坏您的电子设备。因此,我让 Wall-E 在他做任何事情之前等待两秒钟。这意味着我只需按下 Arduino 上的“重置”按钮即可快速断开电池连接,而不会损坏任何东西。

他醒来时会演奏一段小曲子,然后开始开车。当他看到障碍物时,他会停下来,发出“哦”的声音,然后环顾四周以确定最佳方式。我使用的红外线传感器的背面有一个小螺丝,可以让您确定它产生信号的距离。这就是代码中没有距离计算的原因。 (我想先用超声波传感器,但不适合他的眼睛。)

Wall-E 首先检查左侧是否清晰,然后检查右侧是否清晰。如果两边都被挡住,他会像工地上的重型机械一样发出哔哔声,向后倒退,然后转向一个随机的方向继续前进。如果只有一侧被挡住,他会继续向另一侧前进。如果双方都有空,他就随机挑一个继续他的路。

我试图让他做随机转弯,但那部分还没有完全完成。我正在尝试使用内置的 Arduino 计时器。如果您有如何优化它的想法,请在评论中告诉我!

第 2 步 - 连接他

首先是将红外线传感器内置到眼睛中,使其看起来不会太明显。我把它拆开,用超级胶水将乐高别针粘在传感器上(这样他的眼睛可以上下移动),然后用蓝色钉将乐高积木放回传感器周围:

电机最重要的一点是它们有足够的扭矩,因为 Wall-E 车轮的设置需要相当大的力才能移动。我不得不将电线焊接到电机上,并以一种它们牢固地连接到乐高的方式连接它们。所以我把他的轮子拆开,订购了一整袋乐高机械销,用石膏胶带(你是这么叫的?它就像可以贴在你皮肤上的软胶带)缠在电机轴上,然后把它们粘在两个别针上这成为每个车轮的主轴。这工作了几分钟,但摩擦力太高,胶带中的胶水无法固定。幸运的是,Technic 针脚的侧面有小凹槽,所以胶带确实有一个固定的地方,他们在用强力胶浸泡后很高兴地做到了。

我还把他的胸膛切掉了一点,让 LED 穿过。然后我将所有部件和 Arduino 连接起来。

电机护罩只是 适合他的肚子:

图表也不是很清楚,但我尝试对电线进行颜色编码以获得更好的概览:

按照惯例,所有红线都是正极(“送”电),所有黑线都是负极(“接”电)。右上角的黄线承载红外线传感器的信号;橙色和绿色线用于三针双色 LED,紫色线用于告诉电机护罩将电机转动到哪个方向,蓝色电缆告诉电机护罩转动它们的速度。

电机屏蔽有一个非常好的教程,可以轻松连接和使用。不幸的是,Fritzing 部分没有用于设置速度的两个引脚,因此蓝色电缆只是随机结束在图中的电机屏蔽上。

我在将它们粘在一起时遇到的另一个问题是缺少电压和接地引脚。我想直接通过电机屏蔽为电机供电,这样它们就可以获得尽可能多的电力,但我不得不以某种方式向 Arduino 和红外传感器提供 5V 电压。所以我做了网络上几乎每个人都说我不应该做的事情:我将电机屏蔽的 5V 输出连接到 Arduino 的 5V 引脚作为输入。现在使用我正在使用的屏蔽罩,我可以绝对确定它输出稳定的 5V 电压,而没有任何可能损坏我的 Arduino 的讨厌的尖峰信号。如果您将不受监管的电源连接到该引脚,您可能会炸掉一些东西。我一开始想使用 Vin 引脚,但那个引脚有一个内置机制,可以调节一切,所以我的 5V 会变成 3.8V 左右,这不足以让 Arduino 正常运行。相反,我使用免费的 Vin 为(!)5V 红外线传感器供电,因为我没有任何电缆分路器,而且我知道那里也会有 5V 电压。是的,在这一点上它开始感觉有点像弗兰肯斯坦。但它奏效了!

第 3 步 - Wall-E 在行动

以下是一些显示他在行动的视频:

在这里,我测试了如果他被困在角落里会怎么做:

所以这是我的第一个小项目。我现在正计划优化电缆连接,并可能添加一个伺服电机,以便他可以转过头。我什至可能会买分流器和一个更小的电机护罩和电路板,这样我就可以把所有东西都塞进他的肚子里。

所以 Wall-E 住过 快乐 永远 之后。 结束。

代码

  • Wall_e_control
Wall_e_controlArduino
这是 Wall-E 的中央控制文件。这是基本的,但他现在需要的只是。
// 这个程序是控制 Wall-E 乐高机器人。// Wall-E 正在开车。当他看到障碍物时,他会停下来环顾四周并选择另一条路径。// Arduino Nano 有 21 个引脚可用于数字读取和数字写入// PWM 引脚 3、5、6、9、10、11 可用于模拟写入//引脚0和1可用于TTL//引脚2和3可用于外部中断//引脚10、11、12、13支持SPI通信//引脚13可以是内部LED//引脚14到21 也是模拟引脚 A0 到 A7,可用于模拟读取#define INFRA_RED 9 // 可以是任何引脚#define GREEN_LED 7 // 可以是任何引脚,但需要电阻,可能是 220 欧姆 - 或者接地引脚得到 1 kOhm#定义 RED_LED 8 // 可以是任何引脚,但需要电阻,可能是 220 欧姆 - 或者接地引脚获得 1 kOhm#define BUZZER 10 // 需要是 PWM 引脚来设置频率,需要电阻,也许是 1 kOhm // MR 是右电机,ML 是左电机#define MR_1 A1 // 可以是任意引脚,所以让它们对应于 L289N 屏蔽上的引脚编号#define MR_2 A2 // 可以是任意引脚,所以让它们对应于p在 L289N 屏蔽上的数字#define MR_ENABLE 5 // 需要是用于速度控制的 PWM 引脚#define ML_1 A3 // 可以是任何引脚,所以让我们使它们对应于 L289N 屏蔽上的引脚编号#define ML_2 A4 //可以是任何引脚,所以让我们让它们对应于 L289N 屏蔽上的引脚编号#define ML_ENABLE 6 // 需要是用于速度控制的 PWM 引脚 // 将他的正常速度设置为maximumconst int NORMAL_SPEED =255;void setup() { // 在按下重置按钮后,稍等片刻,这样我们就可以通过电压尖峰延迟(2000)将他关闭而不会损坏任何组件; // 初始化 LED 和蜂鸣器 pinMode(GREEN_LED, OUTPUT); pinMode(RED_LED, OUTPUT);// pinMode(BUZZER, OUTPUT); // 没有必要 // 将 LED 重置为绿色 digitalWrite(RED_LED, LOW);数字写入(绿色 LED,高); // 设置直流电机引脚 pinMode(MR_ENABLE, OUTPUT); // 电机右侧 pinMode(MR_1, OUTPUT); pinMode(MR_2,输出); pinMode(ML_ENABLE,输出); // 电机左 pinMode(ML_1, OUTPUT); pinMode(ML_2,输出); // 初始化红外线 pinMode(INFRA_RED, INPUT); // 为随机轮次初始化随机数生成器 randomSeed(analogRead(0)); // 说你好 playHello();}void loop() { // 正常操作 driveForwards(NORMAL_SPEED); // 将 LED 设置为绿色 digitalWrite(RED_LED, LOW);数字写入(绿色 LED,高); // 检查障碍物 if (digitalRead(INFRA_RED) ==LOW) { //LOW 表示检测到障碍物 // 将 LED 更改为红色 digitalWrite(GREEN_LED, LOW);数字写入(RED_LED,高); // 停止电机 stopDriving(); // 播放哦哦的声音 playUhOh(); // 检查左转左(500);布尔障碍左 =假;如果(digitalRead(INFRA_RED)==低){障碍左=真; } // 回到中心延迟(100);右转(500); // 稍等,我们不想显得匆忙 delay(500); // 检查右转右(500);布尔障碍右 =假;如果(digitalRead(INFRA_RED)==低){障碍右=真; } // 回到中心延迟(100);左转(500); // 现在检查如何离开这里 if (obstacleLeft &&barrierRight) { driveBackwards(NORMAL_SPEED / 3); // 后退时发出哔哔声 5 秒 for (int i =0; i <5; i++) {tone(BUZZER, 1000, 500);延迟(1000); } // 为了避免卡在某个地方,在继续旅程之前随机转向一个方向 randomTurn(800, 1600); } else if (obstacleLeft) { turnRight(1000); } else if (obstacleRight) { turnLeft(1000); } else { randomTurn(1000, 1800); } } // 做一些随机的事情以获得更多的互动 int number =random(100); // 创建一个 0 到 99 之间的随机数 if (number ==0) { randomTurn(200,2000); } }void driveForwards(int speed) { // 设置电机朝同一方向运行 digitalWrite(MR_1, LOW);数字写入(MR_2,高);数字写入(ML_1,高);数字写入(ML_2,低); setSpeed(speed);}void driveBackwards(int speed) { // 设置电机向相反方向运行 digitalWrite(MR_1, HIGH);数字写入(MR_2,低);数字写入(ML_1,低);数字写入(ML_2,高); setSpeed(speed);}void turnLeft(int duration) { // 向右转左转,用左轮向后转 digitalWrite(MR_1, HIGH);数字写入(MR_2,低);数字写入(ML_1,高);数字写入(ML_2,低); // 减速转向 setSpeed(NORMAL_SPEED / 2);延迟(持续时间); stopDriving();}void turnRight(int duration) { // 用右轮向后转右转,用左轮向前转 digitalWrite(MR_1, LOW);数字写入(MR_2,高);数字写入(ML_1,低);数字写入(ML_2,高); // 减速转向 setSpeed(NORMAL_SPEED / 2);延迟(持续时间); stopDriving();}void stopDriving() { // 关闭所有电机引脚 digitalWrite(MR_1, LOW);数字写入(MR_2,低);数字写入(ML_1,低);数字写入(ML_2,低); // 不确定如何处理 ENABLE 引脚,但关闭它们也无妨,我猜digitalWrite(MR_ENABLE, LOW); digitalWrite(ML_ENABLE, LOW);}void setSpeed(int speed) { // 速度必须在 0 到 255 之间 speed =constrain(speed, 0, 255); // 在模拟写入(MR_ENABLE,速度)上设置打开电机的速度;模拟写入(ML_ENABLE,速度);}void randomTurn(int 最小值,int 最大值){ 无符号长时间 =毫秒(); int 持续时间 =随机(最小值,最大值); if (time % 2) { turnRight(duration); } else { 左转(持续时间); }}无效播放你好(){音(蜂鸣器,262,250); // 播放 C4 延迟(300);音调(蜂鸣器, 330, 250); // 播放 E4 延迟(300);音调(蜂鸣器,392, 250); // 播放 G4 延迟(300);音调(蜂鸣器,523, 500); // 播放 C5 delay(550);}void playUhOh() {tone(BUZZER, 523, 250); // 播放 C5 延迟(300);音调(蜂鸣器,415, 500); // 播放 Gis4 delay(600);}

示意图

电缆颜色的含义:
红色 =电压(正极)
黑色 =地(负)
黄色 =红外线传感器信号
橙色和绿色 =红色和绿色 LED 输入的连接
紫色 =电机方向控制
蓝色 =电机速度控制(不幸的是,Fritzing 部分没有我的电机桥用于这些连接的两个引脚,所以目前看起来像松散的电线) wall-e2_3P6X71BCnP.fzz

制造工艺

  1. 使用 K30 传感器监测二氧化碳
  2. 聋盲通信与 1Sheeld/Arduino
  3. 使用 Arduino 控制硬币接收器
  4. 自动乐高射击游戏
  5. 带伺服电机的机器人避障
  6. Arduino 带蓝牙控制 LED!
  7. 带有 Arduino 或 ESP8266 的电容式指纹传感器
  8. 线跟随机器人
  9. 玩 Nextion Display
  10. Nunchuk 控制机械臂(使用 Arduino)
  11. 使用 Arduino 和 MPU6050 控制伺服电机
  12. Arduino 培训平台