Skip to content

Commit

Permalink
Merge pull request #17 from gabrielsan/master
Browse files Browse the repository at this point in the history
minor fixes when using softserial
  • Loading branch information
smarmengol authored Jul 20, 2018
2 parents 2297787 + e9d0f9f commit ce3489b
Showing 1 changed file with 42 additions and 67 deletions.
109 changes: 42 additions & 67 deletions ModbusRtu.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* @author Samuel Marco i Armengol
* @contact [email protected]
* @contribution Helium6072
* @contribution gabrielsan
*
* @description
* Arduino library for communicating with Modbus devices
Expand Down Expand Up @@ -167,7 +168,7 @@ class Modbus
uint16_t *au16regs;
uint16_t u16InCnt, u16OutCnt, u16errCnt;
uint16_t u16timeOut;
uint32_t u32time, u32timeOut;
uint32_t u32time, u32timeOut, u32overTime;
uint8_t u8regsize;

void init(uint8_t u8id, uint8_t u8serno, uint8_t u8txenpin);
Expand All @@ -194,9 +195,9 @@ class Modbus
Modbus(uint8_t u8id);
void begin(long u32speed);
void begin(SoftwareSerial *sPort, long u32speed);
void begin(long u32speed, uint8_t u8config);
//void begin(long u32speed, uint8_t u8config);
void begin();
void setTimeOut( uint16_t u16timeout); //!<write communication watch-dog timer
void setTimeOut( uint16_t u16timeOut); //!<write communication watch-dog timer
uint16_t getTimeOut(); //!<get communication watch-dog timer value
boolean getTimeOutState(); //!<get communication watch-dog timer state
int8_t query( modbus_t telegram ); //!<only for master
Expand All @@ -209,6 +210,7 @@ class Modbus
uint8_t getState();
uint8_t getLastError(); //!<get last error message
void setID( uint8_t u8id ); //!<write new ID for the slave
void setTxendPinOverTime( uint32_t u32overTime );
void end(); //!<finish any communication and release serial communication port
};

Expand Down Expand Up @@ -372,7 +374,7 @@ void Modbus::begin(SoftwareSerial *sPort, long u32speed)
* @param config data frame settings (data length, parity and stop bits)
* @ingroup setup
*/
void Modbus::begin(long u32speed,uint8_t u8config)
/* void Modbus::begin(long u32speed,uint8_t u8config)
{
switch( u8serno )
Expand Down Expand Up @@ -411,7 +413,7 @@ void Modbus::begin(long u32speed,uint8_t u8config)
while(port->read() >= 0);
u8lastRec = u8BufferSize = 0;
u16InCnt = u16OutCnt = u16errCnt = 0;
}
} */

/**
* @brief
Expand Down Expand Up @@ -443,6 +445,21 @@ void Modbus::setID( uint8_t u8id)
}
}

/**
* @brief
* Method to write the overtime count for txend pin.
* It waits until count reaches 0 after the transfer is done.
* With this, you can extend the time between txempty and
* the falling edge if needed.
*
* @param uint32_t overtime count for txend pin
* @ingroup setup
*/
void Modbus::setTxendPinOverTime( uint32_t u32overTime )
{
this->u32overTime = u32overTime;
}

/**
* @brief
* Method to read current slave ID address
Expand Down Expand Up @@ -481,7 +498,7 @@ void Modbus::setTimeOut( uint16_t u16timeOut)
*/
boolean Modbus::getTimeOutState()
{
return (millis() > u32timeOut);
return ((unsigned long)(millis() -u32timeOut) > (unsigned long)u16timeOut);
}

