(This is 3 different Arduinos with the sensors attached to TCA9548A multiplexers; one with 4 VL53L4CD, one with 3*MPR121 (capacitative), & one with 2*VL6180X (short range ToF) + 1*MPR121. The Arduinos connect to Max running on a Mac via a USB-Ethernet-USB link.)
The whole system worked well, except that once or twice (or more) a day, that VL53 sensor system stops running. The others work fine, no stopping at all.
Sometimes the VL53L4CD system runs ok for 4-5 hours before it stops, occasionally it stops after 10 or so minutes.
When it stops, sometimes rebooting the Arduino and refreshing the serial object in Max got it going again; sometimes I had to dis/reconnect the USB lead to make things work (USB buss "jammed up"?).
I would also like to modify the sketch such that if one of the sensors gets disconnected the sketch carries on running.(The sensors get pulled around a bit, and maybe the cat7 leads momentarily disconnect on one pin?) At the moment, if I disconnect a sensor, the sketch stops running, which is why I wondered if a dodgy connection was causing things to fail. That's the only hardware related possibility I've come up with; I resoldered all of the connections around the Arduino & in the actual sensors before the workshop, and they all seem solid.
So maybe the sketch is failing for some reason at some point? Given that it can run for several hours with no problems, I wonder if it could be a memory overflow problem?? But though I'm now working my way through the Arduino Cookbook from O'Reilly, I still don't know enough to figure it out.
(Another possibility might be something to do with the VL53s? I tried removing the sensor reading part of the sketch, and replacing it with some tca port checking and serial printing the results. Not quite got it right, but disconnecting one of the sensors no longer stops the sketch running.)
Any suggestions?
Here's the sketch which runs but eventually stops. There might be some redundant bits in, and I just noticed that in the loop, I've got vl1.(whatever) in each of the tca call (rather than vl2. vl3. etc); so maybe I don't need to define four different components for the 4 sensors - the sketch will get the data from whichever tca port is currently selected, and I don't need the separate definitions???)
thanks
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(57600);
//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(100, 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(100, 0);
vl2.VL53L4CD_StartRanging();
tcaselect(2);
vl3.begin();
vl3.VL53L4CD_Off();
vl3.InitSensor();
vl3.VL53L4CD_SetRangeTiming(100, 0);
vl3.VL53L4CD_StartRanging();
tcaselect(3);
vl4.begin();
vl4.VL53L4CD_Off();
vl4.InitSensor();
vl4.VL53L4CD_SetRangeTiming(100, 0);
vl4.VL53L4CD_StartRanging();
}
void loop()
{
uint8_t NewDataReady = 0;
VL53L4CD_Result_t results;
uint8_t status;
tcaselect(0);
do {
status = vl1.VL53L4CD_CheckForDataReady(&NewDataReady);
} while (!NewDataReady);
Serial.println("active");
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);
if (results.range_status == 0) {
Serial.print ("Distance1 ");
Serial.println(results.distance_mm);}
}
tcaselect(1);
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);
if (results.range_status == 0) {
Serial.print ("Distance2 ");
Serial.println(results.distance_mm);}
}
tcaselect(2);
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);
if (results.range_status == 0) {
Serial.print ("Distance3 ");
Serial.println(results.distance_mm);}
}
tcaselect(3);
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);
if (results.range_status == 0) {
Serial.print ("Distance4 ");
Serial.println(results.distance_mm);}
}
}