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

NeoPixel Ring 的陀螺仪乐趣

组件和用品

SparkFun Arduino Pro Mini 328 - 5V/16MHz
× 1
Adafruit NeoPixel Ring:WS2812 5050 RGB LED
× 1
SparkFun IMU Breakout - MPU-9250
× 1
面包板(通用)
× 1
公/公跳线
× 1
公/母跳线
× 1
4 AA 电池座 + 电池
× 1

关于这个项目

在本教程中,我们将使用 MPU6050 陀螺仪,NeoPixel 戒指和一个 Arduino 构建一个设备,根据倾斜角度点亮LED。

这是一个简单而有趣的项目,它将被组装在面包板上。如果您按照步骤操作,您将构建您在视频中看到的内容。这是一个很好的学习陀螺仪和 NeoPixel Ring 的教程。

我正在构建本教程是因为我在其他一些 min. 教程中看到了兴趣。在本教程中,我用 NeoPixel 环替换了简单的 LED。戒指通过 Adafruit 库使用起来更简单,而且绝对更壮观。

因此,如果您有这些组件,那么这是利用它们的好方法,我将尝试带您逐步构建设备,并在最后一步解释它的工作原理。

第 1 步:所需事项

零件

1. Arduino Pro Mini 328P

2.面包板

3. MPU6050陀螺仪

4. 24 NeoPixel LED 环

5. 4 节 AA 电池组,含 4 节电池

6. U 型跨接电缆(可选)。我使用了这些跨接电缆,因为它们在面包板上看起来更好,而且 LED 以这种方式更明显。您可以在 ebay 上以约 4 美元的价格找到一盒 140 个。如果您没有这些电缆,您可以用杜邦线替换它们。

工具:

1. USB转串口FTDI适配器FT232RL对arduino pro mini编程

2. Arduino IDE

技能:

1. 焊接

3. 基本arduino编程

第二步:组装

我附上了 fzz 格式的 Fritzing 原理图和它的图片,以便于可视化连接。

1.你需要在neopixel环的背面焊接3个公针,如图所示

- 焊接正极

- 焊接地面

- 焊接数据输入引脚

2.然后4x电池座应该有一种连接到面包板的方式,一个简单的解决方案是将两条公杜邦线焊接到它的端子上。

3.准备面包板。

- 将新像素环、微控制器和陀螺仪放在面包板上,如图所示

- 放置所有负极线:到微控制器、新像素环、陀螺仪

- 放置所有正极线:到微控制器、新像素环、陀螺仪

- 放置所有数据线:

* 从微控制器到陀螺仪的 SDA 和 SCL

* 从微控制器到新像素环的引脚 D6

- 通电前仔细检查所有连接

- 可选地使用胶带,将电池组粘在布板背面以将其固定到位,使其更便携

第 3 步:代码和校准

第一次 您需要下载并安装两个库:

1. Adafruit neopixel library fir 控制neopixel

2.陀螺仪MPU6050库

它们是两个伟大的图书馆,可以完成繁重的工作!

关于neopixels的更多细节在这里

然后 从这里下载并安装我的库或从下面复制它:

#include "I2Cdev.h" #include  #include "MPU6050_6Axis_MotionApps20.h" #include "Wire.h" #define NEOPIXED_CONTROL_PIN 6 #define NUM_LEDS 24 const int MAX_ANGLE =45; const int LED_OFFSET =12; MPU6050 mpu; Adafruit_NeoPixel 条 =Adafruit_NeoPixel(NUM_LEDS, NEOPIXED_CONTROL_PIN, NEO_RBG + NEO_KHZ800); unsigned long lastPrintTime =0;布尔初始化=假; // 如果 DMP 初始化成功则设置为真 uint8_t mpuIntStatus; // 保存来自 MPU 的实际中断状态字节 uint8_t devStatus; // 每次设备操作后返回状态(0 =成功,!0 =错误) uint16_t packetSize; // 预期的 DMP 数据包大小(默认为 42 字节) uint16_t fifoCount; // 当前在 FIFO 中的所有字节的计数 uint8_t fifoBuffer[64]; // FIFO 存储缓冲区 Quaternion q; // [w, x, y, z] 四元数容器 VectorFloat 重力; // [x, y, z] 重力向量 float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll 容器和重力向量 volatile bool mpuInterrupt =false; // 指示 MPU 中断引脚是否变高

