蚊章汇 - Heiko W.rupp
type: channel
link: https://linuxcn.bwsl.wang/author/966/
description: Heiko W.rupp
items: 如何使用 Arduino 制作一个绘图仪

如何使用 Arduino 制作一个绘图仪
type: item
date: 2018-06-05T04:11:26+08:00
description: 使用开源硬件和软件的 DIY 绘图仪可以自动地绘制、雕刻。在上学时，科学系的壁橱里藏着一台惠普绘图仪。虽然我在上学的期间可以经常使用它，但我还是想拥有一台属于自己的绘图仪。许多年之后，步进电机已经很容易获得了，我又在从事电子产品和微控制器方面的工作，最近，我看到有人用丙烯酸塑料（acrylic）制作了一个显示器。这件事启发了我，并最终制作了我自己的绘图仪。我 DIY 的绘图仪；在这里看它工作的视频。由于我是一个很怀旧的人，我真的很喜欢最初的 Arduino Uno。下面是我用到的其它东西的一个清单（仅供参考，其中一些我也不是很满意）：FabScan shield：承载步进电机驱动器。SilentStepSticks：步进电机驱动器，因为 Arduino 自身不能处理步进电机所需的电压和电流。因此我使用了一个 Trinamic TMC2130 芯片，但它是工作在单独模式。这些替换为 Pololu 4988，但是它们运转更安静。SilentStepStick 保护装置：一个防止你的电机驱动器转动过快的二极管（相信我，你肯定会需要它的）。步进电机：我选择的是使用 12 V 电压的 NEMA 17 电机（如，来自 Watterott 和 SparkFun 的型号）。直线导杆木制的基板木螺丝GT2 皮带GT2 同步滑轮这是我作为个人项目而设计的。如果你想找到一个现成的工具套件，你可以从 German Make 杂志上找到 MaXYposi。硬件安装正如你所看到的，我刚开始做的太大了。这个绘图仪并不合适放在我的桌子上。但是，没有关系，我只是为了学习它（并且，我也将一些东西进行重新制作，下次我将使用一个更小的横梁）。带 X 轴和 Y 轴轨道的绘图仪基板皮带安装在轨道的侧面，并且用它将一些辅助轮和电机挂在一起：电机上的皮带路由我在 Arduino 上堆叠了几个组件。Arduino 在最下面，它之上是 FabScan shield，接着是一个安装在 1 和 2 号电机槽上的 StepStick 保护装置，SilentStepStick 在最上面。注意，SCK 和 SDI 针脚没有连接。Arduino 堆叠配置（高清大图）注意将电机的连接线接到正确的针脚上。如果有疑问，就去查看它的数据表，或者使用欧姆表去找出哪一对线是正确的。软件配置基础部分虽然像 grbl 这样的软件可以解释诸如像装置移动和其它一些动作的 G-codes，并且，我也可以将它刷进 Arduino 中，但是我很好奇，想更好地理解它是如何工作的。（我的 X-Y 绘图仪软件可以在 GitHub 上找到，不过我不提供任何保修。）使用 StepStick（或者其它兼容的）驱动器去驱动步进电机，基本上只需要发送一个高电平信号或者低电平信号到各自的针脚即可。或者使用 Arduino 的术语：digitalWrite(stepPin, HIGH); delayMicroseconds(30); digitalWrite(stepPin, LOW); 在 stepPin 的位置上是步进电机的针脚编号：3 是 1 号电机，而 6 是 2 号电机。在步进电机能够工作之前，它必须先被启用。digitalWrite(enPin, LOW); 实际上，StepStick 能够理解针脚的三个状态：Low：电机已启用High：电机已禁用Pin 未连接：电机已启用，但在一段时间后进入节能模式电机启用后，它的线圈已经有了力量并用来保持位置。这时候几乎不可能用手来转动它的轴。这样可以保证很好的精度，但是也意味着电机和驱动器芯片都“充满着”力量，并且也因此会发热。最后，也是很重要的，我们需要一个决定绘图仪方向的方法：digitalWrite(dirPin, direction); 下面的表列出了功能和针脚：功能1 号电机2 号电机启用25方向47步进36在我们使用这些针脚之前，我们需要在代码的 setup() 节中设置它的 OUTPUT 模式。pinMode(enPin1, OUTPUT); pinMode(stepPin1, OUTPUT); pinMode(dirPin1, OUTPUT); digitalWrite(enPin1, LOW); 了解这些知识后，我们可以很容易地让步进电机四处移动： totalRounds = ... for (int rounds =0 ; rounds < 2*totalRounds; rounds++) { if (dir==0){ // set direction digitalWrite(dirPin2, LOW); } else { digitalWrite(dirPin2, HIGH); } delay(1); // give motors some breathing…