Testing Modbus RS485 commands
Dependencies: mbed BufferedSerial
RS485.h@0:dccd2df6a07c, 2017-02-27 (annotated)
- Committer:
- Allar
- Date:
- Mon Feb 27 21:53:25 2017 +0000
- Revision:
- 0:dccd2df6a07c
- Child:
- 1:f7cead04d73e
Adding comments to library
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 | 0:dccd2df6a07c | 23 | #include <BufferedSerial.h> |
Allar | 0:dccd2df6a07c | 24 | #include "mbed.h" |
Allar | 0:dccd2df6a07c | 25 | |
Allar | 0:dccd2df6a07c | 26 | /** A serial port (UART) is used for RS485 |
Allar | 0:dccd2df6a07c | 27 | * |
Allar | 0:dccd2df6a07c | 28 | * |
Allar | 0:dccd2df6a07c | 29 | * Example: |
Allar | 0:dccd2df6a07c | 30 | * @code |
Allar | 0:dccd2df6a07c | 31 | * #include "mbed.h" |
Allar | 0:dccd2df6a07c | 32 | * #include <RS485.h> |
Allar | 0:dccd2df6a07c | 33 | * Serial pc(USBTX, USBRX); |
Allar | 0:dccd2df6a07c | 34 | * RS485 RS485(PC_10,PC_11,PB_3); // Tx, Rx , enable pin(future use) |
Allar | 0:dccd2df6a07c | 35 | * |
Allar | 0:dccd2df6a07c | 36 | * DigitalOut ho(PB_3); |
Allar | 0:dccd2df6a07c | 37 | * typedef uint8_t byte; |
Allar | 0:dccd2df6a07c | 38 | * |
Allar | 0:dccd2df6a07c | 39 | * byte regvalue[9]; |
Allar | 0:dccd2df6a07c | 40 | * byte data[9] = {0x01,0x04,0x00,0x48,0x00,0x02,0xf1,0xdd};//your data |
Allar | 0:dccd2df6a07c | 41 | * int main() |
Allar | 0:dccd2df6a07c | 42 | * { |
Allar | 0:dccd2df6a07c | 43 | * pc.printf("main\n"); |
Allar | 0:dccd2df6a07c | 44 | * while(1) { |
Allar | 0:dccd2df6a07c | 45 | * pc.printf("Starting\n"); |
Allar | 0:dccd2df6a07c | 46 | * ho = 1; // 3.3V output from digital out pin |
Allar | 0:dccd2df6a07c | 47 | * RS485.sendMsg(data,sizeof(data)); |
Allar | 0:dccd2df6a07c | 48 | * wait_ms(600); // Must wait for all the data to be sent |
Allar | 0:dccd2df6a07c | 49 | * ho = 0; // 0V output from digital out pin |
Allar | 0:dccd2df6a07c | 50 | * pc.printf("Getting data\n"); |
Allar | 0:dccd2df6a07c | 51 | * if(RS485.readable() >0){ |
Allar | 0:dccd2df6a07c | 52 | * memset(regvalue,0,sizeof(regvalue)); |
Allar | 0:dccd2df6a07c | 53 | * wait_ms(200); |
Allar | 0:dccd2df6a07c | 54 | * RS485.recvMsg(regvalue,sizeof(data),500); |
Allar | 0:dccd2df6a07c | 55 | * wait_ms(200); |
Allar | 0:dccd2df6a07c | 56 | * for (int count = 0; count < 9; count++) { |
Allar | 0:dccd2df6a07c | 57 | * pc.printf("%X - ", regvalue[count]); |
Allar | 0:dccd2df6a07c | 58 | * } |
Allar | 0:dccd2df6a07c | 59 | * }else printf("No Data\n"); |
Allar | 0:dccd2df6a07c | 60 | * printf("Done\n"); |
Allar | 0:dccd2df6a07c | 61 | * wait_ms(1000); |
Allar | 0:dccd2df6a07c | 62 | * } |
Allar | 0:dccd2df6a07c | 63 | * } |
Allar | 0:dccd2df6a07c | 64 | * @endcode |
Allar | 0:dccd2df6a07c | 65 | */ |
Allar | 0:dccd2df6a07c | 66 | |
Allar | 0:dccd2df6a07c | 67 | |
Allar | 0:dccd2df6a07c | 68 | /** |
Allar | 0:dccd2df6a07c | 69 | * @class RS485 |
Allar | 0:dccd2df6a07c | 70 | * @communicating using MAX485 modules |
Allar | 0:dccd2df6a07c | 71 | */ |
Allar | 0:dccd2df6a07c | 72 | |
Allar | 0:dccd2df6a07c | 73 | class RS485 : public BufferedSerial |
Allar | 0:dccd2df6a07c | 74 | { |
Allar | 0:dccd2df6a07c | 75 | private: |
Allar | 0:dccd2df6a07c | 76 | typedef unsigned int word; |
Allar | 0:dccd2df6a07c | 77 | typedef uint8_t byte; |
Allar | 0:dccd2df6a07c | 78 | typedef uint8_t boolean; |
Allar | 0:dccd2df6a07c | 79 | typedef void (*voidFuncPtr)(void); |
Allar | 0:dccd2df6a07c | 80 | |
Allar | 0:dccd2df6a07c | 81 | public: |
Allar | 0:dccd2df6a07c | 82 | /** Create a BufferedSerial port, connected to the specified transmit and receive pins |
Allar | 0:dccd2df6a07c | 83 | * @param tx Transmit pin |
Allar | 0:dccd2df6a07c | 84 | * @param rx Receive pin |
Allar | 0:dccd2df6a07c | 85 | * @param dere Enable pin (currently not implemented) |
Allar | 0:dccd2df6a07c | 86 | * @note uses BufferedSerial |
Allar | 0:dccd2df6a07c | 87 | */ |
Allar | 0:dccd2df6a07c | 88 | RS485(PinName tx, PinName rx, PinName dere); |
Allar | 0:dccd2df6a07c | 89 | |
Allar | 0:dccd2df6a07c | 90 | /** calculate 8-bit CRC |
Allar | 0:dccd2df6a07c | 91 | * cyclic redundancy check |
Allar | 0:dccd2df6a07c | 92 | * @addr byte pointer of information to use (typical an char array) |
Allar | 0:dccd2df6a07c | 93 | * @len length of byte of information were converting |
Allar | 0:dccd2df6a07c | 94 | * @return the CRC byte |
Allar | 0:dccd2df6a07c | 95 | */ |
Allar | 0:dccd2df6a07c | 96 | static byte crc8 (const byte *addr, byte len); |
Allar | 0:dccd2df6a07c | 97 | |
Allar | 0:dccd2df6a07c | 98 | /** sendComplemented byte |
Allar | 0:dccd2df6a07c | 99 | * send a byte complemented, repeated |
Allar | 0:dccd2df6a07c | 100 | * only values sent would be (in hex): |
Allar | 0:dccd2df6a07c | 101 | * 0F, 1E, 2D, 3C, 4B, 5A, 69, 78, 87, 96, A5, B4, C3, D2, E1, F0 |
Allar | 0:dccd2df6a07c | 102 | * @what the byte to complement |
Allar | 0:dccd2df6a07c | 103 | */ |
Allar | 0:dccd2df6a07c | 104 | void sendComplemented (const byte what); |
Allar | 0:dccd2df6a07c | 105 | |
Allar | 0:dccd2df6a07c | 106 | /** send message |
Allar | 0:dccd2df6a07c | 107 | * cyclic redundancy check |
Allar | 0:dccd2df6a07c | 108 | * @data the data to be sent through RS485 |
Allar | 0:dccd2df6a07c | 109 | * @length length of the data |
Allar | 0:dccd2df6a07c | 110 | * @note puts STX at start, ETX at end, and add CRC |
Allar | 0:dccd2df6a07c | 111 | */ |
Allar | 0:dccd2df6a07c | 112 | void sendMsg (const byte * data, const byte length); |
Allar | 0:dccd2df6a07c | 113 | |
Allar | 0:dccd2df6a07c | 114 | /** receive message |
Allar | 0:dccd2df6a07c | 115 | * reads serial port and populates data |
Allar | 0:dccd2df6a07c | 116 | * @data buffer to receive into |
Allar | 0:dccd2df6a07c | 117 | * @length length of the data |
Allar | 0:dccd2df6a07c | 118 | * @timeout clock_mseconds before timing out |
Allar | 0:dccd2df6a07c | 119 | * |
Allar | 0:dccd2df6a07c | 120 | */ |
Allar | 0:dccd2df6a07c | 121 | byte recvMsg (byte * data, const byte length, unsigned long timeout); |
Allar | 0:dccd2df6a07c | 122 | |
Allar | 0:dccd2df6a07c | 123 | |
Allar | 0:dccd2df6a07c | 124 | }; |
Allar | 0:dccd2df6a07c | 125 | #endif |