void setup() { Serial.begin(9600); Serial.println("程序启动");初始化 =initializeGyroscope(); strip.begin(); } void loop() { if (!initialization) { return; } } mpuInterrupt =false; mpuIntStatus =mpu.getIntStatus(); fifoCount =mpu.getFIFOCount(); if (hasFifoOverflown(mpuIntStatus, fifoCount)) { mpu.resetFIFO();返回; } if (mpuIntStatus &0x02) { while (fifoCount 0) { lightLeds(y, z, 0, 5, 0, 89); } else if (y <0 and z <0) { lightLeds(y, z, 6, 12, 89, 0); } else if (y> 0 and z <0) { lightLeds(y, z, 13, 19, 0, 89); } else if (y> 0 and z> 0) { lightLeds(y, z, 20, 24, 89, 0); } } void lightLeds(int x, int y, int fromLedPosition, int toLedPosition, int fromAngle, int toAngle) { 双角 =(atan((double) abs(x) / (double) abs (y)) * 4068) / 71; int ledNr =map(angle, fromAngle, toAngle, fromLedPosition, toLedPosition);打印调试(x,y,ledNr,角度); uint32_t 颜色; for (int i=0; i position + LED_OFFSET) { return position + LED_OFFSET; } 返回位置 + LED_OFFSET - NUM_LEDS; } void printDebug(int y, int z, int lightLed, int angle) { if (millis() - lastPrintTime <500) { return; } Serial.print("a=");Serial.print(angle);Serial.print(";"); Serial.print("ll=");Serial.print(lightLed);Serial.print(";"); Serial.print("y=");Serial.print(y);Serial.print(";"); Serial.print("z=");Serial.print(z);Serial.println(";"); lastPrintTime =毫秒(); } bool initializeGyroscope() { Wire.begin(); TWBR =24; mpu.initialize(); Serial.println(mpu.testConnection() ? F("MPU6050 连接成功") :F("MPU6050 连接失败")); Serial.println(F("正在初始化 DMP...")); devStatus =mpu.dmpInitialize(); mpu.setXGyroOffset(220); mpu.setYGyroOffset(76); mpu.setZGyroOffset(-85); mpu.setZAccelOffset(1788); if (devStatus !=0) { Serial.print(F("DMP Initialization failed (code "));Serial.println(devStatus); return false; } mpu.setDMPEnabled(true); Serial.println(F("Enabling中断检测 (Arduino 外部中断 0)...")); attachInterrupt(0, dmpDataReady, RISING); mpuIntStatus =mpu.getIntStatus(); Serial.println(F("DMP 准备好!等待第一个中断..." )); packetSize =mpu.dmpGetFIFOPacketSize(); return true; } void dmpDataReady() { mpuInterrupt =true; }

上传代码:

使用 FTDI 适配器将代码上传到 arduino。

连接电源(电池)

校准:

这里最重要的校准是“LED_OFFSET”常数。在我的示例中是 12。您需要将其从 0 调整到 23,以便在为板供电后 LED 会在您倾斜板的方向上点亮。

如果您想了解有关其工作原理的更多详细信息,请查看下一步

第 4 步:工作原理(可选)

第一次 关于 MPU6050 陀螺仪的一些信息。这是一个MEMS陀螺仪(MEMS代表微机电系统)。

每种类型的 MEMS 陀螺仪都有某种形式的振荡分量,从中可以检测到加速度和方向变化。这是因为,根据运动守恒定律,振动物体喜欢在同一平面内继续振动,任何振动偏差都可以推导出方向变化。

陀螺仪还包含一个自己的微控制器,可以通过一些奇特的数学计算来计算滚转、俯仰和偏航。

但是陀螺仪的原始数据会受到噪声和漂移的影响,所以我们使用了一个外部库来消除这些问题,并为我们提供干净的可用数据。

新像素 RGB LED 可单独寻址并链接成带和环。它们在 5V 电压下工作,并且包含自己的电路,因此您只需为 Neopixels 供电并使用数据线与它们通信。通信是通过包含时钟和数据的单条数据线完成的(更多细节在这里)。 Adafruit 为与新像素环交互提供了一个干净的库。

代码

在 loop() 内部 函数调用 MPU6050_6Axis_MotionApps20 库。当库有来自 gyroscpe 的新数据时,它会调用 redrawLeds(x, y, z) 用 3 个参数表示偏航、俯仰和滚转

redrawLeds 内部 ():

- 我们专注于两个轴:y, z

- 我们将两个轴从 -MAX_ANGLE 约束到 +MAX_ANGLE,我们将最大角度定义为 45 并且它是可变的

- 我们将 360 度分成 4 个象限,并为每个象限调用 lightLeds() 函数,如下所示:

* y 负,z 正第一象限将控制 LED 从 0 到 5,角度从 0 到 89

* y 负,z 负第二象限控制 LED 从 6 到 12,角度从 89 到 0

* ...等

- 在 lightLeds 内 功能

* 我正在使用反正切计算基于两个轴的角度(查看附图)

* 我正在计算使用 arduino 地图功能导致显示的内容

* 我正在重置 LED 灯条,除了两个 LED,一个对应于我之前计算的 LED 位置和之前的 LED 位置(以显示淡入淡出效果)

* 我正在使用一个名为 normalizeLedPosition() 的函数 考虑到新像素校准。校准很有用,因为neopixel环可以随意旋转,并且应该与陀螺仪对齐

*我也在打印牵引轴,什么led有光和角度

数学

我附上了一张带有led环和用于确定角度的三角函数的图片。

代码

arduino 代码
https://github.com/danionescu0/arduino/tree/master/projects/neopixel_ring_gyroscope

示意图

Sketch_gMlSrk3rCX.fzz

制造工艺

  1. Arduino Gyroscope Game with MPU-6050
  2. 使用 Adafruit 1/4 60 Ring Neopixel 的简单挂钟
  3. 使用 K30 传感器监测二氧化碳
  4. 聋盲通信与 1Sheeld/Arduino
  5. Arduino 游戏控制器
  6. 使用 Arduino 控制硬币接收器
  7. Pixie:基于 Arduino 的 NeoPixel 手表
  8. Arduino 带蓝牙控制 LED!
  9. 带有 Arduino 或 ESP8266 的电容式指纹传感器
  10. 使用 Arduino 进行语音识别和合成
  11. 使用 Arduino 测量太阳辐射
  12. 智能手套