Skip to content

Commit

Permalink
Merge pull request #19 from KurtE/continuous_range
Browse files Browse the repository at this point in the history
Add continuous range support also updated example sketch
  • Loading branch information
ladyada authored Jul 27, 2020
2 parents eabe639 + fc64f01 commit 7f81e4f
Show file tree
Hide file tree
Showing 4 changed files with 245 additions and 11 deletions.
42 changes: 41 additions & 1 deletion Adafruit_VL6180X.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
#include "Arduino.h"
#include <Wire.h>

// Define some additional registers mentioned in application notes and we use
///! period between each measurement when in continuous mode
#define SYSRANGE__INTERMEASUREMENT_PERIOD 0x001b // P19 application notes

/**************************************************************************/
/*!
@brief Instantiates a new VL6180X class
Expand Down Expand Up @@ -150,7 +154,8 @@ void Adafruit_VL6180X::loadSettings(void) {
// of the ranging sensor

// Optional: Public registers - See data sheet for more detail
write8(0x001b, 0x09); // Set default ranging inter-measurement
write8(SYSRANGE__INTERMEASUREMENT_PERIOD,
0x09); // Set default ranging inter-measurement
// period to 100ms
write8(0x003e, 0x31); // Set default ALS inter-measurement period
// to 500ms
Expand Down Expand Up @@ -261,6 +266,41 @@ uint8_t Adafruit_VL6180X::readRangeResult(void) {
return range;
}

/**************************************************************************/
/*!
@brief Start continuous ranging
@param period_ms Optional Period between ranges in ms. Values will
be rounded down to 10ms units with minimum of 10ms. Default is 50
*/
/**************************************************************************/

void Adafruit_VL6180X::startRangeContinuous(uint16_t period_ms) {
uint8_t period_reg = 0;
if (period_ms > 10) {
if (period_ms < 2550)
period_reg = (period_ms / 10) - 1;
else
period_reg = 254;
}
// Set ranging inter-measurement
write8(SYSRANGE__INTERMEASUREMENT_PERIOD, period_reg);

// Start a continuous range measurement
write8(VL6180X_REG_SYSRANGE_START, 0x03);
}

/**************************************************************************/
/*!
@brief stop continuous range operation.
*/
/**************************************************************************/

void Adafruit_VL6180X::stopRangeContinuous(void) {
// stop the continuous range operation, by setting the range register
// back to 1, Page 7 of appication notes
write8(VL6180X_REG_SYSRANGE_START, 0x01);
}

