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