第1步:构建电路
《显然,如果你正在关注我的构建,你将不必经历我所做的测试。我做的第一件事是确保我的代码工作,我可以正确地从光隔离器获得信号,并正确控制LED灯条。花了一点时间才弄清楚如何最好地将信号引脚连接到隔离器,但通过反复试验,我找到了正确的方向。我刚刚使用了一个标准的原型板,因为我只构建了一个,并且计算出一个跟踪模式会花费更多的时间而不是它的价值。电路板的顶部看起来很棒,但底部确实看起来有点混乱,但至少它的功能。
基本设计从输入交流电源(仅在摩托车开启时打开的电线)输入12V电源开始。接线图确实可以帮助找到这根电线。将其馈入电压调节器的一侧。一个0.33 uF电容将此输入连接到稳压器的接地端,然后再将电压调回到摩托车的地面。电压调节器的输出将有一个0.1uF的电容器接地。这些电容有助于消除稳压器的电压。如果你在电路板的图片中找不到它们,它们就在电压调节器的下面。从那里,5V线路到达Arduino上的Vin,到为LED灯条供电的电源引脚,以及两个光隔离器的源极侧,它们将馈入Arduino引脚,提供所需的5V信号。
至于光隔离器,有两个方面:一个带有红外LED,另一个带有晶体管和红外探测器。我们想用IR LED侧测量12V信号。由于LED的正向电压为1.2V,因此我们需要一个串联的限流电阻。 12V - 1.2V = 10.8V并且以18 mA运行LED(我总是希望运行时间小于20 mA),你需要一个R = 10.8V/0.018A = 600欧姆的电阻。车辆上的电压也往往更高,可能高达14V,因此最好为此计划,即大约710欧姆,尽管700可能更合理。然后LED侧的输出反馈到地。对于光隔离器的输出侧,输入将使用来自稳压器的5V信号,然后输出将连接到另一个电阻,然后再接地。这个电阻只需要大约10k到20k欧姆,至少这是我的数据表显示的。这将提供快速的信号测量,因为我们没有处理嘈杂的环境。 Arduino引脚的输出将在电阻和光隔离器输出之间脱落,这样当信号关闭时,引脚为低电平,当信号打开时,引脚为高电平。
LED灯条有三条与之相关的电线:电源,接地和数据。电源需要为5V。这个项目总共使用了12个LED(虽然我在条带上有更多LED,但我只使用每三个LED),当白光以全亮度使用时,每个LED需要60mA。这总共提供720 mA。我们在电压调节器的输出功率范围内,所以我们很好。只需确保电线足够大,以便处理电源,我使用的是24号Cat 6以太网电线。以太网线是我坐在它周围的东西,它有8条彩色编码线,所以它很适合这个项目。然后,需要进入顶盒的唯一电线是电源和接地(两者都在条带之间分开)和两条数据线(每条条带一条)。
接线的其余部分连接到arduino上的引脚并为其供电。用于此项目的引脚如下:
Vin - 连接到5V
Gnd - 接地
Pin2 - 连接到左条数据线
Pin3 - 连接到右条带数据线
Pin4 - 连接到来自光隔离器的制动信号
Pin5 - 连接到左转向信号来自光隔离器
Pin6 - 连接到来自光隔离器的右转向灯
步骤2:接线和安装
电路构建完成后,实际将电路连接到位。使用自行车的接线示意图,您需要找到以下内容:
接地
制动信号输入
左转信号输入
右转信号输入
对我来说,有一个插头上有所有这些插件,所以我只是用它。有足够的时间,我可能已经能够找到相同的插头样式,只是插入模块,但我没有,所以我只是删除了绝缘材料,并焊接新的电线。我在这些拼接连接上使用了插头,以便我可以在将来需要时移除其余部分。从那里我把Arduino放在一个密封的工程箱里,放在我附着的座位下面。输出电缆然后沿着机架框架运行到防水插头,然后进入盒子并沿着背部延伸到盖子,在那里它为每一侧分开。电线沿着盖子内部延伸到LED的连接点。使用附在带有粘性背衬的户外级拉链带支架上的拉链将电线帮助到位。你可以在家装店的电缆安装部分找到这些。
我在LED灯条上使用了两个迷你JST插头,因为我需要一个小到足以通过最小直径的孔的插头因为我想要确保有足够的电线来处理当前的要求。再次,它可能是矫枉过正,我没有任何小插头三条线方便。用于光带线穿过的盒子中的孔被密封以防止水流出。至于LED条的定位,因为间距略有不匹配(反射器和LED之间的间距差异大约为1 - 1.5 mm),我将它们放置在一起,这样它们就可以分开LED和LED之间的差异。尽可能的洞。然后我用热胶将它们固定到位并用密封剂完全密封该区域。 LED灯条本身是防水的,所以如果它们弄湿就没问题。虽然安装起来似乎很多,但这使得系统在将来更容易拆卸或者需要更换部件,因为它可能会发生。
第3步:代码
我的源代码应位于此Instructable的开头。我总是大量评论我的代码,以便以后更容易理解。免责声明:我不是专业的代码编写者。代码是用一种更容易上手的方法编写的,并且进行了一些改进,但我知道它可以更精确。我也使用了大量的delay()函数进行定时,这并不理想。然而,相比之下,该单元接收的信号并不是快速信号,所以我仍然觉得有理由让他们使用像millis()这样的东西。我也是一个非常忙碌的父亲和丈夫,因此花时间改进最终不会改变功能的东西并不在名单上。
对于此项目,只需要一个库,即FastLED库。这包含控制WS2811/WS2812B型LED灯条的所有代码。从那里,我将介绍将要使用的基本功能。
标准定义以外的第一个是声明你的两个条带。您将对每个条带使用以下代码:
FastLED.addLeds(leds[0], NUM_LEDS);
此代码行设置引脚2将此条带定义为条带0,其中LED数量由常量NUM_LEDS定义,在我的case设置为16.要定义第二个条带,2将变为3(对于pin3),条带将标记为条带1.
下一行很重要的是颜色定义。
leds[0][1] = Color_high CRGB(r,g,b);
这行代码虽然在不同的外观中使用(我的大多数使用常量)。基本上,此代码将值发送到定义每个亮度的每个LED通道(红色,绿色,蓝色)。亮度值可以通过数字0 - 255定义。通过更改每个通道的亮度级别,您可以定义不同的颜色。对于这个项目,我想要一种白色,以保持光线尽可能明亮。所以我唯一的改变是在所有三个通道中设置相同的亮度级别。
下一组代码用于单独点亮每个灯光。请注意,对于每个条带,每个LED的地址从最接近数据线连接的那个开始为0,一直到最低数量的LED为负1.例如,这些是16个LED条,所以最高的是16 - 1 = 15.原因是第一个LED标记为0.
for (int i = NUM_LEDS-1; i 》 -1; i = i - 3) { // This will change the light for every third LED going from the last to first.
leds[0][i] = Color_low; // Set strip 0 LED color to the chosen color.
leds[1][i] = Color_low; // Set strip 1 LED color to the chosen color.
FastLED.show(); // Show the set colors.
leds[0][i] = CRGB::Black; // Turn off set color in prep for next color.
leds[1][i] = CRGB::Black;
delay(150);
}
FastLED.show(); // Show the set colors.
此代码的工作方式是在for循环中使用变量(i)作为LED地址,然后以全部数量的LED(NUM_LEDS)为参考。这样做的原因是我希望灯光从条带末端而不是从头开始。设置输出到两个条带(LED [0]和LED [1]),然后发出显示更改的命令。之后关闭此灯(CRGB :: Black),下一盏灯亮起。 Black引用是FastLED库中的特定颜色,因此我不必为每个通道发出0,0,0,尽管它们会做同样的事情。 For循环一次前进3个LED(i = i-3),因为我只使用其他所有LED。在此循环结束时,灯光序列将从一个LED转到另一个LED,每个条带只有一个点亮,类似骑士骑士效果。如果你想保持每个灯点亮以便建立条形,你只需要删除关闭LED的线路,这些线路会在程序的下一组代码中发生。
for (int i = 0; i 《 dim; i++) { // Quickly fade lights to running light level.
rt = rt + 1;
gt = gt + 1;
bt = bt + 1;
for (int i = 9; i 《 NUM_LEDS; i = i +3) { // This will light up the last three lights for the position light.
leds[0][i] = CRGB( rt, gt, bt); // Set strip 0 LED color to the chosen color.
leds[1][i] = CRGB( rt, gt, bt); // Set strip 1 LED color to the chosen color.
}
FastLED.show();
delay(3);
}
我用于LED的最后一个代码示例是淡入淡出循环。在这里,我使用临时插槽来获得每个通道(rt,gt,bt)的亮度,并将它们递增1,每次显示之间有一个延迟,以达到我想要的外观。另请注意,此代码仅更改最后三个LED,因为它在运行灯中褪色,因此我从9开始而不是0.
其余的LED代码是这些的迭代。其他一切都集中在寻找三种不同电线上的信号。代码的Loop()区域寻找制动灯,它会在停留之前闪烁一次(如果需要可以调节)或寻找转向信号。对于这个代码,因为我不能假设左右转向灯会在危险的同一时间完全打开,我让代码首先找到一个,然后在一个小延迟之后我检查两个是否都在指示危险警告灯亮起。我所遇到的一个棘手的部分是转向灯,因为灯会熄灭一段时间,所以如何判断仍处于开启但处于关闭期间的信号与取消信号之间的区别?我想出的是实现一个延迟循环,设置为比信号闪烁之间的延迟持续更长时间。如果转向信号仍然打开,则信号回路将继续。如果延迟结束时信号没有重新打开,则返回循环开始()。要调整延迟的长度,请更改常量lightDelay的编号,以便在lightDelay中每1次记住延迟变化100ms。
while (digitalRead(leftTurn) == LOW) { for(int i = 0; i 《 lightDelay; i++) {
leftTurnCheck();
if(digitalRead(leftTurn) == HIGH) {
leftTurnLight();
}
delay(100);
}
for (int i = 0; i 《 NUM_LEDS; i = i +3) { // This will change the light for every third LED going from the last to first.
leds[0][i] = CRGB( 0, 0, 0); // Set strip 0 LED color to the chosen color.
}
for (int i = 9; i 《 NUM_LEDS; i = i +3) { // This will set up the running lights which only use the last three.
leds[0][i] = Color_low; // Set strip 0 LED color to the chosen color.
}
FastLED.show(); // Output settings
return; // Once turn signal is no longer on, go back to loop.
}
希望其余的代码是自我解释的。它只是一组重复的检查和动作信号。
第4步:结果
令人惊奇的是,这个系统第一次连接到自行车。现在,为了公平起见,我在此之前在板凳上对它进行了大量测试,但我仍然期望有问题或调整。事实证明,我不需要对代码和连接进行任何调整。正如您在视频中看到的那样,系统会通过启动顺序(您不必拥有),然后默认为运行灯。在此之后它会查找制动器,在这种情况下,它会将所有LED点亮至全亮度并闪烁一次,然后保持直至制动器释放。当使用转向信号时,我对指示转弯的一侧进行了滚动效果,如果打开则另一侧将是运行灯或刹车灯。危险灯只会与其他灯一起闪烁。
希望通过这些额外的灯光,我会更容易被其他人看到。至少,这是一个很好的补充,使我的盒子比其他人更突出,同时提供实用性。我希望这个项目对其他人也有用,即使他们没有使用摩托车顶盒照明。谢谢!
-
led灯
+关注
关注
22文章
1554浏览量
107044
发布评论请先 登录
相关推荐
评论