| 编程Arduino心情灯 在本篇文章的末尾处给出了该基于Arduino的Neo-pixel心情灯的完整程序,可以在添加所需库后使用。在本节中,我将从代码中摘出几个重要的片段并进行介绍,它们可以帮助您根据需要修改项目。 该程序代码大约有300行,所以如果你在理解程序过程种,遇到任何问题,都可以在论坛上发布帖子。 
 和往常一样,我们首先在程序中添加所需的库,本文需要下面的几个库。 复制代码#include <SoftwareSerial.h> //Bluetooth module works with software serial
#include <Adafruit_NeoPixel.h> //Library for Neo Pixel (Download from Link in article)
#include <DS3231.h> //Library for RTC module (Download from Link in article)
#include <EEPROM.h> //Library for EEPROM (Pre-Loaded into Arduino)
 蓝牙模块通过串行通信工作;我不喜欢使用硬件串行引脚(0和1),因为我将使用串行监视器来调试程序,因此我们将软件串行库包含在程序中。默认情况下,此库将出现在IDE中。
 接下来我们使用Adafruit公司的Adafruit Neo Pixel库,我们在上一节中讨论过这个库。您可以使用此链接下载Adafruit Neo Pixel库,该链接将从GitHub下载ZIP文件。然后,使用sketch -> Include Library -> Add .ZIP library选项将该ZIP文件添加到Arduino IDE中。
 同样,您也可以下载RTC模块的DS3231库,并以相同的方式添加。最后,我们将EEPROM库预先加载到Arduino库中。我们只需添加库来存储唤醒警报和睡眠警报时间,以便在电源故障后Arduino重新启动时它会记住何时进入睡眠状态以及何时唤醒。 
 Neo Pixel LED可以产生多种颜色,但我们不是对心情灯的所有颜色都感兴趣,除了其中8种颜色,分别是红色、橙色、黄色、绿色、青色、蓝色、紫色和粉红色。要得到每种颜色,我们必须传递它的相应值。因此,我们使用宏定义每种颜色的值,如下所示。 复制代码#define Red 1
#define Orange 20
#define Yellow 30
#define Green 70
#define Cyan 100
#define Blue 130
#define Purple 200
#define Pink 240
 接下来,我们必须声明neo Pixel连接了哪些引脚以及Neo Pixel灯条上有多少个LED。 在本文下,Neo pixel灯连接到引脚6,如上面的电路图所示,灯条上总共有5个LED,代码如下: 复制代码Adafruit_NeoPixel strip = Adafruit_NeoPixel(5, 6, NEO_GRB + NEO_KHZ800); //5 LEDs on PIN-6
 在接下来的程序中,我们声明了很多全局变量,您可能感兴趣的是一些数组声明。 有两个数组,即morning_rainbow和evening_rainbow,每个数组由4种颜色组成。 基于上面讨论的色光疗法表,我选择了红色、橙色、绿色和粉红色作为早晨的颜色,黄色、青色、蓝色和紫色作为晚上的颜色,你可以根据需要改变。 复制代码//array declarations
