-1

I'm trying to communicate with a temperature controller using Modbus RTU. I used this Arduino library.

I was able to read PV(current temperature value) using below code. It uses Function code 4.

I want to set SV value(Set Value) using Function code 6

I replaced telegram.u8fct = 0x04; to telegram.u8fct = 0x06; and telegram.u16RegAdd = 0x03E8; to relevant address for SV. But, I couldn't get success.

How can I implement Function Code 6 in this library ?

Code for read PV as below. Its working properly.

    #include <ModbusRtu.h>

    // data array for modbus network sharing
    uint16_t au16data[16];
    uint8_t u8state;

    /**
        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
    */
    //TRANSMISSION CONTROL PIN - 8
    //HADWARE SERIAL NUMBER - 2
    Modbus master(0, 2, 8); // this is master and RS-232 or USB-FTDI

    /*
       This is an structe which contains a query to an slave device
    */
    modbus_t telegram;

    unsigned long u32wait;

    void setup() {
      Serial.begin(9600);
      master.begin(9600); // baud-rate at 9600
      master.setTimeOut( 2000 ); // if there is no answer in 2000 ms, roll over
      u32wait = millis() + 1000;
      u8state = 0;
    }

    void loop() {
      switch ( u8state ) {
        case 0:
          if (millis() > u32wait) u8state++; // wait state
          break;
        case 1:
          telegram.u8id = 0x01; // slave address
          telegram.u8fct = 0x04; // function code (this one is registers read)
          telegram.u16RegAdd = 0x03E8; // start address in slave [CHANNEL 1 PV]
          telegram.u16CoilsNo = 0x01; // number of elements (coils or registers) to read
          telegram.au16reg = au16data; // pointer to a memory array in the Arduino

          master.query( telegram ); // send query (only once)
          u8state++;
          break;
        case 2:
          master.poll(); // check incoming messages
          if (master.getState() == COM_IDLE) {
            u8state = 0;
            u32wait = millis() + 100;
            Serial.println(au16data[0]);//PRINT TEMPARATURE VALUE
          }
          break;
      }
    }
0

I managed to change SV value.

According to the library, when using function code 6, It get sending data(temperature value) from au16regs[0]as below piece of code of library file. Need to setup that value before requesting.

(ModbusRtu.h - line number 601)

case MB_FC_WRITE_REGISTER: //if cunction code 6
    au8Buffer[ NB_HI ]      = highByte(au16regs[0]);
    au8Buffer[ NB_LO ]      = lowByte(au16regs[0]);
|improve this answer|||||
  • It's OK to accept you own answer as the solution to the problem. – VE7JRO Dec 22 '19 at 18:49
  • @VE7JRO yes. Its the ansawer to question. But, you will have to face a problem if you use this code in program with other functions. – user_fs10 Dec 23 '19 at 15:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for?Browse other questions tagged or ask your own question.