This lib allows control of VISHAY VCNL4000 distance/ambient light sensor via I2C bus.
Revision 0:1720792a6e28, committed 2012-02-14
- Comitter:
- bengo
- Date:
- Tue Feb 14 10:55:19 2012 +0000
- Commit message:
- This is first beta
Changed in this revision
VCNL4000.cpp | Show annotated file Show diff for this revision Revisions of this file |
VCNL4000.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VCNL4000.cpp Tue Feb 14 10:55:19 2012 +0000 @@ -0,0 +1,289 @@ +#include "VCNL4000.h" + +const int VCNL4000::VCNL4000address = 0x13; +const int VCNL4000::VCNL4000regAddr = 0x80; +const int VCNL4000::Command = 0x0; +const int VCNL4000::ProdIdRevision = 0x1; +const int VCNL4000::IRLedCurrent = 0x3; +const int VCNL4000::AmbientLightParam = 0x4; +const int VCNL4000::AmbientLightMsb = 0x5; +const int VCNL4000::AmbientLightLsb = 0x6; +const int VCNL4000::ProximityMsb = 0x7; +const int VCNL4000::ProximityLsb = 0x8; +const int VCNL4000::ProximitySigFreq = 0x9; +const int VCNL4000::ProxymityModulationTime = 0xa; + +// --------------------------------------------------- +VCNL4000::VCNL4000( PinName sda, PinName scl ) : _i2c( sda, scl ) { + + int prodId = getProductId(); + int prodRev = getProductRevision(); + + if( prodId == 1 && prodRev == 1 ) { + _status = 0; + } + else { + _status = 1; + } +} + +// --------------------------------------------------- +VCNL4000::~VCNL4000( void ) { +} + +// --------------------------------------------------- +int VCNL4000::registerRead( int reg ) { + + _bytes[0] = ( reg & 0xff ); + _status = _i2c.write( ( VCNL4000address << 1 ), _bytes, 1 ); + if( _status == 0 ) { + _status = _i2c.read( ( ( VCNL4000address << 1 ) + 1 ), _bytes, 1 ); + return( _bytes[0] ); + } + return( 0 ); +} + +// --------------------------------------------------- +void VCNL4000::registerWrite( int reg, unsigned char data ) { + + _bytes[0] = reg & 0xff; + _bytes[1] = data & 0xff; + _status = _i2c.write( VCNL4000address << 1, _bytes, 2 ); + +} + +// --------------------------------------------------- +int VCNL4000::getProximity( void ) { + + startProximityMeasurement(); + while( !proximityDataReady() ) { + wait(0.1); + } + _data = registerRead( VCNL4000regAddr + ProximityMsb ) << 8; + int status = _status; + _data += registerRead( VCNL4000regAddr + ProximityLsb ); + _status = _status | status; + return( _data ); +} + +// --------------------------------------------------- +int VCNL4000::getAmbientLight( void ) { + startAmbientLightMeasurement(); + while( !ambientLightDataReady() ) { + wait(0.1); + } + _data = registerRead( VCNL4000regAddr + AmbientLightMsb ) << 8; + int status = _status; + _data += registerRead( VCNL4000regAddr + AmbientLightLsb ); + _status = _status | status; + return( _data ); +} + +// --------------------------------------------------- +int VCNL4000::getProductId( void ) { + return( ( registerRead( VCNL4000regAddr + ProdIdRevision ) & 0xf0 ) >> 4 ); +} + +// --------------------------------------------------- +int VCNL4000::getProductRevision( void ) { + return( registerRead( VCNL4000regAddr + ProdIdRevision ) & 0x0f ) ; +} + +// --------------------------------------------------- +bool VCNL4000::proximityDataReady( void ) { + return( ( registerRead( VCNL4000regAddr + Command ) & 0x20 ) >> 5 ); +} + +// --------------------------------------------------- +bool VCNL4000::ambientLightDataReady( void ) { + return( ( registerRead( VCNL4000regAddr + Command ) & 0x40 ) >> 6 ); +} + +// --------------------------------------------------- +void VCNL4000::startProximityMeasurement( void ) { + _data = registerRead( VCNL4000regAddr + Command ); + if( _status == 0 ) { + _data = _data | 0x08; + registerWrite( VCNL4000regAddr + Command, _data ); + } +} + +// --------------------------------------------------- +void VCNL4000::startAmbientLightMeasurement( void ) { + _data = registerRead( VCNL4000regAddr + Command ); + if( _status == 0 ) { + _data = _data | 0x10; + registerWrite( VCNL4000regAddr + Command, _data ); + } +} + +// --------------------------------------------------- +void VCNL4000::setIRLedCurrent( int milliAmps ) { + milliAmps /= 10; + if( milliAmps > 20 ) { + _status = 1; + return; + } + _data = registerRead( VCNL4000regAddr + IRLedCurrent ); + if( _status == 0 ) { + _data = ( _data & 0xc0 ) | milliAmps; + registerWrite( VCNL4000regAddr + IRLedCurrent, _data ); + } +} + +// --------------------------------------------------- +void VCNL4000::enableALContinuousConversionMode( void ) { + _data = registerRead( VCNL4000regAddr + AmbientLightParam ); + if( _status == 0 ) { + _data = _data | 0x80; + registerWrite( VCNL4000regAddr + AmbientLightParam, _data ); + } +} + +// --------------------------------------------------- +void VCNL4000::disableALContinuousConversionMode( void ) { + _data = registerRead( VCNL4000regAddr + AmbientLightParam ); + if( _status == 0 ) { + _data = _data & 0x7f; + registerWrite( VCNL4000regAddr + AmbientLightParam, _data ); + } +} + +// --------------------------------------------------- +bool VCNL4000::isALContinuousConversionMode( void ) { + _data = registerRead( VCNL4000regAddr + AmbientLightParam ); + if( ( ( _data >> 7 ) & 1 ) == 1 ) { + return( true ); + } + else { + return( false ); + } +} + +// --------------------------------------------------- +void VCNL4000::enableALAutoOffsetCompensation( void ) { + _data = registerRead( VCNL4000regAddr + AmbientLightParam ); + if( _status == 0 ) { + _data = _data | 0x08; + registerWrite( VCNL4000regAddr + AmbientLightParam, _data ); + } +} + +// --------------------------------------------------- +void VCNL4000::disableALAutoOffsetCompensation( void ) { + _data = registerRead( VCNL4000regAddr + AmbientLightParam ); + if( _status == 0 ) { + _data = _data & 0xf7; + registerWrite( VCNL4000regAddr + AmbientLightParam, _data ); + } +} + +// --------------------------------------------------- +bool VCNL4000::iseALAutoOffsetCompensation( void ) { + _data = registerRead( VCNL4000regAddr + AmbientLightParam ); + if( ( ( _data >> 3 ) & 1 ) == 1 ) { + return( true ); + } + else { + return( false ); + } +} + +// --------------------------------------------------- +void VCNL4000::setALAveragingFunction( int measurements ) { + if( measurements > 7 ) { + _status = 1; + return; + } + _data = registerRead( VCNL4000regAddr + AmbientLightParam ); + if( _status == 0 ) { + _data = ( _data & 0xf8 ) | measurements; + registerWrite( VCNL4000regAddr + AmbientLightParam, _data ); + } +} + +// --------------------------------------------------- +int VCNL4000::gettALAveragingFunction( void ) { + _data = registerRead( VCNL4000regAddr + AmbientLightParam ); + if( _status == 0 ) { + return( _data & 0xf ); + } + else { + return( 0 ); + } +} + +// --------------------------------------------------- +void VCNL4000::setProximityMeasurementSigFreq( int frequency ) { + if( frequency > 3 ) { + _status = 1; + return; + } + _data = registerRead( VCNL4000regAddr + ProximitySigFreq ); + if( _status == 0 ) { + _data = ( _data & 0xfc ) | frequency; + registerWrite( VCNL4000regAddr + ProximitySigFreq, _data ); + } +} + +// --------------------------------------------------- +int VCNL4000::getProximityMeasurementSigFreq( void ) { + _data = registerRead( VCNL4000regAddr + ProximitySigFreq ); + if( _status == 0 ) { + return( _data & 0x3 ); + } + else { + return( 0 ); + } +} + +// --------------------------------------------------- +void VCNL4000::setProxiModulatorDelayTime( int delayTime ) { + if( delayTime > 7 ) { + _status = 1; + return; + } + _data = registerRead( VCNL4000regAddr + ProxymityModulationTime ); + if( _status == 0 ) { + _data = ( _data & 0x1f ) | ( delayTime << 5 ); + registerWrite( VCNL4000regAddr + ProxymityModulationTime, _data ); + } +} + +// --------------------------------------------------- +int VCNL4000::getProxiModulatorDelayTime( void ) { + _data = registerRead( VCNL4000regAddr + ProxymityModulationTime ); + if( _status == 0 ) { + return( ( _data >> 5 ) & 0x7 ); + } + else { + return( 0 ); + } +} + +// --------------------------------------------------- +void VCNL4000::setProxiModulatorDeadTime( int deadTime ) { + if( deadTime > 7 ) { + _status = 1; + return; + } + _data = registerRead( VCNL4000regAddr + ProxymityModulationTime ); + if( _status == 0 ) { + _data = ( _data & 0x07 ) | deadTime; + registerWrite( VCNL4000regAddr + ProxymityModulationTime, _data ); + } +} + +// --------------------------------------------------- +int VCNL4000::getProxiModulatorDeadTime( void ) { + _data = registerRead( VCNL4000regAddr + ProxymityModulationTime ); + if( _status == 0 ) { + return( _data & 0x7 ); + } + else { + return( 0 ); + } +} + +// --------------------------------------------------- +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VCNL4000.h Tue Feb 14 10:55:19 2012 +0000 @@ -0,0 +1,238 @@ +/* mbed VCNL4000 Library version 0beta1 + * Copyright (c) 2012 bengo + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef VCNL4000_H +#define VCNL4000_H + +#include "mbed.h" + +/** VCNL4000 distance/luminosity sensor controller library + * + * Example: + * @code + * #include "mbed.h" + * #include "VCNL4000.h" + * + * Serial pc(USBTX, USBRX); // tx, rx + * + * // ----------------------------------- + * int main() { + * + * VCNL4000 vcnl( p9, p10 ); + * + * int status = vcnl.getStatus(); + * + * if( status != 0 ) { + * pc.printf( "\x1b[2J\x1b[f Something went wrong with VCNL4000 access, status = %d.\n\r", status ); + * exit( 1 ); + * } + * + * vcnl.setALAveragingFunction( 0x0f ); + * vcnl.setIRLedCurrent( 2000 ); + * vcnl.setProximityMeasurementSigFreq( 2 ); + * vcnl.setProxiModulatorDelayTime( 0x04 ); + * vcnl.setProxiModulatorDeadTime( 0x01 ); + * + * while( 1 ) { + * int prox = vcnl.getProximity(); + * int ambl = vcnl.getAmbientLight(); + * pc.printf("\x1b[2J\x1b[f proxy: %d\n\r amb.l: %d\n\r", prox, ambl ); + * wait( 0.1 ); + * } + * } + * @endcode + */ + +class VCNL4000 { + + public: + + /** + * Create a VCNL4000 object connected to the specified I2C pins + * @param sda I2C SDA pin + * @param scl I2C SDL pin + */ + VCNL4000( PinName sda, PinName scl ); + + ~VCNL4000( void ); + + /** + * Return status code of previos function call + */ + inline int getStatus( void ) { return( _status ); } + + /** + * Read VCNL4000 internal register content + * @param reg register address + */ + int registerRead( int reg ); + + /** + * Send data to VCNL4000 internal register + * @param reg register address + * @param data value to be written + */ + void registerWrite( int reg, unsigned char data ); + + /** + * Read VCNL4000 proximity measurement + */ + int getProximity( void ); + + /** + * Read VCNL4000 ambient light measurement + */ + int getAmbientLight( void ); + + /** + * Get VCNL 4000 product id (should be 1) + */ + int getProductId( void ); + + /** + * Get VCNL 4000 product revision (should be 1) + */ + int getProductRevision( void ); + + /** + * Return True when a proximity data measurement completed + */ + bool proximityDataReady( void ); + + /** + * Return True when an ambient light measurement completed + */ + bool ambientLightDataReady( void ); + + /** + * Tell VCNL4000 to start a proximity measurement + */ + void startProximityMeasurement( void ); + + /** + * Tell VCNL4000 to start an ambient light measurement + */ + void startAmbientLightMeasurement( void ); + + /** + * Set VCNL4000 infrared led current + * @param milliAmps current in mA + */ + void setIRLedCurrent( int milliAmps ); + + /* + * Enable VCNL4000 continuous conversion mode + */ + void enableALContinuousConversionMode( void ); + + /* + * Disable VCNL4000 continuous conversion mode + */ + void disableALContinuousConversionMode( void ); + + /* + * Return True if VCNL4000 is set in continuous conversion mode + */ + bool isALContinuousConversionMode( void ); + + /* + * Enable ambient light auto offset compensation + */ + void enableALAutoOffsetCompensation( void ); + + /* + * Disable ambient light auto offset compensation + */ + void disableALAutoOffsetCompensation( void ); + + /* + * Return True if ambient light auto offset compensation is set + */ + bool iseALAutoOffsetCompensation( void ); + + /* + * Set ambient light averaging function + * @param measurements [0-7] 2^(measurements) = number of conversions + */ + void setALAveragingFunction( int measurements ); + + /* + * Return the averaging functions. Number of conversions = 2^value + */ + int gettALAveragingFunction( void ); + + /* + * Set proximity measurement signal frequency + * @param frequency [0-3] IR signal frequency 3.125/(frequency+1) + */ + void setProximityMeasurementSigFreq( int frequency ); + + /* + * Return IR signal frequency. Frequency = 3.125/(value+1) MHz + */ + int getProximityMeasurementSigFreq( void ); + + /* + * Set proximity modulator delay time + * @param delayTime delay time. This value should be provided by Vishay + */ + void setProxiModulatorDelayTime( int delayTime ); + + /* + * Return proximity modulator delay time + */ + int getProxiModulatorDelayTime( void ); + + /* + * Set proximity modulator dead time + * @param deadTime dead time. This value should be provided by Vishay + */ + void setProxiModulatorDeadTime( int deadTime ); + + /* + * Return proximity modulator dead time + */ + int getProxiModulatorDeadTime( void ); + + private: + + int _status; + char _bytes[2]; + int _data; + I2C _i2c; + + static const int VCNL4000address; + static const int VCNL4000regAddr; + static const int Command; + static const int ProdIdRevision; + static const int IRLedCurrent; + static const int AmbientLightParam; + static const int AmbientLightMsb; + static const int AmbientLightLsb; + static const int ProximityMsb; + static const int ProximityLsb; + static const int ProximitySigFreq; + static const int ProxymityModulationTime; + + }; + +#endif \ No newline at end of file