Advertisement
Guest User

Untitled

a guest
Jun 5th, 2015
394
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.67 KB | None | 0 0
  1. #include <OneWire.h>
  2.  
  3.  
  4.  
  5. int DS18S20_Pin = A0;
  6. int sensorValue = 0;
  7.  
  8.  
  9. OneWire ds(DS18S20_Pin);
  10.  
  11.  
  12.  
  13.  
  14.  
  15. /*
  16. Modbus over serial line - RTU Slave Arduino Sketch
  17.  
  18. By Juan Pablo Zometa : jpmzometa@gmail.com
  19. http://sites.google.com/site/jpmzometa/
  20. and Samuel Marco: sammarcoarmengol@gmail.com
  21. and Andras Tucsni.
  22.  
  23. These functions implement functions 3, 6, and 16 (read holding registers,
  24. preset single register and preset multiple registers) of the
  25. Modbus RTU Protocol, to be used over the Arduino serial connection.
  26.  
  27. This implementation DOES NOT fully comply with the Modbus specifications.
  28.  
  29. This Arduino adaptation is derived from the work
  30. By P.Costigan email: phil@pcscada.com.au http://pcscada.com.au
  31.  
  32. These library of functions are designed to enable a program send and
  33. receive data from a device that communicates using the Modbus protocol.
  34.  
  35. Copyright (C) 2000 Philip Costigan P.C. SCADA LINK PTY. LTD.
  36.  
  37. This program is free software; you can redistribute it and/or modify
  38. it under the terms of the GNU General Public License as published by
  39. the Free Software Foundation; either version 2 of the License, or
  40. (at your option) any later version.
  41.  
  42. This program is distributed in the hope that it will be useful,
  43. but WITHOUT ANY WARRANTY; without even the implied warranty of
  44. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  45. GNU General Public License for more details.
  46.  
  47. You should have received a copy of the GNU General Public License
  48. along with this program; if not, write to the Free Software
  49. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  50.  
  51. The functions included here have been derived from the
  52. Modicon Modbus Protocol Reference Guide
  53. which can be obtained from Schneider at www.schneiderautomation.com.
  54.  
  55. This code has its origins with
  56. paul@pmcrae.freeserve.co.uk (http://www.pmcrae.freeserve.co.uk)
  57. who wrote a small program to read 100 registers from a modbus slave.
  58.  
  59. I have used his code as a catalist to produce this more functional set
  60. of functions. Thanks paul.
  61. */
  62.  
  63.  
  64. /*
  65. * configure_mb_slave(baud, parity, tx_en_pin)
  66. *
  67. * sets the communication parameters for of the serial line.
  68. *
  69. * baud: baudrate in bps (typical values 9600, 19200... 115200)
  70. * parity: a single character sets the parity mode (character frame format):
  71. * 'n' no parity (8N1); 'e' even parity (8E1), 'o' for odd parity (8O1).
  72. * tx_en_pin: arduino pin number that controls transmision/reception
  73. * of an external half-duplex device (e.g. a RS485 interface chip).
  74. * 0 or 1 disables this function (for a two-device network)
  75. * >2 for point-to-multipoint topology (e.g. several arduinos)
  76. */
  77. void configure_mb_slave(long baud, char parity, char txenpin);
  78.  
  79. /*
  80. * update_mb_slave(slave_id, holding_regs_array, number_of_regs)
  81. *
  82. * checks if there is any valid request from the modbus master. If there is,
  83. * performs the action requested
  84. *
  85. * slave: slave id (1 to 127)
  86. * regs: an array with the holding registers. They start at address 1 (master point of view)
  87. * regs_size: total number of holding registers.
  88. * returns: 0 if no request from master,
  89. * NO_REPLY (-1) if no reply is sent to the master
  90. * an exception code (1 to 4) in case of a modbus exceptions
  91. * the number of bytes sent as reply ( > 4) if OK.
  92. */
  93.  
  94. int update_mb_slave(unsigned char slave, int *regs,
  95. unsigned int regs_size);
  96.  
  97.  
  98. /* Modbus RTU common parameters, the Master MUST use the same parameters */
  99. enum {
  100. MB_SLAVE = 1, /* modbus slave id */
  101. };
  102. /* slave registers example */
  103. enum {
  104. MB_REG0,
  105. MB_REG1,
  106. MB_REGS /* total number of registers on slave */
  107. };
  108.  
  109. int regs[MB_REGS]; /* this is the slave's modbus data map */
  110.  
  111. void setup()
  112. {
  113. /* Modbus setup example, the master must use the same COM parameters */
  114. /* 115200 bps, 8N1, two-device network */
  115. configure_mb_slave(9600, 'n', 0);
  116.  
  117. /*Serial.begin(9600); */
  118. }
  119.  
  120.  
  121. void loop() {
  122.  
  123.  
  124. /* This is all for the Modbus slave */
  125. update_mb_slave(MB_SLAVE, regs, MB_REGS);
  126.  
  127. /* your code goes here */
  128. regs[0] = getTemp();
  129.  
  130. //analogRead(DS18S20_Pin);
  131.  
  132. float temperature = getTemp();
  133. /* Serial.println(temperature); */
  134.  
  135.  
  136. }
  137.  
  138. float getTemp(){
  139. //returns the temperature from one DS18S20 in DEG Celsius
  140.  
  141. byte data[12];
  142. byte addr[8];
  143.  
  144. if ( !ds.search(addr)) {
  145. //no more sensors on chain, reset search
  146. ds.reset_search();
  147. return -1000;
  148. }
  149.  
  150. if ( OneWire::crc8( addr, 7) != addr[7]) {
  151. /* Serial.println("CRC is not valid!"); */
  152. return -1000;
  153. }
  154.  
  155. if ( addr[0] != 0x10 && addr[0] != 0x28) {
  156. /* Serial.print("Device is not recognized"); */
  157. return -1000;
  158. }
  159.  
  160. ds.reset();
  161. ds.select(addr);
  162. ds.write(0x44,1); // start conversion, with parasite power on at the end
  163.  
  164. byte present = ds.reset();
  165. ds.select(addr);
  166. ds.write(0xBE); // Read Scratchpad
  167.  
  168.  
  169. for (int i = 0; i < 9; i++) { // we need 9 bytes
  170. data[i] = ds.read();
  171. }
  172.  
  173. ds.reset_search();
  174.  
  175. byte MSB = data[1];
  176. byte LSB = data[0];
  177.  
  178. float tempRead = ((MSB << 8) | LSB); //using two's compliment
  179. float TemperatureSum = tempRead / 16;
  180.  
  181. return TemperatureSum;
  182.  
  183. }
  184.  
  185. /****************************************************************************
  186. * BEGIN MODBUS RTU SLAVE FUNCTIONS
  187. ****************************************************************************/
  188.  
  189. /* global variables */
  190. unsigned int Txenpin = 0; /* Enable transmission pin, used on RS485 networks */
  191.  
  192.  
  193. /* enum of supported modbus function codes. If you implement a new one, put its function code here ! */
  194. enum {
  195. FC_READ_REGS = 0x03, //Read contiguous block of holding register
  196. FC_WRITE_REG = 0x06, //Write single holding register
  197. FC_WRITE_REGS = 0x10 //Write block of contiguous registers
  198. };
  199.  
  200. /* supported functions. If you implement a new one, put its function code into this array! */
  201. const unsigned char fsupported[] = { FC_READ_REGS, FC_WRITE_REG, FC_WRITE_REGS };
  202.  
  203. /* constants */
  204. enum {
  205. MAX_READ_REGS = 0x7D,
  206. MAX_WRITE_REGS = 0x7B,
  207. MAX_MESSAGE_LENGTH = 256
  208. };
  209.  
  210.  
  211. enum {
  212. RESPONSE_SIZE = 6,
  213. EXCEPTION_SIZE = 3,
  214. CHECKSUM_SIZE = 2
  215. };
  216.  
  217. /* exceptions code */
  218. enum {
  219. NO_REPLY = -1,
  220. EXC_FUNC_CODE = 1,
  221. EXC_ADDR_RANGE = 2,
  222. EXC_REGS_QUANT = 3,
  223. EXC_EXECUTE = 4
  224. };
  225.  
  226. /* positions inside the query/response array */
  227. enum {
  228. SLAVE = 0,
  229. FUNC,
  230. START_H,
  231. START_L,
  232. REGS_H,
  233. REGS_L,
  234. BYTE_CNT
  235. };
  236.  
  237.  
  238. /*
  239. CRC
  240.  
  241. INPUTS:
  242. buf -> Array containing message to be sent to controller.
  243. start -> Start of loop in crc counter, usually 0.
  244. cnt -> Amount of bytes in message being sent to controller/
  245. OUTPUTS:
  246. temp -> Returns crc byte for message.
  247. COMMENTS:
  248. This routine calculates the crc high and low byte of a message.
  249. Note that this crc is only used for Modbus, not Modbus+ etc.
  250. ****************************************************************************/
  251.  
  252. unsigned int crc(unsigned char *buf, unsigned char start,
  253. unsigned char cnt)
  254. {
  255. unsigned char i, j;
  256. unsigned temp, temp2, flag;
  257.  
  258. temp = 0xFFFF;
  259.  
  260. for (i = start; i < cnt; i++) {
  261. temp = temp ^ buf[i];
  262.  
  263. for (j = 1; j <= 8; j++) {
  264. flag = temp & 0x0001;
  265. temp = temp >> 1;
  266. if (flag)
  267. temp = temp ^ 0xA001;
  268. }
  269. }
  270.  
  271. /* Reverse byte order. */
  272. temp2 = temp >> 8;
  273. temp = (temp << 8) | temp2;
  274. temp &= 0xFFFF;
  275.  
  276. return (temp);
  277. }
  278.  
  279.  
  280.  
  281.  
  282. /***********************************************************************
  283. *
  284. * The following functions construct the required query into
  285. * a modbus query packet.
  286. *
  287. ***********************************************************************/
  288.  
  289. /*
  290. * Start of the packet of a read_holding_register response
  291. */
  292. void build_read_packet(unsigned char slave, unsigned char function,
  293. unsigned char count, unsigned char *packet)
  294. {
  295. packet[SLAVE] = slave;
  296. packet[FUNC] = function;
  297. packet[2] = count * 2;
  298. }
  299.  
  300. /*
  301. * Start of the packet of a preset_multiple_register response
  302. */
  303. void build_write_packet(unsigned char slave, unsigned char function,
  304. unsigned int start_addr,
  305. unsigned char count,
  306. unsigned char *packet)
  307. {
  308. packet[SLAVE] = slave;
  309. packet[FUNC] = function;
  310. packet[START_H] = start_addr >> 8;
  311. packet[START_L] = start_addr & 0x00ff;
  312. packet[REGS_H] = 0x00;
  313. packet[REGS_L] = count;
  314. }
  315.  
  316. /*
  317. * Start of the packet of a write_single_register response
  318. */
  319. void build_write_single_packet(unsigned char slave, unsigned char function,
  320. unsigned int write_addr, unsigned int reg_val, unsigned char* packet)
  321. {
  322. packet[SLAVE] = slave;
  323. packet[FUNC] = function;
  324. packet[START_H] = write_addr >> 8;
  325. packet[START_L] = write_addr & 0x00ff;
  326. packet[REGS_H] = reg_val >> 8;
  327. packet[REGS_L] = reg_val & 0x00ff;
  328. }
  329.  
  330.  
  331. /*
  332. * Start of the packet of an exception response
  333. */
  334. void build_error_packet(unsigned char slave, unsigned char function,
  335. unsigned char exception, unsigned char *packet)
  336. {
  337. packet[SLAVE] = slave;
  338. packet[FUNC] = function + 0x80;
  339. packet[2] = exception;
  340. }
  341.  
  342.  
  343. /*************************************************************************
  344. *
  345. * modbus_query( packet, length)
  346. *
  347. * Function to add a checksum to the end of a packet.
  348. * Please note that the packet array must be at least 2 fields longer than
  349. * string_length.
  350. **************************************************************************/
  351.  
  352. void modbus_reply(unsigned char *packet, unsigned char string_length)
  353. {
  354. int temp_crc;
  355.  
  356. temp_crc = crc(packet, 0, string_length);
  357. packet[string_length] = temp_crc >> 8;
  358. string_length++;
  359. packet[string_length] = temp_crc & 0x00FF;
  360. }
  361.  
  362.  
  363.  
  364. /***********************************************************************
  365. *
  366. * send_reply( query_string, query_length )
  367. *
  368. * Function to send a reply to a modbus master.
  369. * Returns: total number of characters sent
  370. ************************************************************************/
  371.  
  372. int send_reply(unsigned char *query, unsigned char string_length)
  373. {
  374. unsigned char i;
  375.  
  376. if (Txenpin > 1) { // set MAX485 to speak mode
  377. UCSR0A=UCSR0A |(1 << TXC0);
  378. digitalWrite( Txenpin, HIGH);
  379. delay(1);
  380. }
  381.  
  382. modbus_reply(query, string_length);
  383. string_length += 2;
  384.  
  385. for (i = 0; i < string_length; i++) {
  386. Serial.write(byte(query[i]));
  387. }
  388.  
  389. if (Txenpin > 1) {// set MAX485 to listen mode
  390. while (!(UCSR0A & (1 << TXC0)));
  391. digitalWrite( Txenpin, LOW);
  392. }
  393.  
  394. return i; /* it does not mean that the write was succesful, though */
  395. }
  396.  
  397. /***********************************************************************
  398. *
  399. * receive_request( array_for_data )
  400. *
  401. * Function to monitor for a request from the modbus master.
  402. *
  403. * Returns: Total number of characters received if OK
  404. * 0 if there is no request
  405. * A negative error code on failure
  406. ***********************************************************************/
  407.  
  408. int receive_request(unsigned char *received_string)
  409. {
  410. int bytes_received = 0;
  411.  
  412. /* FIXME: does Serial.available wait 1.5T or 3.5T before exiting the loop? */
  413. while (Serial.available()) {
  414. received_string[bytes_received] = Serial.read();
  415. bytes_received++;
  416. if (bytes_received >= MAX_MESSAGE_LENGTH)
  417. return NO_REPLY; /* port error */
  418. }
  419.  
  420. return (bytes_received);
  421. }
  422.  
  423.  
  424. /*********************************************************************
  425. *
  426. * modbus_request(slave_id, request_data_array)
  427. *
  428. * Function to the correct request is returned and that the checksum
  429. * is correct.
  430. *
  431. * Returns: string_length if OK
  432. * 0 if failed
  433. * Less than 0 for exception errors
  434. *
  435. * Note: All functions used for sending or receiving data via
  436. * modbus return these return values.
  437. *
  438. **********************************************************************/
  439.  
  440. int modbus_request(unsigned char slave, unsigned char *data)
  441. {
  442. int response_length;
  443. unsigned int crc_calc = 0;
  444. unsigned int crc_received = 0;
  445. unsigned char recv_crc_hi;
  446. unsigned char recv_crc_lo;
  447.  
  448. response_length = receive_request(data);
  449.  
  450. if (response_length > 0) {
  451. crc_calc = crc(data, 0, response_length - 2);
  452. recv_crc_hi = (unsigned) data[response_length - 2];
  453. recv_crc_lo = (unsigned) data[response_length - 1];
  454. crc_received = data[response_length - 2];
  455. crc_received = (unsigned) crc_received << 8;
  456. crc_received =
  457. crc_received | (unsigned) data[response_length - 1];
  458.  
  459. /*********** check CRC of response ************/
  460. if (crc_calc != crc_received) {
  461. return NO_REPLY;
  462. }
  463.  
  464. /* check for slave id */
  465. if (slave != data[SLAVE]) {
  466. return NO_REPLY;
  467. }
  468. }
  469. return (response_length);
  470. }
  471.  
  472. /*********************************************************************
  473. *
  474. * validate_request(request_data_array, request_length, available_regs)
  475. *
  476. * Function to check that the request can be processed by the slave.
  477. *
  478. * Returns: 0 if OK
  479. * A negative exception code on error
  480. *
  481. **********************************************************************/
  482.  
  483. int validate_request(unsigned char *data, unsigned char length,
  484. unsigned int regs_size)
  485. {
  486. int i, fcnt = 0;
  487. unsigned int regs_num = 0;
  488. unsigned int start_addr = 0;
  489. unsigned char max_regs_num;
  490.  
  491. /* check function code */
  492. for (i = 0; i < sizeof(fsupported); i++) {
  493. if (fsupported[i] == data[FUNC]) {
  494. fcnt = 1;
  495. break;
  496. }
  497. }
  498. if (0 == fcnt)
  499. return EXC_FUNC_CODE;
  500.  
  501. if (FC_WRITE_REG == data[FUNC]) {
  502. /* For function write single reg, this is the target reg.*/
  503. regs_num = ((int) data[START_H] << 8) + (int) data[START_L];
  504. if (regs_num >= regs_size)
  505. return EXC_ADDR_RANGE;
  506. return 0;
  507. }
  508.  
  509. /* For functions read/write regs, this is the range. */
  510. regs_num = ((int) data[REGS_H] << 8) + (int) data[REGS_L];
  511.  
  512. /* check quantity of registers */
  513. if (FC_READ_REGS == data[FUNC])
  514. max_regs_num = MAX_READ_REGS;
  515. else if (FC_WRITE_REGS == data[FUNC])
  516. max_regs_num = MAX_WRITE_REGS;
  517.  
  518. if ((regs_num < 1) || (regs_num > max_regs_num))
  519. return EXC_REGS_QUANT;
  520.  
  521. /* check registers range, start address is 0 */
  522. start_addr = ((int) data[START_H] << 8) + (int) data[START_L];
  523. if ((start_addr + regs_num) > regs_size)
  524. return EXC_ADDR_RANGE;
  525.  
  526. return 0; /* OK, no exception */
  527. }
  528.  
  529.  
  530.  
  531. /************************************************************************
  532. *
  533. * write_regs(first_register, data_array, registers_array)
  534. *
  535. * writes into the slave's holding registers the data in query,
  536. * starting at start_addr.
  537. *
  538. * Returns: the number of registers written
  539. ************************************************************************/
  540.  
  541. int write_regs(unsigned int start_addr, unsigned char *query, int *regs)
  542. {
  543. int temp;
  544. unsigned int i;
  545.  
  546. for (i = 0; i < query[REGS_L]; i++) {
  547. /* shift reg hi_byte to temp */
  548. temp = (int) query[(BYTE_CNT + 1) + i * 2] << 8;
  549. /* OR with lo_byte */
  550. temp = temp | (int) query[(BYTE_CNT + 2) + i * 2];
  551.  
  552. regs[start_addr + i] = temp;
  553. }
  554. return i;
  555. }
  556.  
  557. /************************************************************************
  558. *
  559. * preset_multiple_registers(slave_id, first_register, number_of_registers,
  560. * data_array, registers_array)
  561. *
  562. * Write the data from an array into the holding registers of the slave.
  563. *
  564. *************************************************************************/
  565.  
  566. int preset_multiple_registers(unsigned char slave,
  567. unsigned int start_addr,
  568. unsigned char count,
  569. unsigned char *query,
  570. int *regs)
  571. {
  572. unsigned char function = FC_WRITE_REGS; /* Preset Multiple Registers */
  573. int status = 0;
  574. unsigned char packet[RESPONSE_SIZE + CHECKSUM_SIZE];
  575.  
  576. build_write_packet(slave, function, start_addr, count, packet);
  577.  
  578. if (write_regs(start_addr, query, regs)) {
  579. status = send_reply(packet, RESPONSE_SIZE);
  580. }
  581.  
  582. return (status);
  583. }
  584.  
  585.  
  586. /************************************************************************
  587. *
  588. * write_single_register(slave_id, write_addr, data_array, registers_array)
  589. *
  590. * Write a single int val into a single holding register of the slave.
  591. *
  592. *************************************************************************/
  593.  
  594. int write_single_register(unsigned char slave,
  595. unsigned int write_addr, unsigned char *query, int *regs)
  596. {
  597. unsigned char function = FC_WRITE_REG; /* Function: Write Single Register */
  598. int status = 0;
  599. unsigned int reg_val;
  600. unsigned char packet[RESPONSE_SIZE + CHECKSUM_SIZE];
  601.  
  602. reg_val = query[REGS_H] << 8 | query[REGS_L];
  603. build_write_single_packet(slave, function, write_addr, reg_val, packet);
  604. regs[write_addr] = (int) reg_val;
  605. /*
  606. written.start_addr=write_addr;
  607. written.num_regs=1;
  608. */
  609. status = send_reply(packet, RESPONSE_SIZE);
  610.  
  611. return (status);
  612. }
  613.  
  614.  
  615. /************************************************************************
  616. *
  617. * read_holding_registers(slave_id, first_register, number_of_registers,
  618. * registers_array)
  619. *
  620. * reads the slave's holdings registers and sends them to the Modbus master
  621. *
  622. *************************************************************************/
  623.  
  624. int read_holding_registers(unsigned char slave, unsigned int start_addr,
  625.  
  626. unsigned char reg_count, int *regs)
  627. {
  628. unsigned char function = 0x03; /* Function 03: Read Holding Registers */
  629. int packet_size = 3;
  630. int status;
  631. unsigned int i;
  632. unsigned char packet[MAX_MESSAGE_LENGTH];
  633.  
  634. build_read_packet(slave, function, reg_count, packet);
  635.  
  636. for (i = start_addr; i < (start_addr + (unsigned int) reg_count);
  637. i++) {
  638. packet[packet_size] = regs[i] >> 8;
  639. packet_size++;
  640. packet[packet_size] = regs[i] & 0x00FF;
  641. packet_size++;
  642. }
  643.  
  644. status = send_reply(packet, packet_size);
  645.  
  646. return (status);
  647. }
  648.  
  649.  
  650. void configure_mb_slave(long baud, char parity, char txenpin)
  651. {
  652. Serial.begin(baud);
  653.  
  654. switch (parity) {
  655. case 'e': // 8E1
  656. UCSR0C |= ((1<<UPM01) | (1<<UCSZ01) | (1<<UCSZ00));
  657. // UCSR0C &= ~((1<<UPM00) | (1<<UCSZ02) | (1<<USBS0));
  658. break;
  659. case 'o': // 8O1
  660. UCSR0C |= ((1<<UPM01) | (1<<UPM00) | (1<<UCSZ01) | (1<<UCSZ00));
  661. // UCSR0C &= ~((1<<UCSZ02) | (1<<USBS0));
  662. break;
  663. case 'n': // 8N1
  664. UCSR0C |= ((1<<UCSZ01) | (1<<UCSZ00));
  665. // UCSR0C &= ~((1<<UPM01) | (1<<UPM00) | (1<<UCSZ02) | (1<<USBS0));
  666. break;
  667. default:
  668. break;
  669. }
  670.  
  671. if (txenpin > 1) { // pin 0 & pin 1 are reserved for RX/TX
  672. Txenpin = txenpin; /* set global variable */
  673. pinMode(Txenpin, OUTPUT);
  674. digitalWrite(Txenpin, LOW);
  675. }
  676.  
  677. return;
  678. }
  679.  
  680. /*
  681. * update_mb_slave(slave_id, holding_regs_array, number_of_regs)
  682. *
  683. * checks if there is any valid request from the modbus master. If there is,
  684. * performs the action requested
  685. */
  686.  
  687. unsigned long Nowdt = 0;
  688. unsigned int lastBytesReceived;
  689. const unsigned long T35 = 5;
  690.  
  691. int update_mb_slave(unsigned char slave, int *regs,
  692. unsigned int regs_size)
  693. {
  694. unsigned char query[MAX_MESSAGE_LENGTH];
  695. unsigned char errpacket[EXCEPTION_SIZE + CHECKSUM_SIZE];
  696. unsigned int start_addr;
  697. int exception;
  698. int length = Serial.available();
  699. unsigned long now = millis();
  700.  
  701. if (length == 0) {
  702. lastBytesReceived = 0;
  703. return 0;
  704. }
  705.  
  706. if (lastBytesReceived != length) {
  707. lastBytesReceived = length;
  708. Nowdt = now + T35;
  709. return 0;
  710. }
  711. if (now < Nowdt)
  712. return 0;
  713.  
  714. lastBytesReceived = 0;
  715.  
  716. length = modbus_request(slave, query);
  717. if (length < 1)
  718. return length;
  719.  
  720.  
  721. exception = validate_request(query, length, regs_size);
  722. if (exception) {
  723. build_error_packet(slave, query[FUNC], exception,
  724. errpacket);
  725. send_reply(errpacket, EXCEPTION_SIZE);
  726. return (exception);
  727. }
  728.  
  729.  
  730. start_addr = ((int) query[START_H] << 8) +
  731. (int) query[START_L];
  732. switch (query[FUNC]) {
  733. case FC_READ_REGS:
  734. return read_holding_registers(slave,
  735. start_addr,
  736. query[REGS_L],
  737. regs);
  738. break;
  739. case FC_WRITE_REGS:
  740. return preset_multiple_registers(slave,
  741. start_addr,
  742. query[REGS_L],
  743. query,
  744. regs);
  745. break;
  746. case FC_WRITE_REG:
  747. write_single_register(slave,
  748. start_addr,
  749. query,
  750. regs);
  751. break;
  752. }
  753. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement