Arduino Uno + APDS9930 实现手势控制LED灯亮灭调光等
Posted Love丶伊卡洛斯
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Arduino Uno + APDS9930 实现手势控制LED灯亮灭调光等相关的知识,希望对你有一定的参考价值。
目录
前言
开发板:Arduino Uno Rev3 创客主板
开发环境:Arduino IDE
开发语言:Arduino 语言(类C语言)
模块:APDS9930
源码参考:https://github.com/Depau/APDS9930
功能介绍:
1、靠近亮灯、距离保持约10cm常亮,远离延时熄灭
当有物体靠近传感器约10cm的位置时,触发中断,点亮LED LIGHT_TIME毫秒,持续触发则常亮,无则灭灯。 通过修改 宏定义 LIGHT_TIME调节延时,LED负极接在数字10口(正极 3.3V供电)
2、靠近点亮/熄灭LED,延时期间操作不响应
当有物体靠近传感器约10cm的位置时,触发中断,点亮/熄灭LED,延时RESPONSE_TIME毫秒,延时期间操作不响应。 通过修改 宏定义 RESPONSE_TIME调节延时响应。
3、挥手点亮/熄灭LED,悬停进行非无极pwm调光
当有物体靠近传感器约10cm的位置时,可以触发中断。
- 如果4RESPONSE_TIME毫秒内 没有触发4次中断,即4RESPONSE_TIME毫秒内,划过传感区域,则为开关模式,会进行LED的亮灭操作(亮到设定的pwm_val)
- 如果4RESPONSE_TIME毫秒内 触发了4次中断,即4RESPONSE_TIME毫秒以上,物体一直停留在传感区域内,则为pwm调光模式,会进行LED的pwm非无极调光(每次在当前基础上增加PWM_CHANGE_VAL)
- 如果在pwm调光模式下,物体移出了传感区域,则会结束pwm值的调节。若下次继续快划,则进行开关,若继续悬停,则继续调光。
- 单位延时RESPONSE_TIME毫秒,延时期间操作不响应。
- 通过修改 宏定义 RESPONSE_TIME调节延时响应,若想增加调光速率,可减小此值。
- 通过修改 宏定义 PWM_CHANGE_VAL,调节单次pwm调光的大小,范围1-255。若想要更细致的调光,可减小此值。
接线
Arduino Pin APDS-9930 Board Function
3.3V VL 据说用作参考电压,得接上
3.3V VCC Power
GND GND Ground
A4 SDA I2C Data
A5 SCL I2C Clock
2 INT Interrupt
10 - LED
效果图
Arduino+APDS9930 实现手势控制灯亮灭、调光等
源码
通用部分
APDS9930.cpp
/**
@file APDS-9930.cpp
@brief Library for the SparkFun APDS-9930 breakout board
@author Shawn Hymel (SparkFun Electronics)
@copyright This code is public domain but you buy me a beer if you use
this and we meet someday (Beerware license).
This library interfaces the Avago APDS-9930 to Arduino over I2C. The library
relies on the Arduino Wire (I2C) library. to use the library, instantiate an
APDS9930 object, call init(), and call the appropriate functions.
APDS-9930 current draw tests (default parameters):
Off: 1mA
Waiting for gesture: 14mA
Gesture in progress: 35mA
*/
#include <Arduino.h>
#include <Wire.h>
#include "APDS9930.h"
/**
@brief Constructor - Instantiates APDS9930 object
*/
APDS9930::APDS9930()
{
}
/**
@brief Destructor
*/
APDS9930::~APDS9930()
{
}
/**
@brief Configures I2C communications and initializes registers to defaults
@return True if initialized successfully. False otherwise.
*/
bool APDS9930::init()
{
uint8_t id;
/* Initialize I2C */
Wire.begin();
/* Read ID register and check against known values for APDS-9930 */
if ( !wireReadDataByte(APDS9930_ID, id) ) {
Serial.println(F("ID read"));
return false;
}
if ( !(id == APDS9930_ID_1 || id == APDS9930_ID_2) ) {
Serial.println(F("ID check"));
Serial.println(String("ID is ") + String(id, HEX));
//return false;
}
/* Set ENABLE register to 0 (disable all features) */
if ( !setMode(ALL, OFF) ) {
Serial.println(F("Regs off"));
return false;
}
/* Set default values for ambient light and proximity registers */
if ( !wireWriteDataByte(APDS9930_ATIME, DEFAULT_ATIME) ) {
return false;
}
if ( !wireWriteDataByte(APDS9930_WTIME, DEFAULT_WTIME) ) {
return false;
}
if ( !wireWriteDataByte(APDS9930_PPULSE, DEFAULT_PPULSE) ) {
return false;
}
if ( !wireWriteDataByte(APDS9930_POFFSET, DEFAULT_POFFSET) ) {
return false;
}
if ( !wireWriteDataByte(APDS9930_CONFIG, DEFAULT_CONFIG) ) {
return false;
}
if ( !setLEDDrive(DEFAULT_PDRIVE) ) {
return false;
}
if ( !setProximityGain(DEFAULT_PGAIN) ) {
return false;
}
if ( !setAmbientLightGain(DEFAULT_AGAIN) ) {
return false;
}
if ( !setProximityDiode(DEFAULT_PDIODE) ) {
return false;
}
if ( !setProximityIntLowThreshold(DEFAULT_PILT) ) {
return false;
}
if ( !setProximityIntHighThreshold(DEFAULT_PIHT) ) {
return false;
}
if ( !setLightIntLowThreshold(DEFAULT_AILT) ) {
return false;
}
if ( !setLightIntHighThreshold(DEFAULT_AIHT) ) {
return false;
}
if ( !wireWriteDataByte(APDS9930_PERS, DEFAULT_PERS) ) {
return false;
}
return true;
}
/*******************************************************************************
Public methods for controlling the APDS-9930
******************************************************************************/
/**
@brief Reads and returns the contents of the ENABLE register
@return Contents of the ENABLE register. 0xFF if error.
*/
uint8_t APDS9930::getMode()
{
uint8_t enable_value;
/* Read current ENABLE register */
if ( !wireReadDataByte(APDS9930_ENABLE, enable_value) ) {
return ERROR;
}
return enable_value;
}
/**
@brief Enables or disables a feature in the APDS-9930
@param[in] mode which feature to enable
@param[in] enable ON (1) or OFF (0)
@return True if operation success. False otherwise.
*/
bool APDS9930::setMode(uint8_t mode, uint8_t enable)
{
uint8_t reg_val;
/* Read current ENABLE register */
reg_val = getMode();
if ( reg_val == ERROR ) {
return false;
}
/* Change bit(s) in ENABLE register */
enable = enable & 0x01;
if ( mode >= 0 && mode <= 6 ) {
if (enable) {
reg_val |= (1 << mode);
} else {
reg_val &= ~(1 << mode);
}
} else if ( mode == ALL ) {
if (enable) {
reg_val = 0x7F;
} else {
reg_val = 0x00;
}
}
/* Write value back to ENABLE register */
if ( !wireWriteDataByte(APDS9930_ENABLE, reg_val) ) {
return false;
}
return true;
}
/**
@brief Starts the light (Ambient/IR) sensor on the APDS-9930
@param[in] interrupts true to enable hardware interrupt on high or low light
@return True if sensor enabled correctly. False on error.
*/
bool APDS9930::enableLightSensor(bool interrupts)
{
/* Set default gain, interrupts, enable power, and enable sensor */
if ( !setAmbientLightGain(DEFAULT_AGAIN) ) {
return false;
}
if ( interrupts ) {
if ( !setAmbientLightIntEnable(1) ) {
return false;
}
} else {
if ( !setAmbientLightIntEnable(0) ) {
return false;
}
}
if ( !enablePower() ) {
return false;
}
if ( !setMode(AMBIENT_LIGHT, 1) ) {
return false;
}
return true;
}
/**
@brief Ends the light sensor on the APDS-9930
@return True if sensor disabled correctly. False on error.
*/
bool APDS9930::disableLightSensor()
{
if ( !setAmbientLightIntEnable(0) ) {
return false;
}
if ( !setMode(AMBIENT_LIGHT, 0) ) {
return false;
}
return true;
}
/**
@brief Starts the proximity sensor on the APDS-9930
@param[in] interrupts true to enable hardware external interrupt on proximity
@return True if sensor enabled correctly. False on error.
*/
bool APDS9930::enableProximitySensor(bool interrupts)
{
/* Set default gain, LED, interrupts, enable power, and enable sensor */
if ( !setProximityGain(DEFAULT_PGAIN) ) {
return false;
}
if ( !setLEDDrive(DEFAULT_PDRIVE) ) {
return false;
}
if ( interrupts ) {
if ( !setProximityIntEnable(1) ) {
return false;
}
} else {
if ( !setProximityIntEnable(0) ) {
return false;
}
}
if ( !enablePower() ) {
return false;
}
if ( !setMode(PROXIMITY, 1) ) {
return false;
}
return true;
}
/**
@brief Ends the proximity sensor on the APDS-9930
@return True if sensor disabled correctly. False on error.
*/
bool APDS9930::disableProximitySensor()
{
if ( !setProximityIntEnable(0) ) {
return false;
}
if ( !setMode(PROXIMITY, 0) ) {
return false;
}
return true;
}
/**
Turn the APDS-9930 on
@return True if operation successful. False otherwise.
*/
bool APDS9930::enablePower()
{
if ( !setMode(POWER, 1) ) {
return false;
}
return true;
}
/**
Turn the APDS-9930 off
@return True if operation successful. False otherwise.
*/
bool APDS9930::disablePower()
{
if ( !setMode(POWER, 0) ) {
return false;
}
return true;
}
/*******************************************************************************
Ambient light sensor controls
******************************************************************************/
/**
@brief Reads the ambient (clear) light level as a 16-bit value
@param[out] val value of the light sensor.
@return True if operation successful. False otherwise.
*/
bool APDS9930::readAmbientLightLux(float &val)
{
uint16_t Ch0;
uint16_t Ch1;
/* Read value from channel 0 */
if ( !readCh0Light(Ch0) ) {
return false;
}
/* Read value from channel 1 */
if ( !readCh1Light(Ch1) ) {
return false;
}
val = floatAmbientToLux(Ch0, Ch1);
return true;
}
bool APDS9930::readAmbientLightLux(unsigned long &val)
{
uint16_t Ch0;
uint16_t Ch1;
/* Read value from channel 0 */
if ( !readCh0Light(Ch0) ) {
return false;
}
/* Read value from channel 1 */
if ( !readCh1Light(Ch1) ) {
return false;
}
val = ulongAmbientToLux(Ch0, Ch1);
return true;
}
float APDS9930::floatAmbientToLux(uint16_t Ch0, uint16_t Ch1)
{
uint8_t x[4] = {1, 8, 16, 120};
float ALSIT = 2.73 * (256 - DEFAULT_ATIME);
float iac = max(Ch0 - ALS_B * Ch1, ALS_C * Ch0 - ALS_D * Ch1);
if (iac < 0) iac = 0;
float lpc = GA * DF / (ALSIT * x[getAmbientLightGain()]);
return iac * lpc;
}
unsigned long APDS9930::ulongAmbientToLux(uint16_t Ch0, uint16_t Ch1)
{
uint8_t x[4] = {1, 8, 16, 120};
unsigned long ALSIT = 2.73 * (256 - DEFAULT_ATIME);
unsigned long iac = max(Ch0 - ALS_B * Ch1, ALS_C * Ch0 - ALS_D * Ch1);
if (iac < 0) iac = 0;
unsigned long lpc = GA * DF / (ALSIT * x[getAmbientLightGain()]);
return iac * lpc;
}
bool APDS9930::readCh0Light(uint16_t &val)
{
uint8_t val_byte;
val = 0;
/* Read value from channel 0 */
if ( !wireReadDataByte(APDS9930_Ch0DATAL, val_byte) ) {
return false;
}
val = val_byte;
if ( !wireReadDataByte(APDS9930_Ch0DATAH, val_byte) ) {
return false;
}
val += ((uint16_t)val_byte << 8);
return true;
}
bool APDS9930::readCh1Light(uint16_t &val)
{
uint8_t val_byte;
val = 0;
/* Read value from channel 0 */
if ( !wireReadDataByte(APDS9930_Ch1DATAL, val_byte) ) {
return false;
}
val = val_byte;
if ( !wireReadDataByte(APDS9930_Ch1DATAH, val_byte) ) {
return false;
}
val += ((uint16_t)val_byte << 8);
return true;
}
/*******************************************************************************
Proximity sensor controls
******************************************************************************/
/**
@brief Reads the proximity level as an 8-bit value
@param[out] val value of the proximity sensor.
@return True if operation successful. False otherwise.
*/
bool APDS9930::readProximity(uint16_t &val)
{
val = 0;
uint8_t val_byte;
/* Read value from proximity data register */
if ( !wireReadDataByte(APDS9930_PDATAL, val_byte) ) {
return false;
}
val = val_byte;
if ( !wireReadDataByte(APDS9930_PDATAH, val_byte) ) {
return false;
}
val += ((uint16_t)val_byte << 8);
return true;
}
/*******************************************************************************
Getters and setters for register values
******************************************************************************/
/**
@brief Returns the lower threshold for proximity detection
@return lower threshold
*/
uint16_t APDS9930::getProximityIntLowThreshold()
{
uint16_t val;
uint8_t val_byte;
/* Read value from PILT register */
if ( !wireReadDataByte(APDS9930_PILTL, val_byte) ) {
val = 0;
}
val = val_byte;
if ( !wireReadDataByte(APDS9930_PILTH, val_byte) ) {
val = 0;
}
val |= ((uint16_t)val_byte << 8);
return val;
}
/**
@brief Sets the lower threshold for proximity detection
@param[in] threshold the lower proximity threshold
@return True if operation successful. False otherwise.
*/
bool APDS9930::setProximityIntLowThreshold(uint16_t threshold)
{
uint8_t lo;
uint8_t hi;
hi = threshold >> 8;
lo = threshold & 0x00FF;
if ( !wireWriteDataByte(APDS9930_PILTL, lo) ) {
return false;
}
if ( !wireWriteDataByte(APDS9930_PILTH, hi) ) {
return false;
}
return true;
}
/**
@brief Returns the high threshold for proximity detection
@return high threshold
*/
uint16_t APDS9930::getProximityIntHighThreshold()
{
uint16_t val;
uint8_t val_byte;
怎麼用智峰软件给arduino uno r3烧bootloader
arduino leonardo r3 和 arduino uno r3 有啥区别