import processing.io.*; I2C i2c; // MCP4725 is a Digital-to-Analog converter using I2C // datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/22039d.pdf // also see DigitalAnalog_I2C_MCP4725 for how to write the // same sketch in an object-oriented way private final static char[] hexArray = "0123456789ABCDEF".toCharArray(); public static String bytesToHex(byte[] bytes) { char[] hexChars = new char[bytes.length * 2]; for ( int j = 0; j < bytes.length; j++ ) { int v = bytes[j] & 0xFF; hexChars[j * 2] = hexArray[v >>> 4]; hexChars[j * 2 + 1] = hexArray[v & 0x0F]; } return new String(hexChars); } byte address=0x29; void writeReg(byte reg, byte val) { i2c.beginTransmission(0x29); i2c.write(reg); i2c.write(val); i2c.endTransmission(); } byte [] readRegs(byte reg, int cnt) { i2c.beginTransmission(0x29); i2c.write(reg); byte[] in = i2c.read(cnt); i2c.endTransmission(); return in; } byte [] readRegs(int reg, int cnt) { return readRegs((byte)reg, cnt); } byte readReg(byte reg) { return readRegs(reg,1)[0]; } byte readReg(int reg) { return readReg((byte)reg); } void writeReg(int reg, int val) { writeReg((byte)reg, (byte)val); } void writeMulti(byte reg, byte [] src, int count) { i2c.beginTransmission(address); i2c.write(reg); for (int i = 0; i < count; i++) { i2c.write(src[i]); } i2c.endTransmission(); } void writeReg16Bit(byte reg, short value) { i2c.beginTransmission(address); i2c.write(reg); i2c.write((value >> 8) & 0xFF); // value high byte i2c.write( value & 0xFF); // value low byte i2c.endTransmission(); } void writeReg32Bit(byte reg, int value) { i2c.beginTransmission(address); i2c.write(reg); i2c.write((value >> 24) & 0xFF); // value highest byte i2c.write((value >> 16) & 0xFF); i2c.write((value >> 8) & 0xFF); i2c.write( value & 0xFF); // value lowest byte i2c.endTransmission(); } byte stop_variable; byte MSRC_CONFIG_CONTROL = (byte)0x60; int measurement_timing_budget_us; int getMeasurementTimingBudget() { } boolean setMeasurementTimingBudget(int us) { } boolean setSignalRateLimit(float limit_Mcps) { if (limit_Mcps < 0 || limit_Mcps > 511.99) { return false; } // Q9.7 fixed point format (9 integer bits, 7 fractional bits) writeReg16Bit((byte)0x44, (short) (limit_Mcps * (1 << 7))); //FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT return true; } int count; boolean type_is_aperture; int timeout_start_ms; int io_timeout = 0; void startTimeout() { timeout_start_ms = millis(); } boolean checkTimeoutExpired() { return (io_timeout > 0) && ((millis() - timeout_start_ms) > io_timeout); } boolean getSpadInfo() { byte tmp; writeReg(0x80, 0x01); writeReg(0xFF, 0x01); writeReg(0x00, 0x00); writeReg(0xFF, 0x06); writeReg(0x83, readReg(0x83) | 0x04); writeReg(0xFF, 0x07); writeReg(0x81, 0x01); writeReg(0x80, 0x01); writeReg(0x94, 0x6b); writeReg(0x83, 0x00); startTimeout(); while (readReg(0x83) == 0x00) { if (checkTimeoutExpired()) { return false; } } writeReg(0x83, 0x01); tmp = readReg(0x92); count = tmp & (byte)0x7f; type_is_aperture = ((tmp >> (byte)7) & (byte)0x01) == (byte)0x1; writeReg(0x81, 0x00); writeReg(0xFF, 0x06); writeReg(0x83, readReg(0x83) & ~0x04); writeReg(0xFF, 0x01); writeReg(0x00, 0x01); writeReg(0xFF, 0x00); writeReg(0x80, 0x00); return true; } boolean initVL53LOX() { writeReg(0x88, 0x00); writeReg(0x80, 0x01); writeReg(0xFF, 0x01); writeReg(0x00, 0x00); stop_variable = readReg(0x91); writeReg(0x00, 0x01); writeReg(0xFF, 0x00); writeReg(0x80, 0x00); // disable SIGNAL_RATE_MSRC (bit 1) and SIGNAL_RATE_PRE_RANGE (bit 4) limit checks writeReg(MSRC_CONFIG_CONTROL, readReg(MSRC_CONFIG_CONTROL) | 0x12); // set final range signal rate limit to 0.25 MCPS (million counts per second) setSignalRateLimit(0.25); writeReg(0x01, 0xFF); //SYSTEM_SEQUENCE_CONFIG // VL53L0X_DataInit() end // VL53L0X_StaticInit() begin if (!getSpadInfo()) { return false; } byte spad_count = (byte)count; boolean spad_type_is_aperture = type_is_aperture; // The SPAD map (RefGoodSpadMap) is read by VL53L0X_get_info_from_device() in // the API, but the same data seems to be more easily readable from // GLOBAL_CONFIG_SPAD_ENABLES_REF_0 through _6, so read it from there byte [] ref_spad_map = readRegs((byte)0xB0, 6); //GLOBAL_CONFIG_SPAD_ENABLES_REF_0 writeReg(0xFF, 0x01); writeReg(0x4F, 0x00); //DYNAMIC_SPAD_REF_EN_START_OFFSET writeReg(0x4E, 0x2C); //DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD writeReg(0xFF, 0x00); writeReg(0xB6, 0xB4); //GLOBAL_CONFIG_REF_EN_START_SELECT byte first_spad_to_enable = (byte)(spad_type_is_aperture ? 12 : 0); // 12 is the first aperture spad byte spads_enabled = 0; for (int i = 0; i < 48; i++) { if (i < first_spad_to_enable || spads_enabled == spad_count) { // This bit is lower than the first one that should be enabled, or // (reference_spad_count) bits have already been enabled, so zero this bit ref_spad_map[i / 8] &= ~(1 << (i % 8)); } else if (((ref_spad_map[i / 8] >> (byte)(i % 8)) & (byte)0x1) == (byte)0x01) { spads_enabled++; } } writeMulti((byte)0xB0, ref_spad_map, 6);//GLOBAL_CONFIG_SPAD_ENABLES_REF_0 // -- VL53L0X_set_reference_spads() end // -- VL53L0X_load_tuning_settings() begin // DefaultTuningSettings from vl53l0x_tuning.h writeReg(0xFF, 0x01); writeReg(0x00, 0x00); writeReg(0xFF, 0x00); writeReg(0x09, 0x00); writeReg(0x10, 0x00); writeReg(0x11, 0x00); writeReg(0x24, 0x01); writeReg(0x25, 0xFF); writeReg(0x75, 0x00); writeReg(0xFF, 0x01); writeReg(0x4E, 0x2C); writeReg(0x48, 0x00); writeReg(0x30, 0x20); writeReg(0xFF, 0x00); writeReg(0x30, 0x09); writeReg(0x54, 0x00); writeReg(0x31, 0x04); writeReg(0x32, 0x03); writeReg(0x40, 0x83); writeReg(0x46, 0x25); writeReg(0x60, 0x00); writeReg(0x27, 0x00); writeReg(0x50, 0x06); writeReg(0x51, 0x00); writeReg(0x52, 0x96); writeReg(0x56, 0x08); writeReg(0x57, 0x30); writeReg(0x61, 0x00); writeReg(0x62, 0x00); writeReg(0x64, 0x00); writeReg(0x65, 0x00); writeReg(0x66, 0xA0); writeReg(0xFF, 0x01); writeReg(0x22, 0x32); writeReg(0x47, 0x14); writeReg(0x49, 0xFF); writeReg(0x4A, 0x00); writeReg(0xFF, 0x00); writeReg(0x7A, 0x0A); writeReg(0x7B, 0x00); writeReg(0x78, 0x21); writeReg(0xFF, 0x01); writeReg(0x23, 0x34); writeReg(0x42, 0x00); writeReg(0x44, 0xFF); writeReg(0x45, 0x26); writeReg(0x46, 0x05); writeReg(0x40, 0x40); writeReg(0x0E, 0x06); writeReg(0x20, 0x1A); writeReg(0x43, 0x40); writeReg(0xFF, 0x00); writeReg(0x34, 0x03); writeReg(0x35, 0x44); writeReg(0xFF, 0x01); writeReg(0x31, 0x04); writeReg(0x4B, 0x09); writeReg(0x4C, 0x05); writeReg(0x4D, 0x04); writeReg(0xFF, 0x00); writeReg(0x44, 0x00); writeReg(0x45, 0x20); writeReg(0x47, 0x08); writeReg(0x48, 0x28); writeReg(0x67, 0x00); writeReg(0x70, 0x04); writeReg(0x71, 0x01); writeReg(0x72, 0xFE); writeReg(0x76, 0x00); writeReg(0x77, 0x00); writeReg(0xFF, 0x01); writeReg(0x0D, 0x01); writeReg(0xFF, 0x00); writeReg(0x80, 0x01); writeReg(0x01, 0xF8); writeReg(0xFF, 0x01); writeReg(0x8E, 0x01); writeReg(0x00, 0x01); writeReg(0xFF, 0x00); writeReg(0x80, 0x00); // -- VL53L0X_load_tuning_settings() end // "Set interrupt config to new sample ready" // -- VL53L0X_SetGpioConfig() begin writeReg(0x0A, 0x04);//SYSTEM_INTERRUPT_CONFIG_GPIO writeReg(0x84, readReg(0x84) & ~0x10); // active low GPIO_HV_MUX_ACTIVE_HIGH writeReg(0x0B, 0x01); //SYSTEM_INTERRUPT_CLEAR // -- VL53L0X_SetGpioConfig() end measurement_timing_budget_us = getMeasurementTimingBudget(); // "Disable MSRC and TCC by default" // MSRC = Minimum Signal Rate Check // TCC = Target CentreCheck // -- VL53L0X_SetSequenceStepEnable() begin writeReg(0x01, 0xE8); //SYSTEM_SEQUENCE_CONFIG // -- VL53L0X_SetSequenceStepEnable() end // "Recalculate timing budget" setMeasurementTimingBudget(measurement_timing_budget_us); // VL53L0X_StaticInit() end // VL53L0X_PerformRefCalibration() begin (VL53L0X_perform_ref_calibration()) // -- VL53L0X_perform_vhv_calibration() begin writeReg(0x01, 0x01); //SYSTEM_SEQUENCE_CONFIG if (!performSingleRefCalibration(0x40)) { return false; } // -- VL53L0X_perform_vhv_calibration() end // -- VL53L0X_perform_phase_calibration() begin writeReg(0x01, 0x02); //SYSTEM_SEQUENCE_CONFIG if (!performSingleRefCalibration(0x00)) { return false; } // -- VL53L0X_perform_phase_calibration() end // "restore the previous Sequence Config" writeReg(0x01, 0xE8); //SYSTEM_SEQUENCE_CONFIG // VL53L0X_PerformRefCalibration() end return true; } void setup() { //printArray(I2C.list()); print("Hello World"); i2c = new I2C(I2C.list()[0]); printArray(I2C.list()); println("scanning"); try { i2c.beginTransmission(0x29); i2c.write(0x00); byte[] in = i2c.read(256); i2c.endTransmission(); println("found device: "); int i =0; print(" : "); for (i=0;i<16;i++) { print(bytesToHex(new byte[] {(byte)i})); print(" "); } for (i=0;i<=255;i++) { if (i % 16 == 0) { println(": "); print(bytesToHex(new byte[] {(byte)i})); print(" : "); } print( bytesToHex(new byte[] { in[i] })); print(" "); } println("!"); } catch (RuntimeException e) { print("exception "); println(e); } initVL53LOX(); print("Goodbye world"); } void draw() { background(map(mouseX, 0, width, 0, 255)); }