3D打印电子动画眼睛与Arduino
在这个项目中,我们将用Arduino构建一个电子动画的眼睛。首先,它看起来很酷,并且具有简单的机制,我在从事这个项目时学到了很多关于机电一体化的知识。这个电子动画眼睛设计有两个版本,一个是简单版本,一个是高级版本,对于这个项目,我们想构建简单的一个,在这个过程中,我们会让你知道构建体验以及我们遇到的问题。
该项目的BOM非常小,因为所有艰苦的工作都是由3D打印机完成的,我们只需要一些螺丝和粗体,其中大部分都可以在当地的业余爱好商店中找到。下面给出了 BOM 的完整列表。
要处理这个项目,我们需要首先打印所有3D模型,您可以在Ikkalebob instructables中找到3D模型。打印完所有3D部件后,您需要打磨眼睛和其他一些所必需的部件,一旦这些部件完成,我们就可以继续进行组装过程。如果您已正确打印每个部件,则您的产品应类似于下图。
我们将通过将6个伺服电机中的5个连接到Servo_Block模块,如下图所示。
现在,我们将Servo_Block连接到Main_Base该Main_Base如下所示。我们还使用了四个12mm M3内六角螺钉来制作设备的支腿。
接下来,我们将双眼的Fork连接Eye_Adaptor。完成后,我们将把Eye_Holder与Eye_adaptor连接,将Three-point_Connector与Fork连接。完成所有这些过程后,它将如下图所示。
完成此操作后,我们将第六个和最后一个伺服器连接到Sub_Base然后用螺钉将Sub_Base连接到Main_Base。在此之后,我们将 PlaceHolder Eye 连接到Eye_Adaptor。我们还用螺钉连接了 X 臂和 Y 臂。
现在,我们将眼睑(Eyelid)连接器连接到Eyelid,并使用M3螺钉从两侧将眼睑固定到位。
如果您正确完成了所有操作,图像将看起来像上面显示的图像,您可以看到我们已经将所有眼睑与眼睑连接器连接在一起,并且我们已经用伺服电机的臂拧紧了它们。完成此操作后,我们可以进入编码过程。
DIY 3D打印电子动画眼睛的示意图如下所示,如您所见,它非常简单易懂。虽然PCA9685 IC(一个16通道12位PWM伺服电机驱动器)在项目设计者和作者提供的原理图中使用,但我们不会将其用于该项目,因为Arduino的Servo库可以轻松处理六个Servo。
如前所述,硬件连接非常简单。我们使用Arduino的六个引脚来控制六个伺服电机。如果我们快速浏览一下Arduino的规格,您可以看到Arduino有六个PWM引脚,我们正在使用所有这些引脚来控制所有六个伺服电机。
电子动画眼Arduino代码非常简单易懂。为了使此代码正常工作,我们将使用Arduino的Servo.h库。
我们通过包含所需的库并定义控制所有六个伺服电机所需的所有实例来开始我们的代码。
#include
Servo top_left_eyelid;
Servo bottom_left_eyelid;
Servo top_right_eyelid;
Servo bottom_right_eyelid;
Servo Yarm;
Servo Xarm;
接下来,在setup**()** 设置函数中,我们声明了眼睛的哪个部分连接到Arduino的哪个引脚。这非常有用,因为我们可以将所有连接器并完全按照原样连接它。
top_left_eyelid.attach(10);
bottom_left_eyelid.attach(11);
top_right_eyelid.attach(5);
bottom_right_eyelid.attach(6);
Yarm.attach(9);
Xarm.attach(3);
接下来,我们初始化串行以进行调试,并调用一些函数以保持眼睛睁开和合,并且我们还添加了一些延迟以保持稳定性。
Serial.begin(9600);
open_eye();
eye_ball_centert();
delay(2000);
接下来,是 loop() 函数,但在解释循环函数之前,我们将解释一些更重要的函数,这些函数对于理解循环函数中的内容是必要的。这些功能是最重要的功能,有了这些功能,我们将移动系统的眼球。首先,我们有**open_eye()**函数。如果您查看硬件,则需要顺时针方向移动一个伺服器,逆时针方向移动另一个伺服器,我们将对左右眼睑(eyelid)执行相同的操作。
void open_eye() {
top_left_eyelid.write(55);
bottom_left_eyelid.write(36);
top_right_eyelid.write(2);
bottom_right_eyelid.write(160);
}
接下来是close_eye() 函数,在close_eye函数中,我们将执行与open_eye函数完全相同的事情,但相反。
void close_eye() {
top_left_eyelid.write(2);
bottom_left_eyelid.write(120);
top_right_eyelid.write(46);
bottom_right_eyelid.write(55);
}
接下来,我们有look_up() 和 look_down() 函数。如果您查看硬件,移动设备的Y臂将上下移动眼球。
void look_up() {
Yarm.write(132);
}
void look_down() {
Yarm.write(45);
}
接下来,我们有**eye_ball_left()和eye_ball_right()**函数,它与向上和向下函数相同,唯一的区别在于设备的角度。
void eye_ball_left() {
Xarm.write(50);
}
void eye_ball_right() {
Xarm.write(130);
}
接下来我们有**eye_ball_centert()**函数。在这个函数中,我们将X臂和Y臂设置为90度角,以便我们可以将眼睛移动到头部中心。
void eye_ball_centert() {
Xarm.write(90);
Yarm.write(90);
}
现在我们还有其他一些我写的函数,让我们的生活更轻松。在该列表中,我们首先有**synchronous_close()**函数,调用此函数将关闭并打开一次眼睛。
void synchronous_close() {
close_eye();
delay(420);
open_eye();
delay(222);
}
然后我们有**random_close()**函数,它将随机打开和关闭眼睛。这将产生很酷的效果。
void random_close() {
close_eye();
delay(random(220, 880));
open_eye();
delay(random(220, 880));
}
接下来,我们有**random_movement()函数。在这个函数中,我们在延迟函数中使用了Arduino的random()**函数,使眼睛随机移动。
void random_movement() {
Xarm.write(60);
delay(random(250, 340));
Yarm.write(80);
delay(random(250, 340));
Xarm.write(120);
delay(random(250, 340));
Yarm.write(140);
Xarm.write(60);
delay(random(250, 340));
Yarm.write(80);
delay(random(250, 340));
Xarm.write(120);
delay(random(250, 340));
Yarm.write(140);
eye_ball_centert();
delay(300);
synchronous_close();
random_close();
}
现在我们将解释void loop
函数,它是Arduino的主要函数。在这个函数中,我们将眼睛向左,向右,向中间移动,然后上下移动,然后我们将使眼睛眨眼。我们将这样做几次,并做出随机运动。最后,我们有两个 for 循环。for循环是关于如何实现平滑运动或移动眼球的示例。
void loop() {
eye_ball_left();
delay(680);
eye_ball_right();
delay(680);
eye_ball_centert();
delay(450);
synchronous_close();
eye_ball_centert();
delay(450);
look_up();
delay(400);
look_down();
delay(400);
eye_ball_centert();
delay(300);
random_close();
delay(450);
look_up();
delay(400);
look_down();
delay(400);
random_movement();
delay(400);
eye_ball_centert();
delay(300);
top_left_eyelid.write(2);
bottom_left_eyelid.write(120);
delay(200);
top_left_eyelid.write(55);
bottom_left_eyelid.write(36);
delay(200);
open_eye();
delay(500);
for (int i = 60; i < 120; i++)
{
Xarm.write(i);
Yarm.write(i - 5);
delay(10);
}
eye_ball_centert();
delay(400);
synchronous_close();
for (int i = 120; i > 60; i--) {
Xarm.write(i);
Yarm.write(i - 5);
delay(10);
}
}
这标志着代码部分的结束,我们可以继续到本文的下一部分。
由于该项目的机械部分有点复杂,因此有很多事情在第一次开始时不起作用,因此在本节中,我想讨论这些主题。
我们遇到的第一个问题是eye_place_holders移动不顺畅,eye_place_holders和eye_lids之间有很多摩擦。
这个问题的解决方案是拿掉(lose)固定眼罩和设备底座的螺钉,这些螺钉是上面显示的标记螺钉。
下一个问题是如何将伺服臂连接到eye_lid臂以及X臂和Y臂的臂上。这是一个巨大的问题,因为没有适当的关节,设备将无法顺利工作,因此在下图中,您可以看到所有伺服臂的图片。
除此之外,一切都运行良好,最终结果看起来像下面显示的gif。
代码:
#include
Servo top_left_eyelid;
Servo bottom_left_eyelid;
Servo top_right_eyelid;
Servo bottom_right_eyelid;
Servo Yarm;
Servo Xarm;
void setup() {
top_left_eyelid.attach(10);
bottom_left_eyelid.attach(11);
top_right_eyelid.attach(5);
bottom_right_eyelid.attach(6);
Yarm.attach(9);
Xarm.attach(3);
Serial.begin(9600);
open_eye();
eye_ball_centert();
delay(2000);
}
void loop() {
eye_ball_left();
delay(680);
eye_ball_right();
delay(680);
eye_ball_centert();
delay(450);
synchronous_close();
//synchronous_close();
eye_ball_centert();
delay(450);
look_up();
delay(400);
look_down();
delay(400);
eye_ball_centert();
delay(300);
random_close();
delay(450);
look_up();
delay(400);
look_down();
delay(400);
random_movement();
delay(400);
eye_ball_centert();
delay(300);
top_left_eyelid.write(2);
bottom_left_eyelid.write(120);
delay(200);
top_left_eyelid.write(55);
bottom_left_eyelid.write(36);
delay(200);
open_eye();
delay(500);
for (int i = 60; i < 120; i++)
{
Xarm.write(i);
Yarm.write(i - 5);
delay(10);
}
eye_ball_centert();
delay(400);
synchronous_close();
for (int i = 120; i > 60; i--) {
Xarm.write(i);
Yarm.write(i - 5);
delay(10);
}
}
void random_movement() {
Xarm.write(60);
delay(random(250, 340));
Yarm.write(80);
delay(random(250, 340));
Xarm.write(120);
delay(random(250, 340));
Yarm.write(140);
Xarm.write(60);
delay(random(250, 340));
Yarm.write(80);
delay(random(250, 340));
Xarm.write(120);
delay(random(250, 340));
Yarm.write(140);
eye_ball_centert();
delay(300);
synchronous_close();
random_close();
}
void random_close() {
close_eye();
delay(random(220, 880));
open_eye();
delay(random(220, 880));
}
void synchronous_close() {
close_eye();
delay(420);
open_eye();
delay(222);
}
void eye_ball_left() {
Xarm.write(50);
}
void eye_ball_right() {
Xarm.write(130);
}
void eye_ball_centert() {
Xarm.write(90);
Yarm.write(90);
}
void look_up() {
Yarm.write(132);
}
void look_down() {
Yarm.write(45);
}
void close_eye() {
top_left_eyelid.write(2);
bottom_left_eyelid.write(120);
top_right_eyelid.write(46);
bottom_right_eyelid.write(55);
}
void open_eye() {
top_left_eyelid.write(55);
bottom_left_eyelid.write(36);
top_right_eyelid.write(2);
bottom_right_eyelid.write(160);
}
几乎所有组件都可以在没有支撑的情况下轻松打印。以这种方式设计模型确实会牺牲一些功能,但我将来会发布优化的设计。如果您想构建一个功能强大且逼真的眼部机制,不一定使用车床或专业组件等工具,那么这个项目是理想的选择。
这种设计的另一个特点是,它被设计为使用可以替换的咬接眼,并与其他3D打印组件一起使用,以在涂漆的眼睛上投射高度逼真的圆顶。这个过程非常复杂,所以我有另一个关于如何制作眼睛的指导,但如果你更喜欢使用简单的3D打印眼睛,你也可以这样做。
这个项目将需要对你的打印件进行一些后处理,包括一些(手工)钻孔和打磨,但除了基础知识(3D打印机,工艺刀,螺丝刀,艾伦键)之外,不需要特殊的工具。
基本下载包.zip
材料和组件:
工具:
由于零件很小,打印可能有些挑战,但大多数零件在没有支撑的情况下可以快速轻松地打印。我使用PLA来打印除眼睛以外的所有部位(使用ABS看起来更自然)。还有一些精致的零件需要注意,但是如果您使用质量不错的PLA,并且对打印设置感到满意,那么您应该没问题。最后,我使用了0.2mm的层高,这对于这个模型来说已经足够精确了 - 我怀疑甚至可以用0.3mm。
眼睛可以根据需要进行打磨,但是在打印机打印悬垂的模型底部可能需要进行最少的打磨。这只是为了确保眼睛可以在眼睑内平滑旋转。我唯一打磨的其他部分是eye adaptor组件,只是因为它们紧密贴合,并且我打印的底部几层总是有点肿。
这些零件的设计目的是打印出一些孔,尺寸过小,可以直接拧入,而其他孔的尺寸足够大,因此螺钉会紧紧地穿过它们。如果您的打印机正在使孔变小以拧入或平稳旋转,但是您可以使用一点手钻来钻出一些孔以使其更精确,并且自攻丝也是一种选择(尽管PLA通常可以很好地夹住螺钉)。检查图像以获取有关哪些孔应为哪种尺寸的指南。
一旦您的所有零件都打印和处理完毕,您就可以组装模型了!参考视频以了解它们是如何结合在一起的可能会有所帮助。此外,在我下载的一个文件夹中还有所有参考图片,包括您可以查看的完整模型的stl。
根据图形,将代码上传到arduino并将所有内容连接起来。如果您需要有关设置伺服驱动器板的帮助,请查看Adafruit指南。现在,所有舵机都应通电并处于空档位置,因此请利用这个机会将所有伺服臂连接到舵机,使眼睛在空档位置朝前。您只需插入它们,然后断开电源即可将其正确拧入。Y轴伺服臂处于一个尴尬的位置,无法接受螺钉,但我发现它无论如何都可以在没有螺钉的情况下保持良好状态。如果你的没有,取下其中一个眼睑伺服器以将其拧入可能会有所帮助。我建议在此阶段使用操纵杆测试运动,以确保没有问题。
对于眼睑,最好将舵机设置为眨眼(blinking)位置,以便将它们全部排在中心。通过按住blink开关或在其上创建短路来执行此操作。一旦所有伺服臂都就位,就很容易将它们拧入。
您的模型应该是完整的!如果你想看看如何使逼真的眼睛,检查我以前的指导。我还计划很快发布一个可说明的,向您展示如何制作控制器,所以如果您有兴趣,请回来查看!