电子说
曾经希望您拥有自己的Knight Industries 2000(KITT)汽车-您知道吗,来自Knight Rider?通过构建LED扫描仪,使您的梦想更接近现实!这是最终结果:
您需要什么
该项目不需要很多零件,您可能已经有很多零件了:
1 x Arduino UNO或类似的
1 x面包板
8 x红色LEDs
8 x 220欧姆电阻
1 x 10k欧姆电位器
公对公连接线
如果您有Arduino入门套件,则很可能所有这些部件都可以(用入门工具可以做什么)套件。)
只要有八个可用的引脚(几乎从未使用过Arduino?请从这里开始),几乎任何Arduino都可以使用。您可以使用移位寄存器来控制LED,尽管该项目不需要此操作,因为Arduino具有足够的引脚。
构建计划
这是一个非常简单的项目。尽管从大量的电线来看可能看起来很复杂,但是每个单独的部分都非常简单。每个发光二极管(LED)连接到其自己的Arduino引脚。这意味着每个LED均可单独打开和关闭。电位计连接到Arduino模拟输入引脚,用于调整扫描仪的速度。
电路
电位器的外部左引脚(从正面看,引脚在底部)接地。将相反的外部引脚连接到+ 5v。如果不能正常工作,则将这些引脚接反。在2中将中间引脚连接到Arduino模拟量。
将每个LED的阳极(长脚)连接到数字引脚1至8。将阴极(短脚)连接到Arduino地面。
代码
创建一个新草图并将其另存为“ knightRider”。代码如下:
const int leds[] = {1,2,3,4,5,6,7,8}; // Led pins
const int totalLeds = 8;
int time = 50; // Default speed
void setup() {
// Initialize all outputs
for(int i = 0; i 《= totalLeds; ++i) {
pinMode(leds[i], OUTPUT);
}
}
void loop() {
for(int i = 0; i 《 totalLeds - 1; ++i) {
// Scan left to right
time = analogRead(2);
digitalWrite(leds[i], HIGH);
delay(time);
digitalWrite(leds[i + 1], HIGH);
delay(time);
digitalWrite(leds[i], LOW);
}
for(int i = totalLeds; i 》 0; --i) {
// Scan right to left
time = analogRead(2);
digitalWrite(leds[i], HIGH);
delay(time);
digitalWrite(leds[i - 1], HIGH);
delay(time);
digitalWrite(leds[i], LOW);
}
}
让我们对其进行分解。每个LED引脚都存储在一个数组中:
const int leds[] = {1,2,3,4,5,6,7,8};
数组本质上是相关项目的集合。这些元素被定义为常量(“ const”),这意味着它们以后无法更改。尽管建议使用常量,但不必使用常量(如果删除“ const”,代码将正常工作)。
使用方括号(“ []”)访问数组的元素和一个称为索引的整数。索引从零开始,因此“ leds [2]”将返回数组中的第三个元素—针脚3。数组使代码更快地编写且更易于阅读,它们使计算机难以完成工作!
一个for循环用于将每个引脚设置为输出:
for(int i = 0; i 《= totalLeds; ++i) {
pinMode(leds[i], OUTPUT);
}
此代码位于“ setup()”函数内部,因为它仅需要在以下位置运行一次程序的开始。 For循环非常有用。它们允许您一次又一次地运行相同的代码,每次都使用不同的值。它们非常适合使用数组。声明了整数“ i”,并且只有循环内部的代码才能访问此变量(称为“作用域”)。 i的值从零开始,对于循环的每次迭代,i都增加1。一旦i的值小于或等于“ totalLeds”变量,则循环“中断”(停止)。
i的值用于访问“ leds”数组。该循环访问数组中的每个元素,并将其配置为输出。您可以手动键入“ pinMode(pin,OUTPUT)”八次,但是为什么您可以写八行却可以写三行呢?
尽管有些编程语言可以告诉您数组中有多少个元素(通常使用像array.length这样的语法),Arduino并没有使其变得如此简单(它涉及到更多的数学运算)。由于数组中元素的数目是已知的,所以这不是问题。
在主循环内部( void loop())是另外两个for循环。第一个循环将LED从1 – 8设置为ON,然后关闭。第二个循环将LED从8 – 1设置为ON,然后关闭。请注意,如何将电流引脚设置为ON,同时将电流引脚加一个也设置为ON。这样可以确保始终同时有两个LED,从而使扫描仪看起来更逼真。
在每个循环开始时,电位计的值都将被读取到“时间”变量中:/p》 time = analogRead(2);
此操作执行两次,每个循环一次。这需要不断检查和更新。如果此操作不在循环中,它仍然可以工作,但是会有一个小的延迟-它仅在循环完成执行后才运行。电位计是模拟的,因此为什么要使用“ analogRead(pin)”。这将返回零(最小值)到1023(最大值)之间的值。 Arduino能够将这些值转换为更有用的值,但是对于这种使用情况,它们是完美的选择。
更改LED的间隔(或扫描仪的速度)之间的延迟以毫秒为单位(1/1000秒) ),因此最长时间仅为1秒。
高级扫描器
现在,您已经了解了基本知识,让我们来看一下在更复杂的地方。该扫描仪将从外部开始并在工作中成对点亮LED。然后将其反转,从内部到外部成对发光。以下是代码:
const int leds[] = {1,2,3,4,5,6,7,8}; // Led pins
const int totalLeds = 8;
const int halfLeds = 4;
int time = 50; // Default speed
void setup() {
// Initialize all outputs
for(int i = 0; i 《= totalLeds; ++i) {
pinMode(leds[i], OUTPUT);
}
}
void loop() {
for(int i = 0; i 《 (halfLeds - 1); ++i) {
// Scan outside pairs in
time = analogRead(2);
digitalWrite(leds[i], HIGH);
digitalWrite(leds[(totalLeds - i) - 1], HIGH);
delay(time);
digitalWrite(leds[i], LOW);
digitalWrite(leds[(totalLeds - i) - 1], LOW);
delay(time);
}
for(int i = (halfLeds - 1); i 》 0; --i) {
// Scan inside pairs out
time = analogRead(2);
digitalWrite(leds[i], HIGH);
digitalWrite(leds[(totalLeds - i) - 1], HIGH);
delay(time);
digitalWrite(leds[i], LOW);
digitalWrite(leds[(totalLeds - i) - 1], LOW);
delay(time);
}
}
此代码稍微复杂一些。请注意,两个循环如何从零变为“ halfLeds – 1”(3)。这使扫描仪更好。如果两个循环都从4 – 0和0 – 4变为循环,则相同的LED将以相同的顺序闪烁两次-看起来效果不佳。
您现在应该拥有一台工作正常的Knight Rider LED扫描仪!修改它以使用更多或更大的LED或实现您自己的图案将很容易。该电路很容易移植到Raspberry Pi(是Pi的新功能?从此处开始)或ESP8266。
责任编辑:wv
全部0条评论
快来发表一下你的评论吧 !