Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for DYP A02YYU ultrasonic sensor #2622

Merged
merged 5 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
a02yyu: add support for DYP-A02YYU ultrasonic sensor
  • Loading branch information
toniSg committed Oct 23, 2024
commit 193c66bd01af0c5cb3c88ed8c6da73131d07f815
14 changes: 14 additions & 0 deletions code/espurna/config/sensors.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,19 @@
// =============================================================================

//------------------------------------------------------------------------------
// A02YYUx (DYP) Ultrasonic Sensor
// Enable support by passing A02YYU_SUPPORT=1 build flag
//------------------------------------------------------------------------------

#ifndef A02YYU_SUPPORT
#define A02YYU_SUPPORT 0
#endif

#ifndef A02YYU_PORT
#define A02YYU_PORT 1 // By default, use the first port
// (needs `UART[1-3]_BAUDRATE 9600`)
mcspr marked this conversation as resolved.
Show resolved Hide resolved
#endif

// AM2320 Humidity & Temperature sensor over I2C
// Enable support by passing AM2320_SUPPORT=1 build flag
//------------------------------------------------------------------------------
Expand Down Expand Up @@ -1519,6 +1532,7 @@
// Provide generic way to detect sensor presence
#ifndef SENSOR_SUPPORT
#define SENSOR_SUPPORT ( \
A02YYU_SUPPORT || \
mcspr marked this conversation as resolved.
Show resolved Hide resolved
ADE7953_SUPPORT || \
AM2320_SUPPORT || \
ANALOG_SUPPORT || \
Expand Down
1 change: 1 addition & 0 deletions code/espurna/config/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@
#define SENSOR_SM300D2_ID 43
#define SENSOR_PM1006_ID 44
#define SENSOR_INA219_ID 45
#define SENSOR_A02YYU_ID 46

//--------------------------------------------------------------------------------
// Magnitudes
Expand Down
17 changes: 17 additions & 0 deletions code/espurna/sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ Copyright (C) 2020-2022 by Maxim Prokhorov <prokhorov dot max at outlook dot com
#include "sensors/DummySensor.h"
#endif

#if A02YYU_SUPPORT
#include "sensors/A02YYUSensor.h"
#endif
#if AM2320_SUPPORT
#include "sensors/AM2320Sensor.h"
#endif
Expand Down Expand Up @@ -2034,6 +2037,20 @@ size_t count() {
// - update config/custom.h or config/sensor.h, adding `#define DHT2_PIN ...` and `#define DHT2_TYPE ...`

void load() {
#if A02YYU_SUPPORT
{
const auto port = uartPort(A02YYU_PORT - 1);

if (!port) {
return;
}

auto* sensor = new A02YYUSensor();
sensor->setPort(port->stream);

add(sensor);
}
#endif
#if AM2320_SUPPORT
{
auto* sensor = new AM2320Sensor();
Expand Down
148 changes: 148 additions & 0 deletions code/espurna/sensors/A02YYUSensor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// -----------------------------------------------------------------------------
// DYP A02YYUx Ultrasonic Distance Sensor
// Copyright (C) 2024 by tsouthiv @ gmail dot com
// -----------------------------------------------------------------------------

// This should be also compatible with other similar sensors like JSN-SR04T
// or AJ-SR04M in auto UART mode.

#if SENSOR_SUPPORT && A02YYU_SUPPORT

#pragma once

#include "Arduino.h"
#include "BaseSensor.h"

#define _RX_LEN 16
#define _RX_MASK (_RX_LEN - 1)
toniSg marked this conversation as resolved.
Show resolved Hide resolved

class A02YYUSensor : public BaseSensor {

public:

void setPort(Stream* port) {
_serial = port;
_dirty = true;
}

// ---------------------------------------------------------------------
// Sensor API
// ---------------------------------------------------------------------

unsigned char id() const override {
return SENSOR_A02YYU_ID;
}

unsigned char count() const override {
return 1;
}

// Initialization method, must be idempotent
void begin() {
if (!_dirty) return;
_ready = true;
_dirty = false;
}

// Descriptive name of the sensor
String description() const override {
return F("A02YYU");
}

// Address of the sensor (it could be the GPIO or I2C address)
String address(unsigned char index) const override {
return String(A02YYU_PORT, 10);
}

// Type for slot # index
unsigned char type(unsigned char index) const override {
if (index == 0) return MAGNITUDE_DISTANCE;
return MAGNITUDE_NONE;
}

// Current value for slot # index
double value(unsigned char index) override {
if (index == 0) return _distance;
return 0;
}

// Loop-like method, call it in your main loop
void tick() override {
_read();
}

protected:

// ---------------------------------------------------------------------
// Protected
// ---------------------------------------------------------------------

int _parse(uint8_t startIndex)
{
uint8_t i = startIndex;

if (_rx[i] != 0xff)
return -1;

int vh = _rx[(i + 1) & _RX_MASK];
int vl = _rx[(i + 2) & _RX_MASK];
int cs = _rx[(i + 3) & _RX_MASK];

if (cs != ((0xff + vh + vl) & 0xff))
return -2;

return (vh << 8) + vl;
}

void _read() {

int n;

_error = SENSOR_ERROR_OK;

// read all available bytes into rx circular buffer
while ((n = _serial->available()))
{
for (; n > 0; n--)
{
char c = _serial->read();
mcspr marked this conversation as resolved.
Show resolved Hide resolved

if (_rxCount < _RX_LEN) {
_rx[_rxIndex] = c;
_rxIndex = (_rxIndex + 1) & _RX_MASK;
_rxCount++;
} else {
// overflow
_error = SENSOR_ERROR_OTHER;
}
}
yield();
}

while (_rxCount >= 4)
{
int d = _parse(_rdIndex);

if (d > 0) {
_rdIndex = (_rdIndex + 4) & _RX_MASK;
_rxCount -= 4;
_distance = d / 1000.0;
} else {
_rdIndex = (_rdIndex + 1) & _RX_MASK;
_rxCount--;
}
}
}

// ---------------------------------------------------------------------

char _rx[_RX_LEN];
mcspr marked this conversation as resolved.
Show resolved Hide resolved
Stream* _serial { nullptr };
double _distance = 0;
uint8_t _rxIndex = 0;
uint8_t _rxCount = 0;
uint8_t _rdIndex = 0;
uint8_t _rdCount = 0;
};

#endif // SENSOR_SUPPORT && A02YYU_SUPPORT