Skip to content

Use an unsigned long for the baudrate and use Arduino core methods #2

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

Merged
merged 1 commit into from
Feb 22, 2016
Merged
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
43 changes: 16 additions & 27 deletions src/ModbusSlave.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,23 @@ Modbus::Modbus(uint8_t _unitID, int _ctrlPin) {
*
* @param boud the serial port boud rate.
*/
void Modbus::begin(int boud) {
void Modbus::begin(unsigned long boud) {
// set control pin
if (ctrlPin) {
pinMode(ctrlPin, OUTPUT);
}

// open port and set the timeout for 3.5 chars.
Serial.begin(boud);
Serial.flush();
Serial.setTimeout(0);

// set the T35 interframe timout to 5 milliseconds.
timeout = 5;
// set the T35 interframe timeout
if (boud > 19200) {
timeout = 1750;
}
else {
timeout = 35000000 / boud; // 1T * 3.5 = T3.5
}

// init last received values
last_receive_len = 0;
Expand Down Expand Up @@ -86,20 +91,6 @@ uint16_t Modbus::calcCRC(uint8_t *buf, int length) {
return crc;
}

/**
* Read all bytes available in serial port.
*/
int serialRead(uint8_t *buffer, uint8_t len) {
uint8_t size = 0;

while (Serial.available() && size < len) {
buffer[size] = Serial.read();
size++;
}

return size;
}

/**
* wait for end of frame, parse request and answer it.
*/
Expand All @@ -123,18 +114,18 @@ int Modbus::poll() {
// if we have new data, update last received time and length.
if (available_len != last_receive_len) {
last_receive_len = available_len;
last_receive_time = millis();
last_receive_time = micros();

return 0;
}

// if no new data, wait for T35 milliseconds.
if (millis() < (last_receive_time + timeout)) {
// if no new data, wait for T35 microseconds.
if (micros() < (last_receive_time + timeout)) {
return 0;
}

// we waited for the inter-frame timeout, read the frame.
lengthIn = serialRead(bufIn, MAX_BUFFER);
lengthIn = Serial.readBytes(bufIn, MAX_BUFFER);
last_receive_len = 0;
last_receive_time = 0;
} else {
Expand Down Expand Up @@ -267,18 +258,16 @@ int Modbus::poll() {
// send buffer
Serial.write(bufOut, lengthOut);

// wait until serial port register (UCSRnA)
// transfer complete bit (TXCn) is on
// and then set rs485 control pin to read
// wait for the transmission of outgoing data
// to complete and then set rs485 control pin to read
// [ on SoftwareSerial use delay ? ]
while (!(UCSR0A & (1 << TXC0)));
Serial.flush();
digitalWrite(ctrlPin, LOW);
} else {
// just send the buffer.
Serial.write(bufOut, lengthOut);
}

Serial.flush();
return lengthOut;
}

Expand Down
2 changes: 1 addition & 1 deletion src/ModbusSlave.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ typedef void(*CallBackFunc)(uint8_t, uint16_t, uint16_t);
class Modbus {
public:
Modbus(uint8_t unitID, int ctrlPin);
void begin(int boud);
void begin(unsigned long boud);
int poll();
uint16_t readRegisterFromBuffer(int offset);
void writeCoilToBuffer(int offset, uint16_t state);
Expand Down