Activity Forums Questions & Troubleshooting Modbus communication via Controllino

  • Modbus communication via Controllino

     ryan updated 3 years ago 4 Members · 12 Posts
  • aramzawn

    Member
    July 29, 2021 at 8:58 am

    Hello friends,

    I have a question about Modbus communication. I have a sensor (OLS20-BB1118142 | Lokalisierungs- und Positionierlösungen | SICK) which is Modbus capable and a Controllino Maxi. I intend to use the Controllino as a master and have therefore already loaded the example code, from the Website, for a Modbus Master on the Controllino ( RS485 & ModbusRTU – CONTROLLINO )

    Now I would like to ask if anyone is more familiar with the subject than I am, as I am unfortunately still quite new to this topic.

    What I know so far is that my sensor has the baud rate 9600 and the slave address 10 (in the code, as far as I know, adapted).

    I also know that the master has to send a request so that the slave can respond.

    The status query in HEX, whether the sensor recognizes something or not, would be in this case:

    0A 04 00 C0 00 01 30 8D

    where 0A is the slave address, 04 is my function code, 00C0 is my start address, 0001 is my register count and 308D is my checksum.

    If the sensor detects something (OK), it gives the answer: 0A 04 02 00 02 9D 30 and with NOK it would be 0A 04 02 00 00 10 F1.

    Does anyone know how I have to change the above code to establish communication?

    I have also tried to enter everything here, but unfortunately, nothing changes.

    // ModbusQuery 0: read registers

    ModbusQuery[0].u8id = SlaveModbusAdd; // slave address

    ModbusQuery[0].u8fct = 3; // function code (this one is registers read)

    ModbusQuery[0].u16RegAdd = 0; // start address in slave

    ModbusQuery[0].u16CoilsNo = 4; // number of elements (coils or registers) to read

    ModbusQuery[0].au16reg = ModbusSlaveRegisters; // pointer to a memory array in the CONTROLLINO

    or do I need a simple if-else command? I would be very grateful if someone could help me with this 😀

    Thanks a lot and greetings

  • Lukas

    Member
    July 29, 2021 at 2:29 pm

    Hello,

    please find some information about the Modbus commands here.

    You should set function code to 4, start address to 12 and number of elements to 1.

    Let us know if it works!

    Best regards,

    Lukas

    • This reply was modified 3 years, 2 months ago by  Lukas.
    • aramzawn

      Member
      July 29, 2021 at 3:50 pm

      Hello Lukas,

      thank you very much for your response. I would like to ask where you got those numbers from. I’ve connected my Sensor with my Computer and Software and I’ve got the start address 192.

      • aramzawn

        Member
        July 30, 2021 at 7:54 am

        I’ve also tried the simple_master Code from GitHub – smarmengol/Modbus-Master-Slave-for-Arduino: Modbus Master-Slave library for Arduino but the response I get is are weird signs and question marks. I’ve changed the address etc. in the Code to the numbers I have (in DEC) but it won’t work and I don’t know what the problem is.

        • Lukas

          Member
          July 30, 2021 at 2:16 pm

          You say weird signs and question marks? Then you have something wrong with the RS845 – baudrate, or swapped +/-.

          • aramzawn

            Member
            August 2, 2021 at 6:22 am

            I’ve chosen the right Baudrate for my serial monitor and swapped the wires but I still get those blank boxes and question marks. I really don’t know what the problem is

      • Lukas

        Member
        July 30, 2021 at 2:14 pm

        You have stated 0A 04 00 C0 00 01 30 8D where 0A is the slave address, 04 is my function code, 00C0 is my start address, 0001 is my register count and 308D is my checksum.

        C0 = 12.

        • aramzawn

          Member
          August 2, 2021 at 6:23 am

          yes but don’t I have to get it from HEX to DEC? Because then I get C0 = 192.

    • aneh2killa

      Member
      September 28, 2021 at 1:30 pm

      Hello Sir,

      I hope you are doing well. I am also having a problem with Modbus sensors and can’t get them to work. Previously, I used ESP32 and Sparkfun RS485 Breakout and it worked fine. From my understanding, the program I use on ESP32 should work on the Controllino because the structure of the program is similar, the only difference is the pin and voltage logic (Sparkfun RS485 uses 3.3v). I also tried the provided example programs but had no luck. Perhaps my understanding is wrong somewhere. For this reason, is possible to get any information or guide to get reading from a Modbus sensor like this one;-

      https://www.amazon.com/<wbr>Temperature-Humidity-<wbr>Transmitter-Acquisition-<wbr>Transducer/dp/B07VNFDQRJ

      The program I used to read the sensor can be found in the attachment. Thank you very much for your time and support.

      #include <SPI.h>

      #include <Controllino.h>

      float RH;

      //———————————————————————————–

      #define MAX_MILLIS_TO_WAIT 300

      #define FRAMESIZE 9

      //———————————————————————————–

      #define ADDRESS 0x01 // BYTE 1

      #define FUNCTION_CODE 0x04 // BYTE 2

      #define BYTE_03 0x00 // BYTE 3

      #define BYTE_04 0x02 // BYTE 4

      #define BYTE_05 0x00 // BYTE 5

      #define BYTE_06 0x01 // BYTE 6

      //———————————————————————————–

      void setup() {

      Serial.begin(115200);

      // initialize the modbus communication

      Serial3.begin(9600);

      Controllino_RS485Init();

      Controllino_RS485RxEnable();

      /* This will initialize Controllino RS485 pins */

      }

      void loop() {

      if (runEvery(3000)) {

      Serial.println(“===================================”);

      uint16_t ws;

      soil(&ws);

      //for debugging purpose

      RH = ws/10; Serial.println(” Temp: \t” + String(RH));

      }

      }

      /////////////////////////////function: access modbus data/////////////////////

      float soil(uint16_t* ws){

      uint16_t temp;

      unsigned long resptime;

      uint8_t frame[FRAMESIZE] = {ADDRESS, FUNCTION_CODE, BYTE_03, BYTE_04, BYTE_05, BYTE_06, 0, 0, 0};

      temp = calculateCRC(frame, FRAMESIZE – 3); // calculate out crc only from first 6 bytes

      frame[6] = lowByte(temp);

      frame[7] = highByte(temp);

      Serial.println(“=========================================================”);

      //=====================For debugging purposes======================//

      String request = “Request: “;

      for(int n=0; n<FRAMESIZE – 1; n++) {

      request += frame[n] < 0x10 ? ” 0″ : ” “;

      request += String(frame[n], HEX);

      request.toUpperCase();

      }

      Serial.println(request);

      //=========================================================//

      Controllino_RS485TxEnable();

      Serial3.write(frame, FRAMESIZE – 1); // send 8 bytes

      Serial3.flush(); // wait until the trasmission is complete

      Controllino_RS485RxEnable();

      resptime = millis();

      while ((Serial3.available() < FRAMESIZE) && ((millis() – resptime) < MAX_MILLIS_TO_WAIT) ) {

      delay(50);

      }

      String Response = “Response: “;

      if(Serial3.available()) {

      for(int n=0; n<FRAMESIZE – 2; n++) {

      frame[n] = Serial3.read();

      //debugging//

      Response += frame[n] < 0x10 ? ” 0″ : ” “;

      Response += String(frame[n], HEX);

      Response.toUpperCase();

      Serial.println(Response);

      //debugging//

      }

      *ws = ((uint16_t)frame[3] << 8) | frame[4];

      }

      }

      /////////////////////////////function: access modbus data/////////////////////

      uint16_t calculateCRC(uint8_t *array, uint8_t num) {

      uint16_t temp, flag;

      temp = 0xFFFF;

      for (uint8_t i = 0; i < num; i++) {

      temp = temp ^ array[i];

      for (uint8_t j = 8; j; j–) {

      flag = temp & 0x0001;

      temp >>= 1;

      if (flag)

      temp ^= 0xA001;

      }

      }

      return temp;

      }

      //————————————————-//

      boolean runEvery(unsigned long interval)

      {

      static unsigned long previousMillis = 0;

      unsigned long currentMillis = millis();

      if (currentMillis – previousMillis >= interval)

      {

      previousMillis = currentMillis;

      return true;

      }

      return false;

      }

      • ryan

        Member
        September 29, 2021 at 5:50 am

        I am not sure whether you only want to use the board, but ,if you are open to use the controllino only, you should use the Modbus RTU example from the controllino page. You should use the modbusRtu.h that is provided by the controllino team(very important: you should see modified by controllino team in the modbusRtu.h ) After that, all you need to do is change the given example according to your need.

  • aramzawn

    Member
    August 16, 2021 at 7:30 am

    Hello,

    it’s working now. I had to change the parity. 🙂

    • Lukas

      Member
      August 17, 2021 at 9:11 am

      Great! Good job!

Viewing 1 - 3 of 3 replies

Log in to reply.

Original Post
0 of 0 posts June 2018
Now