Arduino Modbus 讀取與寫入範例
讀取多個並寫入多個
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
#include <ModbusRtu.h> /// oled debuging #include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define OLED_RESET 4 // not used / nicht genutzt bei diesem Display Adafruit_SSD1306 display(OLED_RESET); /// uint16_t au16data[32]; //!< data array for modbus network sharing Array uint8_t u8state; //!< machine state uint8_t u8query; //!< pointer to message query /** * Modbus object declaration * u8id : node id = 0 for master, = 1..247 for slave * u8serno : serial port (use 0 for Serial) * u8txenpin : 0 for RS-232 and USB-FTDI * or any pin number > 1 for RS-485 */ Modbus master(0,0,7); // this is master and RS-232 or USB-FTDI /// 7 = PIN ENEABLE rs485 /** * This is an structe which contains a query to an slave device */ modbus_t telegram[2]; unsigned long u32wait; void setup() { // initialize with the I2C addr 0x3C / mit I2C-Adresse 0x3c initialisieren display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.display(); delay(2000); display.clearDisplay(); display.setTextSize(0.5); display.setTextColor(INVERSE); ////////////////////////////// // telegram 0: read registers telegram[0].u8id = 1; // slave address telegram[0].u8fct = 3; // function code (registers read multiple 3) telegram[0].u16RegAdd = 0; // start address in slave - direccion de Inicio 0 telegram[0].u16CoilsNo = 10; // number of elements (coils or registers) to read 0 - 16 telegram[0].au16reg = au16data; // pointer to a memory array in the Arduino - Almacenamiento en Array de memoria de arduino // telegram 1: write a multiple register = function 16 telegram[1].u8id = 1; // slave address telegram[1].u8fct = 16; // function code (write multiple registers 16 ) telegram[1].u16RegAdd = 10; // start address in slave - direccion de Inicio 10 telegram[1].u16CoilsNo = 10; // number of elements (coils or registers) to read telegram[1].au16reg = au16data+10; // pointer to a memory array in the Arduino - Almacenamiento en Array de memoria de arduino 10 posiciones despues master.begin( 19200 ); // baud-rate at 19200 master.setTimeOut( 5000 ); // if there is no answer in 5000 ms, roll over u32wait = millis() + 1000; u8state = u8query = 0; } void loop() { switch( u8state ) { case 0: if (millis() > u32wait) u8state++; // wait state break; case 1: master.query( telegram[u8query] ); // send query (only once) u8state++; u8query++; if (u8query > 2) u8query = 0; break; case 2: master.poll(); // check incoming messages if (master.getState() == COM_IDLE) { u8state = 0; u32wait = millis() + 1000; } break; } display.clearDisplay(); //Read Multiple Holding Register - Lectura de multiples registros display.setCursor(0,0); display.print(au16data[0]); // Read Holding Register [0] display.print(","); display.print(au16data[1]); // Read Holding Register [1] display.print(","); display.print(au16data[2]); // Read Holding Register [2] display.print(","); display.print(au16data[3]); // Read Holding Register [3] display.print(","); display.print(au16data[4]); // Read Holding Register [4] display.print(" Hold 0-4"); display.setCursor(0,8); display.print(au16data[5]); // Read Holding Register [5] display.print(","); display.print(au16data[6]); // Read Holding Register [6] display.print(","); display.print(au16data[7]); // Read Holding Register [7] display.print(","); display.print(au16data[8]); // Read Holding Register [8] display.print(","); display.print(au16data[9]); // Read Holding Register [9] display.print(" Hold 5-9"); //Write Multiple Holding Register - Escritura de multiples registros au16data[10] = analogRead( 0 ); // Write Holding Register [10] au16data[11] = analogRead( 0 ); // Write Holding Register [11] au16data[12] = analogRead( 0 ); // Write Holding Register [12] au16data[13] = analogRead( 0 ); // Write Holding Register [13] au16data[14] = analogRead( 0 ); // Write Holding Register [14] au16data[15] = analogRead( 0 ); // Write Holding Register [15] au16data[16] = analogRead( 0 ); // Write Holding Register [16] au16data[17] = analogRead( 0 ); // Write Holding Register [17] au16data[18] = analogRead( 0 ); // Write Holding Register [18] au16data[19] = analogRead( 0 ); // Write Holding Register [19] // Print Oled Write Holding Register display.setCursor(0,16); display.print(au16data[10]); display.print(","); display.print(au16data[11]); display.print(","); display.print(au16data[12]); display.print(","); display.print(au16data[13]); display.print(","); display.print(au16data[14]); display.print(","); display.print(au16data[15]); display.print(","); display.print(au16data[16]); display.print(","); display.print(au16data[17]); display.print(","); display.print(au16data[18]); display.print(","); display.print(au16data[19]); display.print(" Hold 10-19"); display.display(); } |
讀取單個並寫入單個
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
/** * Modbus master example 2: * The purpose of this example is to query an array of data * from an external Modbus slave device. * This example is similar to "simple_master", but this example * allows you to use software serial instead of hardware serial * in case that you want to use D1 & D2 for other purposes. * The link media can be USB or RS232. The circuit: * software serial rx(D3) connect to tx pin of another device * software serial tx(D4) connect to rx pin of another device * In this example, we will use two important methods so that we can use * software serial. * * 1. Modbus::Modbus(uint8_t u8id) * This is a constructor for a Master/Slave through USB/RS232C via software serial * This constructor only specifies u8id (node address) and should be only * used if you want to use software serial instead of hardware serial. * This method is called if you create a ModBus object with only on parameter "u8id" * u8id is the node address of the arduino that will be programmed on, * 0 for master and 1..247 for slave * for example: Modbus master(0); * If you use this constructor you have to begin ModBus object by * using "void Modbus::begin(SoftwareSerial *softPort, long u32speed)". * * 2. void Modbus::begin(SoftwareSerial *sPort, long u32speed) * Initialize class object. * This is the method you have to use if you construct the ModBus object by using * Modbus::Modbus(uint8_t u8id) in order to use software serial and to avoid problems. * You have to create a SoftwareSerial object on your own, as shown in the example. * sPort is a pointer to your SoftwareSerial object, u32speed is the baud rate, in * standard increments (300..115200) created long time ago by smarmengol modified 29 July 2016 by Helium6072 This example code is in the public domain. */ #include <ModbusRtu.h> #include <SoftwareSerial.h> uint16_t au16data[16]; //!< data array for modbus network sharing uint8_t u8state; //!< machine state uint8_t u8query; //!< pointer to message query /** * Modbus object declaration * u8id : node id = 0 for master, = 1..247 for slave * u8serno : serial port (use 0 for Serial) * u8txenpin : 0 for RS-232 and USB-FTDI * or any pin number > 1 for RS-485 */ Modbus master(0); // this is master and RS-232 or USB-FTDI via software serial /** * This is an structe which contains a query to an slave device */ modbus_t telegram[2]; unsigned long u32wait; SoftwareSerial mySerial(12, 13);//Create a SoftwareSerial object so that we can use software serial. Search "software serial" on Arduino.cc to find out more details. void setup() { Serial.begin(9600);//use the hardware serial if you want to connect to your computer via usb cable, etc. master.begin( &mySerial, 38400 ); // begin the ModBus object. The first parameter is the address of your SoftwareSerial address. Do not forget the "&". 9600 means baud-rate at 9600 // telegram 0: read registers telegram[0].u8id = 1; // slave address telegram[0].u8fct = 3; // function code (this one is registers read) telegram[0].u16RegAdd = 1; // start address in slave telegram[0].u16CoilsNo = 3; // number of elements (coils or registers) to read telegram[0].au16reg = au16data; // pointer to a memory array in the Arduino // telegram 1: write a single register telegram[1].u8id = 1; // slave address telegram[1].u8fct = 6; // function code (this one is write a single register) telegram[1].u16RegAdd = 6; // start address in slave telegram[1].u16CoilsNo = 1; // number of elements (coils or registers) to read telegram[1].au16reg = au16data+4; // pointer to a memory array in the Arduino master.setTimeOut( 2000 ); // if there is no answer in 5000 ms, roll over u32wait = millis() + 1000; u8state = u8query = 0; } void loop() { switch( u8state ) { case 0: if (millis() > u32wait) u8state++; // wait state break; case 1: master.query( telegram[u8query] ); // send query (only once) u8state++; u8query++; if (u8query > 2) u8query = 0; break; case 2: master.poll(); // check incoming messages if (master.getState() == COM_IDLE) { u8state = 0; u32wait = millis() + 300; Serial.println(au16data[0]); Serial.println(au16data[1]); Serial.println(au16data[2]); } break; } au16data[4] = random(1000); } |