当我们玩涉及骰子的游戏时,一个或多个骰子不可避免地会在过度热情的玩家试图掷双 6 后落在地板上。这个骰子头骨解决了这个问题,并且添加了 Arduino Nano,只要检测到掷骰子就会亮起红色。我希望它发出一声“吼叫!” 声音,但 Nano 不能真正播放音频。第 1 步:制作头骨和电池座
头骨是根据 Windham Graves 提供的模型 3D 打印出来的。有关3D 打印头骨所需的文件,请访问 ThingIVerse.com 。请注意,使用标准质量设置和 PLA 灯丝在 Creality 3 S1 打印机上打印需要 26 小时。
头骨的背面是空心的,因此更容易在后面安装电子设备。
可选 - 打印后,使用泡沫刷在头骨上涂上环氧树脂,之后可以将其扔掉。环氧树脂干燥后,使用 Rust-oleum Ultra Matte 油漆和底漆喷涂骷髅哑光黑色。
寻找或购买一个开/关开关。使用 Dremel 工具在头骨右耳附近开出开/关开关的开口。暂时不要将开关放入孔中,需要先添加一些电线(更多内容见下文)。
钻开开关开口进入头骨的“喉咙”,为照亮眼睛的 RGB LED 开一个口。使用与 LED 直径大致相同的钻头。开关放置在头骨的右耳上,使喉咙相对难以接近的右侧可以进行钻孔。喉咙的倾斜角度使从左侧钻孔更容易,因此无需在该侧的外颅骨上打孔。
在喉管的另一侧为光敏电阻钻另一个孔。当骰子中断从 LED 进入光敏电阻的光时,它们将被检测到。检测逻辑对光照水平的变化相当敏感,所以只要在眼孔周围挥动你的手就足以触发它们。光敏电阻越靠近 LED 的正对面,电路检测骰子的能力就越好。
9V 电池座也是 3D 打印的。有关打印文件,请参阅ThingIVerse.com 。使用了打印文件的“紧凑”版本,但头骨中的任何一个版本都有足够的空间。
一个小的 PCB 用于固定 Nano 和一个用于电池/开关引线的两端连接器。
步骤 2.1:将纳米、LED、光敏电阻和相关电阻焊接在一起
在将电池和开关放入头骨之前,可以将纳米、光敏电阻、常规电阻和 LED 焊接在一起。使用 PCB 上的小型两导体旋入式接线柱连接到 Nano 的 Vin 和 GND 端子。该接线柱将在总装期间派上用场。
步骤 2.2:将开关和 9V 电池连接器焊接在一起
开关和电池座可以与 2 英寸(5 厘米)的电线一起焊接在一起。不要将电池/开关引线拧到 PCB 上。
使用 Arduino IDE,将以下代码上传到 Nano。
// Light up skull code for Arduino Nano
// (C) Copyright 2021 John Dillenburg
// john _at_ dillenburg.org
//
double avgWhenOn;
double avgWhenOff;
long last = 0;
int lightOnLevel = 4;
long lastTrigger = 0;
long triggerCooldown = 500; // milliseconds
int detectThreshold = 10;
long recalibrateInterval = 300000; // milliseconds
long lastRecalibrate = 0;
void setup() {
Serial.begin(115200);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(A0, INPUT);
calibrate();
if (Serial) {
Serial.print("lightOnLevel = ");
Serial.print(lightOnLevel);
Serial.print(" avgWhenOn = ");
Serial.print(avgWhenOn);
Serial.print(" avgWhenOff = ");
Serial.println(avgWhenOff);
}
detectMode();
}
void calibrate() {
lightOnLevel = 20;
avgWhenOn = average(500, lightOnLevel);
avgWhenOff = average(500, 0);
while (avgWhenOff - avgWhenOn < detectThreshold && lightOnLevel < 255) {
lightOnLevel += 16;
avgWhenOn = average(500, lightOnLevel);
}
if (lightOnLevel > 255) lightOnLevel = 255;
lastRecalibrate = millis();
}
void rgb(int r, int g, int b) {
analogWrite(9, 255 - r);
analogWrite(10, 255 - g);
analogWrite(11, 255 - b);
}
void movementDetected() {
rgb(255, 0, 0);
delay(3000);
}
void detectMode() {
rgb(lightOnLevel, lightOnLevel, lightOnLevel);
}
double average(int duration, int level) {
rgb(level, level, level);
long start = millis();
long count = 0;
double sum = 0.0;
while (millis() < start + duration) {
sum += analogRead(A0);
count++;
}
return sum / count;
}
void loop() {
int detector = analogRead(A0);
avgWhenOn = avgWhenOn * 0.999 + detector * 0.001;
if (Serial && millis() > last + 1000) {
Serial.print("detector = ");
Serial.print(detector);
Serial.print(" avg = ");
Serial.println(avgWhenOn);
last = millis();
}
if (detector > avgWhenOn + detectThreshold && millis() > lastTrigger + triggerCooldown) {
if (Serial) {
Serial.print("triggered ");
Serial.println(detector);
}
movementDetected();
lastTrigger = millis();
detectMode();
}
if (millis() > lastRecalibrate + recalibrateInterval) {
calibrate();
}
}
该代码使用 avgWhenOn 变量跟踪环境 + LED 灯级别。如果阴影从连接到引脚 A0 的光敏电阻前面经过,则从 A0 读取的值将增加,这将触发 movementDetected() 函数。movementDetected() 函数将 LED 变为红色 3 秒。
avgWhenOn 变量使用无限脉冲响应系统对最新的光敏电阻读数与旧读数进行平均。我选择 0.999 和 0.001 作为权重。这似乎只是对最新读数的轻微加权,但 Nano loop() 函数被调用得如此频繁,以至于变量在一秒钟内稳定到平均值。
Serial print 语句是可选的,其编码方式使得在安装后将跳过它们。
在头骨的后部/底部工作,光敏电阻器被放置在喉咙左侧钻出的孔中,并使用大量热熔胶粘在适当的位置。
喉咙右侧的 LED 灯也是如此。
将开关和 9V 电池连接器的电线穿过开关孔。将两条引线拧到小型 Nano PCB 上。
将 9V 电池放入电池座中,并在下面涂上热熔胶。
PCB 本身可以塞入底部,并在缠结的电线中保持原位。
打开头骨后,它会在测量初始光照水平时闪烁白色。之后,即使是最轻微的阴影从眼前掠过,头骨也会将 LED 灯切换为亮红色。
享受!
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
全部0条评论
快来发表一下你的评论吧 !