Merge pull request #3678 from meshtastic/RCWL-9620

Support radar sensor RCWL-9620 on i2c
pull/3787/head
Thomas Göttgens 2024-05-03 20:37:27 +02:00 zatwierdzone przez GitHub
commit 4d9081b3b1
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
15 zmienionych plików z 136 dodań i 38 usunięć

Wyświetl plik

@ -128,6 +128,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define LPS22HB_ADDR_ALT 0x5D
#define SHT31_ADDR 0x44
#define PMSA0031_ADDR 0x12
#define RCWL9620_ADDR 0x57
// -----------------------------------------------------------------------------
// ACCELEROMETER

Wyświetl plik

@ -41,6 +41,7 @@ class ScanI2C
BQ24295,
LSM6DS3,
TCA9555,
RCWL9620,
NCP5623,
} DeviceType;

Wyświetl plik

@ -294,6 +294,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
SCAN_SIMPLE_CASE(SHT31_ADDR, SHT31, "SHT31 sensor found\n")
SCAN_SIMPLE_CASE(SHTC3_ADDR, SHTC3, "SHTC3 sensor found\n")
SCAN_SIMPLE_CASE(RCWL9620_ADDR, RCWL9620, "RCWL9620 sensor found\n")
case LPS22HB_ADDR_ALT:
SCAN_SIMPLE_CASE(LPS22HB_ADDR, LPS22HB, "LPS22HB sensor found\n")

Wyświetl plik

@ -62,10 +62,10 @@ void GPS::CASChecksum(uint8_t *message, size_t length)
// Iterate over the payload as a series of uint32_t's and
// accumulate the cksum
uint32_t *payload = (uint32_t *)(message + 6);
uint32_t const *payload = (uint32_t *)(message + 6);
for (size_t i = 0; i < (length - 10) / 4; i++) {
uint32_t p = payload[i];
cksum += p;
uint32_t pl = payload[i];
cksum += pl;
}
// Place the checksum values in the message

Wyświetl plik

@ -540,6 +540,7 @@ void setup()
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::QMI8658, meshtastic_TelemetrySensorType_QMI8658)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::QMC5883L, meshtastic_TelemetrySensorType_QMC5883L)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::PMSA0031, meshtastic_TelemetrySensorType_PMSA003I)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::RCWL9620, meshtastic_TelemetrySensorType_RCWL9620)
i2cScanner.reset();

Wyświetl plik

@ -192,9 +192,7 @@ void MeshService::handleToRadio(meshtastic_MeshPacket &p)
return;
}
#endif
if (p.from != 0) { // We don't let phones assign nodenums to their sent messages
p.from = 0;
}
p.from = 0; // We don't let phones assign nodenums to their sent messages
if (p.id == 0)
p.id = generatePacketId(); // If the phone didn't supply one, then pick one

Wyświetl plik

