Testing Modbus RS485 commands
Dependencies: mbed BufferedSerial
RS485.h@3:9af77202cc27, 2017-05-21 (annotated)
- Committer:
- Allar
- Date:
- Sun May 21 20:37:59 2017 +0000
- Revision:
- 3:9af77202cc27
- Parent:
- 2:2701d79eba7c
- Child:
- 4:6a8a69b660c2
Updated Class Reference
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Allar | 0:dccd2df6a07c | 1 | |
Allar | 0:dccd2df6a07c | 2 | /** |
Allar | 0:dccd2df6a07c | 3 | * @file RS485.h |
Allar | 0:dccd2df6a07c | 4 | * @brief RS485 protocol - using half duplex method |
Allar | 0:dccd2df6a07c | 5 | * @author Aaron Allar |
Allar | 0:dccd2df6a07c | 6 | * @version 1.0 |
Allar | 0:dccd2df6a07c | 7 | * @see |
Allar | 0:dccd2df6a07c | 8 | * |
Allar | 0:dccd2df6a07c | 9 | * based on this method https://www.gammon.com.au/forum/?id=11428 |
Allar | 0:dccd2df6a07c | 10 | * |
Allar | 0:dccd2df6a07c | 11 | * Can send from 1 to 255 bytes from one node to another with: |
Allar | 0:dccd2df6a07c | 12 | * |
Allar | 0:dccd2df6a07c | 13 | * Packet start indicator (STX) |
Allar | 0:dccd2df6a07c | 14 | * Each data byte is doubled and inverted to check validity |
Allar | 0:dccd2df6a07c | 15 | * Packet end indicator (ETX) |
Allar | 0:dccd2df6a07c | 16 | * Packet CRC (checksum) |
Allar | 0:dccd2df6a07c | 17 | */ |
Allar | 0:dccd2df6a07c | 18 | |
Allar | 0:dccd2df6a07c | 19 | |
Allar | 0:dccd2df6a07c | 20 | |
Allar | 0:dccd2df6a07c | 21 | #ifndef RS485_H |
Allar | 0:dccd2df6a07c | 22 | #define RS485_H |
Allar | 1:f7cead04d73e | 23 | |
Allar | 1:f7cead04d73e | 24 | #include "BufferedSerial.h" |
Allar | 0:dccd2df6a07c | 25 | #include "mbed.h" |
Allar | 0:dccd2df6a07c | 26 | |
Allar | 0:dccd2df6a07c | 27 | /** A serial port (UART) is used for RS485 |
Allar | 0:dccd2df6a07c | 28 | * |
Allar | 0:dccd2df6a07c | 29 | * |
Allar | 0:dccd2df6a07c | 30 | * Example: |
Allar | 0:dccd2df6a07c | 31 | * @code |
Allar | 0:dccd2df6a07c | 32 | * #include "mbed.h" |
Allar | 0:dccd2df6a07c | 33 | * #include <RS485.h> |
Allar | 0:dccd2df6a07c | 34 | * Serial pc(USBTX, USBRX); |
Allar | 3:9af77202cc27 | 35 | * RS485 RS485(PC_10,PC_11,PB_3); // Tx, Rx , !RE and DE MAX485 pin |
Allar | 0:dccd2df6a07c | 36 | * |
Allar | 3:9af77202cc27 | 37 | * DigitalOut ho(PB_3); // this pin should be connected to !RE and DE |
Allar | 0:dccd2df6a07c | 38 | * typedef uint8_t byte; |
Allar | 0:dccd2df6a07c | 39 | * |
Allar | 0:dccd2df6a07c | 40 | * byte regvalue[9]; |
Allar | 0:dccd2df6a07c | 41 | * byte data[9] = {0x01,0x04,0x00,0x48,0x00,0x02,0xf1,0xdd};//your data |
Allar | 0:dccd2df6a07c | 42 | * int main() |
Allar | 0:dccd2df6a07c | 43 | * { |
Allar | 0:dccd2df6a07c | 44 | * pc.printf("main\n"); |
Allar | 0:dccd2df6a07c | 45 | * while(1) { |
Allar | 0:dccd2df6a07c | 46 | * pc.printf("Starting\n"); |
Allar | 3:9af77202cc27 | 47 | * ho = 1; // Enable sending on MAX485 |
Allar | 0:dccd2df6a07c | 48 | * RS485.sendMsg(data,sizeof(data)); |
Allar | 0:dccd2df6a07c | 49 | * wait_ms(600); // Must wait for all the data to be sent |
Allar | 3:9af77202cc27 | 50 | * ho = 0; // Enable receiving on MAX485 |
Allar | 0:dccd2df6a07c | 51 | * pc.printf("Getting data\n"); |
Allar | 0:dccd2df6a07c | 52 | * if(RS485.readable() >0){ |
Allar | 0:dccd2df6a07c | 53 | * memset(regvalue,0,sizeof(regvalue)); |
Allar | 0:dccd2df6a07c | 54 | * wait_ms(200); |
Allar | 0:dccd2df6a07c | 55 | * RS485.recvMsg(regvalue,sizeof(data),500); |
Allar | 0:dccd2df6a07c | 56 | * wait_ms(200); |
Allar | 0:dccd2df6a07c | 57 | * for (int count = 0; count < 9; count++) { |
Allar | 0:dccd2df6a07c | 58 | * pc.printf("%X - ", regvalue[count]); |
Allar | 0:dccd2df6a07c | 59 | * } |
Allar | 0:dccd2df6a07c | 60 | * }else printf("No Data\n"); |
Allar | 0:dccd2df6a07c | 61 | * printf("Done\n"); |
Allar | 0:dccd2df6a07c | 62 | * wait_ms(1000); |
Allar | 0:dccd2df6a07c | 63 | * } |
Allar | 0:dccd2df6a07c | 64 | * } |
Allar | 0:dccd2df6a07c | 65 | * @endcode |
Allar | 0:dccd2df6a07c | 66 | */ |
Allar | 0:dccd2df6a07c | 67 | |
Allar | 0:dccd2df6a07c | 68 | |
Allar | 0:dccd2df6a07c | 69 | /** |
Allar | 0:dccd2df6a07c | 70 | * @class RS485 |
Allar | 0:dccd2df6a07c | 71 | * @communicating using MAX485 modules |
Allar | 0:dccd2df6a07c | 72 | */ |
Allar | 0:dccd2df6a07c | 73 | |
Allar | 0:dccd2df6a07c | 74 | class RS485 : public BufferedSerial |
Allar | 0:dccd2df6a07c | 75 | { |
Allar | 0:dccd2df6a07c | 76 | private: |
Allar | 0:dccd2df6a07c | 77 | typedef unsigned int word; |
Allar | 0:dccd2df6a07c | 78 | typedef uint8_t byte; |
Allar | 0:dccd2df6a07c | 79 | typedef uint8_t boolean; |
Allar | 0:dccd2df6a07c | 80 | typedef void (*voidFuncPtr)(void); |
Allar | 0:dccd2df6a07c | 81 | |
Allar | 0:dccd2df6a07c | 82 | public: |
Allar | 0:dccd2df6a07c | 83 | /** Create a BufferedSerial port, connected to the specified transmit and receive pins |
Allar | 0:dccd2df6a07c | 84 | * @param tx Transmit pin |
Allar | 0:dccd2df6a07c | 85 | * @param rx Receive pin |
Allar | 3:9af77202cc27 | 86 | * @param dere Enable pin, this pin should be connected to !RE and DE |
Allar | 0:dccd2df6a07c | 87 | * @note uses BufferedSerial |
Allar | 0:dccd2df6a07c | 88 | */ |
Allar | 0:dccd2df6a07c | 89 | RS485(PinName tx, PinName rx, PinName dere); |
Allar | 0:dccd2df6a07c | 90 | |
Allar | 0:dccd2df6a07c | 91 | /** calculate 8-bit CRC |
Allar | 0:dccd2df6a07c | 92 | * cyclic redundancy check |
Allar | 2:2701d79eba7c | 93 | * @param addr byte pointer of information to use (typical an byte array) |
Allar | 1:f7cead04d73e | 94 | * @param len length of byte of information were converting |
Allar | 0:dccd2df6a07c | 95 | * @return the CRC byte |
Allar | 0:dccd2df6a07c | 96 | */ |
Allar | 0:dccd2df6a07c | 97 | static byte crc8 (const byte *addr, byte len); |
Allar | 0:dccd2df6a07c | 98 | |
Allar | 0:dccd2df6a07c | 99 | /** sendComplemented byte |
Allar | 0:dccd2df6a07c | 100 | * send a byte complemented, repeated |
Allar | 0:dccd2df6a07c | 101 | * only values sent would be (in hex): |
Allar | 0:dccd2df6a07c | 102 | * 0F, 1E, 2D, 3C, 4B, 5A, 69, 78, 87, 96, A5, B4, C3, D2, E1, F0 |
Allar | 0:dccd2df6a07c | 103 | * @what the byte to complement |
Allar | 0:dccd2df6a07c | 104 | */ |
Allar | 0:dccd2df6a07c | 105 | void sendComplemented (const byte what); |
Allar | 0:dccd2df6a07c | 106 | |
Allar | 0:dccd2df6a07c | 107 | /** send message |
Allar | 0:dccd2df6a07c | 108 | * cyclic redundancy check |
Allar | 1:f7cead04d73e | 109 | * @param data the data to be sent through RS485 |
Allar | 1:f7cead04d73e | 110 | * @param length length of the data |
Allar | 0:dccd2df6a07c | 111 | * @note puts STX at start, ETX at end, and add CRC |
Allar | 0:dccd2df6a07c | 112 | */ |
Allar | 0:dccd2df6a07c | 113 | void sendMsg (const byte * data, const byte length); |
Allar | 0:dccd2df6a07c | 114 | |
Allar | 0:dccd2df6a07c | 115 | /** receive message |
Allar | 0:dccd2df6a07c | 116 | * reads serial port and populates data |
Allar | 1:f7cead04d73e | 117 | * @param data buffer to receive into |
Allar | 1:f7cead04d73e | 118 | * @param length length of the data |
Allar | 1:f7cead04d73e | 119 | * @param timeout clock_mseconds before timing out |
Allar | 1:f7cead04d73e | 120 | * @return the number of bytes received |
Allar | 0:dccd2df6a07c | 121 | * |
Allar | 0:dccd2df6a07c | 122 | */ |
Allar | 0:dccd2df6a07c | 123 | byte recvMsg (byte * data, const byte length, unsigned long timeout); |
Allar | 0:dccd2df6a07c | 124 | |
Allar | 0:dccd2df6a07c | 125 | |
Allar | 0:dccd2df6a07c | 126 | }; |
Allar | 0:dccd2df6a07c | 127 | #endif |