/**************************************************************************/
/*!
@brief Request ranging success/error message (retreive after ranging)
Expand Down
4 changes: 4 additions & 0 deletions Adafruit_VL6180X.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ class Adafruit_VL6180X {
boolean waitRangeComplete(void);
uint8_t readRangeResult(void);

void startRangeContinuous(uint16_t period_ms = 50);
void stopRangeContinuous(void);
// readRangeResult and isRangeComplete apply here is well

private:
void loadSettings(void);

Expand Down
208 changes: 198 additions & 10 deletions examples/vl6180x_triple/vl6180x_triple.ino
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,37 @@
#define SHT_LOX2 6
#define SHT_LOX3 5

// Optional define GPIO pins to check to see if complete
#define GPIO_LOX1 4
#define GPIO_LOX2 3
#define GPIO_LOX3 2

#define TIMING_PIN 13

// objects for the VL6180X
Adafruit_VL6180X lox1 = Adafruit_VL6180X();
Adafruit_VL6180X lox2 = Adafruit_VL6180X();
Adafruit_VL6180X lox3 = Adafruit_VL6180X();

// Setup mode for doing reads
typedef enum {RUN_MODE_DEFAULT, RUN_MODE_TIMED, RUN_MODE_ASYNC} runmode_t;
typedef enum {RUN_MODE_DEFAULT, RUN_MODE_TIMED, RUN_MODE_ASYNC, RUN_MODE_GPIO, RUN_MODE_CONT} runmode_t;

runmode_t run_mode = RUN_MODE_DEFAULT;
uint8_t show_command_list = 1;

//==========================================================================
// Define some globals used in the continuous range mode
// Note: going to start table drive this part, may back up and do the rest later
Adafruit_VL6180X *sensors[] = {&lox1, &lox2, &lox3};
const uint8_t COUNT_SENSORS = sizeof(sensors) / sizeof(sensors[0]);
const int sensor_gpios[COUNT_SENSORS] = {GPIO_LOX1, GPIO_LOX2, GPIO_LOX3}; // if any are < 0 will poll instead

uint8_t sensor_ranges[COUNT_SENSORS];
uint8_t sensor_status[COUNT_SENSORS];
// Could do with uint8_t for 8 sensors, but just in case...
const uint16_t ALL_SENSORS_PENDING = ((1 << COUNT_SENSORS) - 1);
uint16_t sensors_pending = ALL_SENSORS_PENDING;
uint32_t sensor_last_cycle_time;


/*
Expand Down Expand Up @@ -130,6 +152,7 @@ void read_sensors() {
}

void timed_read_sensors() {
digitalWrite(TIMING_PIN, HIGH);
uint32_t start_time = millis();
uint8_t range_lox1 = lox1.readRange();
uint8_t status_lox1 = lox1.readRangeStatus();
Expand All @@ -138,6 +161,7 @@ void timed_read_sensors() {
uint8_t range_lox3 = lox3.readRange();
uint8_t status_lox3 = lox3.readRangeStatus();
uint32_t delta_time = millis() - start_time;
digitalWrite(TIMING_PIN, LOW);
Serial.print(delta_time, DEC);
Serial.print(" : ");
if (status_lox1 == VL6180X_ERROR_NONE) Serial.print(range_lox1, DEC);
Expand All @@ -153,25 +177,27 @@ void timed_read_sensors() {
}

void timed_async_read_sensors() {
digitalWrite(TIMING_PIN, HIGH);
uint32_t start_time = millis();

// lets start up all three
lox1.startRange();
lox2.startRange();
lox3.startRange();

// wait for each of them to complete
lox1.waitRangeComplete();
lox2.waitRangeComplete();
lox3.waitRangeComplete();

uint8_t range_lox1 = lox1.readRangeResult();
uint8_t status_lox1 = lox1.readRangeStatus();
uint8_t range_lox2 = lox2.readRangeResult();
uint8_t status_lox2 = lox2.readRangeStatus();
uint8_t range_lox3 = lox3.readRangeResult();
uint8_t status_lox3 = lox3.readRangeStatus();
uint32_t delta_time = millis() - start_time;
digitalWrite(TIMING_PIN, LOW);
Serial.print(delta_time, DEC);
Serial.print(" : ");
if (status_lox1 == VL6180X_ERROR_NONE) Serial.print(range_lox1, DEC);
Expand All @@ -184,10 +210,130 @@ void timed_async_read_sensors() {
else Serial.print("###");

Serial.println();


}

void timed_async_read_gpio() {
#ifdef GPIO_LOX1
uint8_t range_lox1 = 0;
uint8_t status_lox1 = VL6180X_ERROR_NONE;
uint8_t range_lox2 = 0;
uint8_t status_lox2 = VL6180X_ERROR_NONE;
uint8_t range_lox3 = 0;
uint8_t status_lox3 = VL6180X_ERROR_NONE;


digitalWrite(TIMING_PIN, HIGH);
uint8_t pending_sensors = 0x7;
uint32_t start_time = millis();

// lets start up all three
lox1.startRange();
lox2.startRange();
lox3.startRange();

while (pending_sensors && ((millis() - start_time) < 1000)) {
if ((pending_sensors & 0x1) && !digitalRead(GPIO_LOX1)) {
range_lox1 = lox1.readRangeResult();
status_lox1 = lox1.readRangeStatus();
pending_sensors ^= 0x1;
}
if ((pending_sensors & 0x2) && !digitalRead(GPIO_LOX2)) {
range_lox2 = lox2.readRangeResult();
status_lox2 = lox2.readRangeStatus();
pending_sensors ^= 0x2;
}
if ((pending_sensors & 0x4) && !digitalRead(GPIO_LOX3)) {
range_lox3 = lox3.readRangeResult();
status_lox3 = lox3.readRangeStatus();
pending_sensors ^= 0x4;
}
}
uint32_t delta_time = millis() - start_time;
digitalWrite(TIMING_PIN, LOW);
Serial.print(delta_time, DEC);
Serial.print("(");
Serial.print(pending_sensors, DEC);
Serial.print(") : ");
if (status_lox1 == VL6180X_ERROR_NONE) Serial.print(range_lox1, DEC);
else Serial.print("###");
Serial.print(" : ");
if (status_lox2 == VL6180X_ERROR_NONE) Serial.print(range_lox2, DEC);
else Serial.print("###");
Serial.print(" : ");
if (status_lox3 == VL6180X_ERROR_NONE) Serial.print(range_lox3, DEC);
else Serial.print("###");

Serial.println();
#endif
}

//===============================================================
// Continuous range test code
//===============================================================
void start_continuous_range() {
Serial.println("start Continuous range mode");
for (uint8_t i = 0; i < COUNT_SENSORS; i++) {
sensors[i]->startRangeContinuous();
}
sensors_pending = ALL_SENSORS_PENDING;
sensor_last_cycle_time = millis();
}

void stop_continuous_range() {
Serial.println("Stop Continuous range mode");
for (uint8_t i = 0; i < COUNT_SENSORS; i++) {
sensors[i]->stopRangeContinuous();
}
delay(100); // give time for it to complete.
}


void Process_continuous_range() {

uint16_t mask = 1;
for (uint8_t i = 0; i < COUNT_SENSORS; i++) {
bool range_complete = false;
if (sensors_pending & mask) {
if (sensor_gpios[i] >= 0)
range_complete = !digitalRead(sensor_gpios[i]);
else
range_complete = sensors[i]->isRangeComplete();
if (range_complete) {
sensor_ranges[i] = sensors[i]->readRangeResult();
sensor_status[i] = sensors[i]->readRangeStatus();
sensors_pending ^= mask;
}
}
mask <<= 1; // setup to test next one
}
// See if we have all of our sensors read OK
uint32_t delta_time = millis() - sensor_last_cycle_time;
if (!sensors_pending || (delta_time > 1000)) {
Serial.print(delta_time, DEC);
Serial.print("(");
Serial.print(sensors_pending, HEX);
Serial.print(")");
mask = 1;
for (uint8_t i = 0; i < COUNT_SENSORS; i++) {
Serial.print(" : ");
if (sensors_pending & mask) Serial.print("TTT"); // show timeout in this one
else if (sensor_status[i] == VL6180X_ERROR_NONE) Serial.print(sensor_ranges[i], DEC);
else {
Serial.print("#");
Serial.print(sensor_status[i], DEC);
}
}
// setup for next pass
Serial.println();
sensor_last_cycle_time = millis();
sensors_pending = ALL_SENSORS_PENDING;
}
}

//===============================================================
// Setup
//===============================================================
void setup() {
Serial.begin(115200);

Expand All @@ -200,12 +346,22 @@ void setup() {
pinMode(SHT_LOX2, OUTPUT);
pinMode(SHT_LOX3, OUTPUT);

// Enable timing pin so easy to see when pass starts and ends
pinMode(TIMING_PIN, OUTPUT);

#ifdef GPIO_LOX1
// If we defined GPIO pins, enable them as PULL UP
pinMode(GPIO_LOX1, INPUT_PULLUP);
pinMode(GPIO_LOX2, INPUT_PULLUP);
pinMode(GPIO_LOX3, INPUT_PULLUP);
#endif

Serial.println("Shutdown pins inited...");

digitalWrite(SHT_LOX1, LOW);
digitalWrite(SHT_LOX2, LOW);
digitalWrite(SHT_LOX3, LOW);

digitalWrite(TIMING_PIN, LOW);
Serial.println("All in reset mode...(pins are low)");


Expand All @@ -214,11 +370,14 @@ void setup() {

}

//===============================================================
// Loop
//===============================================================
void loop() {
if (Serial.available()) {
uint8_t ch = Serial.read();
while (Serial.read() != -1) ; // remove the rest

runmode_t prev_run_mode = run_mode;
// See what the user typed in
switch (ch) {
case 'd':
Expand All @@ -233,13 +392,37 @@ void loop() {
case 'A':
run_mode = RUN_MODE_ASYNC;
break;
#ifdef GPIO_LOX1
case 'g':
case 'G':
run_mode = RUN_MODE_GPIO;
break;
#endif
case 'c':
case 'C':
run_mode = RUN_MODE_CONT;
break;

default:
Serial.println("\nSet run mode by entering one of the following letters");
Serial.println(" D - Default mode");
Serial.println(" T - Timed mode - Reads done one after another");
Serial.println(" A - Asynchronous mode - Try starting all three at once");
show_command_list = 1;
run_mode = RUN_MODE_DEFAULT;
}
if (run_mode != prev_run_mode) {
// if previous mode was continuous mode, shut it down
if (prev_run_mode == RUN_MODE_CONT) stop_continuous_range();
if (run_mode == RUN_MODE_CONT) start_continuous_range();
}
}
if (show_command_list) {
Serial.println("\nSet run mode by entering one of the following letters");
Serial.println(" D - Default mode");
Serial.println(" T - Timed mode - Reads done one after another");
Serial.println(" A - Asynchronous mode - Try starting all three at once");
#ifdef GPIO_LOX1
Serial.println(" G - Asynchronous mode - Like above use GPIO pins");
#endif
Serial.println(" C - Continuous mode - Try starting all three at once");
show_command_list = 0;
}
switch (run_mode) {
case RUN_MODE_DEFAULT:
Expand All @@ -251,6 +434,11 @@ void loop() {
case RUN_MODE_ASYNC:
timed_async_read_sensors();
break;
case RUN_MODE_GPIO:
timed_async_read_gpio();
break;
case RUN_MODE_CONT:
Process_continuous_range();
}
delay(100);
}
2 changes: 2 additions & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ startRange KEYWORD2
isRangeComplete KEYWORD2
waitRangeComplete KEYWORD2
readRangeResult KEYWORD2
startRangeContinuous KEYWORD2
stopRangeContinuous KEYWORD2

0 comments on commit 7f81e4f

Please sign in to comment.