CJMCU-530 показывает нули
- Войдите на сайт для отправки комментариев
Втр, 12/12/2017 - 18:49
Доброго дня !
Пришел долгожданный датчик дальномер CJMCU-530
Подключал как положено питание SDA SCL. Бибилотеку использовал - VL53L0X.h
При всех вариация показывет или НОЛЬ или 65535 TIME OUT
Кто сталкивался с такой проблемой - отпишитесь что получилось решить ?
или датчик бракованый попался
Доброго.
Скетч?
Скетч стандартный из библиотеки:
Пробовал разные режимы: LONG_RANGE, HIGH_SPEED, HIGH_ACCURACY
/* This example shows how to get single-shot range measurements from the VL53L0X. The sensor can optionally be configured with different ranging profiles, as described in the VL53L0X API user manual, to get better performance for a certain application. This code is based on the four "SingleRanging" examples in the VL53L0X API. The range readings are in units of mm. */ #include <Wire.h> #include <VL53L0X.h> VL53L0X sensor; // Uncomment this line to use long range mode. This // increases the sensitivity of the sensor and extends its // potential range, but increases the likelihood of getting // an inaccurate reading because of reflections from objects // other than the intended target. It works best in dark // conditions. //#define LONG_RANGE // Uncomment ONE of these two lines to get // - higher speed at the cost of lower accuracy OR // - higher accuracy at the cost of lower speed //#define HIGH_SPEED //#define HIGH_ACCURACY void setup() { Serial.begin(9600); Wire.begin(); sensor.init(); sensor.setTimeout(500); #if defined LONG_RANGE // lower the return signal rate limit (default is 0.25 MCPS) sensor.setSignalRateLimit(0.1); // increase laser pulse periods (defaults are 14 and 10 PCLKs) sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18); sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14); #endif #if defined HIGH_SPEED // reduce timing budget to 20 ms (default is about 33 ms) sensor.setMeasurementTimingBudget(20000); #elif defined HIGH_ACCURACY // increase timing budget to 200 ms sensor.setMeasurementTimingBudget(200000); #endif } void loop() { Serial.print(sensor.readRangeSingleMillimeters()); if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); } Serial.println(); }Мда... видимо тут народ умеет только Скетч просить.
А шо, вы думаете, что тут люди весь алиэкспресс скупили и прямо-таки сидят и ждут, пока их спросят почему такой-то датчик не работает?
Посмотрели, убедились, что не blink заливаете, мыслей нет - никто не отвечает.
Тыркайте I2C сканером. Если на шине найдется сенсор, значит дело в программной части. Не найдется - в аппаратной (провода, питание, сам модуль).
Ну так у тебя же написано:
Кто сталкивался с такой проблемой - отпишитесь что получилось решить ?
Так как датчик сильно специфический, не думаю, что многанароду с ним работало. Поэтому и откликов нет. И дак еще не вечер же, основные писатели форумов внаработе.
Просто Гпнег с таким "умным видом лица" попросил скетч... Ладно ждемс...
пока "ждёмс" можно, как в #4 посоветовали, I2C сканером пройтися.
Нет такого сканера.
Нет такого сканера.
Есть такой сканер: https://playground.arduino.cc/Main/I2cScanner
Понял. Результат:
Scanning...
Понял. Результат:
Scanning...
Проверьте, что возвращает init() - должна возвращать true:
bool init(bool io_2v8 = true)Iniitializes and configures the sensor. If the optional argument
io_2v8is true (the default if not specified), the sensor is configured for 2V8 mode (2.8 V I/O); if false, the sensor is left in 1V8 mode. The return value is a boolean indicating whether the initialization completed successfully.Сори за тупость, но куда и как точно написать ? bool init(bool io_2v8 = true)
У тебя в твоём скетче строчка sensor.init(); есть? Есть. Вот результат отработки этой строчки и надо проверять:
if(sensor.init()) { Serial.println("Inited!"); } else { Serial.println("Failed!"); while(1); }Вернул Inited
Вернул Inited
Как проверяете? Рукой перед датчиком водите?
Всяко разно... или 0 или 65535
Всяко разно... или 0 или 65535
Попробуйте поставить delay(500) в конец loop, и посмотрите, изменится ли чего. И не мельтешить рукой перед датчиком, просто поставить перед ним препятствие.
Попробуйте сделать то, что в 26 строке скетча написано. Вдруг поможет.
Пробовал все 3 варианта... Не помогает...
Попробовать sensor.init(false) ? Если не поможет - возможно, с модулем проблемы, посмотрите на сопли, непропай - бывает, случается.
Вообще неплохо бы глянуть на то, какой библиотекой там ТС орудует. Что у него там в init() - можно только предполагать.
Не знаю, каким датчиком и какой библиотекой Вы пользуетесь, но у меня с этим:
https://ru.aliexpress.com/item/GY-530-VL53L0X-World-smallest-Time-o-f-Fl...
и этим:
#ifndef VL53L0X_h #define VL53L0X_h #include <Arduino.h> class VL53L0X { public: // register addresses from API vl53l0x_device.h (ordered as listed there) enum regAddr { SYSRANGE_START = 0x00, SYSTEM_THRESH_HIGH = 0x0C, SYSTEM_THRESH_LOW = 0x0E, SYSTEM_SEQUENCE_CONFIG = 0x01, SYSTEM_RANGE_CONFIG = 0x09, SYSTEM_INTERMEASUREMENT_PERIOD = 0x04, SYSTEM_INTERRUPT_CONFIG_GPIO = 0x0A, GPIO_HV_MUX_ACTIVE_HIGH = 0x84, SYSTEM_INTERRUPT_CLEAR = 0x0B, RESULT_INTERRUPT_STATUS = 0x13, RESULT_RANGE_STATUS = 0x14, RESULT_CORE_AMBIENT_WINDOW_EVENTS_RTN = 0xBC, RESULT_CORE_RANGING_TOTAL_EVENTS_RTN = 0xC0, RESULT_CORE_AMBIENT_WINDOW_EVENTS_REF = 0xD0, RESULT_CORE_RANGING_TOTAL_EVENTS_REF = 0xD4, RESULT_PEAK_SIGNAL_RATE_REF = 0xB6, ALGO_PART_TO_PART_RANGE_OFFSET_MM = 0x28, I2C_SLAVE_DEVICE_ADDRESS = 0x8A, MSRC_CONFIG_CONTROL = 0x60, PRE_RANGE_CONFIG_MIN_SNR = 0x27, PRE_RANGE_CONFIG_VALID_PHASE_LOW = 0x56, PRE_RANGE_CONFIG_VALID_PHASE_HIGH = 0x57, PRE_RANGE_MIN_COUNT_RATE_RTN_LIMIT = 0x64, FINAL_RANGE_CONFIG_MIN_SNR = 0x67, FINAL_RANGE_CONFIG_VALID_PHASE_LOW = 0x47, FINAL_RANGE_CONFIG_VALID_PHASE_HIGH = 0x48, FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT = 0x44, PRE_RANGE_CONFIG_SIGMA_THRESH_HI = 0x61, PRE_RANGE_CONFIG_SIGMA_THRESH_LO = 0x62, PRE_RANGE_CONFIG_VCSEL_PERIOD = 0x50, PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI = 0x51, PRE_RANGE_CONFIG_TIMEOUT_MACROP_LO = 0x52, SYSTEM_HISTOGRAM_BIN = 0x81, HISTOGRAM_CONFIG_INITIAL_PHASE_SELECT = 0x33, HISTOGRAM_CONFIG_READOUT_CTRL = 0x55, FINAL_RANGE_CONFIG_VCSEL_PERIOD = 0x70, FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI = 0x71, FINAL_RANGE_CONFIG_TIMEOUT_MACROP_LO = 0x72, CROSSTALK_COMPENSATION_PEAK_RATE_MCPS = 0x20, MSRC_CONFIG_TIMEOUT_MACROP = 0x46, SOFT_RESET_GO2_SOFT_RESET_N = 0xBF, IDENTIFICATION_MODEL_ID = 0xC0, IDENTIFICATION_REVISION_ID = 0xC2, OSC_CALIBRATE_VAL = 0xF8, GLOBAL_CONFIG_VCSEL_WIDTH = 0x32, GLOBAL_CONFIG_SPAD_ENABLES_REF_0 = 0xB0, GLOBAL_CONFIG_SPAD_ENABLES_REF_1 = 0xB1, GLOBAL_CONFIG_SPAD_ENABLES_REF_2 = 0xB2, GLOBAL_CONFIG_SPAD_ENABLES_REF_3 = 0xB3, GLOBAL_CONFIG_SPAD_ENABLES_REF_4 = 0xB4, GLOBAL_CONFIG_SPAD_ENABLES_REF_5 = 0xB5, GLOBAL_CONFIG_REF_EN_START_SELECT = 0xB6, DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD = 0x4E, DYNAMIC_SPAD_REF_EN_START_OFFSET = 0x4F, POWER_MANAGEMENT_GO1_POWER_FORCE = 0x80, VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV = 0x89, ALGO_PHASECAL_LIM = 0x30, ALGO_PHASECAL_CONFIG_TIMEOUT = 0x30, }; enum vcselPeriodType { VcselPeriodPreRange, VcselPeriodFinalRange }; uint8_t last_status; // status of last I2C transmission VL53L0X(void); void setAddress(uint8_t new_addr); inline uint8_t getAddress(void) { return address; } bool init(bool io_2v8 = true); void writeReg(uint8_t reg, uint8_t value); void writeReg16Bit(uint8_t reg, uint16_t value); void writeReg32Bit(uint8_t reg, uint32_t value); uint8_t readReg(uint8_t reg); uint16_t readReg16Bit(uint8_t reg); uint32_t readReg32Bit(uint8_t reg); void writeMulti(uint8_t reg, uint8_t const * src, uint8_t count); void readMulti(uint8_t reg, uint8_t * dst, uint8_t count); bool setSignalRateLimit(float limit_Mcps); float getSignalRateLimit(void); bool setMeasurementTimingBudget(uint32_t budget_us); uint32_t getMeasurementTimingBudget(void); bool setVcselPulsePeriod(vcselPeriodType type, uint8_t period_pclks); uint8_t getVcselPulsePeriod(vcselPeriodType type); void startContinuous(uint32_t period_ms = 0); void stopContinuous(void); uint16_t readRangeContinuousMillimeters(void); uint16_t readRangeSingleMillimeters(void); inline void setTimeout(uint16_t timeout) { io_timeout = timeout; } inline uint16_t getTimeout(void) { return io_timeout; } bool timeoutOccurred(void); private: // TCC: Target CentreCheck // MSRC: Minimum Signal Rate Check // DSS: Dynamic Spad Selection struct SequenceStepEnables { boolean tcc, msrc, dss, pre_range, final_range; }; struct SequenceStepTimeouts { uint16_t pre_range_vcsel_period_pclks, final_range_vcsel_period_pclks; uint16_t msrc_dss_tcc_mclks, pre_range_mclks, final_range_mclks; uint32_t msrc_dss_tcc_us, pre_range_us, final_range_us; }; uint8_t address; uint16_t io_timeout; bool did_timeout; uint16_t timeout_start_ms; uint8_t stop_variable; // read by init and used when starting measurement; is StopVariable field of VL53L0X_DevData_t structure in API uint32_t measurement_timing_budget_us; bool getSpadInfo(uint8_t * count, bool * type_is_aperture); void getSequenceStepEnables(SequenceStepEnables * enables); void getSequenceStepTimeouts(SequenceStepEnables const * enables, SequenceStepTimeouts * timeouts); bool performSingleRefCalibration(uint8_t vhv_init_byte); static uint16_t decodeTimeout(uint16_t value); static uint16_t encodeTimeout(uint16_t timeout_mclks); static uint32_t timeoutMclksToMicroseconds(uint16_t timeout_period_mclks, uint8_t vcsel_period_pclks); static uint32_t timeoutMicrosecondsToMclks(uint32_t timeout_period_us, uint8_t vcsel_period_pclks); }; #endifпроблем не возникло.
Что-то не так у вас с модулем, VL53L0X имеет заводской адрес 0х52, поменять его можно при иничиализации, но только до выключения питания, потом он станет снова 0х52, так что не может он у вас быть 0x29.
Библиотека работает именно с 0x52 и работает хорошо. а с вашим 0x29 она соответственно не работает.
Приехала новая партия на "ушастых" платах, так на них VL53L0X откликается на 0x29, но с библиотекой VL53L0X.h из ардуино работает. Там смысл в том что у чипа VL53L0X адрес меняется не аппаратно, а програмно в момент инициализации после включения питания, верояно 0x29 задает библиотека при инициализации. Три датчика повесил на шину - все работают, передают корректные показания, только реальная дальнось у них очень далека от рекламных двух метров.
по докам должен измерять до 2 м, у меня почему-то измеряет до 1.2м дальше отображает 8192.
как сделать чтоб вывод был не в мм, а в том что датчик измеряет, тикак, тактах или ещё в чем...
Плохо доки вы читали, если вы откроете 5 параграф раздела документации то увидите что 2м это максимум в режиме лонг рейдж при работе на белую поверхность с отражением 88% внутри закрытого помещения без посторонних источников ик света. То есть на какую нибудь глянцевую белую дверь в темном туалете срабает, в остальных случаях нет. Гарантированная дальность работы в помещении без ик света 120см на поверхность с отражением 88% и 70см на серую с отражением 17%. А с присутствием ик света производитель не обещает более 40см дальности. Читайте доки а не ведитесь на рекламу.
2yray
спасибо, меня 120см вполне устраивает.
а что по второму вопросу?
Читайте доки а не ведитесь на рекламу.
Это я с радостю бы делал, дак где ж взять на vl53l0x нормальное описание регистров. Не встречали юзер мануал i2c?
А то приехало, а как работать с ним напрямую непонятно. С адафруктом завелось нормально, но простейший экземпл дает
На сайте производителя полный sdk был, вот апи где все есть https://www.st.com/content/st_com/en/products/embedded-software/proximit...
кроме адафрута есть и более легкая и быстрая библиотека в ардуино https://github.com/pololu/vl53l0x-arduino
кстати может кто не в курсе - вышла новая модификация vl53l1x с рекламными аж 4 метрами дистанции измерения и по цене порядка 1т.р. Но если почитать доки то 4м это чистый маркетинг, реальная дальнось гарантируется 70см
По ссылке только
VL53L0X API is based on Photonic Abstraction Layer (PAL) specification. API is defined as the implementation of the PAL. The API exposes high level functions to be used by the customer application to control the device.
Бесполезно. Только сишные функции из этой самой PAL :(
Чем закончилось?
Уже закончилось?