55 * @author Samuel Marco i Armengol
6677 * @contribution Helium6072
8+ * @contribution gabrielsan
89 *
910 * @description
1011 * Arduino library for communicating with Modbus devices
@@ -167,7 +168,7 @@ class Modbus
167168 uint16_t *au16regs;
168169 uint16_t u16InCnt, u16OutCnt, u16errCnt;
169170 uint16_t u16timeOut;
170- uint32_t u32time, u32timeOut;
171+ uint32_t u32time, u32timeOut, u32overTime ;
171172 uint8_t u8regsize;
172173
173174 void init (uint8_t u8id, uint8_t u8serno, uint8_t u8txenpin);
@@ -194,7 +195,7 @@ class Modbus
194195 Modbus (uint8_t u8id);
195196 void begin (long u32speed);
196197 void begin (SoftwareSerial *sPort , long u32speed);
197- void begin (long u32speed, uint8_t u8config);
198+ // void begin(long u32speed, uint8_t u8config);
198199 void begin ();
199200 void setTimeOut ( uint16_t u16timeout); // !<write communication watch-dog timer
200201 uint16_t getTimeOut (); // !<get communication watch-dog timer value
@@ -209,6 +210,7 @@ class Modbus
209210 uint8_t getState ();
210211 uint8_t getLastError (); // !<get last error message
211212 void setID ( uint8_t u8id ); // !<write new ID for the slave
213+ void setTxendPinOverTime ( uint32_t u32overTime );
212214 void end (); // !<finish any communication and release serial communication port
213215};
214216
@@ -372,7 +374,7 @@ void Modbus::begin(SoftwareSerial *sPort, long u32speed)
372374 * @param config data frame settings (data length, parity and stop bits)
373375 * @ingroup setup
374376 */
375- void Modbus::begin (long u32speed,uint8_t u8config)
377+ /* void Modbus::begin(long u32speed,uint8_t u8config)
376378{
377379
378380 switch( u8serno )
@@ -411,7 +413,7 @@ void Modbus::begin(long u32speed,uint8_t u8config)
411413 while(port->read() >= 0);
412414 u8lastRec = u8BufferSize = 0;
413415 u16InCnt = u16OutCnt = u16errCnt = 0;
414- }
416+ } */
415417
416418/* *
417419 * @brief
@@ -443,6 +445,21 @@ void Modbus::setID( uint8_t u8id)
443445 }
444446}
445447
448+ /* *
449+ * @brief
450+ * Method to write the overtime count for txend pin.
451+ * It waits until count reaches 0 after the transfer is done.
452+ * With this, you can extend the time between txempty and
453+ * the falling edge if needed.
454+ *
455+ * @param uint32_t overtime count for txend pin
456+ * @ingroup setup
457+ */
458+ void Modbus::setTxendPinOverTime ( uint32_t u32overTime )
459+ {
460+ this ->u32overTime = u32overTime;
461+ }
462+
446463/* *
447464 * @brief
448465 * Method to read current slave ID address
@@ -824,6 +841,7 @@ void Modbus::init(uint8_t u8id, uint8_t u8serno, uint8_t u8txenpin)
824841 this ->u8serno = u8serno;
825842 this ->u8txenpin = u8txenpin;
826843 this ->u16timeOut = 1000 ;
844+ this ->u32overTime = 0 ;
827845}
828846
829847void Modbus::init (uint8_t u8id)
@@ -832,6 +850,7 @@ void Modbus::init(uint8_t u8id)
832850 this ->u8serno = 4 ;
833851 this ->u8txenpin = 0 ;
834852 this ->u16timeOut = 1000 ;
853+ this ->u32overTime = 0 ;
835854}
836855
837856/* *
@@ -896,74 +915,28 @@ void Modbus::sendTxBuffer()
896915 u8BufferSize++;
897916 au8Buffer[ u8BufferSize ] = u16crc & 0x00ff ;
898917 u8BufferSize++;
899-
900- // set RS485 transceiver to transmit mode
918+
901919 if (u8txenpin > 1 )
902920 {
903- switch ( u8serno )
904- {
905- #if defined(UBRR1H)
906- case 1 :
907- UCSR1A=UCSR1A |(1 << TXC1);
908- break ;
909- #endif
910-
911- #if defined(UBRR2H)
912- case 2 :
913- UCSR2A=UCSR2A |(1 << TXC2);
914- break ;
915- #endif
916-
917- #if defined(UBRR3H)
918- case 3 :
919- UCSR3A=UCSR3A |(1 << TXC3);
920- break ;
921- #endif
922- case 0 :
923- UCSR0A=UCSR0A |(1 << TXC0);
924- break ;
925- default :
926- break ;
927- }
921+ // set RS485 transceiver to transmit mode
928922 digitalWrite ( u8txenpin, HIGH );
929923 }
930924
931925 // transfer buffer to serial line
932- if (u8serno< 4 )
926+ if (u8serno < 4 )
933927 port->write ( au8Buffer, u8BufferSize );
934928 else
935929 softPort->write ( au8Buffer, u8BufferSize );
936930
937- // keep RS485 transceiver in transmit mode as long as sending
938931 if (u8txenpin > 1 )
939932 {
940- switch ( u8serno )
941- {
942- #if defined(UBRR1H)
943- case 1 :
944- while (!(UCSR1A & (1 << TXC1)));
945- break ;
946- #endif
947-
948- #if defined(UBRR2H)
949- case 2 :
950- while (!(UCSR2A & (1 << TXC2)));
951- break ;
952- #endif
953-
954- #if defined(UBRR3H)
955- case 3 :
956- while (!(UCSR3A & (1 << TXC3)));
957- break ;
958- #endif
959- case 0 :
960- while (!(UCSR0A & (1 << TXC0)));
961- break ;
962- default :
963- break ;
964- }
965-
933+ // must wait transmission end before changing pin state
934+ // soft serial does not need it since it is blocking
935+ if (u8serno < 4 )
936+ port->flush ();
966937 // return RS485 transceiver to receive mode
938+ volatile uint32_t u32overTimeCountDown = u32overTime;
939+ while ( u32overTimeCountDown-- > 0 );
967940 digitalWrite ( u8txenpin, LOW );
968941 }
969942 if (u8serno<4 )
0 commit comments