用Arduino来体验一次“放生萤火虫”吧

1 引言

笔者的出生和成长都在农村,依稀记得小的时候捉萤火虫的事儿。每当夏季,小伙伴们都可以在草丛里捉到很多的萤火虫,把它们放在玻璃罐里,黄绿色的光很是好看,如图所示。为了读大学来到城市,毕业之后便在城市定居,却发现很少有机会能够看到萤火虫,很难再有小时候的乐趣了。想必很多的读者也都怀念小时候捉萤火虫的乐趣,下面教大家如何使用Arduino来制作一个电子萤火虫,重新找回儿时的快乐。

本文采用Arduino NANO控制器、LED灯来实现仿生萤火虫,Arduino控制器控制4个翠绿色的LED灯以亮灭随机、亮度随机、顺序随机、时间随机的模式来模仿自然界中萤火虫的习性。

2 原理及材料

仿生萤火虫的系统原理图如图所示,4个翠绿色的LED灯的正极依次连接至Arduino NANO控制器的数字端口D3、D5、D6、D9上,因为Arduino NANO控制器的只有数字端口3、5、 6、9、10和11具有PWM输出功能,可以实现LED灯亮度的调节;4个LED灯的负极通过排针连接至Arduino NANO控制器的GND引脚上;另外,通过4个AA电池或者2个CR2032纽扣电池为Arduino NANO控制器及4个LED灯提供工作电压。 需要注意的是,在实际制作中使用的是翠绿色的LED灯,而不是图2所示的红色LED灯,因为萤火虫的翠绿色的灯光更加逼真。


仿生萤火虫Arduino原理图

图3列出了制作仿生萤火虫所需要的材料及数量,按需备齐即可开始下面的制作。

仿生萤火虫材料清单

3 手工制作

第一步:将杜邦线从中间剪断并剥线,把LED灯的负极(短引脚)引脚剪去一部分,将热缩管剪成7mm~10mm的小段,如图4所示。

第二步:将小段的热缩管套进剥好的杜邦线,每一根杜邦线上套一个热缩管段,如图所示。


前期准备


将热缩管套进杜邦线上

第三步:使用电烙铁或焊台将黑色杜邦线与LED灯的负极焊接在一起,【注意:在焊接时不要使用过多的焊锡】;将排针上面用焊锡连接起来并焊接至蓝色的杜邦线,如图6所示。

第四步:使用尖嘴钳将LED灯的正极引脚剪去,并使用电烙铁或焊台焊接至红色的杜邦线,如图所示。


焊接好LED灯负极与黑色杜邦线及负极排线


焊接好LED灯正极与红色杜邦线

第五步:将热风枪的温度调至150℃左右,风量调节至较小风量。将热缩管移至LED引脚与杜邦线的焊接处,并使用热风枪加热热缩管,使热缩管收缩,包住焊接处,如图8所示。经过热风枪加工之后的LED灯,如图所示。

使用热风枪加热热缩管


制作完毕的LED灯


制作好的LED灯与其他材料

第六步:使用电烙铁或焊台将纽扣电池盒的正极(红线)与负极(黑线)焊接至Arduino NANO控制器的5V和GND引脚,如图所示。

第七步:将制作好的LED灯的负极(黑线)连接至含有蓝色杜邦线的排针上,蓝色杜邦线接至Arduino NANO控制器的GND引脚,将LED灯的正极(红线)依次接至Arduino NANO控制器的数字端口D3、D5、D6、D9引脚上,如图所示。


将电池盒焊接至Arduino NANO控制器


将LED灯连接至Arduino NANO控制器

4 Arduino程序设计

4 .1 数目随机和随机顺序

首先,通过随机数以获得点亮LED灯的数目,然后再通过随机数以获取LED灯点亮的顺序,并且通过随机数来获得点亮的时间。程序代码如下所示。

int randNumber;
int delaytime;

