Feature: rxen/txen support for RS485 transceiver for SDM power meter (#1269)
This allows to talk to the SDM power meter through an RS485 transceiver with separate rxen and txen pins, like on the OpenDTU Fusion board.
This commit is contained in:
parent
c16b3aa21b
commit
2637e32145
@ -67,6 +67,8 @@ struct PinMapping_t {
|
||||
int8_t powermeter_rx;
|
||||
int8_t powermeter_tx;
|
||||
int8_t powermeter_dere;
|
||||
int8_t powermeter_rxen;
|
||||
int8_t powermeter_txen;
|
||||
};
|
||||
|
||||
class PinMappingClass {
|
||||
|
||||
@ -38,6 +38,15 @@ SDM::SDM(SoftwareSerial& serial, long baud, int dere_pin, int config, int8_t rx_
|
||||
this->_rx_pin = rx_pin;
|
||||
this->_tx_pin = tx_pin;
|
||||
}
|
||||
SDM::SDM(SoftwareSerial &serial, long baud, int dere_pin, int re_pin, int config, int8_t rx_pin, int8_t tx_pin) : sdmSer(serial)
|
||||
{
|
||||
this->_baud = baud;
|
||||
this->_dere_pin = dere_pin;
|
||||
this->_re_pin = re_pin;
|
||||
this->_config = config;
|
||||
this->_rx_pin = rx_pin;
|
||||
this->_tx_pin = tx_pin;
|
||||
}
|
||||
#else
|
||||
SDM::SDM(SoftwareSerial& serial, long baud, int dere_pin) : sdmSer(serial) {
|
||||
this->_baud = baud;
|
||||
@ -73,6 +82,9 @@ void SDM::begin(void) {
|
||||
if (_dere_pin != NOT_A_PIN) {
|
||||
pinMode(_dere_pin, OUTPUT); //set output pin mode for DE/RE pin when used (for control MAX485)
|
||||
}
|
||||
if (_re_pin != NOT_A_PIN) {
|
||||
pinMode(_re_pin, OUTPUT); // set output pin mode /RE pin when used (for control MAX485)
|
||||
}
|
||||
dereSet(LOW); //set init state to receive from SDM -> DE Disable, /RE Enable (for control MAX485)
|
||||
}
|
||||
|
||||
@ -360,6 +372,8 @@ void SDM::flush(unsigned long _flushtime) {
|
||||
void SDM::dereSet(bool _state) {
|
||||
if (_dere_pin != NOT_A_PIN)
|
||||
digitalWrite(_dere_pin, _state); //receive from SDM -> DE Disable, /RE Enable (for control MAX485)
|
||||
if (_re_pin != NOT_A_PIN)
|
||||
digitalWrite(_re_pin, _state); //receive from SDM -> /RE Enable (for control MAX485)
|
||||
}
|
||||
|
||||
bool SDM::validChecksum(const uint8_t* data, size_t messageLength) const {
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
|
||||
#if !defined ( DERE_PIN )
|
||||
#define DERE_PIN NOT_A_PIN // default digital pin for control MAX485 DE/RE lines (connect DE & /RE together to this pin)
|
||||
#define RE_PIN NOT_A_PIN // default digital pin for control MAX485 RE line (use DERE_PIN for DE line)
|
||||
#endif
|
||||
|
||||
#if defined ( USE_HARDWARESERIAL )
|
||||
@ -332,6 +333,7 @@ class SDM {
|
||||
#else // software serial
|
||||
#if defined ( ESP8266 ) || defined ( ESP32 ) // on esp8266/esp32
|
||||
SDM(SoftwareSerial& serial, long baud = SDM_UART_BAUD, int dere_pin = DERE_PIN, int config = SDM_UART_CONFIG, int8_t rx_pin = SDM_RX_PIN, int8_t tx_pin = SDM_TX_PIN);
|
||||
SDM(SoftwareSerial& serial, long baud = SDM_UART_BAUD, int dere_pin = DERE_PIN, int re_pin = RE_PIN, int config = SDM_UART_CONFIG, int8_t rx_pin = SDM_RX_PIN, int8_t tx_pin = SDM_TX_PIN);
|
||||
#else // on avr
|
||||
SDM(SoftwareSerial& serial, long baud = SDM_UART_BAUD, int dere_pin = DERE_PIN);
|
||||
#endif
|
||||
@ -390,6 +392,7 @@ class SDM {
|
||||
#endif
|
||||
long _baud = SDM_UART_BAUD;
|
||||
int _dere_pin = DERE_PIN;
|
||||
int _re_pin = RE_PIN;
|
||||
uint16_t readingerrcode = SDM_ERR_NO_ERROR; // 4 = timeout; 3 = not enough bytes; 2 = number of bytes OK but bytes b0,b1 or b2 wrong, 1 = crc error
|
||||
uint16_t msturnaround = WAITING_TURNAROUND_DELAY;
|
||||
uint16_t mstimeout = RESPONSE_TIMEOUT;
|
||||
|
||||
@ -170,6 +170,14 @@
|
||||
#define POWERMETER_PIN_DERE -1
|
||||
#endif
|
||||
|
||||
#ifndef POWERMETER_PIN_TXEN
|
||||
#define POWERMETER_PIN_TXEN -1
|
||||
#endif
|
||||
|
||||
#ifndef POWERMETER_PIN_RXEN
|
||||
#define POWERMETER_PIN_RXEN -1
|
||||
#endif
|
||||
|
||||
#ifndef W5500_SCLK
|
||||
#define W5500_SCLK -1
|
||||
#endif
|
||||
@ -267,6 +275,8 @@ PinMappingClass::PinMappingClass()
|
||||
_pinMapping.powermeter_rx = POWERMETER_PIN_RX;
|
||||
_pinMapping.powermeter_tx = POWERMETER_PIN_TX;
|
||||
_pinMapping.powermeter_dere = POWERMETER_PIN_DERE;
|
||||
_pinMapping.powermeter_rxen = POWERMETER_PIN_RXEN;
|
||||
_pinMapping.powermeter_txen = POWERMETER_PIN_TXEN;
|
||||
}
|
||||
|
||||
PinMapping_t& PinMappingClass::get()
|
||||
@ -359,6 +369,8 @@ bool PinMappingClass::init(const String& deviceMapping)
|
||||
_pinMapping.powermeter_rx = doc[i]["powermeter"]["rx"] | POWERMETER_PIN_RX;
|
||||
_pinMapping.powermeter_tx = doc[i]["powermeter"]["tx"] | POWERMETER_PIN_TX;
|
||||
_pinMapping.powermeter_dere = doc[i]["powermeter"]["dere"] | POWERMETER_PIN_DERE;
|
||||
_pinMapping.powermeter_rxen = doc[i]["powermeter"]["rxen"] | POWERMETER_PIN_RXEN;
|
||||
_pinMapping.powermeter_txen = doc[i]["powermeter"]["txen"] | POWERMETER_PIN_TXEN;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -28,8 +28,8 @@ bool PowerMeterSerialSdm::init()
|
||||
{
|
||||
const PinMapping_t& pin = PinMapping.get();
|
||||
|
||||
MessageOutput.printf("[PowerMeterSerialSdm] rx = %d, tx = %d, dere = %d\r\n",
|
||||
pin.powermeter_rx, pin.powermeter_tx, pin.powermeter_dere);
|
||||
MessageOutput.printf("[PowerMeterSerialSdm] rx = %d, tx = %d, dere = %d, rxen = %d, txen = %d \r\n",
|
||||
pin.powermeter_rx, pin.powermeter_tx, pin.powermeter_dere, pin.powermeter_rxen, pin.powermeter_txen);
|
||||
|
||||
if (pin.powermeter_rx < 0 || pin.powermeter_tx < 0) {
|
||||
MessageOutput.println("[PowerMeterSerialSdm] invalid pin config for SDM "
|
||||
@ -38,8 +38,17 @@ bool PowerMeterSerialSdm::init()
|
||||
}
|
||||
|
||||
_upSdmSerial = std::make_unique<SoftwareSerial>();
|
||||
_upSdm = std::make_unique<SDM>(*_upSdmSerial, 9600, pin.powermeter_dere,
|
||||
|
||||
if (pin.powermeter_rxen > -1 && pin.powermeter_txen > -1){
|
||||
_upSdm = std::make_unique<SDM>(*_upSdmSerial, 9600, pin.powermeter_rxen, pin.powermeter_txen,
|
||||
SWSERIAL_8N1, pin.powermeter_rx, pin.powermeter_tx);
|
||||
}
|
||||
else
|
||||
{
|
||||
_upSdm = std::make_unique<SDM>(*_upSdmSerial, 9600, pin.powermeter_dere,
|
||||
SWSERIAL_8N1, pin.powermeter_rx, pin.powermeter_tx);
|
||||
}
|
||||
|
||||
_upSdm->begin();
|
||||
|
||||
return true;
|
||||
|
||||
@ -116,6 +116,13 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request)
|
||||
huaweiPinObj["cs"] = pin.huawei_cs;
|
||||
huaweiPinObj["power"] = pin.huawei_power;
|
||||
|
||||
auto powermeterPinObj = curPin["powermeter"].to<JsonObject>();
|
||||
powermeterPinObj["rx"] = pin.powermeter_rx;
|
||||
powermeterPinObj["tx"] = pin.powermeter_tx;
|
||||
powermeterPinObj["dere"] = pin.powermeter_dere;
|
||||
powermeterPinObj["rxen"] = pin.powermeter_rxen;
|
||||
powermeterPinObj["txen"] = pin.powermeter_txen;
|
||||
|
||||
WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user