Lightbox II 三轴加速度传感器与RGBLED
来自t-table林宏的分享!
用三轴加速度计,rgb,简易电路,arduino编写的浪漫小灯!
详细内容请戳http://www.i-element.org/%E3%80%90%E6%95%99%E7%A8%8B%E3%80%91%E3%80%90lightbox-ii%E3%80%91%E4%B8%89%E8%BD%B4%E5%8A%A0%E9%80%9F%E5%BA%A6%E4%BC%A0%E6%84%9F%E5%99%A8%E4%B8%8Ergbled/
优酷地址:http://v.youku.com/v_show/id_XNzk3NDM3MzQw.html
代码如下:
#include <MsTimer2.h> //调用定时器库
#include <Wire.h>
#define Register_ID 0
#define Register_2D 0x2D
#define Register_X0 0x32
#define Register_X1 0x33
#define Register_Y0 0x34
#define Register_Y1 0x35
#define Register_Z0 0x36
#define Register_Z1 0x37
int ADXAddress = 0xA7 >> 1;
//存储加速度信息的变量
int X0, X1, Xg;
int Y0, Y1, Yg;
int Z1, Z0, Zg;
//三种颜色对应的引脚
int ledx = 9;
int ledy = 5;
int ledz = 6;
//声明7个计数器
int counterX, counterY, counterZ, counterT, counterx, countery, counterz;
//3个记录状态的变量
int stateX, stateY, stateZ;
//自变色状态下三种颜色的初始强度(相当于3个呼吸灯)
int valx = 60;
int valy = 130;
int valz = 195;
//自变色状态下三种颜色的变化速度
int fadeAmount1 = 3;
int fadeAmount2 = 6;
int fadeAmount3 = 9;
void setup() {
// Serial.begin(9600); //可以启动串口程序方便调试
// 各项初始化
Wire.begin();
delay(10);
Wire.beginTransmission(ADXAddress);
Wire.write(Register_2D);
Wire.write(8);
Wire.endTransmission();
pinMode(ledx, OUTPUT);
pinMode(ledy, OUTPUT);
pinMode(ledz, OUTPUT);
counterY = 0;
counterX = 0;
counterT = 0;
//X,Y,Z轴触发的状态均为关闭状态
stateX = 0;
stateY = 0;
stateZ = 0;
}
void loop() {
//全部熄灭
digitalWrite(ledx, 0);
digitalWrite(ledy, 0);
digitalWrite(ledz, 0);
//开始读取X,Y,Z轴加速度
Wire.beginTransmission(ADXAddress);
Wire.write(Register_X0);
Wire.write(Register_X1);
Wire.endTransmission();
Wire.requestFrom(ADXAddress, 2);
if (Wire.available() <= 2);
{
X0 = Wire.read();
X1 = Wire.read();
X1 = X1 << 8;
Xg = X0 + X1;
}
Wire.beginTransmission(ADXAddress);
Wire.write(Register_Y0);
Wire.write(Register_Y1);
Wire.endTransmission();
Wire.requestFrom(ADXAddress, 2);
if (Wire.available() <= 2);
{
Y0 = Wire.read();
Y1 = Wire.read();
Y1 = Y1 << 8;
Yg = Y0 + Y1;
}
Wire.beginTransmission(ADXAddress);
Wire.write(Register_Z0);
Wire.write(Register_Z1);
Wire.endTransmission();
Wire.requestFrom(ADXAddress, 2);
if (Wire.available() <= 2);
{
Z0 = Wire.read();
Z1 = Wire.read();
Z1 = Z1 << 8;
Zg = Z0 + Z1;
}
//判断X轴上的加速度是否到达阈值,到达则计数器X自加
if (Xg >= 500 || Xg <= -500) {
counterX++;
//如果计数器X开始计数,那么计时器开始计时,0.5秒后进入清零函数
if (counterX == 1) {
MsTimer2::set(500, Clear);
MsTimer2::start();
}
}
//如果在进入清零函数之前计数达到16以上,就打开X轴触发的状态(进入自变色状态)
if (counterX >= 16) { //16可改为其他数字,数字越小灵敏度越高
stateX = !stateX;
while (stateX == 1) {
fading();
}
}
if (Yg >= 500 || Yg <= -500) {
// checking Y
counterY++;
if (counterY == 1) {
MsTimer2::set(500, Clear);
MsTimer2::start();
}
}
if (counterY >= 16) {
stateY = !stateY;
while (stateY == 1) {
following();
}
}
if (Zg >= 500 || Zg <= -500) {
// checking Z
counterZ++;
if (counterZ == 1) {
MsTimer2::set(500, Clear);
MsTimer2::start();
}
}
if (counterZ >= 14) {
stateZ = !stateZ;
while (stateZ == 1) {
white();
}
}
delay(6);
// Serial.print("X=");
// Serial.print(Xg);
// Serial.print(" Y=");
// Serial.print(Yg);
// Serial.print(" Z=");
// Serial.print(Zg);
// Serial.print(" CX=");
// Serial.print(counterX);
// Serial.print(" CY=");
// Serial.print(counterY);
// Serial.print(" CZ=");
// Serial.println(counterZ);
}
void Clear() {
//所有的计数器清零
counterX = 0;
counterx = 0;
counterY = 0;
countery = 0;
counterZ = 0;
counterz = 0;
}
void white() {
//白光程序
digitalWrite(ledx, 1);
digitalWrite(ledy, 1);
digitalWrite(ledz, 1);
//读取Z轴上的加速度
Wire.beginTransmission(ADXAddress);
Wire.write(Register_Z0);
Wire.write(Register_Z1);
Wire.endTransmission();
Wire.requestFrom(ADXAddress, 2);
if (Wire.available() <= 2);
{
Z0 = Wire.read();
Z1 = Wire.read();
Z1 = Z1 << 8;
Zg = Z0 + Z1;
}
if (Zg >= 500 || Zg <= -500) {
counterz++;
if (counterz == 1) {
MsTimer2::set(500, Clear);
MsTimer2::start();
}
}
//如果计数器Z计数达到140以上,就关闭Z轴触发的状态,回到主程序
if (counterz >= 140) {
stateZ = !stateZ;
return;
}
// Serial.print("Z=");
// Serial.print(Zg);
// Serial.print(" CZ=");
// Serial.println(counterz);
}
void following() {
//跟随姿态变色的程序
int xfollow, yfollow, zfollow;
Wire.beginTransmission(ADXAddress);
Wire.write(Register_X0);
Wire.write(Register_X1);
Wire.endTransmission();
Wire.requestFrom(ADXAddress, 2);
if (Wire.available() <= 2);
{
X0 = Wire.read();
X1 = Wire.read();
X1 = X1 << 8;
Xg = X0 + X1;
}
Wire.beginTransmission(ADXAddress);
Wire.write(Register_Y0);
Wire.write(Register_Y1);
Wire.endTransmission();
Wire.requestFrom(ADXAddress, 2);
if (Wire.available() <= 2);
{
Y0 = Wire.read();
Y1 = Wire.read();
Y1 = Y1 << 8;
Yg = Y0 + Y1;
}
Wire.beginTransmission(ADXAddress);
Wire.write(Register_Z0);
Wire.write(Register_Z1);
Wire.endTransmission();
Wire.requestFrom(ADXAddress, 2);
if (Wire.available() <= 2);
{
Z0 = Wire.read();
Z1 = Wire.read();
Z1 = Z1 << 8;
Zg = Z0 + Z1;
}
//限定X,Z轴的数值,避免出现颜色的跳变,Y轴由于要留作退出程序的判断所以不限定
Xg = constrain(Xg, -272, 272);
// Yg = constrain(Yg, -272, 272);
Zg = constrain(Zg, -272, 272);
xfollow = map(Xg, -272, 272, 5, 250);
analogWrite(ledx, xfollow);
yfollow = map(Yg, -290, 290, 5, 250);
analogWrite(ledy, yfollow);
zfollow = map(Zg, -272, 272, 5, 250);
analogWrite(ledz, zfollow);
//防止溢出产生的颜色跳变
xfollow = constrain(xfollow, 1, 255);
yfollow = constrain(yfollow, 1, 255);
zfollow = constrain(zfollow, 1, 255);
if (Yg >= 500 || Yg <= -500) {
countery++;
if (countery == 1) {
MsTimer2::set(500, Clear);
MsTimer2::start();
}
}
if (countery >= 40 ) {
stateY = !stateY;
return;
}
// Serial.print("Y=");
// Serial.print(Yg);
// Serial.print(" CY=");
// Serial.println(countery);
}
void fading() {
//自变色函数
analogWrite(ledx, valx);
analogWrite(ledy, valy);
analogWrite(ledz, valz);
valx = valx + fadeAmount1;
valy = valy + fadeAmount2;
valz = valz + fadeAmount3;
if (valx <= 4 || valx >= 252) {
fadeAmount1 = -fadeAmount1 ;
}
if (valy <= 7 || valy >= 249) {
fadeAmount2 = -fadeAmount2 ;
}
if (valz <= 10 || valz >= 246) {
fadeAmount3 = -fadeAmount3 ;
}
delay(90);
Wire.beginTransmission(ADXAddress);
Wire.write(Register_X0);
Wire.write(Register_X1);
Wire.endTransmission();
Wire.requestFrom(ADXAddress, 2);
if (Wire.available() <= 2);
{
X0 = Wire.read();
X1 = Wire.read();
X1 = X1 << 8;
Xg = X0 + X1;
}
if (Xg >= 500 || Xg <= -500) {
counterx++;
if (counterx == 1) {
MsTimer2::set(500, Clear);
MsTimer2::start();
}
}
if (counterx >= 2) {
stateX = !stateX;
return;
}
// Serial.print("X=");
// Serial.print(Xg);
// Serial.print(" CX=");
// Serial.println(counterx);
}
|