Skip to content

Instantly share code, notes, and snippets.

@DrewDahlman
Last active March 15, 2017 19:21
Show Gist options
  • Save DrewDahlman/247d524fd62d74b9d04f411857b1b0e2 to your computer and use it in GitHub Desktop.
Save DrewDahlman/247d524fd62d74b9d04f411857b1b0e2 to your computer and use it in GitHub Desktop.
"use strict"
/*
Copyright (c) 2017. All Rights Reserved.
Author: Drew Dahlman - Legwork Studio.
VL53L0X API Wrapper ported to tessel. This acts as a simple wrapper for the VL53L0X Time Of Flight Sensor.
Ported from https://github.com/pololu/vl53l0x-arduino
*/
// Constants
const tessel = require('tessel');
const Queue = require('sync-queue');
const FloatBuffer = require('../utils/float-buffer');
const REGISTRY = require('../lib/registry');
const EventEmitter = require('events').EventEmitter;
const util = require('util');
class VL53L0X extends EventEmitter {
/*
------------------------------------------
| constructor:void (-)
------------------------------------------ */
constructor( port ){
super();
// Assign I2C Address
this.i2c = new port.I2C( REGISTRY.I2C_ADDR );
// Queue system
this.queue = new Queue();
// Internal Variables
this._last_status;
this._io_timeout = 0; // 16
this._did_timeout = false;
this._timeout_start_ms = Date.now(); // 16
this._stop_variable; // 8
this._measurement_timing_budget_us; // 32
this._sequenceStepEnables = {
tcc: true,
msrc: true,
dss: true,
pre_range: true,
final_range: true
};
this._sequenceStepTimeouts = {
pre_range_vcsel_period_pclks: 0, // 16_t
final_range_vcsel_period_pclks: 0, // 16_t
msrc_dss_tcc_mclks: 0, // 16_t
pre_range_mclks: 0, // 16_t
final_range_mclks: 0, // 16_t
msrc_dss_tcc_us: 0, // 32_t
pre_range_us: 0, // 32_t
final_range_us: 0 // 32_t
}
// Internal Helper Methods
this._startTimeout = () => { return this._timeout_start_ms };
this._checkTimeoutExpired = () => {
return (this._io_timeout > 0 && Date.now() - this._timeout_start_ms > this._io_timeout);
};
this._decodeVcselPeriod = ( reg_val ) => {
return (((reg_val) + 1) << 1);
};
this._encodeVcselPeriod = ( period_pclks ) => {
return (((period_pclks) >> 1) - 1);
};
this._calcMacroPeriod = ( vcsel_period_pclks ) => {
return (((2304 * (vcsel_period_pclks) * 1655) + 500) / 1000);
};
// Not totally clear yet
this._getSequenceStepEnables = ( sequences ) => {
};
this._getSequenceStepTimeouts = ( callback ) => {
// pre_range_vcsel_period_pclks
this._readRegisters(REGISTRY.PRE_RANGE_CONFIG_VCSEL_PERIOD, 8, (err, data) => {
this._sequenceStepTimeouts.pre_range_vcsel_period_pclks = data.readInt16BE(0);
// msrc_dss_tcc_mclks
this._readRegisters(REGISTRY.MSRC_CONFIG_TIMEOUT_MACROP, 8, (err, data) => {
this._sequenceStepTimeouts.msrc_dss_tcc_mclks = data.readInt16BE(0) + 1;
// msrc_dss_tcc_us
this._sequenceStepTimeouts.msrc_dss_tcc_us = this.timeoutMclksToMicroseconds(this._sequenceStepTimeouts.msrc_dss_tcc_mclks, this._sequenceStepTimeouts.pre_range_vcsel_period_pclks);
// pre_range_mclks
this._readRegisters(REGISTRY.PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI, 8, (err, data) => {
this._sequenceStepTimeouts.pre_range_mclks = this.decodeTimeout( data.readInt16BE(0) );
// pre_range_us
this._sequenceStepTimeouts.pre_range_us = this.timeoutMclksToMicroseconds(this._sequenceStepTimeouts.pre_range_mclks, this._sequenceStepTimeouts.pre_range_vcsel_period_pclks);
// final_range_vcsel_period_pclks
this._readRegisters(REGISTRY.FINAL_RANGE_CONFIG_VCSEL_PERIOD, 8, (err, data) => {
this._sequenceStepTimeouts.final_range_vcsel_period_pclks = data.readInt16BE(0);
// final_range_mclks
this._readRegisters(REGISTRY.FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI, 8, (err, data) => {
this._sequenceStepTimeouts.final_range_mclks = this.decodeTimeout(data.readInt16BE(0));
//final_range_us
this._sequenceStepTimeouts.final_range_us = this.timeoutMclksToMicroseconds(this._sequenceStepTimeouts.final_range_mclks, this._sequenceStepTimeouts.final_range_vcsel_period_pclks);
callback( this._sequenceStepTimeouts );
});
});
});
});
});
};
}
/*
------------------------------------------
| method_name:void (-)
|
| Description.
------------------------------------------ */
startCapture(){
this._writeRegisters(REGISTRY.SYSRANGE_START, 0x02);
let _distanceBuffer = new FloatBuffer( 15 );
_distanceBuffer.update(1);
setInterval( () => {
// this._readRegisters(REGISTRY.RESULT_RANGE_STATUS, 16, (err, data) => {
this._readRegisters(REGISTRY.RESULT_RANGE_STATUS, 16, (err, data) => {
// console.log(data.readInt16BE(8));
// var distance = data.readInt16BE(8);
// self.emit('laser', distance);
// console.log(data);
// console.log(data.readInt8())
var _dis = (data.readInt16BE(8) + 10);
_distanceBuffer.update( _dis );
var _distance = Math.round(_distanceBuffer.average());
// console.log( _distance )
this.emit('laser', _distance);
});
},33);
}
/*
------------------------------------------
| setSignalRateLimit:bool (-)
|
| Set the return signal rate limit check value in units of MCPS (mega counts
| per second). "This represents the amplitude of the signal reflected from the
| target and detected by the device"; setting this limit presumably determines
| the minimum measurement necessary for the sensor to report a valid reading.
|
| Setting a lower limit increases the potential range of the sensor but also
| seems to increase the likelihood of getting an inaccurate reading because of
| unwanted reflections from objects other than the intended target.
| Defaults to 0.25 MCPS as initialized by the ST API and this library.
------------------------------------------ */
setSignalRateLimit( limit_Mcps, callback ){
if (limit_Mcps < 0 || limit_Mcps > 511.99) { return false; }
let _data = (limit_Mcps * (1 << 7)).toFixed(7);
// Q9.7 fixed point format (9 integer bits, 7 fractional bits)
this._writeRegisters( REGISTRY.FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT, _data, (err, data) => {
console.log("SIGNAL SET: " + data);
if( callback ){
callback()
}
});
return true;
}
/*
------------------------------------------
| getSignalRateLimit:void (-)
| Get the return signal rate limit check value in MCPS
------------------------------------------ */
getSignalRateLimit( callback ){
this._readRegisters( REGISTRY.FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT, 16, (err, data) => {
let _data = (data.readInt16BE(0)) / (1 << 7);
if( callback ){
callback( _data );
}
});
}
/*
------------------------------------------
| setMeasurementTimingBudget:bool (-)
|
| Set the measurement timing budget in microseconds, which is the time allowed
| for one measurement; the ST API and this library take care of splitting the
| timing budget among the sub-steps in the ranging sequence. A longer timing
| budget allows for more accurate measurements. Increasing the budget by a
| factor of N decreases the range measurement standard deviation by a factor of
| sqrt(N). Defaults to about 33 milliseconds; the minimum is 20 ms.
| based on VL53L0X_set_measurement_timing_budget_micro_seconds()
------------------------------------------ */
setMeasurementTimingBudget( budget_us ){
// SequenceStepEnables enables;
// SequenceStepTimeouts timeouts;
// const timeouts = this._sequenceStepTimeouts;
// const callback = cb;
this._getSequenceStepTimeouts( (timeouts) => {
const enables = this._sequenceStepEnables;
const StartOverhead = 1320; // note that this is different than the value in get_
const EndOverhead = 960;
const MsrcOverhead = 660;
const TccOverhead = 590;
const DssOverhead = 690;
const PreRangeOverhead = 660;
const FinalRangeOverhead = 550;
const MinTimingBudget = 20000;
// if ( budget_us < MinTimingBudget ) { return false; }
let used_budget_us = StartOverhead + EndOverhead;
// getSequenceStepEnables(&enables);
// getSequenceStepTimeouts(&enables, &timeouts);
if (enables.tcc) {
used_budget_us += (timeouts.msrc_dss_tcc_us + TccOverhead);
}
if (enables.dss) {
used_budget_us += 2 * (timeouts.msrc_dss_tcc_us + DssOverhead);
}
else if (enables.msrc) {
used_budget_us += (timeouts.msrc_dss_tcc_us + MsrcOverhead);
}
if (enables.pre_range) {
used_budget_us += (timeouts.pre_range_us + PreRangeOverhead);
}
if (enables.final_range) {
used_budget_us += FinalRangeOverhead;
// "Note that the final range timeout is determined by the timing
// budget and the sum of all other timeouts within the sequence.
// If there is no room for the final range timeout, then an error
// will be set. Otherwise the remaining time will be applied to
// the final range."
// if (used_budget_us > budget_us) {
// // "Requested timeout too big."
// console.log("FAIL");
// console.log(used_budget_us, budget_us)
// return false;
// }
let final_range_timeout_us = budget_us - used_budget_us;
// set_sequence_step_timeout() begin
// (SequenceStepId == VL53L0X_SEQUENCESTEP_FINAL_RANGE)
// "For the final range timeout, the pre-range timeout
// must be added. To do this both final and pre-range
// timeouts must be expressed in macro periods MClks
// because they have different vcsel periods."
let final_range_timeout_mclks = this.timeoutMicrosecondsToMclks(final_range_timeout_us, timeouts.final_range_vcsel_period_pclks);
if (enables.pre_range) {
final_range_timeout_mclks += timeouts.pre_range_mclks;
}
// writeReg16Bit(FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI, this.encodeTimeout(final_range_timeout_mclks));
console.log(final_range_timeout_mclks);
this._writeRegisters( REGISTRY.FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI, this.encodeTimeout(final_range_timeout_mclks) );
// set_sequence_step_timeout() end
this._measurement_timing_budget_us = budget_us; // store for internal reuse
}
// callback()
console.log(this._measurement_timing_budget_us)
});
return true;
}
/*
------------------------------------------
| getMeasurementTimingBudget:void (-)
| Get the measurement timing budget in microseconds
| based on VL53L0X_get_measurement_timing_budget_micro_seconds()
| in us
------------------------------------------ */
getMeasurementTimingBudget( callback ){
const enables = this._sequenceStepEnables;
// const timeouts = this._sequenceStepTimeouts;
this._getSequenceStepTimeouts( (timeouts) => {
const StartOverhead = 1910; // note that this is different than the value in set_
const EndOverhead = 960;
const MsrcOverhead = 660;
const TccOverhead = 590;
const DssOverhead = 690;
const PreRangeOverhead = 660;
const FinalRangeOverhead = 550;
// "Start and end overhead times always present"
let budget_us = StartOverhead + EndOverhead;
if (enables.tcc) {
budget_us += (timeouts.msrc_dss_tcc_us + TccOverhead);
}
if (enables.dss) {
budget_us += 2 * (timeouts.msrc_dss_tcc_us + DssOverhead);
}
else if (enables.msrc) {
budget_us += (timeouts.msrc_dss_tcc_us + MsrcOverhead);
}
if (enables.pre_range) {
budget_us += (timeouts.pre_range_us + PreRangeOverhead);
}
if (enables.final_range) {
budget_us += (timeouts.final_range_us + FinalRangeOverhead);
}
this._measurement_timing_budget_us = budget_us; // store for internal reuse
callback( budget_us );
return budget_us;
});
}
/*
------------------------------------------
| setVcselPulsePeriod:bool (-)
|
| Set the VCSEL (vertical cavity surface emitting laser) pulse period for the
| given period type (pre-range or final range) to the given value in PCLKs.
| Longer periods seem to increase the potential range of the sensor.
| Valid values are (even numbers only):
| pre: 12 to 18 (initialized default: 14)
| final: 8 to 14 (initialized default: 10)
| based on VL53L0X_set_vcsel_pulse_period()
------------------------------------------ */
setVcselPulsePeriod(vcselPeriodType, period_pclks, callback){
let vcsel_period_reg = this._encodeVcselPeriod(period_pclks);
const enables = this._sequenceStepEnables;
this._getSequenceStepTimeouts( ( timeouts ) => {
// "Apply specific settings for the requested clock period"
// "Re-calculate and apply timeouts, in macro periods"
// "When the VCSEL period for the pre or final range is changed,
// the corresponding timeout must be read from the device using
// the current VCSEL period, then the new VCSEL period can be
// applied. The timeout then must be written back to the device
// using the new VCSEL period.
//
// For the MSRC timeout, the same applies - this timeout being
// dependant on the pre-range vcsel period."
if (vcselPeriodType == "VcselPeriodPreRange") {
// "Set phase check limits"
switch (period_pclks) {
case 12:
this._writeRegisters(REGISTRY.PRE_RANGE_CONFIG_VALID_PHASE_HIGH, 0x18);
break;
case 14:
this._writeRegisters(REGISTRY.PRE_RANGE_CONFIG_VALID_PHASE_HIGH, 0x30);
break;
case 16:
this._writeRegisters(REGISTRY.PRE_RANGE_CONFIG_VALID_PHASE_HIGH, 0x40);
break;
case 18:
this._writeRegisters(REGISTRY.PRE_RANGE_CONFIG_VALID_PHASE_HIGH, 0x50);
break;
default:
// invalid period
return false;
}
this._writeRegisters(REGISTRY.PRE_RANGE_CONFIG_VALID_PHASE_LOW, 0x08);
// apply new VCSEL period
this._writeRegisters(REGISTRY.PRE_RANGE_CONFIG_VCSEL_PERIOD, vcsel_period_reg);
// update timeouts
// set_sequence_step_timeout() begin
// (SequenceStepId == VL53L0X_SEQUENCESTEP_PRE_RANGE)
let new_pre_range_timeout_mclks = this.timeoutMicrosecondsToMclks(timeouts.pre_range_us, period_pclks);
this._writeRegisters(REGISTRY.PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI, this.encodeTimeout(new_pre_range_timeout_mclks));
// set_sequence_step_timeout() end
// set_sequence_step_timeout() begin
// (SequenceStepId == VL53L0X_SEQUENCESTEP_MSRC)
let new_msrc_timeout_mclks = this.timeoutMicrosecondsToMclks(timeouts.msrc_dss_tcc_us, period_pclks);
this._writeRegisters(REGISTRY.MSRC_CONFIG_TIMEOUT_MACROP, (new_msrc_timeout_mclks > 256) ? 255 : (new_msrc_timeout_mclks - 1));
// set_sequence_step_timeout() end
} else if (vcselPeriodType == "VcselPeriodFinalRange") {
switch (period_pclks){
case 8:
this._writeRegisters(REGISTRY.FINAL_RANGE_CONFIG_VALID_PHASE_HIGH, 0x10);
this._writeRegisters(REGISTRY.FINAL_RANGE_CONFIG_VALID_PHASE_LOW, 0x08);
this._writeRegisters(REGISTRY.GLOBAL_CONFIG_VCSEL_WIDTH, 0x02);
this._writeRegisters(REGISTRY.ALGO_PHASECAL_CONFIG_TIMEOUT, 0x0C);
this._writeRegisters(0xFF, 0x01);
this._writeRegisters(REGISTRY.ALGO_PHASECAL_LIM, 0x30);
this._writeRegisters(0xFF, 0x00);
break;
case 10:
this._writeRegisters(REGISTRY.FINAL_RANGE_CONFIG_VALID_PHASE_HIGH, 0x28);
this._writeRegisters(REGISTRY.FINAL_RANGE_CONFIG_VALID_PHASE_LOW, 0x08);
this._writeRegisters(REGISTRY.GLOBAL_CONFIG_VCSEL_WIDTH, 0x03);
this._writeRegisters(REGISTRY.ALGO_PHASECAL_CONFIG_TIMEOUT, 0x09);
this._writeRegisters(0xFF, 0x01);
this._writeRegisters(REGISTRY.ALGO_PHASECAL_LIM, 0x20);
this._writeRegisters(0xFF, 0x00);
break;
case 12:
this._writeRegisters(REGISTRY.FINAL_RANGE_CONFIG_VALID_PHASE_HIGH, 0x38);
this._writeRegisters(REGISTRY.FINAL_RANGE_CONFIG_VALID_PHASE_LOW, 0x08);
this._writeRegisters(REGISTRY.GLOBAL_CONFIG_VCSEL_WIDTH, 0x03);
this._writeRegisters(REGISTRY.ALGO_PHASECAL_CONFIG_TIMEOUT, 0x08);
this._writeRegisters(0xFF, 0x01);
this._writeRegisters(REGISTRY.ALGO_PHASECAL_LIM, 0x20);
this._writeRegisters(0xFF, 0x00);
break;
case 14:
this._writeRegisters(REGISTRY.FINAL_RANGE_CONFIG_VALID_PHASE_HIGH, 0x48);
this._writeRegisters(REGISTRY.FINAL_RANGE_CONFIG_VALID_PHASE_LOW, 0x08);
this._writeRegisters(REGISTRY.GLOBAL_CONFIG_VCSEL_WIDTH, 0x03);
this._writeRegisters(REGISTRY.ALGO_PHASECAL_CONFIG_TIMEOUT, 0x07);
this._writeRegisters(0xFF, 0x01);
this._writeRegisters(REGISTRY.ALGO_PHASECAL_LIM, 0x20);
this._writeRegisters(0xFF, 0x00);
break;
default:
// invalid period
return false;
}
// apply new VCSEL period
this._writeRegisters(REGISTRY.FINAL_RANGE_CONFIG_VCSEL_PERIOD, vcsel_period_reg);
// update timeouts
// set_sequence_step_timeout() begin
// (SequenceStepId == VL53L0X_SEQUENCESTEP_FINAL_RANGE)
// "For the final range timeout, the pre-range timeout
// must be added. To do this both final and pre-range
// timeouts must be expressed in macro periods MClks
// because they have different vcsel periods."
let new_final_range_timeout_mclks = this.timeoutMicrosecondsToMclks(timeouts.final_range_us, period_pclks);
if (enables.pre_range) {
new_final_range_timeout_mclks += timeouts.pre_range_mclks;
}
this._writeRegisters(REGISTRY.FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI, this.encodeTimeout(new_final_range_timeout_mclks));
// set_sequence_step_timeout end
} else {
// invalid type
return false;
}
// "Finally, the timing budget must be re-applied"
this.setMeasurementTimingBudget(this._measurement_timing_budget_us);
// "Perform the phase calibration. This is needed after changing on vcsel period."
// VL53L0X_perform_phase_calibration() begin
this._readRegisters(REGISTRY.SYSTEM_SEQUENCE_CONFIG, 16, (err, data) => {
let sequence_config = data.readInt8();
this._writeRegisters(REGISTRY.SYSTEM_SEQUENCE_CONFIG, 0x02, () => {
this.performSingleRefCalibration(0x0);
this._writeRegisters(REGISTRY.SYSTEM_SEQUENCE_CONFIG, sequence_config, (data) => {
if( callback ){
callback(data)
}
});
// VL53L0X_perform_phase_calibration() end
return true;
});
});
});
}
/*
------------------------------------------
| getVcselPulsePeriod:void (-)
| Get the VCSEL pulse period in PCLKs for the given period type.
| based on VL53L0X_get_vcsel_pulse_period()
| ## TODO: Come Back
------------------------------------------ */
getVcselPulsePeriod(vcselPeriodType){
if (type == VcselPeriodPreRange) {
return this._decodeVcselPeriod(this._readRegisters(REGISTRY.PRE_RANGE_CONFIG_VCSEL_PERIOD));
}
else if (type == VcselPeriodFinalRange) {
return this._decodeVcselPeriod(this._readRegisters(REGISTRY.FINAL_RANGE_CONFIG_VCSEL_PERIOD));
}
else { return 255; }
}
/*
------------------------------------------
| startContinuous:void (-)
| Start continuous ranging measurements. If period_ms (optional) is 0 or not
| given, continuous back-to-back mode is used (the sensor takes measurements as
| often as possible); otherwise, continuous timed mode is used, with the given
| inter-measurement period in milliseconds determining how often the sensor
| takes a measurement.
| based on VL53L0X_StartMeasurement()
------------------------------------------ */
startContinuous(period_ms){
this._writeRegisters(0x80, 0x01);
this._writeRegisters(0xFF, 0x01);
this._writeRegisters(0x00, 0x00);
this._writeRegisters(0x91, this._stop_variable);
this._writeRegisters(0x00, 0x01);
this._writeRegisters(0xFF, 0x00);
this._writeRegisters(0x80, 0x00);
if (period_ms != 0) {
// continuous timed mode
// VL53L0X_SetInterMeasurementPeriodMilliSeconds() begin
this._readRegisters(REGISTRY.OSC_CALIBRATE_VAL, 16, (err, data) => {
let osc_calibrate_val = data;
if (osc_calibrate_val != 0) {
period_ms *= osc_calibrate_val;
this._writeRegisters(REGISTRY.SYSTEM_INTERMEASUREMENT_PERIOD, period_ms);
// VL53L0X_SetInterMeasurementPeriodMilliSeconds() end
this._writeRegisters(REGISTRY.SYSRANGE_START, 0x04); // VL53L0X_REG_SYSRANGE_MODE_TIMED
} else {
// continuous back-to-back mode
this._writeRegisters(REGISTRY.SYSRANGE_START, 0x02); // VL53L0X_REG_SYSRANGE_MODE_BACKTOBACK
}
});
}
}
/*
------------------------------------------
| stopContinuous:void (-)
|
| Stop continuous measurements
| based on VL53L0X_StopMeasurement()
------------------------------------------ */
stopContinuous(){
this._writeRegisters(REGISTRY.SYSRANGE_START, 0x01); // VL53L0X_REG_SYSRANGE_MODE_SINGLESHOT
this._writeRegisters(0xFF, 0x01);
this._writeRegisters(0x00, 0x00);
this._writeRegisters(0x91, 0x00);
this._writeRegisters(0x00, 0x01);
this._writeRegisters(0xFF, 0x00);
}
/*
------------------------------------------
| readRangeContinuousMillimeters:void (-)
| Returns a range reading in millimeters when continuous mode is active
| (readRangeSingleMillimeters() also calls this function after starting a
| single-shot range measurement)
| ## TODO: Come back
------------------------------------------ */
readRangeContinuousMillimeters(){
this._startTimeout();
while ((this._readRegisters(REGISTRY.RESULT_INTERRUPT_STATUS) & 0x07) == 0) {
if (checkTimeoutExpired()) {
this._did_timeout = true;
return 65535;
}
}
// assumptions: Linearity Corrective Gain is 1000 (default);
// fractional ranging is not enabled
let range = this._readRegisters(REGISTRY.RESULT_RANGE_STATUS + 10);
this._writeRegisters(REGISTRY.SYSTEM_INTERRUPT_CLEAR, 0x01);
return range;
}
/*
------------------------------------------
| readRangeSingleMillimeters:void (-)
| uint16_t
------------------------------------------ */
readRangeSingleMillimeters(){
}
/*
------------------------------------------
| timeoutOccurred:bool (-)
------------------------------------------ */
timeoutOccurred(){
let tmp = this._did_timeout;
this._did_timeout = false;
return tmp;
}
/*
------------------------------------------
| getSpadInfo:bool (-)
------------------------------------------ */
getSpadInfo( count, type_is_aperture ){
}
/*
------------------------------------------
| performSingleRefCalibration:void (-)
| based on VL53L0X_perform_single_ref_calibration()
------------------------------------------ */
performSingleRefCalibration( vhv_init_byte ){
this._writeRegisters(REGISTRY.SYSRANGE_START, 0x01 | vhv_init_byte); // VL53L0X_REG_SYSRANGE_MODE_START_STOP
// // startTimeout();
// while ((readReg(RESULT_INTERRUPT_STATUS) & 0x07) == 0)
// {
// if (checkTimeoutExpired()) { return false; }
// }
this._writeRegisters(REGISTRY.SYSTEM_INTERRUPT_CLEAR, 0x01);
this._writeRegisters(REGISTRY.SYSRANGE_START, 0x00);
return true;
}
/*
------------------------------------------
| decodeTimeout:uint16_t (-)
| Decode sequence step timeout in MCLKs from register value
| based on VL53L0X_decode_timeout()
| Note: the original function returned a uint32_t, but the return value is
| always stored in a uint16_t.
------------------------------------------ */
decodeTimeout( value ){
return ((value & 0x00FF) << ((value & 0xFF00) >> 8)) + 1;
}
/*
------------------------------------------
| encodeTimeout:uint16_t (-)
| Encode sequence step timeout register value from timeout in MCLKs
| based on VL53L0X_encode_timeout()
| Note: the original function took a uint16_t, but the argument passed to it
| is always a uint16_t.
------------------------------------------ */
encodeTimeout( timeout_mclks ){
// format: "(LSByte * 2^MSByte) + 1"
let ls_byte = 0;
let ms_byte = 0;
if (timeout_mclks > 0) {
ls_byte = timeout_mclks - 1;
while ((ls_byte & 0xFFFFFF00) > 0) {
ls_byte >>= 1;
ms_byte++;
}
return (ms_byte << 8) | (ls_byte & 0xFF);
}
else { return 0; }
}
/*
------------------------------------------
| timeoutMclksToMicroseconds:uint32_t (-)
| Convert sequence step timeout from MCLKs to microseconds with given VCSEL period in PCLKs
------------------------------------------ */
timeoutMclksToMicroseconds( timeout_period_mclks, vcsel_period_pclks ){
let macro_period_ns = this._calcMacroPeriod(vcsel_period_pclks);
return ((timeout_period_mclks * macro_period_ns) + (macro_period_ns / 2)) / 1000;
}
/*
------------------------------------------
| timeoutMicrosecondsToMclks:uint32_t (-)
| Convert sequence step timeout from microseconds to MCLKs with given VCSEL period in PCLKs
| based on VL53L0X_calc_timeout_mclks()
------------------------------------------ */
timeoutMicrosecondsToMclks( timeout_period_us, vcsel_period_pclks ){
let macro_period_ns = this._calcMacroPeriod(vcsel_period_pclks);
return (((timeout_period_us * 1000) + (macro_period_ns / 2)) / macro_period_ns);
}
/*
------------------------------------------
| _readRegisters:void (-)
|
| Read the registers via I2C.
------------------------------------------ */
_readRegisters(addressToRead, bytesToRead, callback){
this.queue.place( () => {
this.i2c.transfer( new Buffer([addressToRead]), bytesToRead, (err, data) => {
this.queue.next();
if( callback ){
callback(err, data);
}
})
});
}
/*
------------------------------------------
| _writeRegisters:void (-)
|
| Write to the register via I2C.
------------------------------------------ */
_writeRegisters(addressToRead, dataToWrite, callback){
// console.log(addressToRead, dataToWrite, callback);
this.queue.place( () => {
this.i2c.send( new Buffer([addressToRead, dataToWrite]), (err, data) => {
this.queue.next();
if( callback ){
callback(err, data);
}
})
});
}
}
module.exports = VL53L0X;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment