1
0
Fork 0
mirror of https://github.com/iNavFlight/inav.git synced 2025-07-24 16:55:29 +03:00

Merge pull request #6792 from emtrax-ltd/rangefinder-gy-us42-master

Added rangefinder "GY-US42(v2) Ultrasonic Range Sensor"
This commit is contained in:
Paweł Spychalski 2021-04-09 09:55:15 +02:00 committed by GitHub
commit 5dbcc9b6aa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 183 additions and 4 deletions

View file

@ -238,7 +238,9 @@ main_sources(COMMON_SRC
drivers/rangefinder/rangefinder_vl53l1x.h
drivers/rangefinder/rangefinder_virtual.c
drivers/rangefinder/rangefinder_virtual.h
drivers/rangefinder/rangefinder_us42.c
drivers/rangefinder/rangefinder_us42.h
drivers/resource.c
drivers/resource.h
drivers/rcc.c

View file

@ -141,6 +141,7 @@ typedef enum {
DEVHW_HCSR04_I2C, // DIY-style adapter
DEVHW_VL53L0X,
DEVHW_VL53L1X,
DEVHW_US42,
/* Other hardware */
DEVHW_MS4525, // Pitot meter

View file

@ -174,7 +174,7 @@ bool i2cWriteBuffer(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t len_,
HAL_StatusTypeDef status;
if (reg_ == 0xFF && allowRawAccess) {
if ((reg_ == 0xFF || len_ == 0) && allowRawAccess) {
status = HAL_I2C_Master_Transmit(&state->handle, addr_ << 1, (uint8_t *)data, len_, I2C_DEFAULT_TIMEOUT);
}
else {

View file

@ -0,0 +1,132 @@
/*
* This file is part of Cleanflight.
*
* Cleanflight is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Cleanflight is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdbool.h>
#include <stdint.h>
#include "platform.h"
#if defined(USE_RANGEFINDER) && defined(USE_RANGEFINDER_US42)
#include "build/build_config.h"
#include "drivers/time.h"
#include "drivers/bus_i2c.h"
#include "drivers/rangefinder/rangefinder.h"
#include "drivers/rangefinder/rangefinder_us42.h"
#include "build/debug.h"
// GY-US42(v2) Ultrasonic Range Sensor
#define US42_MAX_RANGE_CM 400 // vcc=3.3v -> 500cm; vcc=5v -> 700cm; Ardupilot recommends a maximum of 400cm
#define US42_DETECTION_CONE_DECIDEGREES 250
#define US42_DETECTION_CONE_EXTENDED_DECIDEGREES 300
#define US42_MIN_PROBE_INTERVAL 50
#define US42_I2C_ADDRESS 0x70
#define US42_I2C_REGISTRY_BASE 0x00
#define US42_I2C_REGISTRY_PROBE 0x51
#define US42_I2C_REGISTRY_STATUS_OK 0x00
#define US42_I2C_REGISTRY_DISTANCE_HIGH 0x00
#define US42_I2C_REGISTRY_DISTANCE_LOW 0x01
volatile int32_t us42MeasurementCm = RANGEFINDER_OUT_OF_RANGE;
static int16_t minimumReadingIntervalMs = US42_MIN_PROBE_INTERVAL;
static uint32_t timeOfLastMeasurementMs;
uint8_t nullProbeCommandValue[0];
static bool isUs42Responding = false;
static void us42Init(rangefinderDev_t *rangefinder)
{
busWriteBuf(rangefinder->busDev, US42_I2C_REGISTRY_PROBE, nullProbeCommandValue, 0);
}
void us42Update(rangefinderDev_t *rangefinder)
{
uint8_t data[2];
isUs42Responding = busReadBuf(rangefinder->busDev, US42_I2C_REGISTRY_PROBE, data, 2);
if (isUs42Responding) {
us42MeasurementCm = (int32_t)data[0] << 8 | (int32_t)data[1];
if (us42MeasurementCm > US42_MAX_RANGE_CM) {
us42MeasurementCm = RANGEFINDER_OUT_OF_RANGE;
}
} else {
us42MeasurementCm = RANGEFINDER_HARDWARE_FAILURE;
}
const timeMs_t timeNowMs = millis();
if (timeNowMs > timeOfLastMeasurementMs + minimumReadingIntervalMs) {
// measurement repeat interval should be greater than minimumReadingIntervalMs
// to avoid interference between connective measurements.
timeOfLastMeasurementMs = timeNowMs;
busWriteBuf(rangefinder->busDev, US42_I2C_REGISTRY_PROBE, nullProbeCommandValue, 0);
}
}
/**
* Get the distance that was measured by the last pulse, in centimeters.
*/
int32_t us42GetDistance(rangefinderDev_t *rangefinder)
{
UNUSED(rangefinder);
return us42MeasurementCm;
}
static bool deviceDetect(busDevice_t * busDev)
{
for (int retry = 0; retry < 5; retry++) {
uint8_t inquiryResult;
delay(150);
bool ack = busRead(busDev, US42_I2C_REGISTRY_BASE, &inquiryResult);
if (ack && inquiryResult == US42_I2C_REGISTRY_STATUS_OK) {
return true;
}
};
return false;
}
bool us42Detect(rangefinderDev_t *rangefinder)
{
rangefinder->busDev = busDeviceInit(BUSTYPE_I2C, DEVHW_US42, 0, OWNER_RANGEFINDER);
if (rangefinder->busDev == NULL) {
return false;
}
if (!deviceDetect(rangefinder->busDev)) {
busDeviceDeInit(rangefinder->busDev);
return false;
}
rangefinder->delayMs = RANGEFINDER_US42_TASK_PERIOD_MS;
rangefinder->maxRangeCm = US42_MAX_RANGE_CM;
rangefinder->detectionConeDeciDegrees = US42_DETECTION_CONE_DECIDEGREES;
rangefinder->detectionConeExtendedDeciDegrees = US42_DETECTION_CONE_EXTENDED_DECIDEGREES;
rangefinder->init = &us42Init;
rangefinder->update = &us42Update;
rangefinder->read = &us42GetDistance;
return true;
}
#endif

View file

@ -0,0 +1,22 @@
/*
* This file is part of Cleanflight.
*
* Cleanflight is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Cleanflight is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#define RANGEFINDER_US42_TASK_PERIOD_MS 100
bool us42Detect(rangefinderDev_t *dev);

View file

@ -7,7 +7,7 @@ tables:
values: ["NONE", "AUTO", "ADXL345", "MPU6050", "MMA845x", "BMA280", "LSM303DLHC", "MPU6000", "MPU6500", "MPU9250", "BMI160", "ICM20689", "BMI088", "FAKE"]
enum: accelerationSensor_e
- name: rangefinder_hardware
values: ["NONE", "HCSR04", "SRF10", "INAV_I2C", "VL53L0X", "MSP", "UNUSED", "BENEWAKE", "VL53L1X"]
values: ["NONE", "HCSR04", "SRF10", "INAV_I2C", "VL53L0X", "MSP", "UNUSED", "BENEWAKE", "VL53L1X", "US42"]
enum: rangefinderType_e
- name: secondary_imu_hardware
values: ["NONE", "BNO055"]

View file

@ -42,6 +42,7 @@
#include "drivers/rangefinder/rangefinder_vl53l0x.h"
#include "drivers/rangefinder/rangefinder_vl53l1x.h"
#include "drivers/rangefinder/rangefinder_virtual.h"
#include "drivers/rangefinder/rangefinder_us42.h"
#include "fc/config.h"
#include "fc/runtime_config.h"
@ -160,7 +161,16 @@ static bool rangefinderDetect(rangefinderDev_t * dev, uint8_t rangefinderHardwar
#endif
break;
case RANGEFINDER_NONE:
case RANGEFINDER_US42:
#ifdef USE_RANGEFINDER_US42
if (us42Detect(dev)) {
rangefinderHardware = RANGEFINDER_US42;
rescheduleTask(TASK_RANGEFINDER, TASK_PERIOD_MS(RANGEFINDER_US42_TASK_PERIOD_MS));
}
#endif
break;
case RANGEFINDER_NONE:
rangefinderHardware = RANGEFINDER_NONE;
break;
}

View file

@ -31,6 +31,7 @@ typedef enum {
RANGEFINDER_UNUSED = 6, // Was UIB
RANGEFINDER_BENEWAKE = 7,
RANGEFINDER_VL53L1X = 8,
RANGEFINDER_US42 = 9,
} rangefinderType_e;
typedef struct rangefinderConfig_s {

View file

@ -72,6 +72,7 @@
#define USE_RANGEFINDER
#define USE_RANGEFINDER_HCSR04_I2C
#define USE_RANGEFINDER_US42
#define RANGEFINDER_I2C_BUS BUS_I2C2
#define PITOT_I2C_BUS BUS_I2C2
#define TEMPERATURE_I2C_BUS BUS_I2C2

View file

@ -99,6 +99,7 @@
#define USE_RANGEFINDER_VL53L0X
#define USE_RANGEFINDER_VL53L1X
#define USE_RANGEFINDER_HCSR04_I2C
#define USE_RANGEFINDER_US42
// Allow default optic flow boards
#define USE_OPFLOW

View file

@ -320,6 +320,15 @@
#endif
#endif
#if defined(USE_RANGEFINDER_US42)
#if !defined(US42_I2C_BUS) && defined(RANGEFINDER_I2C_BUS)
#define US42_I2C_BUS RANGEFINDER_I2C_BUS
#endif
#if defined(US42_I2C_BUS)
BUSDEV_REGISTER_I2C(busdev_us42, DEVHW_US42, US42_I2C_BUS, 0x70, NONE, DEVFLAGS_USE_RAW_REGISTERS, 0); // Requires null data to passthrough
#endif
#endif
/** AIRSPEED SENSORS **/
#if defined(PITOT_I2C_BUS) && !defined(MS4525_I2C_BUS)