I'm currently using a VL6180X ToF Distance sensor connected to a trinket 3V that is again connected to a Arduino Micro Board or a Mbientlab MetamotionR board. I established an I2C Bus between the ToF Sensor(Slave) and the Trinket (Master using a Software I2C Wire on the pins 3 and 4) and if something is in range the trinket starts to blink. This part works perfectly fine.
Then I want to send the signal to the Arduino Micro/MetamotionR to read the data and to print it. In this case the trinket is the slave(using the TinyWireS library on the I2C pins 0 and 2) and the Arduino Micro/Metamotion R is the slave. This configuration works perfectly fine, only that after approximately one minute the connection between the trinket and the Arduino/MetamotionR interrupts. I got the same problem for both boards. Basically the trinket doesn't send any data even though the Arduino or the MetamotionR requests it. Could it have to do with the clock speed of 8 MHz? Is there any way to solve this problem?
My code
Code: Select all
#include <TinyWireS.h>
#include <SoftwareWire.h>
SoftwareWire myWire( 3, 4);
//needed for the VL6180X
uint8_t address = 0b0101001;
uint8_t scaling = 0;
uint8_t ptp_offset = 0;
uint16_t io_timeout = 0;
bool did_timeout = false;
static uint16_t const ScalerValues[] = {0, 253, 127, 84};
//int Pin = 8;
int i=0;
uint8_t i2crange = 0;
uint8_t slowi2c = 0;
int ledState = LOW;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
TinyWireS.begin(8);
TinyWireS.onRequest(requestEvent);
myWire.begin();
//initialise VL6180X sensor
ptp_offset = readReg(0x024);
if (readReg(0x016) == 1)
{
scaling = 1;
writeReg(0x207, 0x01);
writeReg(0x208, 0x01);
writeReg(0x096, 0x00);
writeReg(0x097, 0xFD); // RANGE_SCALER = 253
writeReg(0x0E3, 0x00);
writeReg(0x0E4, 0x04);
writeReg(0x0E5, 0x02);
writeReg(0x0E6, 0x01);
writeReg(0x0E7, 0x03);
writeReg(0x0F5, 0x02);
writeReg(0x0D9, 0x05);
writeReg(0x0DB, 0xCE);
writeReg(0x0DC, 0x03);
writeReg(0x0DD, 0xF8);
writeReg(0x09F, 0x00);
writeReg(0x0A3, 0x3C);
writeReg(0x0B7, 0x00);
writeReg(0x0BB, 0x3C);
writeReg(0x0B2, 0x09);
writeReg(0x0CA, 0x09);
writeReg(0x198, 0x01);
writeReg(0x1B0, 0x17);
writeReg(0x1AD, 0x00);
writeReg(0x0FF, 0x05);
writeReg(0x100, 0x05);
writeReg(0x199, 0x05);
writeReg(0x1A6, 0x1B);
writeReg(0x1AC, 0x3E);
writeReg(0x1A7, 0x1F);
writeReg(0x030, 0x00);
writeReg(0x016, 0);
}
else
{
// Sensor has already been initialized, so try to get scaling settings by
// reading registers.
uint16_t s = readReg16Bit(0x096);
if (s == ScalerValues[3]) { scaling = 3; }
else if (s == ScalerValues[2]) { scaling = 2; }
else { scaling = 1; }
// Adjust the part-to-part range offset value read earlier to account for
// existing scaling. If the sensor was already in 2x or 3x scaling mode,
// precision will be lost calculating the original (1x) offset, but this can
// be resolved by resetting the sensor and Arduino again.
ptp_offset *= scaling;
}
//default configuration
// "Recommended : Public registers"
// readout__averaging_sample_period = 48
writeReg(0x10A, 0x30);
// sysals__analogue_gain_light = 6 (ALS gain = 1 nominal, actually 1.01 according to Table 14 in datasheet)
writeReg(0x03F, 0x46);
// sysrange__vhv_repeat_rate = 255 (auto Very High Voltage temperature recalibration after every 255 range measurements)
writeReg(0x031, 0xFF);
// sysals__integration_period = 99 (100 ms)
// AN4545 incorrectly recommends writing to register 0x040; 0x63 should go in the lower byte, which is register 0x041.
writeReg16Bit(0x040, 0x0063);
// sysrange__vhv_recalibrate = 1 (manually trigger a VHV recalibration)
writeReg(0x02E, 0x01);
// "Optional: Public registers"
// sysrange__intermeasurement_period = 9 (100 ms)
writeReg(0x01B, 0x09);
// sysals__intermeasurement_period = 49 (500 ms)
writeReg(0x01B, 0x31);
// als_int_mode = 4 (ALS new sample ready interrupt); range_int_mode = 4 (range new sample ready interrupt)
writeReg(0x014, 0x24);
// Reset other settings to power-on defaults
// sysrange__max_convergence_time = 49 (49 ms)
writeReg(0x01C, 0x31);
// disable interleaved mode
writeReg(0x2A3, 0);
// reset range scaling factor to 1x
//setScaling(1);
io_timeout = 500;
}
void loop() {
i2crange = readRangeSingle();
//TinyWireS.send(i2crange);
if(i2crange < 255)
{
digitalWrite(LED_BUILTIN, HIGH);
delay(50);
digitalWrite(LED_BUILTIN, LOW);
delay(50);
}
}
//functions for the sensor
uint8_t readReg(uint16_t reg)
{
uint8_t value;
myWire.beginTransmission(0b0101001);
myWire.write((reg >> 8) & 0xff); // reg high byte
myWire.write(reg & 0xff); // reg low byte
myWire.endTransmission();
myWire.requestFrom(0b0101001, (uint8_t)1);
value = myWire.read();
myWire.endTransmission();
return value;
}
void writeReg(uint16_t reg, uint8_t value)
{
myWire.beginTransmission(0b0101001);
myWire.write((reg >> 8) & 0xff); // reg high byte
myWire.write(reg & 0xff); // reg low byte
myWire.write(value);
myWire.endTransmission();
}
uint16_t readReg16Bit(uint16_t reg)
{
uint16_t value;
myWire.beginTransmission(0b0101001);
myWire.write((reg >> 8) & 0xff); // reg high byte
myWire.write(reg & 0xff); // reg low byte
myWire.endTransmission();
myWire.requestFrom(0b0101001, (uint8_t)2);
value = (uint16_t)myWire.read() << 8; // value high byte
value |= myWire.read(); // value low byte
myWire.endTransmission();
return value;
}
void writeReg16Bit(uint16_t reg, uint16_t value)
{
myWire.beginTransmission(0b0101001);
myWire.write((reg >> 8) & 0xff); // reg high byte
myWire.write(reg & 0xff); // reg low byte
myWire.write((value >> 8) & 0xff); // value high byte
myWire.write(value & 0xff); // value low byte
myWire.endTransmission();
}
uint8_t readRangeSingle()
{
writeReg(0x018, 0x01);
uint8_t range = 0;
return readRangeContinuous();
}
uint8_t readRangeContinuous()
{
uint16_t millis_start = millis();
while ((readReg(0x04F) & 0x04) == 0)
{
if (io_timeout > 0 && ((uint16_t)millis() - millis_start) > io_timeout)
{
did_timeout = true;
return 255;
}
}
uint8_t range = readReg(0x062);
writeReg(0x015, 0x01);
slowi2c = range;
return range;
}
//when using onrequest
void requestEvent() {
TinyWireS.send(slowi2c);
}