I'm very noob in microcntroller modbus. I want to do Modbus RTU slave device using RS232. I read modbus documentation from modbus.org site. But still I'm not clear about few things.

How to define the holding registers in Atmega32? Or is any new storage element need to be interfaced with mcu? Or does the internal memory of MCU need to be used? Please provide some examples.

  • \$\begingroup\$ Which framework are you using for MODBUS on the MCU? \$\endgroup\$ – Ignacio Vazquez-Abrams Dec 13 '13 at 15:18

A modbus holding register is just a 16 bit value. You can just allocate an array of uint16_t to store them.

There are open source MODBUS libraries available.

  • \$\begingroup\$ Thanks jwygralak67 for your answer. But how to store in the exact address say 40101, so that it can be accessed using another Master MCU. \$\endgroup\$ – user2721044 Dec 14 '13 at 16:41
  • \$\begingroup\$ The modbus register number doesn't have to match the memory address where it is stored. You just have to know the relationship between register number and memory location. For example, if you have 10 holding registers, 40101 thru 40110, and you declare an array, uint16_t holding[10]; to store them, then you know that you simply subtract 40101 from the modbus register number of any incoming request to get the array index where that register value is stored. If you're not using sequentially nubmered modbus registers, it gets more complex. You'll have to maintain a lookup table or something then. \$\endgroup\$ – jwygralak67 Dec 16 '13 at 18:37

Holding Registers are concepts for Modbus they are just we can say data types of two bytes. You can map the holding registers to things like the sensors connected to the microcontroller, timers in microcontroller or any application data that the microcontroller is getting.

For example you could associate Holding register 40003 to Temperature sensor connected to the port pin of the controller and if the device id of the controller is 0x32 . Then if the following modbus query is issued to the controller

32 03 02 01 3E 3C

The above query is a Read query to Analog Holding register for the device id 0x32 and the analog holding register no 40003 . When this query is received to your controller at uart then you can send the response as

32 03 02 2345 64 83

The response says that there are two bytes in the response since the requested query is of only one analog holding register and analog holding register is of 2 bytes, and since the temperature reading is mapped to analog holding register you can send the 2345 or the reading of the temperature at the port pin.

Like this the status of the port pin can be mapped to Discrete Coils and Discrete Contacts, and the values that u get which are not bit values can be mapped to analog input and holding registers and the modbus can be used to share information.

  • \$\begingroup\$ This doesn't quite answer the question because it doesn't talk about how you would store this value inside the Atmega processor. \$\endgroup\$ – David Dec 18 '13 at 15:55

I've done similar projects before, but i'm not sure what exactly you're having trouble with. If I were building a slave program for a microprocessor (I use arduino and basic stamp) there would be a loop function that scans the IO pins, and all pin states would be assigned variables eg pin1 = REG(0), pin2 = REG(1) etc. I find it simpler to create a few arrays :

DIM I(16)
DIM Q(16)
DIM F(64)


and assign all similar IO types to the same array (all inputs together, all outputs together, all registers together) The next step will be to process the incoming requests from the master so that the slave knows what (if any) data to respond with. You can use hardware (such as a modbus shield), or software libraries (arduino has a few but I don't know about atmega32). . . or my favorite option - write your own code.

The modbus response packet has to be built based on what data was requested. this link]1 was a help full site for learning to build the response packets.

The completed packets should look something like this

01 01 01 00 51 88 [coils]

01 02 01 00 A1 88 [inputs]

01 03 80 00 00 00... [holding registers]

The final step is to convert the above responses to ascii and send to the master (via rs232).

Also, I find it easier to write all my code to do calculations in 2 character hex format (00-FF) because it mimics the way data is handled in modbus. One analog register can store from 0-245, and registers are combined to store larger numbers.


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.