char current_rainbow[8] = {}; //the main array
char morning_rainbow[4] = {Red, Orange, Green, Pink}; //colours to show during day time
char evening_rainbow[4] = {Yellow, Cyan, Blue, Purple}; //colours to show during night time
char all_rainbow[8] = {Red, Orange, Yellow, Green, Cyan, Blue, Purple, Pink}; //colours that can be controlled thorugh Bluetooth
 在void setup()函数中,我们初始化蓝牙模块,以9600波特率初始化串行监视器。 蓝牙用于与手机通信,串行监视器用于调试。 只需启动串行监视器,您就可以监视程序中的所有重要变量。 除此之外,如果用户先前已将它们设置并将它们存储在相应的变量中,我们还会读取EEPROM值。 复制代码void setup(){//Execute once during the launch of program
    Initialize_RTC();
    Bluetooth.begin(9600); 
    Serial.begin (9600); //for debugging
    strip.begin();
    strip.show(); // Initialize all pixels to 'off'
    Bluetooth.println("Mood Lamp Alarm -CircuitDigest");
    Serial.println("Mood Lamp Alarm -CircuitDigest");
//If anything was stored previously in EEPROM copy it to the alarm variables
    sleep_alarm_hour = EEPROM.read(0);
    sleep_alarm_minute = EEPROM.read(1);
    wake_alarm_hour =  EEPROM.read(2);
    wake_alarm_minute = EEPROM.read(3);
 }
 在main循环内部,我们首先读取LDR的值开,如果房间非常明亮,程序将所有LED变暗,从而关闭它,然后等待房间再次变亮。 当房间明亮时,还会检查Interactive_BT函数,以便用户仍然可以强制从手机打开灯。 在这里,我选择800作为阈值,但是如果你想在明亮的日光下工作,你可以简单地增加800的值。范围是0-1024。 复制代码 while (lightvalue>800) //IF the room is very brigt (you can increase this values to make it glow even duringf day)
  {
       for (int i=0; i<=5; i++) //turn of all LED
        {
          strip.setBrightness(0); //by setting brightness to zero
          strip.show();
        }
   lightvalue = analogRead(A0); //kepp checking if the room is getting darker
    Serial.print("Too bright to glow: ");
    Serial.println(lightvalue); //for debugging
   Interactive_BT();  //Also check if the user is trying to access through bluetooth
   delay(100);
  }
 用户可以在interactive_BT函数中设置闹钟,或从手机控制灯。这个函数里面的代码注释部分介绍的很详细,因此我不再逐行解释。该程序的特点是它可以使用Android应用程序商店或Iphone商店中的任何蓝牙应用程序,并仍然可以与它进行交互。 
 接下来我们读取当前时间并更新时间对象“t”。我们使用t.hour和t.min得到小时和分钟值,并分别将它存储在变量current_time_hour和current_time_minute中。 复制代码  t = rtc.getTime(); //get the current time
  current_time_hour = t.hour; //get hour value
  current_time_minute = t.min; //get minute value
 在程序中,我每5秒更改一次Neo pixel的颜色,因此接下来的代码段将每5秒执行一次。在该代码段中,我们增加count的值并调用名为glow_rainbow的函数。此函数根据存储在current_rainbow数组中的颜色点亮LED。所以在调用该函数之前,我们必须根据一天中的时间使用morning_rainbow或evening_rainbow中的一组颜色加载当前颜色值,如下所示。 复制代码if (sleeping == false) //If we are not sleeping
      glow_rainbow(colour_count); //dsplay the colours
    if (sleeping == true) //if we are sleeping
      night_lamp(); //display the night lamp effect
   if (t.hour>=17) //During evening time
  {
    for (int i=0; i<=3; i++)
     { current_rainbow[i] = evening_rainbow[i]; delay(100);} //copy evening raninbow into current_rainbow
  }
  else //During Morning
  {
    for (int i=0; i<=3; i++)
     { current_rainbow[i] = morning_rainbow[i]; delay(100);} //copy  mornign rainboe into current rainbow
  }
 在glow_rainbow函数内部,我们使用了两个for循环,一个用于调暗LED,另一个用于根据所需颜色增加LED的亮度。 从数组current_rainboe [count]中选择所需的颜色,其中count决定数组的当前颜色。 在灯条中总共有5个LED,所以我使用变量i最大到5,根据你想减少多少亮度,j的值可以在0-255之间变化。 复制代码void glow_rainbow(int count)
{
    for (int j=150; j>=10; j--) //decrease the brightness to create dim effect
    {
      for (int i=0; i<=5; i++) //do it for all 5 leds
        {
          strip.setBrightness(j);
          strip.show();
        }
         1         delay(2);
    }
  for (int j=0; j<=255; j++) //increase the brightness
{
      for (int i=0; i<=5; i++) //do it for all 5 leds
        {
          strip.setPixelColor(i,Wheel(current_rainbow[count]));//select the colour based on count value
          strip.setBrightness(j);
          strip.show();
        }
                  delay(10);
}
}
 wheel函数直接取自Adafruit示例程序。 它接收0到255之间的值,并根据该值生成颜色。 这个值是我们最初在程序中使用#define宏定义的值。 函数如下所示。 复制代码// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color( (255 - WheelPos * 3), 0, (WheelPos * 3) );
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, (WheelPos * 3) , (255 - WheelPos * 3) );
  }
  WheelPos -= 170;
  return strip.Color((WheelPos * 3), (255 - WheelPos) * 3, 0);
}
 strip.Color(x,y,z) 函数很重要,它决定LED的颜色。 变量x、y和z各自取0-255的值,并根据该值确定LED应发射的红色、绿色和蓝色光的量。 因此x、y和z直接控制LED像素的红色、绿色和蓝色光强度。 |