Testing Modbus RS485 commands
Dependencies: mbed BufferedSerial
Revision 5:ddf182356d90, committed 2021-10-06
- Comitter:
- zillkhan
- Date:
- Wed Oct 06 11:43:00 2021 +0000
- Parent:
- 4:6a8a69b660c2
- Commit message:
- Initial changes
Changed in this revision
diff -r 6a8a69b660c2 -r ddf182356d90 BufferedSerial.lib --- a/BufferedSerial.lib Sun May 21 20:41:37 2017 +0000 +++ b/BufferedSerial.lib Wed Oct 06 11:43:00 2021 +0000 @@ -1,1 +1,1 @@ -http://developer.mbed.org/users/sam_grove/code/BufferedSerial/#a0d37088b405 +https://os.mbed.com/users/sam_grove/code/BufferedSerial/#7e5e866edd3d
diff -r 6a8a69b660c2 -r ddf182356d90 RS485.cpp --- a/RS485.cpp Sun May 21 20:41:37 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,143 +0,0 @@ -#include "RS485.h" -#include <stdarg.h> - -typedef unsigned int word; -typedef uint8_t byte; -typedef uint8_t boolean; -typedef void (*voidFuncPtr)(void); -Timer lapse; - const byte STX = '\2'; - const byte ETX = '\3'; - -RS485::RS485(PinName tx, PinName rx, PinName dere) - : BufferedSerial(tx, rx) -{ - return; -} - - -byte RS485::crc8(const byte *addr, byte len) -{ - byte crc = 0; - while (len--) - { - byte inbyte = *addr++; - for (byte i = 8; i; i--) - { - byte mix = (crc ^ inbyte) & 0x01; - crc >>= 1; - if (mix) - crc ^= 0x8C; - inbyte >>= 1; - } // end of for - } // end of while - return crc; -} // end of crc8 - -void RS485::sendComplemented( const byte what) -{ - byte c ; - // first nibble - c = what >> 4; - putc((c << 4) | (c ^ 0x0F)); - - // second nibble - c = what & 0x0F; - putc((c << 4) | (c ^ 0x0F)); -} // end of sendComplemented - - -void RS485::sendMsg(const byte * data, const byte length) -{ - putc(STX); // STX - for (byte i = 0; i < length; i++) - sendComplemented (data[i]); - putc(ETX); // ETX - sendComplemented(crc8(data, length)); -} // end of sendMsg - -// receive a message, maximum "length" bytes, timeout after "timeout" clock_mseconds -// if nothing received, or an error (eg. bad CRC, bad data) return 0 -// otherwise, returns length of received data -byte RS485::recvMsg (byte * data, // buffer to receive into - const byte length, // maximum buffer size - unsigned long timeout) // clock_mseconds before timing out - { - - unsigned long start_time = lapse.read_ms(); - - bool have_stx = false; - - // variables below are set when we get an STX - bool have_etx; - byte input_pos; - bool first_nibble; - byte current_byte; - - while (lapse.read_ms() - start_time < timeout) - { - if (readable() > 0) - { - byte inByte = getc(); - - switch (inByte) - { - - case STX: // start of text - have_stx = true; - have_etx = false; - input_pos = 0; - first_nibble = true; - start_time = lapse.read_ms(); // reset timeout period - break; - - case ETX: // end of text - have_etx = true; - break; - - default: - // wait until packet officially starts - if (!have_stx) - break; - - // check byte is in valid form (4 bits followed by 4 bits complemented) - if ((inByte >> 4) != ((inByte & 0x0F) ^ 0x0F) ) - return 0; // bad character - - // convert back - inByte >>= 4; - - // high-order nibble? - if (first_nibble) - { - current_byte = inByte; - first_nibble = false; - break; - } // end of first nibble - - // low-order nibble - current_byte <<= 4; - current_byte |= inByte; - first_nibble = true; - - // if we have the ETX this must be the CRC - if (have_etx) - { - if (crc8 (data, input_pos) != current_byte) - return 0; // bad crc - return input_pos; // return received length - } // end if have ETX already - - // keep adding if not full - if (input_pos < length) - data [input_pos++] = current_byte; - else - return 0; // overflow - break; - - } // end of switch - } // end of incoming data - } // end of while not timed out - - return 0; // timeout -} // end of recvMsg \ No newline at end of file
diff -r 6a8a69b660c2 -r ddf182356d90 RS485.h --- a/RS485.h Sun May 21 20:41:37 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,135 +0,0 @@ - -/** - * @file RS485.h - * @brief RS485 protocol - using half duplex method - * @author Aaron Allar - * @version 1.0 - * @see - * - * based on this method https://www.gammon.com.au/forum/?id=11428 - * - * Can send from 1 to 255 bytes from one node to another with: - * - * Packet start indicator (STX) - * Each data byte is doubled and inverted to check validity - * Packet end indicator (ETX) - * Packet CRC (checksum) - */ - - - -#ifndef RS485_H -#define RS485_H - -#include "BufferedSerial.h" -#include "mbed.h" - -/** RS485 Library - * - * Can send from 1 to 255 bytes from one node to another with: - * - * Packet start indicator (STX) - * Each data byte is doubled and inverted to check validity - * Packet end indicator (ETX) - * Packet CRC (checksum) - * - * Using MAX485 modules or the MAX485 CSA+ - * - * Example: - * @code - * #include "mbed.h" - * #include <RS485.h> - * Serial pc(USBTX, USBRX); - * RS485 RS485(PC_10,PC_11,PB_3); // Tx, Rx , !RE and DE MAX485 pin - * - * DigitalOut ho(PB_3); // this pin should be connected to !RE and DE - * typedef uint8_t byte; - * - * byte regvalue[9]; - * byte data[9] = {0x01,0x04,0x00,0x48,0x00,0x02,0xf1,0xdd};//your data - * int main() - * { - * pc.printf("main\n"); - * while(1) { - * pc.printf("Starting\n"); - * ho = 1; // Enable sending on MAX485 - * RS485.sendMsg(data,sizeof(data)); - * wait_ms(600); // Must wait for all the data to be sent - * ho = 0; // Enable receiving on MAX485 - * pc.printf("Getting data\n"); - * if(RS485.readable() >0){ - * memset(regvalue,0,sizeof(regvalue)); - * wait_ms(200); - * RS485.recvMsg(regvalue,sizeof(data),500); - * wait_ms(200); - * for (int count = 0; count < 9; count++) { - * pc.printf("%X - ", regvalue[count]); - * } - * }else printf("No Data\n"); - * printf("Done\n"); - * wait_ms(1000); - * } - * } - * @endcode - */ - - -/** - * @class RS485 - * @communicating - */ - -class RS485 : public BufferedSerial -{ -private: - typedef unsigned int word; - typedef uint8_t byte; - typedef uint8_t boolean; - typedef void (*voidFuncPtr)(void); - -public: - /** Create a BufferedSerial port, connected to the specified transmit and receive pins - * @param tx Transmit pin - * @param rx Receive pin - * @param dere Enable pin, this pin should be connected to !RE and DE - * @note uses BufferedSerial - */ - RS485(PinName tx, PinName rx, PinName dere); - - /** calculate 8-bit CRC - * cyclic redundancy check - * @param addr byte pointer of information to use (typical an byte array) - * @param len length of byte of information were converting - * @return the CRC byte - */ - static byte crc8 (const byte *addr, byte len); - - /** sendComplemented byte - * send a byte complemented, repeated - * only values sent would be (in hex): - * 0F, 1E, 2D, 3C, 4B, 5A, 69, 78, 87, 96, A5, B4, C3, D2, E1, F0 - * @what the byte to complement - */ - void sendComplemented (const byte what); - - /** send message - * cyclic redundancy check - * @param data the data to be sent through RS485 - * @param length length of the data - * @note puts STX at start, ETX at end, and add CRC - */ - void sendMsg (const byte * data, const byte length); - - /** receive message - * reads serial port and populates data - * @param data buffer to receive into - * @param length length of the data - * @param timeout clock_mseconds before timing out - * @return the number of bytes received - * - */ - byte recvMsg (byte * data, const byte length, unsigned long timeout); - - -}; -#endif \ No newline at end of file
diff -r 6a8a69b660c2 -r ddf182356d90 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Oct 06 11:43:00 2021 +0000 @@ -0,0 +1,61 @@ +#include "mbed.h" +#include "BufferedSerial.h" + +Serial pc(USBTX, USBRX,115200); +Serial RS485(D1,D0); // Tx, Rx +DigitalOut ho(D2); + +typedef uint8_t byte; + +//byte data[9] = {0x01,0x04,0x00,0x48,0x00,0x02,0xf1,0xdd};//your data +byte enable[9] = {0x01,0x06,0x20,0x0E,0x00,0x08,0xE2,0x0F};//your data +byte run[9] = {0x01,0x06,0x20,0x89,0x00,0x0A,0xD3,0xE7};//your data +byte stop[9] = {0x01,0x06,0x20,0x0E,0x00,0x07,0xA2,0x0B};//your data + +int main() +{ + printf("Main\n"); + RS485.baud(115200); + pc.baud(115200); + while(1) { + RS485.baud(115200); + pc.printf("Starting\n"); + ho = 1; // 3.3V output from digital out pin + + for (int i=0; i<(sizeof(enable)-1);i++) + { + RS485.putc(enable[i]); + } + + wait_ms(2000); // Silent interval + + for (int i=0; i<(sizeof(run)-1);i++) + { + RS485.putc(run[i]); + } + + wait_ms(5000); // Silent interval + + for (int i=0; i<(sizeof(stop)-1);i++) + { + RS485.putc(stop[i]); + } + + wait_ms(50); // Silent interval + + pc.printf("Getting data\n"); + + ho = 0; + pc.printf("The RS485 value %d\n",RS485.readable()); + + char buffer[50]; + RS485.gets(buffer, 9); + + for (int count = 0; count < 8; count++) { + pc.printf("%02hhX", buffer[count]); + } + pc.printf("\n"); + pc.printf("Done\n"); + wait_ms(1000); + } +} \ No newline at end of file
diff -r 6a8a69b660c2 -r ddf182356d90 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Wed Oct 06 11:43:00 2021 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400 \ No newline at end of file