emelianov / modbus-esp8266

Most complete Modbus library for Arduino. A library that allows your Arduino board to communicate via Modbus protocol, acting as a master, slave or both. Supports network transport (Modbus TCP) and Serial line/RS-485 (Modbus RTU). Supports Modbus TCP Security for ESP8266/ESP32.
Other
534 stars 188 forks source link

Hardware Limits for Arduino Nano #251

Closed tkempf closed 2 years ago

tkempf commented 2 years ago

Hi, im trying to use your library for a modbus rtu slave on a module which makes multiple s0 inputs readable via modbus rtu on an arduino nano. For my purpose each of the 16 s0 input needs about 10 different registers for configuration/readout, so in sum i need 160 Hregs .I can add those registers via addHREG, which returns true for all of them, so i thought all of them were created. when i try to read the registers via mbpoll, i get errors (invalid register address) for addresses higher than the first 32 registers. So i checked your code and found the MODBUS_MAX_REGS limit of 32 in ModbusSettings.h together with a comment "// Limit resources usage for entry level boards". When i try to increase MODBUS_MAX_REGS to i.e. 160, the code compiles and uploads fine, but i get many errors (most of them beeing CRC errors) when trying to read any register via modbus. I double checked my code against your examples, the documtation and your source ( as far as i understand it ;-) but found no obvius errors in it. I can't imagine why the maximum register count should be dependant on the power of the board. Each register needs a little RAM, thats clear. Shouldn't the NANO have enough power to deliver the contents of 160 registers via Modbus? I'd really appreciate your help with this matter. TIA Tom

tkempf commented 2 years ago

Ok, trying to answer my own question. After compiling and uploading my program to the Nano, there were already 1200 Bytes of the 2k RAM used and it looks as though the 800 Bytes still available are just not enough for working within my program with your library and so many registers... When i decrease the initially allocated RAM size in my program for testing purposes, i can work with some more than the first 32 registers without problems. So here are some other questions which arise for me in that context. How much RAM will be allocated (roundabout) for one register, is it only the 16Bits for the value or more for needed helper strucures ? Is there anything i could to to minimize memory needs for your library ? When adding a register, is the parameter value copied to some internal var in the register, or is it possible to work with a pointer to already allocated variables here ? Kind Regards Tom

emelianov commented 2 years ago

Hello Tom, For sure in terms of Nano/Uno/Leonardo the library is memory hog. Each local register requires 5 bytes of RAM that is allocated at runtime. Unfortunately there is no way to illuminate usage of internal registers without major code rewrite.

tkempf commented 2 years ago

Hi Alexander, thank you for your reply. I managed to save about 600 Bytes of RAM by limiting inputs to 8 S0 Counters and reorganizing my static variables. The Compiler tells my i have used about 650 Byte of SRAM. I implemented SRAM Measurement like it is described here https://docs.arduino.cc/learn/programming/memory-guide. The value of free SRAM is written to one IREG, which i can poll with your library and which shows at least 250 Byte free after Initializing all Registers. During Setup i first create 4 IRegs with things like free SRAM size, registercount, and oneWire Sensorcount. There are 10 18B120 Sensors delivering float values for which i need the next 20 IRegs. After that, for the 8-S0 Counters i add 80 HRegs in sum, which makes a total of 105 Modbus Registers. If each of them needs 5 Bytes of RAM, There should be enough SRAM to poll those registers, I can read all IREGS without Errors, but when polling the HREGs i get Illegal Register Address errors. Even though i check the return value of the addHREG, which is true for all of those registers. What is your opinion to this? Do you think the NANO does not have enough Resources to use for such a project ? Should i try to switch to another Board? Or should i keep on searching errors in my code ? Kind Regards Tom

emelianov commented 2 years ago

Probably some differences in register addressing: the library uses 0-based while your simulator or documentation may use 1-based. Additionally note, that the library additionally dynamically allocates buffers to fit incoming and outgoing Modbus frames during transfer. There are boards not so limited in resources as classic Arduino Uno/Nano/etc and costs are very affordable. So I see no reason to stay with Nano except that case if you want to have a fun while implementing powerful thing with little resources.

tkempf commented 2 years ago

well, i fear it must be indeed some sort of fun to make this work on a nano. Apart of this, i already soldered the nano with a max485 and surroundings on a board which fits into a dinrail case and wired all output ports to terminals. So it'd be work to rebuild from scratch with a new board. But after removing the modbusfile functions by #undef MODBUS_FILES i was able to gain another 200 Bytes of free ram and the program including your library runs fine with 10 S0 Counter-Inputs, and 2 Onewire Pins with 10 connected 18B120-Sensors. So i think i close this with a big thank you for your input and for your great work on this library! Tom