void setup() {
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(9, OUTPUT);
  Serial.begin(9600);
  randomSeed(analogRead(0));
}
void delay_time(void){
  delaytime = random(1,5);
  switch(delaytime){
  case 1:delay(800);
        break;
  case 2:delay(900);
        break;
  case 3:delay(1000);
        break;
  case 4:delay(1100);
        break;
  }
}

void RandLED_2(void)
{
  randNumber = random(1,5);
  Serial.println(randNumber);
  switch(randNumber)
  {
  case 1: analogWrite(3, 255);
          analogWrite(5, 255);
          delay_time();
          digitalWrite(3, LOW);
          delay_time();
          digitalWrite(5, LOW);
          break;
  case 2: analogWrite(6, 255);
          analogWrite(9, 255);
          delay_time();
          digitalWrite(6, LOW);
          delay_time();
          digitalWrite(9, LOW);
          break;
  case 3: analogWrite(3, 255);
          analogWrite(9, 255);
          delay_time();
          digitalWrite(3, LOW);
          delay_time();
          digitalWrite(9, LOW);
          break;
  case 4: analogWrite(5, 255);
          analogWrite(9, 255);
          delay_time();
          digitalWrite(5, LOW);
          delay_time();
          digitalWrite(9, LOW);
          break;
  case 5: analogWrite(3, 255);
          analogWrite(6, 255);
          delay_time();
          digitalWrite(6, LOW);
          delay_time();
          digitalWrite(3, LOW);
          break;
  case 6: analogWrite(5, 255);
          analogWrite(6, 255);
          delay_time();
          digitalWrite(6, LOW);
          delay_time();
          digitalWrite(5, LOW);
          break;
  }
}
void RandLED_3(void)
{
  randNumber = random(1,5);
  Serial.println(randNumber);
  switch(randNumber)
  {
  case 1: analogWrite(5,255);
          analogWrite(6,255);
          analogWrite(9,255);
          delay_time();
          digitalWrite(5, LOW);
          delay_time();
          digitalWrite(9, LOW);
          delay_time();
          digitalWrite(6, LOW);
          break;
  case 2: analogWrite(6,255);
          analogWrite(3,255);
          analogWrite(9,255);
          delay_time();
          digitalWrite(9, LOW);
          delay_time();
          digitalWrite(3, LOW);
          delay_time();
          digitalWrite(6, LOW);
          break;
  case 3: analogWrite(5,255);
          analogWrite(3,255);
          analogWrite(9,255);
          delay_time();
          digitalWrite(9, LOW);
          delay_time();
          digitalWrite(5, LOW);
          delay_time();
          digitalWrite(3, LOW);
          break;
  case 4: analogWrite(5,255);
          analogWrite(6,255);
          analogWrite(3,255);
          delay_time();
          digitalWrite(3, LOW);
          delay_time();
          digitalWrite(5, LOW);
          delay_time();
          digitalWrite(6, LOW);
          break;
  }
}
void RandLED_4(void)
{
  randNumber = random(1,5);
  Serial.println(randNumber);
  switch(randNumber)
  {
  case 1: analogWrite(3,255);
          analogWrite(5,255);
          analogWrite(6,255);
          analogWrite(9,255);
          delay_time();
          digitalWrite(3, LOW);
          delay_time();
          digitalWrite(5, LOW);
          delay_time();
          digitalWrite(6, LOW);
          delay_time();
          digitalWrite(9, LOW);
          break;
  case 2: analogWrite(3,255);
          analogWrite(5,255);
          analogWrite(6,255);
          analogWrite(9,255);
          delay_time();
          digitalWrite(3, LOW);
          delay_time();
          digitalWrite(6, LOW);
          delay_time();
          digitalWrite(9, LOW);
          delay_time();
          digitalWrite(5, LOW);
          break;
  case 3: analogWrite(3,255);
          analogWrite(5,255);
          analogWrite(6,255);
          analogWrite(9,255);
          delay_time();
          digitalWrite(9, LOW);
          delay_time();
          digitalWrite(3, LOW);
          delay_time();
          digitalWrite(5, LOW);
          delay_time();
          digitalWrite(6, LOW);
          break;
  case 4: analogWrite(3,255);
          analogWrite(5,255);
          analogWrite(6,255);
          analogWrite(9,255);
          delay_time();
          digitalWrite(6, LOW);
          delay_time();
          digitalWrite(9, LOW);
          delay_time();
          digitalWrite(3, LOW);
          delay_time();
          digitalWrite(5, LOW);
          break;
  }
}

