原文标题:RGB Infinity Mirror with 3D Magnetic Sensor 原作者:Abdullah Sadiq
由于本人翻译水平有限,翻译以意译为主,难免有翻译不严谨以及不准的问题,欢迎指正。
已完成翻译! =========================================================== 这是一个带有RGB LED灯带的无限镜子,这个灯带能使用连接到Arduino MKR1000的英飞凌3D磁传感器旋钮改变其颜色。
用于这个项目的东西
硬件元件 | |
英飞凌3D磁传感器2Go | x1 |
Arduino MKR1000 | x1 |
达林顿大功率晶体管 | x3 | RGB LED灯带 | x1 |
跳线(通用) | x1 | 软件应用程序和在线服务 | |
Arduino IDE | | 手动工具和装配工具 | |
烙铁(通用) | |
用于这个项目的东西
当我第一次看到无限镜子的效果时,我就对它印象深刻。
我想建立我自己的版本。因此,我决定使用英飞凌的3D磁传感器套件和旋钮通过一条RGB LED灯条来控制的无限镜子上的颜色。
在进行实际制作之前,请务必查看最终成品的演示视频:
注意:无限效果不是那么明显。由于相机的原因,我还需要试验摆放镜子的位置,使其显得更加明显。
这些是制作它所需的部件(仅电子部分):
细节
我对这个项目的灵感来自于techydiy的无限镜子(这里)。看一下它吧,以便明白无限镜子的理念。
由于3D磁传感器2Go套件没有足够的PWM引脚,我使用了Arduino MKR1000板来扩展它,因此我可以轻松地向无限镜子添加任何其他东西。
除此之外,颜色变化算法通过将RGB值(从0到255)转换为HSV(色调饱和度值)来工作,其中将色调值从0改变为360将改变LED的颜色。
注意:我没有编写从HSV转换到RGB的代码。在网上搜索后,我从这个网站(这里)找到了代码。因此,我使用了修改后适配了3D Magnetic 2Go套件的算法。
这是我转换的代码片段:
- void setLedColorHSV(int h, double s, double v) {
- //this is the algorithm to convert from RGB to HSV
- double r=0;
- double g=0;
- double b=0;
- double hf=h/60.0;
- int i=(int)floor(h/60.0);
- double f = h/60.0 - i;
- double pv = v * (1 - s);
- double qv = v * (1 - s*f);
- double tv = v * (1 - s * (1 - f));
- switch (i)
- {
- case 0: //rojo dominante
- r = v;
- g = tv;
- b = pv;
- break;
- case 1: //verde
- r = qv;
- g = v;
- b = pv;
- break;
- case 2:
- r = pv;
- g = v;
- b = tv;
- break;
- case 3: //azul
- r = pv;
- g = qv;
- b = v;
- break;
- case 4:
- r = tv;
- g = pv;
- b = v;
- break;
- case 5: //rojo
- r = v;
- g = pv;
- b = qv;
- break;
- }
- //set each component to a integer value between 0 and 255
- int red=constrain((int)255*r,0,255);
- int green=constrain((int)255*g,0,255);
- int blue=constrain((int)255*b,0,255);
- setLedColor(red,green,blue);
- }
复制代码
以下是整个项目如何运作的概要: - 3D Magnetic 2Go通过其硬件串口发送旋钮的当前位置(范围从0到360度)。
- MKR1000连接到3D Magnetic 2Go的UART引脚,它会解析之前发送的角度。
- 这个角度在上面的代码片段中用于代替色调(正如我之前所说的那样,范围从0到360)。
- 此功能根据该角度生成三个值(红色,绿色和蓝色),范围从0到255。
- 用analogWrite函数将这些值写入到连接到MKR1000的RGB LED灯条(当然使用像TIP120这样的晶体管!)。只需旋转旋钮,就可以将光变换为色环上最亮的颜色,从而得到一个漂亮的效果。
话虽如此,让我们继续讨论这个项目本身。
配置3D Magnetic 2Go套件
这是连接到套件的旋钮:
这是套件的引脚:
注意:我将使用Arduino IDE对套件进行编程(版本1.1.2)。
假设您了解了基础知识,比如如何上传代码以及已经设置好套件并从Arduino IDE获得程序模板,这一步将非常简单。
只需下载XMC1100的附加代码即可。
选择正确的板子和COM端口,并将“串行输出选择”设置为“PC”。完成后,上传代码并打开串行监视器。 你应该看到一个从0到360这样的数字,通过旋钮来改变:
如果和上图一样,则意味着一切正常,再次上传相同的代码,但这一次,将“串行输出选择”设置为“在板上”,并确保正确地上传。
现在你不会在串行监视器中看到任何输出,这是完全正常的,只需继续下一步。
配置MKR1000
这是MKR1000:
这是MKR1000的引脚,供您参考:
下载Arduino MKR1000附上的代码,然后将其简单地上传到Arduino MKR1000。这很容易,不是吗?
连接一切和测试
现在,只需将一块板的Tx引脚连接到另一块板的Rx引脚,将一块板的Rx引脚连接到另一块板的Tx,然后将MKR1000的3.3v电源连接到XMC2Go的3.3v引脚(如果你想的话!),并确保地线也连接。
注意:我已将3.3v从MKR1000连接到XMC2Go; 这将直接从MKR1000启动XMC2Go。引自XMC2Go引脚图:
如果电路板通过3.3v引脚供电,则不建议通过USB供电,反之亦然
这是它们应该看起来的样子:
注意:我会建议您首先搭起所有电子部件,当它运行得完美时,然后继续搭建无限镜子。
如果要测试MKR1000和3D磁传感器套件之间的连接是否正常,请将MKR1000连接到计算机的USB端口,以9600波特打开串行监视器。你应该看到这样:
正在发生的事情是3D磁传感器套件正在发送旋钮的角度(从0到360度),MKR1000分析该角度并将其转换为RGB颜色编码(每个从0到255),循环处理所有颜色。旋转旋钮,查看值的变化。
现在是时候将晶体管连接到MKR1000了。根据此连接图:
注意:我使用的是共阳极型RGB LED灯条,Adafruit上的这篇文章对它的设置很有帮助。
我将晶体管连接在一个单独的小面包板上:
连接完所有东西之后:
插入LED灯条的12伏电源,以及MKR1000的电源(我假设您已经从MKR1000上的3.3v为XMC2Go供电),LED灯条应该如下那样点亮:
旋转旋钮,看到颜色变化:
一个用旋钮LED灯条变色的视频,循环显示所有颜色:
制作无限镜子
现在您已经完成了电子部分并且能够改变RGB LED灯条的颜色,我们继续制作无限镜子本身。
我不会更详细地介绍这个,因为我不是专家; 这是我第一次做这样的事情,但最终的结果还不是那么糟糕。 我再次在YouTube上看到了这个视频,它确实帮助我搭建了它。
这些是我如何搭建它的一些图片,只是为了让你明白个大概。
我已经有了这个木制框架,我在制作PCB时用它作为边框,它作为无限镜子时看起来更好用。
框架也有这个透明玻璃,可以删除:
但要使无限镜子错觉起作用,需要对玻璃进行着色。要做到这一点,首先需要清洁玻璃:
我用这个车窗色调(我从一家汽车店买到的)用肥皂水和一张用于压出气泡的卡片。
并将线焊接到带子上并通过镜子中的一个孔将它们取出,以使后镜(稍后将安装)与框架平放。
将LED灯条安装到框架上后(后面没有镜子)测试LED灯条。
现在换另一个完全反光的镜子,它放在镜架的后面,但因为我现在还没有这个,我只是将镜架(配有RGB LED条带)放在梳妆台镜子前面测试。 最后使用3D磁传感器旋钮更改无限镜子的颜色。
最后的总结
所以现在您可以使用旋钮柄和Arduino MKR1000更改RGB LED灯条的颜色。您可以轻松更改XMC2Go中的代码以更改另一种RGB LED的颜色,但是当按下开关时,您还可以添加更多效果。您甚至可以使用相同的旋钮来调暗或照亮另一个LED,只需更改代码即可。
我找不到一个有多色LED的RGB LED灯条; 我找到的那个有红色,绿色和蓝色LED。使用带有多色LED的RGB灯条会产生更明显的颜色变化,因此如果您找到它们,它们看起来会更好看。
任何人都可以想出另一种用处,而不是无限镜子,你可以在任何你能想到的东西中使用它。 它可以为您的汽车后备箱,自行车或踏板车照明,或为您的桌子照明,如:
请务必评论您对该项目的想法和意见。
原理图
连接示意图
将代码上传到3D磁传感器套件和MKR1000,并根据此图连接所有内容。
代码
3D磁传感器代码:
在Arduino IDE上安装这块板后,上传这个代码到3D磁传感器。
- #include <Tle493d_w2b6.h>
- const float pi = (22.0 / 7.0);
- bool switchPressed;
- Tle493d_w2b6 Tle493dMagnetic3DSensor = Tle493d_w2b6();
- void setup() {
- Serial.begin(9600);
- Tle493dMagnetic3DSensor.begin();
- Tle493dMagnetic3DSensor.begin();
- }
- void loop() {
- Tle493dMagnetic3DSensor.updateData();
- delay(100);
- isSwitchPressed();
- float angle = pi + Tle493dMagnetic3DSensor.getAzimuth();
- angle = (angle * 180.0) / pi;
- if (!switchPressed) {
- Serial.println(angle);
- } else if (switchPressed) {
- //Do here whatever you want to do when the switch is pressed
- }
- }
- void isSwitchPressed() {
- if (Tle493dMagnetic3DSensor.getNorm() < 55) {
- switchPressed = false;
- }
- else if (Tle493dMagnetic3DSensor.getNorm() > 85) {
- switchPressed = true;
- }
- }
复制代码
Arduino MKR1000代码
上传这个代码到Arduino MKR1000,并且根据连接示意图连接所有组件(在上传这个代码到XMC2GO)。
- float deg;
- int pinRed = 2;
- int pinGreen = 3;
- int pinBlue = 4;
- void setup() {
- Serial.begin(9600);
- Serial1.begin(9600);
- pinMode(pinRed, OUTPUT);
- pinMode(pinGreen, OUTPUT);
- pinMode(pinBlue, OUTPUT);
- }
- void loop() {
- if (Serial1.available() > 0) {
- deg = Serial1.parseFloat();
- setLedColorHSV(deg, 1, 1);
- }
- }
- void setLedColorHSV(int h, double s, double v) {
- //this is the algorithm to convert from RGB to HSV
- double r = 0;
- double g = 0;
- double b = 0;
- double hf = h / 60.0;
- int i = (int)floor(h / 60.0);
- double f = h / 60.0 - i;
- double pv = v * (1 - s);
- double qv = v * (1 - s * f);
- double tv = v * (1 - s * (1 - f));
- switch (i) {
- case 0:
- r = v;
- g = tv;
- b = pv;
- break;
- case 1:
- r = qv;
- g = v;
- b = pv;
- break;
- case 2:
- r = pv;
- g = v;
- b = tv;
- break;
- case 3:
- r = pv;
- g = qv;
- b = v;
- break;
- case 4:
- r = tv;
- g = pv;
- b = v;
- break;
- case 5:
- r = v;
- g = pv;
- b = qv;
- break;
- }
- //set each component to a integer value between 0 and 255
- int red = constrain((int)255 * r, 0, 255);
- int green = constrain((int)255 * g, 0, 255);
- int blue = constrain((int)255 * b, 0, 255);
- Serial.print("Red: "); Serial.print(red);
- Serial.print(" Green: "); Serial.print(green);
- Serial.print(" Blue: "); Serial.print(blue);
- Serial.println();
- analogWrite(pinRed, red);
- analogWrite(pinGreen, green);
- analogWrite(pinBlue, blue);
- }
复制代码
|