Added mutex to MODBUS and I@c for mutithreading
This commit is contained in:
BIN
docs/mi004700-i-e.pdf
Normal file
BIN
docs/mi004700-i-e.pdf
Normal file
Binary file not shown.
@@ -24,7 +24,7 @@
|
|||||||
namespace drivers
|
namespace drivers
|
||||||
{
|
{
|
||||||
|
|
||||||
class Ethernet
|
class Ethernet : public ETHClass
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -3,21 +3,20 @@
|
|||||||
namespace drivers
|
namespace drivers
|
||||||
{
|
{
|
||||||
|
|
||||||
I2C::I2C()
|
I2C::I2C(): m_initialized(true)
|
||||||
{
|
{
|
||||||
Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN);
|
Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN);
|
||||||
isInitialized = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
I2C::~I2C()
|
I2C::~I2C()
|
||||||
{
|
{
|
||||||
Wire.end();
|
Wire.end();
|
||||||
isInitialized = true;
|
m_initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool I2C::read(const uint8_t deviceAddr, const uint8_t deviceReg, const uint8_t len, std::vector<uint8_t> &data)
|
const bool I2C::read(const uint8_t deviceAddr, const uint8_t deviceReg, const uint8_t len, std::vector<uint8_t> &data)
|
||||||
{
|
{
|
||||||
//busy.try_lock();
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
Wire.beginTransmission(deviceAddr);
|
Wire.beginTransmission(deviceAddr);
|
||||||
Wire.write(deviceReg);
|
Wire.write(deviceReg);
|
||||||
switch (Wire.endTransmission(true))
|
switch (Wire.endTransmission(true))
|
||||||
@@ -45,13 +44,12 @@ namespace drivers
|
|||||||
{
|
{
|
||||||
data[i] = static_cast<uint8_t>(Wire.read());
|
data[i] = static_cast<uint8_t>(Wire.read());
|
||||||
}
|
}
|
||||||
//busy.unlock();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool I2C::write(const uint8_t deviceAddr, const uint8_t deviceReg, const std::vector<uint8_t> &data)
|
const bool I2C::write(const uint8_t deviceAddr, const uint8_t deviceReg, const std::vector<uint8_t> &data)
|
||||||
{
|
{
|
||||||
//busy.lock();
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
Wire.beginTransmission(deviceAddr);
|
Wire.beginTransmission(deviceAddr);
|
||||||
Wire.write(deviceReg);
|
Wire.write(deviceReg);
|
||||||
for (auto d : data)
|
for (auto d : data)
|
||||||
@@ -73,7 +71,6 @@ namespace drivers
|
|||||||
LOG_ERROR("Unknown Error");
|
LOG_ERROR("Unknown Error");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//busy.unlock();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,16 +14,16 @@ namespace drivers
|
|||||||
|
|
||||||
class I2C
|
class I2C
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
bool isInitialized = false;
|
|
||||||
//std::mutex busy;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
I2C(void);
|
I2C(void);
|
||||||
~I2C(void);
|
~I2C(void);
|
||||||
|
|
||||||
const bool read(const uint8_t deviceAddr, const uint8_t deviceReg, const uint8_t len, std::vector<uint8_t> &data);
|
const bool read(const uint8_t deviceAddr, const uint8_t deviceReg, const uint8_t len, std::vector<uint8_t> &data);
|
||||||
const bool write(const uint8_t deviceAddr, const uint8_t deviceReg, const std::vector<uint8_t> &data);
|
const bool write(const uint8_t deviceAddr, const uint8_t deviceReg, const std::vector<uint8_t> &data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_initialized;
|
||||||
|
std::mutex m_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ namespace drivers
|
|||||||
const bool MODBUS::readCoils(const uint8_t device, const uint16_t reg, const uint16_t num, std::vector<bool> &coils)
|
const bool MODBUS::readCoils(const uint8_t device, const uint16_t reg, const uint16_t num, std::vector<bool> &coils)
|
||||||
{
|
{
|
||||||
constexpr uint8_t func = 0x01;
|
constexpr uint8_t func = 0x01;
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
LOG_DEBUG("Read coils: dev[", device, "], reg[", reg, "], num[", num, "]");
|
LOG_DEBUG("Read coils: dev[", device, "], reg[", reg, "], num[", num, "]");
|
||||||
return readBinary(device, func, reg, num, coils);
|
return readBinary(device, func, reg, num, coils);
|
||||||
}
|
}
|
||||||
@@ -79,6 +80,7 @@ namespace drivers
|
|||||||
const bool MODBUS::readInputs(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector<bool> &inputs)
|
const bool MODBUS::readInputs(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector<bool> &inputs)
|
||||||
{
|
{
|
||||||
constexpr uint8_t func = 0x02;
|
constexpr uint8_t func = 0x02;
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
LOG_DEBUG("Read multi inputs: dev[", device, "], reg[", reg, "], num[", num, "]");
|
LOG_DEBUG("Read multi inputs: dev[", device, "], reg[", reg, "], num[", num, "]");
|
||||||
return readBinary(device, func, reg, num, inputs);
|
return readBinary(device, func, reg, num, inputs);
|
||||||
}
|
}
|
||||||
@@ -87,6 +89,7 @@ namespace drivers
|
|||||||
const bool MODBUS::readHoldingRegisters(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector<uint16_t> &values)
|
const bool MODBUS::readHoldingRegisters(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector<uint16_t> &values)
|
||||||
{
|
{
|
||||||
constexpr uint8_t func = 0x03;
|
constexpr uint8_t func = 0x03;
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
LOG_DEBUG("Read multi holding registers: dev[", device, "], reg[", reg, "], num[", num, "]");
|
LOG_DEBUG("Read multi holding registers: dev[", device, "], reg[", reg, "], num[", num, "]");
|
||||||
return readInteger(device, func, reg, num, values);
|
return readInteger(device, func, reg, num, values);
|
||||||
}
|
}
|
||||||
@@ -95,6 +98,7 @@ namespace drivers
|
|||||||
const bool MODBUS::readInputRegisters(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector<uint16_t> &values)
|
const bool MODBUS::readInputRegisters(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector<uint16_t> &values)
|
||||||
{
|
{
|
||||||
constexpr uint8_t func = 0x04;
|
constexpr uint8_t func = 0x04;
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
LOG_DEBUG("Read multi input registers: dev[", device, "], reg[", reg, "], num[", num, "]");
|
LOG_DEBUG("Read multi input registers: dev[", device, "], reg[", reg, "], num[", num, "]");
|
||||||
return readInteger(device, func, reg, num, values);
|
return readInteger(device, func, reg, num, values);
|
||||||
}
|
}
|
||||||
@@ -103,6 +107,7 @@ namespace drivers
|
|||||||
const bool MODBUS::writeCoil(const uint8_t device, const uint16_t coil, const bool value)
|
const bool MODBUS::writeCoil(const uint8_t device, const uint16_t coil, const bool value)
|
||||||
{
|
{
|
||||||
constexpr uint8_t func = 0x05;
|
constexpr uint8_t func = 0x05;
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
LOG_DEBUG("Write single coil: dev[", device, "], coil[", coil, "], value[", value ? "true" : "false", "]");
|
LOG_DEBUG("Write single coil: dev[", device, "], coil[", coil, "], value[", value ? "true" : "false", "]");
|
||||||
return writeBinary(device, func, coil, {value});
|
return writeBinary(device, func, coil, {value});
|
||||||
}
|
}
|
||||||
@@ -111,6 +116,7 @@ namespace drivers
|
|||||||
const bool MODBUS::writeRegister(const uint8_t device, const uint16_t reg, const uint16_t value)
|
const bool MODBUS::writeRegister(const uint8_t device, const uint16_t reg, const uint16_t value)
|
||||||
{
|
{
|
||||||
constexpr uint8_t func = 0x06;
|
constexpr uint8_t func = 0x06;
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
LOG_DEBUG("Write single register: dev[", device, "], reg[", reg, "], value[", value, "]");
|
LOG_DEBUG("Write single register: dev[", device, "], reg[", reg, "], value[", value, "]");
|
||||||
return writeInteger(device, func, reg, {value}, false);
|
return writeInteger(device, func, reg, {value}, false);
|
||||||
}
|
}
|
||||||
@@ -119,6 +125,7 @@ namespace drivers
|
|||||||
const bool MODBUS::writeCoils(const uint8_t device, const uint16_t coils, const std::vector<bool> &values)
|
const bool MODBUS::writeCoils(const uint8_t device, const uint16_t coils, const std::vector<bool> &values)
|
||||||
{
|
{
|
||||||
constexpr uint8_t func = 0x0F;
|
constexpr uint8_t func = 0x0F;
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
LOG_DEBUG("Write multi coils: dev[", device, "], start[", coils, "], num[", values.size(), "]");
|
LOG_DEBUG("Write multi coils: dev[", device, "], start[", coils, "], num[", values.size(), "]");
|
||||||
return writeBinary(device, func, coils, values);
|
return writeBinary(device, func, coils, values);
|
||||||
}
|
}
|
||||||
@@ -127,6 +134,7 @@ namespace drivers
|
|||||||
const bool MODBUS::writeRegisters(const uint8_t device, const uint16_t reg, const std::vector<uint16_t> &values)
|
const bool MODBUS::writeRegisters(const uint8_t device, const uint16_t reg, const std::vector<uint16_t> &values)
|
||||||
{
|
{
|
||||||
constexpr uint8_t func = 0x10;
|
constexpr uint8_t func = 0x10;
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
LOG_DEBUG("Write multi registers: dev[", device, "], start[", reg, "], num[", values.size(), "]");
|
LOG_DEBUG("Write multi registers: dev[", device, "], start[", reg, "], num[", values.size(), "]");
|
||||||
return writeInteger(device, func, reg, values, true);
|
return writeInteger(device, func, reg, values, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <HardwareSerial.h> // Reference the ESP32 built-in serial port library
|
#include <HardwareSerial.h> // Reference the ESP32 built-in serial port library
|
||||||
#include <CRC16.h>
|
#include <CRC16.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace drivers
|
namespace drivers
|
||||||
{
|
{
|
||||||
@@ -80,6 +81,7 @@ namespace drivers
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
CRC16 m_crc;
|
CRC16 m_crc;
|
||||||
|
std::mutex m_mutex;
|
||||||
const std::vector<uint8_t> singleRequest(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t data);
|
const std::vector<uint8_t> singleRequest(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t data);
|
||||||
const std::vector<uint8_t> multiRequest(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t qty, const std::vector<uint8_t> &data);
|
const std::vector<uint8_t> multiRequest(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t qty, const std::vector<uint8_t> &data);
|
||||||
const bool readBinary(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t bits, std::vector<bool> &out);
|
const bool readBinary(const uint8_t device, const uint8_t func, const uint16_t reg, const uint16_t bits, std::vector<bool> &out);
|
||||||
|
|||||||
11
src/main.cpp
11
src/main.cpp
@@ -24,11 +24,14 @@ void callback(char *topic, uint8_t *payload, unsigned int length)
|
|||||||
|
|
||||||
void myTask(void *mqtt)
|
void myTask(void *mqtt)
|
||||||
{
|
{
|
||||||
while (true)
|
auto client = (PubSubClient *)(mqtt);
|
||||||
|
while (client->connected())
|
||||||
{
|
{
|
||||||
((PubSubClient *)(mqtt))->loop();
|
client->loop();
|
||||||
vTaskDelay(pdMS_TO_TICKS(100));
|
vTaskDelay(pdMS_TO_TICKS(100));
|
||||||
}
|
}
|
||||||
|
LOG_ERROR("Mqtt Loop Ended, client disconnected");
|
||||||
|
vTaskDelete(NULL); // delete the current task
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////// GLOBALS ///////////////
|
/////////////// GLOBALS ///////////////
|
||||||
@@ -42,7 +45,7 @@ void loop()
|
|||||||
{
|
{
|
||||||
const uint8_t tempBoardAddr(0xAA);
|
const uint8_t tempBoardAddr(0xAA);
|
||||||
const uint8_t relayBoardAddr(0x01);
|
const uint8_t relayBoardAddr(0x01);
|
||||||
const uint8_t senecadAddr(0xBB);
|
const uint8_t senecaMeterAddr(0xBB);
|
||||||
const uint8_t baseRegister(0x00);
|
const uint8_t baseRegister(0x00);
|
||||||
uint16_t k(0);
|
uint16_t k(0);
|
||||||
uint8_t ethRetries(0);
|
uint8_t ethRetries(0);
|
||||||
@@ -58,7 +61,7 @@ void loop()
|
|||||||
delay(100);
|
delay(100);
|
||||||
auto io = digitalIO(i2c, bus, {relayBoardAddr});
|
auto io = digitalIO(i2c, bus, {relayBoardAddr});
|
||||||
delay(100);
|
delay(100);
|
||||||
auto seneca = drivers::S50140(bus, senecadAddr);
|
auto seneca = drivers::S50140(bus, senecaMeterAddr);
|
||||||
|
|
||||||
Network.onEvent([ð](arduino_event_id_t event, arduino_event_info_t info)
|
Network.onEvent([ð](arduino_event_id_t event, arduino_event_info_t info)
|
||||||
{ eth.onEvent(event, info); });
|
{ eth.onEvent(event, info); });
|
||||||
|
|||||||
Reference in New Issue
Block a user