/**
Expand Down Expand Up @@ -668,7 +685,7 @@ int8_t Modbus::poll()
else
u8current = softPort->available();

if (millis() > u32timeOut)
if ((unsigned long)(millis() -u32timeOut) > (unsigned long)u16timeOut)
{
u8state = COM_IDLE;
u8lastError = NO_REPLY;
Expand All @@ -682,10 +699,10 @@ int8_t Modbus::poll()
if (u8current != u8lastRec)
{
u8lastRec = u8current;
u32time = millis() + T35;
u32time = millis();
return 0;
}
if (millis() < u32time) return 0;
if ((unsigned long)(millis() -u32time) < (unsigned long)T35) return 0;

// transfer Serial buffer frame to auBuffer
u8lastRec = 0;
Expand Down Expand Up @@ -764,10 +781,10 @@ int8_t Modbus::poll( uint16_t *regs, uint8_t u8size )
if (u8current != u8lastRec)
{
u8lastRec = u8current;
u32time = millis() + T35;
u32time = millis();
return 0;
}
if (millis() < u32time) return 0;
if ((unsigned long)(millis() -u32time) < (unsigned long)T35) return 0;

u8lastRec = 0;
int8_t i8state = getRxBuffer();
Expand All @@ -790,7 +807,7 @@ int8_t Modbus::poll( uint16_t *regs, uint8_t u8size )
return u8exception;
}

u32timeOut = millis() + long(u16timeOut);
u32timeOut = millis();
u8lastError = 0;

// process message
Expand Down Expand Up @@ -827,9 +844,10 @@ int8_t Modbus::poll( uint16_t *regs, uint8_t u8size )
void Modbus::init(uint8_t u8id, uint8_t u8serno, uint8_t u8txenpin)
{
this->u8id = u8id;
this->u8serno = (u8serno > 3) ? 0 : u8serno;
this->u8serno = u8serno;
this->u8txenpin = u8txenpin;
this->u16timeOut = 1000;
this->u32overTime = 0;
}

void Modbus::init(uint8_t u8id)
Expand All @@ -838,6 +856,7 @@ void Modbus::init(uint8_t u8id)
this->u8serno = 4;
this->u8txenpin = 0;
this->u16timeOut = 1000;
this->u32overTime = 0;
}

/**
Expand Down Expand Up @@ -902,72 +921,28 @@ void Modbus::sendTxBuffer()
u8BufferSize++;
au8Buffer[ u8BufferSize ] = u16crc & 0x00ff;
u8BufferSize++;

// set RS485 transceiver to transmit mode

if (u8txenpin > 1)
{
switch( u8serno )
{
#if defined(UBRR1H)
case 1:
UCSR1A=UCSR1A |(1 << TXC1);
break;
#endif

#if defined(UBRR2H)
case 2:
UCSR2A=UCSR2A |(1 << TXC2);
break;
#endif

#if defined(UBRR3H)
case 3:
UCSR3A=UCSR3A |(1 << TXC3);
break;
#endif
case 0:
default:
UCSR0A=UCSR0A |(1 << TXC0);
break;
}
// set RS485 transceiver to transmit mode
digitalWrite( u8txenpin, HIGH );
}

// transfer buffer to serial line
if(u8serno<4)
if (u8serno < 4)
port->write( au8Buffer, u8BufferSize );
else
softPort->write( au8Buffer, u8BufferSize );

// keep RS485 transceiver in transmit mode as long as sending
if (u8txenpin > 1)
{
switch( u8serno )
{
#if defined(UBRR1H)
case 1:
while (!(UCSR1A & (1 << TXC1)));
break;
#endif

#if defined(UBRR2H)
case 2:
while (!(UCSR2A & (1 << TXC2)));
break;
#endif

#if defined(UBRR3H)
case 3:
while (!(UCSR3A & (1 << TXC3)));
break;
#endif
case 0:
default:
while (!(UCSR0A & (1 << TXC0)));
break;
}

// must wait transmission end before changing pin state
// soft serial does not need it since it is blocking
if (u8serno < 4)
port->flush();
// return RS485 transceiver to receive mode
volatile uint32_t u32overTimeCountDown = u32overTime;
while ( u32overTimeCountDown-- > 0);
digitalWrite( u8txenpin, LOW );
}
if(u8serno<4)
Expand All @@ -978,7 +953,7 @@ void Modbus::sendTxBuffer()
u8BufferSize = 0;

// set time-out for master
u32timeOut = millis() + (unsigned long) u16timeOut;
u32timeOut = millis();

// increase message counter
u16OutCnt++;
Expand Down

0 comments on commit ce3489b

Please sign in to comment.