@ -56,7 +56,7 @@ meshtastic_OEMStore oemStore;
bool meshtastic_DeviceState_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field)
{
if (ostream) {
std::vector<meshtastic_NodeInfoLite> *vec = (std::vector<meshtastic_NodeInfoLite> *)field->pData;
std::vector<meshtastic_NodeInfoLite> const *vec = (std::vector<meshtastic_NodeInfoLite> *)field->pData;
for (auto item : *vec) {
if (!pb_encode_tag_for_field(ostream, field))
return false;

Wyświetl plik

@ -95,12 +95,11 @@ template <class T> class ProtobufModule : protected SinglePortModule
*/
virtual void alterReceived(meshtastic_MeshPacket &mp) override
{
auto &p = mp.decoded;
T scratch;
T *decoded = NULL;
if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.decoded.portnum == ourPortNum) {
memset(&scratch, 0, sizeof(scratch));
auto &p = mp.decoded;
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) {
decoded = &scratch;
} else {

Wyświetl plik

@ -116,9 +116,8 @@ Will be used for broadcast.
*/
int32_t NeighborInfoModule::runOnce()
{
bool requestReplies = false;
if (airTime->isTxAllowedChannelUtil(true) && airTime->isTxAllowedAirUtil()) {
sendNeighborInfo(NODENUM_BROADCAST, requestReplies);
sendNeighborInfo(NODENUM_BROADCAST, false);
}
return Default::getConfiguredOrDefaultMs(moduleConfig.neighbor_info.update_interval, default_broadcast_interval_secs);
}

Wyświetl plik

@ -343,7 +343,7 @@ int32_t PositionModule::runOnce()
// The minimum time (in seconds) that would pass before we are able to send a new position packet.
auto smartPosition = getDistanceTraveledSinceLastSend(node->position);
uint32_t msSinceLastSend = now - lastGpsSend;
msSinceLastSend = now - lastGpsSend;
if (smartPosition.hasTraveledOverThreshold &&
Throttle::execute(

Wyświetl plik

@ -24,6 +24,7 @@
#include "Sensor/BMP280Sensor.h"
#include "Sensor/LPS22HBSensor.h"
#include "Sensor/MCP9808Sensor.h"
#include "Sensor/RCWL9620Sensor.h"
#include "Sensor/SHT31Sensor.h"
#include "Sensor/SHTC3Sensor.h"
@ -35,6 +36,7 @@ MCP9808Sensor mcp9808Sensor;
SHTC3Sensor shtc3Sensor;
LPS22HBSensor lps22hbSensor;
SHT31Sensor sht31Sensor;
RCWL9620Sensor rcwl9620Sensor;
#define FAILED_STATE_SENSOR_READ_MULTIPLIER 10
#define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true
@ -93,6 +95,8 @@ int32_t EnvironmentTelemetryModule::runOnce()
result = ina219Sensor.runOnce();
if (ina260Sensor.hasSensor())
result = ina260Sensor.runOnce();
if (rcwl9620Sensor.hasSensor())
result = rcwl9620Sensor.runOnce();
}
return result;
} else {
@ -186,6 +190,9 @@ void EnvironmentTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiSt
String(lastMeasurement.variant.environment_metrics.current, 0) + "mA");
if (lastMeasurement.variant.environment_metrics.iaq != 0)
display->drawString(x, y += fontHeight(FONT_SMALL), "IAQ: " + String(lastMeasurement.variant.environment_metrics.iaq));
if (lastMeasurement.variant.environment_metrics.distance != 0)
display->drawString(x, y += fontHeight(FONT_SMALL),
"Water Level: " + String(lastMeasurement.variant.environment_metrics.distance, 0) + "mm");
}
bool EnvironmentTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *t)
@ -195,10 +202,13 @@ bool EnvironmentTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPac
const char *sender = getSenderShortName(mp);
LOG_INFO("(Received from %s): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, "
"temperature=%f, voltage=%f\n",
"temperature=%f\n",
sender, t->variant.environment_metrics.barometric_pressure, t->variant.environment_metrics.current,
t->variant.environment_metrics.gas_resistance, t->variant.environment_metrics.relative_humidity,
t->variant.environment_metrics.temperature, t->variant.environment_metrics.voltage);
t->variant.environment_metrics.temperature);
LOG_INFO("(Received from %s): voltage=%f, IAQ=%d, distance=%f\n", sender, t->variant.environment_metrics.voltage,
t->variant.environment_metrics.iaq, t->variant.environment_metrics.distance);
#endif
// release previous packet before occupying a new spot
if (lastMeasurementPacket != nullptr)
@ -223,6 +233,8 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
m.variant.environment_metrics.relative_humidity = 0;
m.variant.environment_metrics.temperature = 0;
m.variant.environment_metrics.voltage = 0;
m.variant.environment_metrics.iaq = 0;
m.variant.environment_metrics.distance = 0;
if (sht31Sensor.hasSensor())
valid = sht31Sensor.getMetrics(&m);
@ -244,13 +256,16 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
valid = ina219Sensor.getMetrics(&m);
if (ina260Sensor.hasSensor())
valid = ina260Sensor.getMetrics(&m);
if (rcwl9620Sensor.hasSensor())
valid = rcwl9620Sensor.getMetrics(&m);
if (valid) {
LOG_INFO("(Sending): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, temperature=%f, "
"voltage=%f\n",
LOG_INFO("(Sending): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, temperature=%f\n",
m.variant.environment_metrics.barometric_pressure, m.variant.environment_metrics.current,
m.variant.environment_metrics.gas_resistance, m.variant.environment_metrics.relative_humidity,
m.variant.environment_metrics.temperature, m.variant.environment_metrics.voltage);
m.variant.environment_metrics.temperature);
LOG_INFO("(Sending): voltage=%f, IAQ=%d, distance=%f\n", m.variant.environment_metrics.voltage,
m.variant.environment_metrics.iaq, m.variant.environment_metrics.distance);
sensor_read_error_count = 0;

Wyświetl plik

@ -0,0 +1,60 @@
#include "RCWL9620Sensor.h"
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include "configuration.h"
RCWL9620Sensor::RCWL9620Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_RCWL9620, "RCWL9620") {}
int32_t RCWL9620Sensor::runOnce()
{
LOG_INFO("Init sensor: %s\n", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
status = 1;
begin(nodeTelemetrySensorsMap[sensorType].second, nodeTelemetrySensorsMap[sensorType].first);
return initI2CSensor();
}
void RCWL9620Sensor::setup() {}
bool RCWL9620Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
LOG_DEBUG("RCWL9620Sensor::getMetrics\n");
measurement->variant.environment_metrics.distance = getDistance();
return true;
}
void RCWL9620Sensor::begin(TwoWire *wire, uint8_t addr, uint8_t sda, uint8_t scl, uint32_t speed)
{
_wire = wire;
_addr = addr;
_sda = sda;
_scl = scl;
_speed = speed;
_wire->begin();
}
float RCWL9620Sensor::getDistance()
{
uint32_t data;
_wire->beginTransmission(_addr); // Transfer data to addr.
_wire->write(0x01);
_wire->endTransmission(); // Stop data transmission with the Ultrasonic
// Unit.
_wire->requestFrom(_addr,
(uint8_t)3); // Request 3 bytes from Ultrasonic Unit.
data = _wire->read();
data <<= 8;
data |= _wire->read();
data <<= 8;
data |= _wire->read();
float Distance = float(data) / 1000;
if (Distance > 4500.00) {
return 4500.00;
} else {
return Distance;
}
}

Wyświetl plik

@ -0,0 +1,23 @@
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <Wire.h>
class RCWL9620Sensor : public TelemetrySensor
{
private:
uint8_t _addr = 0x57;
TwoWire *_wire = &Wire;
uint8_t _scl = -1;
uint8_t _sda = -1;
uint32_t _speed = 200000UL;
protected:
virtual void setup() override;
void begin(TwoWire *wire = &Wire, uint8_t addr = 0x57, uint8_t sda = -1, uint8_t scl = -1, uint32_t speed = 200000UL);
float getDistance();
public:
RCWL9620Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
};

Wyświetl plik

@ -75,20 +75,20 @@ void portduinoSetup()
{
printf("Setting up Meshtastic on Portduino...\n");
int max_GPIO = 0;
configNames GPIO_lines[] = {cs,
irq,
busy,
reset,
txen,
rxen,
displayDC,
displayCS,
displayBacklight,
displayBacklightPWMChannel,
displayReset,
touchscreenCS,
touchscreenIRQ,
user};
const configNames GPIO_lines[] = {cs,
irq,
busy,
reset,
txen,
rxen,
displayDC,
displayCS,
displayBacklight,
displayBacklightPWMChannel,
displayReset,
touchscreenCS,
touchscreenIRQ,
user};
std::string gpioChipName = "gpiochip";
settingsStrings[i2cdev] = "";
@ -103,7 +103,7 @@ void portduinoSetup()
std::cout << "Using " << configPath << " as config file" << std::endl;
try {
yamlConfig = YAML::LoadFile(configPath);
} catch (YAML::Exception e) {
} catch (YAML::Exception &e) {
std::cout << "Could not open " << configPath << " because of error: " << e.what() << std::endl;
exit(EXIT_FAILURE);
}
@ -111,7 +111,7 @@ void portduinoSetup()
std::cout << "Using local config.yaml as config file" << std::endl;
try {
yamlConfig = YAML::LoadFile("config.yaml");
} catch (YAML::Exception e) {
} catch (YAML::Exception &e) {
std::cout << "*** Exception " << e.what() << std::endl;
exit(EXIT_FAILURE);
}
@ -119,7 +119,7 @@ void portduinoSetup()
std::cout << "Using /etc/meshtasticd/config.yaml as config file" << std::endl;
try {
yamlConfig = YAML::LoadFile("/etc/meshtasticd/config.yaml");
} catch (YAML::Exception e) {
} catch (YAML::Exception &e) {
std::cout << "*** Exception " << e.what() << std::endl;
exit(EXIT_FAILURE);
}
@ -276,7 +276,7 @@ void portduinoSetup()
settingsMap[maxnodes] = (yamlConfig["General"]["MaxNodes"]).as<int>(200);
} catch (YAML::Exception e) {
} catch (YAML::Exception &e) {
std::cout << "*** Exception " << e.what() << std::endl;
exit(EXIT_FAILURE);
}
@ -347,7 +347,7 @@ void portduinoSetup()
return;
}
int initGPIOPin(int pinNum, std::string gpioChipName)
int initGPIOPin(int pinNum, const std::string gpioChipName)
{
std::string gpio_name = "GPIO" + std::to_string(pinNum);
try {

Wyświetl plik

@ -186,9 +186,9 @@ int File::available(void)
_fs->_lockFS();
if (!this->_is_dir) {
uint32_t size = lfs_file_size(_fs->_getFS(), _file);
uint32_t fsize = lfs_file_size(_fs->_getFS(), _file);
uint32_t pos = lfs_file_tell(_fs->_getFS(), _file);
ret = size - pos;
ret = fsize - pos;
}
_fs->_unlockFS();