触彩感应:无接触RGB色彩控制器

ChangeCode
转载
发布时间: 2025-06-14 15:16:20 | 阅读数 0收藏数 0评论数 0
封面
该项目探索了使用铝箔、导线和电阻器来创建非接触式RGB颜色控制器的电容式触摸感应。系统通过检测手部靠近传感器时电容的变化,从而改变信号在两个引脚之间传输所需的时间。干扰和数据不稳定问题可通过绝缘和接地有效缓解。

准备工作:

材料:

电子元件:

  1. 2 x 22MΩ 电阻(阻值越大,传感器的感应距离越远。我使用的是 22MΩ,据我测试,能获得可用数据的最小阻值为 10MΩ)
  2. 3x 330Ω 电阻
  3. 导线
  4. 面包板
  5. 电路板(我使用的是带有连续铜条的电路板)
  6. 多个共阴极 RGB LED 灯(我用了 8 个,但数量可以根据你想要的灯光效果增减)
  7. 铝箔纸
  8. 保鲜膜
  9. Arduino Uno 开发板
  10. 胶带

外壳材料:

  1. 木材(我使用的是 50 x 50 x 1.8 cm 的中密度纤维板 MDF;你可以使用任何材料,取决于你想达到的效果和手头的工具)
  2. 亚克力透明板(我使用的是 50 x 50 x 0.3 cm;也可以使用其他透明或半透明材料,如棉纸)
  3. 细砂纸
  4. 木工胶
  5. 木皮贴面(可选)
  6. 亚克力胶

工具:

工具:

  1. 剥线钳
  2. 电烙铁和焊锡
  3. 美工刀
  4. 电钻
  5. 锯子(我使用的是台锯)
1

原型制作

现在我们已经准备好了所有材料,可以开始制作原型,以测试它的工作效果:

准备工作:

从铝箔纸上剪下4个矩形(我的尺寸约为10厘米×5厘米),用保鲜膜包裹起来,以防止直接触摸,并在上面接上导线。我只是将剥了皮的导线一端用胶带固定在铝箔上(只要保持良好接触即可)。

为了确保铝箔被安全绝缘,我用保鲜膜将其包裹起来,并在两张纸之间轻轻熨烫几秒钟(这样可以封得更牢,但注意不要完全融化保鲜膜)。

然后按照图示搭建电路。

其中,引脚4 作为两个传感器的发送引脚(send pin),而接收引脚(receive pins)分别是 引脚2引脚5。你也可以为每个传感器使用不同的发送引脚,但由于它们无法完全同步,可能会引起问题。

在焊接所有元件之前,请先使用这个布局进行调试,以确保一切按预期工作。

2

代码

现在我们已经准备好一切,可以开始调试传感器了。

要使用我的代码,你需要先从 Arduino 官网下载并按照说明安装 电容感应库(Capacitive Sensing Library)点击这里下载(注:此处应为实际链接)

代码说明:(我不是专业的程序员,如果你有更好的写法,欢迎改进)

#include <CapacativeSensor.h> //import the code library

CapacitiveSensor cs_4_2 = CapacitiveSensor(4,2); //Send pin = 4, receive are 2 and 5
CapacitiveSensor cs_4_5 = CapacitiveSensor(4,5);

const int redPin = 11;
const int greenPin = 10;
const int bluePin = 9;

const int numIndexR = 10; // array size
const int numIndexG = 10;

int colorR = 0;
int colorG = 0;
float colorB = 0;

int indexR [numIndexR];
int posIndexR = 0;
long totalR = 0; //it needs to be a long because the total of my array was to big for an integer.
int averageR = 0;

int indexG [numIndexG];
int posIndexG = 0;
long totalG = 0;
int averageG = 0;

void setup()
{
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);

for (int thisIndexR = 0; thisIndexR < numIndexR; thisIndexR++) { //sets the array to 0
indexR [thisIndexR] = 0;
}

for (int thisIndexG = 0; thisIndexG < numIndexG; thisIndexG++) {
indexG [thisIndexG] = 0;
}

colorR = 255; //turns on all leds colors
colorG = 255;
colorB = 255;
Serial.begin(9600);
}

void loop()
{
long start = millis();
long total1 = cs_4_2.capacitiveSensor(10); //Save the raw sensor data to a variable
long total2 = cs_4_5.capacitiveSensor(10);
if (total1 >= 4500){ //cap the sensor values to a usable maximum, this is not the same for every resistor value and also might differ a bit from environment to environment you might need to tweak this to your own needs.
total1 = 4500;
}

if (total2 >= 4500){
total2 = 4500;
}

totalR = totalR - indexR[posIndexR]; //this here creates an array that continuously adds a sensor output and produces the average.
indexR[posIndexR] = total1;
totalR = totalR + indexR[posIndexR];
posIndexR = posIndexR + 1;


if (posIndexR >= numIndexR){
posIndexR = 0;
}

averageR = totalR / numIndexR; //we use the average instead of the raw data to smooth out the output, it slows the process down slightly but it also creates a really nice smooth flow.

totalG = totalG - indexG[posIndexG];
indexG[posIndexG] = total2;
totalG = totalG + indexG[posIndexG];
posIndexG = posIndexG + 1;

if (posIndexG >= numIndexG){
posIndexG = 0;
}

averageG = totalG / numIndexG;

if (averageR >= 2000 ){ // we don't want the leds to constantly changes value unless there is input from your hand, so this makes sure all lower environmental readings are not taken into account.
colorR = map(averageR, 1000, 4500, 255, 0);
analogWrite (redPin, colorR);
}
else if (averageR <= 2000){
colorR = 255;
analogWrite (redPin, colorR);
}
if (averageG >= 1000 ){
colorG = map(averageG, 1000, 4500, 255, 0);
analogWrite (greenPin, colorG);
}
else if (averageG <= 1000){

colorG = 255;
analogWrite (greenPin, colorG);
}

if (colorR <= 125 && colorG <= 125){ //B works a bit different because I only used 2 sensors so I mapped B on both sensors
colorB = map(colorR, 255, 125, 0, 127.5) + map(colorG, 255, 125, 0, 127.5);
analogWrite (bluePin, colorB);
}

else{
colorB = map(colorR, 255, 125, 127.5, 0) + map(colorG, 255, 125, 127.5, 0);
if (colorB >= 255){
colorB = 255;
}

if (colorB <= 0){
colorB = 0;
}
analogWrite (bluePin, colorB);
}
Serial.print(millis() - start); //this is for debugging purposes
Serial.print("\t");

Serial.print(colorR);
Serial.print("\t");
Serial.print(colorG);
Serial.print("\t");
Serial.println(colorB);

delay(1);
}

