Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
37 changes: 19 additions & 18 deletions Modbusino.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@ ModbusinoSlave::ModbusinoSlave(uint8_t slave)
}
}

void ModbusinoSlave::setup(long baud)
void ModbusinoSlave::setup(long baud, HardwareSerial* port)
{
Serial.begin(baud);
_port = port;
(*port).begin(baud);
}

static int check_integrity(uint8_t *msg, uint8_t msg_length)
Expand Down Expand Up @@ -93,14 +94,14 @@ static int build_response_basis(uint8_t slave, uint8_t function, uint8_t *rsp)
return _MODBUS_RTU_PRESET_RSP_LENGTH;
}

static void send_msg(uint8_t *msg, uint8_t msg_length)
static void send_msg(uint8_t *msg, uint8_t msg_length, Stream* _port)
{
uint16_t crc = crc16(msg, msg_length);

msg[msg_length++] = crc >> 8;
msg[msg_length++] = crc & 0x00FF;

Serial.write(msg, msg_length);
(*_port).write(msg, msg_length);
}

static uint8_t response_exception(uint8_t slave, uint8_t function,
Expand All @@ -116,19 +117,19 @@ static uint8_t response_exception(uint8_t slave, uint8_t function,
return rsp_length;
}

static void flush(void)
static void flush(Stream* _port)
{
uint8_t i = 0;

/* Wait a moment to receive the remaining garbage but avoid getting stuck
* because the line is saturated */
while (Serial.available() && i++ < 10) {
Serial.flush();
while ((*_port).available() && i++ < 10) {
(*_port).flush(_port);
delay(3);
}
}

static int receive(uint8_t *req, uint8_t _slave)
static int receive(uint8_t *req, uint8_t _slave, Stream* _port)
{
uint8_t i;
uint8_t length_to_read;
Expand All @@ -148,9 +149,9 @@ static int receive(uint8_t *req, uint8_t _slave)
/* The timeout is defined to ~10 ms between each bytes. Precision is
not that important so I rather to avoid millis() to apply the KISS
principle (millis overflows after 50 days, etc) */
if (!Serial.available()) {
if (!(*_port).available()) {
i = 0;
while (!Serial.available()) {
while (!(*_port).available()) {
if (++i == 10) {
/* Too late, bye */
return -1 - MODBUS_INFORMATIVE_RX_TIMEOUT;
Expand All @@ -159,7 +160,7 @@ static int receive(uint8_t *req, uint8_t _slave)
}
}

req[req_index] = Serial.read();
req[req_index] = (*_port).read();

/* Moves the pointer to receive other data */
req_index++;
Expand All @@ -170,7 +171,7 @@ static int receive(uint8_t *req, uint8_t _slave)
if (length_to_read == 0) {
if (req[_MODBUS_RTU_SLAVE] != _slave
&& req[_MODBUS_RTU_SLAVE != MODBUS_BROADCAST_ADDRESS]) {
flush();
flush(_port);
return -1 - MODBUS_INFORMATIVE_NOT_FOR_US;
}

Expand All @@ -184,14 +185,14 @@ static int receive(uint8_t *req, uint8_t _slave)
length_to_read = 5;
} else {
/* Wait a moment to receive the remaining garbage */
flush();
flush(_port);
if (req[_MODBUS_RTU_SLAVE] == _slave
|| req[_MODBUS_RTU_SLAVE] == MODBUS_BROADCAST_ADDRESS) {
/* It's for me so send an exception (reuse req) */
uint8_t rsp_length = response_exception(
_slave, function, MODBUS_EXCEPTION_ILLEGAL_FUNCTION,
req);
send_msg(req, rsp_length);
send_msg(req, rsp_length, _port);
return -1 - MODBUS_EXCEPTION_ILLEGAL_FUNCTION;
}

Expand All @@ -207,14 +208,14 @@ static int receive(uint8_t *req, uint8_t _slave)

if ((req_index + length_to_read)
> _MODBUSINO_RTU_MAX_ADU_LENGTH) {
flush();
flush(_port);
if (req[_MODBUS_RTU_SLAVE] == _slave
|| req[_MODBUS_RTU_SLAVE] == MODBUS_BROADCAST_ADDRESS) {
/* It's for me so send an exception (reuse req) */
uint8_t rsp_length = response_exception(
_slave, function,
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, req);
send_msg(req, rsp_length);
send_msg(req, rsp_length, _port);
return -1 - MODBUS_EXCEPTION_ILLEGAL_FUNCTION;
}
return -1;
Expand Down Expand Up @@ -277,15 +278,15 @@ static void reply(uint16_t *tab_reg, uint16_t nb_reg, uint8_t *req,
}
}

send_msg(rsp, rsp_length);
send_msg(rsp, rsp_length, _port);
}

int ModbusinoSlave::loop(uint16_t *tab_reg, uint16_t nb_reg)
{
int rc = 0;
uint8_t req[_MODBUSINO_RTU_MAX_ADU_LENGTH];

if (Serial.available()) {
if ((*_port).available()) {
rc = receive(req, _slave);
if (rc > 0) {
reply(tab_reg, nb_reg, req, rc, _slave);
Expand Down
3 changes: 2 additions & 1 deletion Modbusino.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@

class ModbusinoSlave {
public:
ModbusinoSlave(uint8_t slave);
ModbusinoSlave(uint8_t slave, HardwareSerial* port);
void setup(long baud);
int loop(uint16_t *tab_reg, uint16_t nb_reg);
private:
int _slave;
Stream* _port;
};

#endif
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ ModbusinoSlave modbusino_slave(1);
uint16_t tab_reg[10];

void setup() {
/* The transfer speed is set to 115200 bauds */
modbusino_slave.setup(115200);
/* The transfer speed is set to 115200 bauds and the port to Serial */
modbusino_slave.setup(115200, &Serial);
}

void loop() {
Expand Down