|
编程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像素的红色、绿色和蓝色光强度。 |