void loop() {
  randNumber = random(1,4);
  switch(randNumber){
  case 1:RandLED_2();
        break;
  case 2:RandLED_3();
        break;
  case 3:RandLED_4();
        break;
  }
}

4 .2 添加随机亮度和优化点亮时间

首先,通过随机数以获得点亮LED灯的数目,然后再通过随机数以获取LED灯的亮度值,将LED灯全部点亮,然后通过随机数来获得点亮的时间按照顺序来依次熄灭LED灯。程序代码如下所示。

int randNumber;
int pwm,delaytime;

void setup() {
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  Serial.begin(9600);
  randomSeed(analogRead(0));
}
void delay_time_2(void){
  delaytime = random(1,5);
  switch(delaytime){
  case 1:delay(1000);
        break;
  case 2:delay(1250);
        break;
  case 3:delay(1500);
        break;
  case 4:delay(1250);
        break;
  }
}

void delay_time_3(void){
  delaytime = random(1,5);
  switch(delaytime){
  case 1:delay(1000);
        break;
  case 2:delay(1250);
        break;
  case 3:delay(1500);
        break;
  case 4:delay(1000);
        break;
  }
}

void delay_time_4(void){
  delaytime = random(1,5);
  switch(delaytime){
  case 1:delay(800);
        break;
  case 2:delay(1000);
        break;
  case 3:delay(900);
        break;
  case 4:delay(700);
        break;
  }
}