这段代码的作用是从传感器中读取原始数据(由于各种因素影响,这些数据会有些不稳定),然后持续将这些数据存入一个数组中。当数组达到最大容量(在我的代码中是10个数值)时,它会清除最早的一个数值,并添加一个新的数值。每次加入新值时,程序都会重新计算这个数组的平均值,并将其保存到一个新的变量中。

这个平均值会被用来映射成一个从 0 到 255 的范围,这个范围正是控制 RGB LED 每个颜色通道亮度所需要的。三个通道分别对应红色(R)、绿色(G)和蓝色(B)。

测试效果:

当你把代码上传到 Arduino 并打开串口监视器后,你应该能看到随着你的手在每个传感器上方悬停,RGB 数值会相应地降低,LED 灯的颜色也会随之发生变化。

3

外壳制作

这个外壳是我使用学校提供的工具制作的,因此这个制作流程可能并不适合所有人。不过这个盒子本身并没有什么特别之处——只需要在一侧开一个孔,让 Arduino 的 USB 接口可以穿过即可,除此之外它就是一个顶部开放的盒子。

尺寸说明:

  1. 透明顶部: 15 x 15 厘米
  2. 木质底座: 15 x 8 厘米(我使用的木板厚度为 1.8 厘米)

制作过程:

我使用台锯将一块 MDF 板切割成所需的尺寸:

  1. 四块 15 x 8 厘米的板子作为四周侧板
  2. 一块 15 x 15 厘米的板子作为底部

接着我把所有板材的边角切成 45 度角以便拼接。所有部件都使用木工胶和夹具固定在一起,并至少晾干 30 分钟。

对于 亚克力部分我也采用了相同的步骤,但使用了专用的锯片进行切割。

在其中一块木制侧板上,我在与 Arduino USB 插口等高的位置打了一个中心孔,以便插入 USB 线进行供电或编程。

贴面处理:

我对底座进行了木皮贴面装饰:

  1. 将木皮剪裁得比每块表面略大一些
  2. 涂上胶水后用夹子将每一块单独夹紧约 30 分钟,以确保不会滑动
  3. 待胶水干透后,把多余的部分修剪掉

盖子粘合:

我使用一种专门用于粘合亚克力材料的胶水——Acryfix 来粘合盖子。

需要注意的是,如果你使用的是亚克力板(Plexiglas),这种胶水会轻微溶解亚克力表面,所以操作时要尽可能精准且迅速,因为胶水暴露在空气中几秒钟就会开始固化,几分钟内完全干透。

雾面处理:

为了让盖子看起来更柔和,我使用喷砂机对亚克力盒进行了雾面处理。你也可以使用细砂纸手工打磨来达到类似效果,只是需要花费更多时间才能打磨均匀。

如果使用砂纸,请注意以下几点:

  1. 使用颗粒较细的砂纸
  2. 在打磨完成后才进行粘合,以免用力过猛导致材料破裂

防滑处理:

为了防止盖子滑动,我在木盒边缘粘上了几个小木条作为限位结构。

4

最终效果演示


5

重点词汇 AI润色 10/5000 通用场景 焊接!

如果你有一块电路板,就可以开始将各个元件焊接在一起了,按照之前在面包板上的布局来连接即可。

我的电路板带有连续的铜条,使用起来非常方便。

对于每个传感器,我剪下一块小方块,用来焊接电阻和导线。

发送信号的导线(即从 Arduino 的第 4 引脚连接到每个传感器的导线)依次焊接到各自的小方块上,并通过一根导线统一连接到引脚 4。

我还保留了一块长条形区域,用来制作一个临时的 LED 灯带(尺寸要测量好,确保能放进盖子中,同时贴合底座边缘)。你可以依次焊接多个 LED(请注意,在图片中我错误地把 LED 和电阻焊在了电路板的正面;正确的做法是将铜条放在背面)。

当你完成所有元件的焊接后,就可以将它们装入外壳中了。我没有直接把每根导线焊死,这样方便以后需要时更换线路。

将所有部件装入底座:

这一步其实是最简单的:

首先将 Arduino 放置在底座中,确保 USB 接口穿过外壳背面的孔。

接着安装传感器,确保铝箔部分紧贴木盒两侧,接地箔也要平整地贴合在木头上。

当一切就位后,将 RGB LED 插入对应的引脚(9、10、11),并让它们靠在底座边缘即可。

阅读记录0
点赞0
收藏0
禁止 本文未经作者允许授权,禁止转载
猜你喜欢
评论/提问(已发布 0 条)
评论 评论
收藏 收藏
分享 分享
pdf下载 下载