I hope this is the correct forum for this...
I have a working setup with 4 ToF (VL53L4CD) sensors connected to an Arduino Micro via a MUX (TCA9548A). This is part of a system that will go into a school, and so I want to make sure that the code keeps running if one of the sensors gets pulled out.
So something like: in void loop() check pin X on the TCA, if there's no data (implying that the sensor is no longer connected), go to the next pin and check that.
(At this point I'm not too worried whether or not the sensor is connected at start up (which would make void setup() fail), though I'm hoping the solution for the loop will transfer to setup.)
At the moment, the loop looks something like this (I'll post the code below, but I want to get the abstract idea out of my head first)...
void loop() {
set local variables;
select pin 0 of the TCA; as soon as new data is ready, clear the interupt, then get the new data, and report it;
select pin 1 of the TCA: as soon as new data is ready, clear the interupt, then get the new data, and report it;
etc for pins 2 & 3.
I've tried various things with if & while. The closest I got was:
select pin 0; if (NewDataReady !=0); {then the existing code} else { select the next pin etc}.
If I added this extra code in the sketch after the first pin was selected, and then bracketed {} the code for the second pin, the sketch not only ran, but continued running if I disconnected the first sensor. (Though if I reconnected it, the sensor was still not seen).
But when I added the extra code to the parts of the code for the other sensors, the { } brackets got out of control (it looked like they would have gto be endlessly recursive!), and I couldn't see how to include an }else{ after the last sensor so that it would return to the beginning of the loop.
Surely there's a much simpler way of implementing an "if (!x) then goto" in my code??
Here's the code that's running ok.
And below that is the part of the sketch I modified that almost works (except for the endlessly recursive nesting)
Code: Select all
/* Includes ------------------------------------------------------------------*/
#include <Arduino.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <vl53l4cd_class.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <assert.h>
#include <stdlib.h>
#define DEV_I2C Wire
#define SerialPort Serial
#define TCAADDR 0x70
#ifndef _BV
#define _BV(bit) (1 << (bit))
#endif
void tcaselect(uint8_t i) {
if (i > 7) return;
Wire.beginTransmission(TCAADDR);
Wire.write(1 << i);
Wire.endTransmission();
}
// Components.
// VL53L4CD sensor_vl53l4cd_sat(&DEV_I2C, A1);
VL53L4CD vl1(&DEV_I2C, 0);
VL53L4CD vl2(&DEV_I2C, 0);
VL53L4CD vl3(&DEV_I2C, 0);
VL53L4CD vl4(&DEV_I2C, 0);
/* Setup ---------------------------------------------------------------------*/
void setup()
{
SerialPort.begin(115200);
// Initialize I2C bus.
DEV_I2C.begin();
tcaselect(0);
vl1.begin(); // Configure VL53L4CD satellite component.
vl1.VL53L4CD_Off(); // Switch off VL53L4CD satellite component.
vl1.InitSensor(); //Initialize VL53L4CD satellite component.
vl1.VL53L4CD_SetRangeTiming(200, 0); // Program the highest possible TimingBudget, without enabling the
// low power mode. This should give the best accuracy
vl1.VL53L4CD_StartRanging(); // Start Measurements
tcaselect(1);
vl2.begin();
vl2.VL53L4CD_Off();
vl2.InitSensor();
vl2.VL53L4CD_SetRangeTiming(200, 0);
vl2.VL53L4CD_StartRanging();
tcaselect(2);
vl3.begin();
vl3.VL53L4CD_Off();
vl3.InitSensor();
vl3.VL53L4CD_SetRangeTiming(200, 0);
vl3.VL53L4CD_StartRanging();
tcaselect(3);
vl4.begin();
vl4.VL53L4CD_Off();
vl4.InitSensor();
vl4.VL53L4CD_SetRangeTiming(200, 0);
vl4.VL53L4CD_StartRanging();
}
void loop()
{
uint8_t NewDataReady = 0;
VL53L4CD_Result_t results;
uint8_t status;
char report[64];
tcaselect(0);
do {
status = vl1.VL53L4CD_CheckForDataReady(&NewDataReady);
} while (!NewDataReady);
if ((!status) && (NewDataReady != 0)) {
// (Mandatory) Clear HW interrupt to restart measurements
vl1.VL53L4CD_ClearInterrupt();
// Read measured distance. RangeStatus = 0 means valid data
vl1.VL53L4CD_GetResult(&results);
snprintf(report, sizeof(report), "Status1 %3u Distance1 %5u \r\n",
results.range_status,
results.distance_mm,
results.signal_per_spad_kcps);
SerialPort.print(report);
}
tcaselect(1);
do {
status = vl2.VL53L4CD_CheckForDataReady(&NewDataReady);
} while (!NewDataReady);
if ((!status) && (NewDataReady != 0)) {
// (Mandatory) Clear HW interrupt to restart measurements
vl2.VL53L4CD_ClearInterrupt();
// Read measured distance. RangeStatus = 0 means valid data
vl2.VL53L4CD_GetResult(&results);
snprintf(report, sizeof(report), "Status2 %3u Distance2 %5u \r\n",
results.range_status,
results.distance_mm,
results.signal_per_spad_kcps);
SerialPort.print(report);
}
tcaselect(2);
do {
status = vl3.VL53L4CD_CheckForDataReady(&NewDataReady);
} while (!NewDataReady);
if ((!status) && (NewDataReady != 0)) {
// (Mandatory) Clear HW interrupt to restart measurements
vl3.VL53L4CD_ClearInterrupt();
// Read measured distance. RangeStatus = 0 means valid data
vl3.VL53L4CD_GetResult(&results);
snprintf(report, sizeof(report), "Status3 %3u Distance3 %5u \r\n",
results.range_status,
results.distance_mm,
results.signal_per_spad_kcps);
SerialPort.print(report);
}
tcaselect(3);
do {
status = vl4.VL53L4CD_CheckForDataReady(&NewDataReady);
} while (!NewDataReady);
if ((!status) && (NewDataReady != 0)) {
// (Mandatory) Clear HW interrupt to restart measurements
vl4.VL53L4CD_ClearInterrupt();
// Read measured distance. RangeStatus = 0 means valid data
vl4.VL53L4CD_GetResult(&results);
snprintf(report, sizeof(report), "Status4 %3u Distance4 %5u \r\n",
results.range_status,
results.distance_mm,
results.signal_per_spad_kcps);
SerialPort.print(report);
}
}
Code: Select all
void loop()
{
uint8_t NewDataReady = 0;
VL53L4CD_Result_t results;
uint8_t status;
char report[64];
tcaselect(0);
if (NewDataReaady != 0); {
do {
status = vl1.VL53L4CD_CheckForDataReady(&NewDataReady);
} while (!NewDataReady);
if ((!status) && (NewDataReady != 0)) {
// (Mandatory) Clear HW interrupt to restart measurements
vl1.VL53L4CD_ClearInterrupt();
// Read measured distance. RangeStatus = 0 means valid data
vl1.VL53L4CD_GetResult(&results);
snprintf(report, sizeof(report), "Status1 %3u Distance1 %5u \r\n",
results.range_status,
results.distance_mm,
results.signal_per_spad_kcps);
SerialPort.print(report);
}
else} {
tcaselect(1);