int pwm_value(void){
  int pwmvalue;
  pwmvalue = random(1,5);
  switch(pwmvalue){
  case 1: return 255 ;
          break;
  case 2: return 180;
          break;
  case 3: return 110;
          break;
  case 4: return 40;
          break;
  }
}
void RandLED_2(void)
{
  randNumber = random(1,5);
  Serial.println(randNumber);
  switch(randNumber)
  {
  case 1: pwm=pwm_value();
          analogWrite(5, pwm);
          analogWrite(6, pwm);
          delay_time_2();
          digitalWrite(5, LOW);
          delay_time_2();
          digitalWrite(6, LOW);
          break;
  case 2: pwm=pwm_value();
          analogWrite(5, pwm);
          analogWrite(10, pwm);
          delay_time_2();
          digitalWrite(5, LOW);
          delay_time_2();
          digitalWrite(10, LOW);
          break;
  case 3: pwm=pwm_value();
          analogWrite(5, pwm);
          analogWrite(11, pwm);
          delay_time_2();
          digitalWrite(5, LOW);
          delay_time_2();
          digitalWrite(11, LOW);
          break;
  case 4: pwm=pwm_value();
          analogWrite(6, pwm);
          analogWrite(10, pwm);
          delay_time_2();
          digitalWrite(6, LOW);
          delay_time_2();
          digitalWrite(10, LOW);
          break;
  case 5: pwm=pwm_value();
          analogWrite(6, pwm);
          analogWrite(11, pwm);
          delay_time_2();
          digitalWrite(6, LOW);
          delay_time_2();
          digitalWrite(11, LOW);
          break;
  case 6: pwm=pwm_value();
         analogWrite(10, pwm);
          analogWrite(11, pwm);
          delay_time_2();
          digitalWrite(6, LOW);
          delay_time_2();
          digitalWrite(11, LOW);
          break;
  }
}
void RandLED_3(void)
{
  randNumber = random(1,5);
  Serial.println(randNumber);
  switch(randNumber)
  {
  case 1: pwm=pwm_value();
          analogWrite(5, pwm);
          analogWrite(6, pwm);
          analogWrite(10, pwm);
          delay_time_3();
          digitalWrite(5, LOW);
          delay_time_3();
          digitalWrite(10, LOW);
          delay_time_3();
          digitalWrite(6, LOW);
          break;
  case 2: pwm=pwm_value();
          analogWrite(6, pwm);
          analogWrite(10, pwm);
          analogWrite(11, pwm);
          delay_time_3();
          digitalWrite(6, LOW);
          delay_time_3();
          digitalWrite(10, LOW);
          delay_time_3();
          digitalWrite(11, LOW);
          break;
  case 3: pwm=pwm_value();
          analogWrite(5, pwm);
          analogWrite(10, pwm);
          analogWrite(11, pwm);
          delay_time_3();
          digitalWrite(10, LOW);
          delay_time_3();
          digitalWrite(5, LOW);
          delay_time_3();
          digitalWrite(11, LOW);
          break;
  case 4: pwm=pwm_value();
          analogWrite(5, pwm);
          analogWrite(6, pwm);
          analogWrite(11, pwm);
          delay_time_3();
          digitalWrite(6, LOW);
          delay_time_3();
          digitalWrite(5, LOW);
          delay_time_3();
          digitalWrite(11, LOW);
          break;
  }
}
void RandLED_4(void)
{
  randNumber = random(1,5);
  Serial.println(randNumber);
  switch(randNumber)
  {
  case 1: pwm=pwm_value();
          analogWrite(5, pwm);
          analogWrite(6, pwm);
          analogWrite(10, pwm);
          analogWrite(11, pwm);
          delay_time_4();
          digitalWrite(6, LOW);
          delay_time_4();
          digitalWrite(10, LOW);
          delay_time_4();
          digitalWrite(5, LOW);
          delay_time_4();
          digitalWrite(11, LOW);
          break;
  case 2: pwm=pwm_value();
          analogWrite(5, pwm);
          analogWrite(6, pwm);
          analogWrite(10, pwm);
          analogWrite(11, pwm);
          delay_time_4();
          digitalWrite(10, LOW);
          delay_time_4();
          digitalWrite(6, LOW);
          delay_time_4();
          digitalWrite(11, LOW);
          delay_time_4();
          digitalWrite(5, LOW);
          break;
  case 3: pwm=pwm_value();
          analogWrite(5, pwm);
          analogWrite(6, pwm);
          analogWrite(10, pwm);
          analogWrite(11, pwm);
          delay_time_4();
          digitalWrite(6, LOW);
          delay_time_4();
          digitalWrite(11, LOW);
          delay_time_4();
          digitalWrite(5, LOW);
          delay_time_4();
          digitalWrite(10, LOW);
          break;
  case 4: pwm=pwm_value();
          analogWrite(5, pwm);
          analogWrite(6, pwm);
          analogWrite(10, pwm);
          analogWrite(11, pwm);
          delay_time_4();
          digitalWrite(11, LOW);
          delay_time_4();
          digitalWrite(10, LOW);
          delay_time_4();
          digitalWrite(6, LOW);
          delay_time_4();
          digitalWrite(5, LOW);
          break;
  }
}

void loop() {
  randNumber = random(1,4);
  Serial.println(randNumber);
  switch(randNumber){
  case 1:RandLED_2();
        break;
  case 2:RandLED_3();
        break;
  case 3:RandLED_4();
        break;

  }


}

5 总结

为了更好的仿真萤火虫的发光习性,可以将所有可能发光的情况都列举出来,并通过随机数来筛选本次执行的情况。另外,通过选择Microduino替代Arduino NANO控制器,可以将控制器及电池盒放置于瓶盖下面,这会更加美观。还可以在瓶子内放置一些绿色的丝带,以模仿野外草丛的情况。最后,还可以选用可充电锂电池,并使用太阳能电池来为锂电池充电,这样一来,白天晒晒太阳,晚上就可以享受萤火虫的夜晚,环保健康。

>南京创客空间 沈金鑫 陈大庆

坐沙发

发表评论

你的邮件地址不会公开


*