View previous topic :: View next topic |
Author |
Message |
José Aparecido
Joined: 29 May 2019 Posts: 21
|
|
Posted: Tue Jun 04, 2019 11:44 am |
|
|
dluu13 wrote: | You will need to provide a modbus master driver for the master and a slave driver for the slave.
read_holding_registers will put the contents of the slave's holding registers into modbus_rx.data
And I advise against simulating using Proteus. There have been a number of cases documented on this forum where a design simulated in Proteus will work there and not in real life, and vice versa.
It is more reliable to simulate in real life using real components. |
What microcontroller memory are the holding registers? |
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Tue Jun 04, 2019 11:52 am |
|
|
If you read modbus.c comments at the header, it also tells you what kind of defines you need to make to make it work. You have not done all of them. For example, the DE and RE pins are not defined.
You also have a #define MODBUS_BUS, which I don't believe is correct.
Your nbuf is never defined... It could be any number from 0 to 255 right now... Also, how can you be sure that modbus_read_holding_registers() is completing with no exceptions?
The holding registers will need to be defined by you in the modbus slave driver. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19549
|
|
Posted: Tue Jun 04, 2019 11:53 am |
|
|
They are not directly.
If you are the slave, _you_ determine what is sent for any particular
register request. It could be a value from a variable, or just a constant.
Completely up to you.
The register address is passed as part of the transaction to the slave.
The way to normally work, would be to sit down and decide what
values you want to send, and then allocate these values register addresses.
Then your slave code would pass the values when asked. |
|
|
José Aparecido
Joined: 29 May 2019 Posts: 21
|
|
Posted: Tue Jun 04, 2019 11:59 am |
|
|
dluu13 wrote: | If you read modbus.c comments at the header, it also tells you what kind of defines you need to make to make it work. You have not done all of them. For example, the DE and RE pins are not defined.
You also have a #define MODBUS_BUS, which I don't believe is correct.
Your nbuf is never defined... It could be any number from 0 to 255 right now... Also, how can you be sure that modbus_read_holding_registers() is completing with no exceptions?
The holding registers will need to be defined by you in the modbus slave driver. |
Sorry for my ignorance, I'm [censored] lost.
I thought that (#define MODBUS_SERIAL_RX_ENABLE PIN_C7) defined RE, and (#define MODBUS_SERIAL_ENABLE_PIN PIN_C6) defined DE, but how do I define each transceiver pin? |
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Tue Jun 04, 2019 12:00 pm |
|
|
To be clear, Modbus is not something that you can throw together in a few minutes...
There's a lot to understand:
hardware protocol
communication protocol
your own hardware interface to the protocol
the software implementation of the communication protocol
how your specific software library works
how you wish you implement these protocols within your own project
and the list goes on...
The first time I ever messed around with this I made all the mistakes you could probably make starting with wiring things wrong and it took me a couple of weeks on and off before I could even get the example code working.
If it is your first time then it is probably best to directly implement ex_modbus_master.c and ex_modbus_slave.c and get those working first. At least then you can know your hardware is in a certain working state. |
|
|
José Aparecido
Joined: 29 May 2019 Posts: 21
|
|
Posted: Tue Jun 04, 2019 12:03 pm |
|
|
Ttelmah wrote: | They are not directly.
If you are the slave, _you_ determine what is sent for any particular
register request. It could be a value from a variable, or just a constant.
Completely up to you.
The regsiter address is passed as part of the transaction to the slave.
The way to normally work, would be to sit down and decide what
values you want to send, and then allocate these values register addresses.
Then your slave code would pass the values when asked. |
In order to write the contents of the registers I could use write_eeprom (address, data);? |
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Tue Jun 04, 2019 12:03 pm |
|
|
José Aparecido wrote: | Sorry for my ignorance, I'm [spam] lost.
I thought that (#define MODBUS_SERIAL_RX_ENABLE PIN_C7) defined RE, and (#define MODBUS_SERIAL_ENABLE_PIN PIN_C6) defined DE, but how do I define each transceiver pin? |
Yes, you need to define MODBUS_SERIAL_RX_ENABLE and MODBUS_SERIAL_ENABLE_PIN as two IO pins (c4 and c5)
You also need to define these two:
MODBUS_SERIAL_TX_PIN PIN_C6
MODBUS_SERIAL_RX_PIN PIN_C7 |
|
|
José Aparecido
Joined: 29 May 2019 Posts: 21
|
|
Posted: Tue Jun 04, 2019 12:06 pm |
|
|
dluu13 wrote: | To be clear, Modbus is not something that you can throw together in a few minutes...
There's a lot to understand:
hardware protocol
communication protocol
your own hardware interface to the protocol
the software implementation of the communication protocol
how your specific software library works
how you wish you implement these protocols within your own project
and the list goes on...
The first time I ever messed around with this I made all the mistakes you could probably make starting with wiring things wrong and it took me a couple of weeks on and off before I could even get the example code working.
If it is your first time then it is probably best to directly implement ex_modbus_master.c and ex_modbus_slave.c and get those working first. At least then you can know your hardware is in a certain working state. |
Yes, I'm realizing the difficulty, but how could I modify ex_modbus_master.c and ex_modbus_slave.c to simulate with two PIC18F4550 microcontrollers?
|
|
|
José Aparecido
Joined: 29 May 2019 Posts: 21
|
|
Posted: Tue Jun 04, 2019 12:11 pm |
|
|
dluu13 wrote: | José Aparecido wrote: | Sorry for my ignorance, I'm [spam] lost.
I thought that (#define MODBUS_SERIAL_RX_ENABLE PIN_C7) defined RE, and (#define MODBUS_SERIAL_ENABLE_PIN PIN_C6) defined DE, but how do I define each transceiver pin? |
Yes, you need to define MODBUS_SERIAL_RX_ENABLE and MODBUS_SERIAL_ENABLE_PIN as two IO pins (c4 and c5)
You also need to define these two:
MODBUS_SERIAL_TX_PIN PIN_C6
MODBUS_SERIAL_RX_PIN PIN_C7 |
I changed and it looked like this:
#define MODBUS_SERIAL_RX_ENABLE PIN_C4 //pino DE RS-485
#define MODBUS_SERIAL_ENABLE_PIN PIN_C5 //pino RE RS-485
#define MODBUS_SERIAL_TX_PIN PIN_C6
#define MODBUS_SERIAL_RX_PIN PIN_C7 |
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Tue Jun 04, 2019 12:13 pm |
|
|
Unfortunately, that is the part that you will need to do the work yourself. Start by building the hardware and writing the basic blinking program, and start building up from there. Use the code provided in the examples and adapt the setup to match your own hardware. Do this for both the master and slave, and then work up to add multiple slaves and make sure that addressing works properly for all of them.
Like I said before, there's no easy way to do it...
Defining the pins is a good step forward :D
Also, write_eeprom() is not the correct way to set the slave register data. You should study ex_modbus_slave.c to see how they deal with the registers.
(well it COULD be, but it's not the way the example does it. I would also not recommend it unless you only change the value every once in a while AND you want it to remember the value between power cycles.)
See that's the hard part... the modbus protocol is just a surface thing that specifies how the messages should be structured, which suggests how your data should be stored locally. But, beyond that, you can do whatever you want. |
|
|
José Aparecido
Joined: 29 May 2019 Posts: 21
|
|
Posted: Tue Jun 04, 2019 12:16 pm |
|
|
dluu13 wrote: | Unfortunately, that is the part that you will need to do the work yourself. Start by building the hardware and writing the basic blinking program, and start building up from there. Use the code provided in the examples and adapt the setup to match your own hardware. Do this for both the master and slave, and then work up to add multiple slaves and make sure that addressing works properly for all of them.
Like I said before, there's no easy way to do it...
Defining the pins is a good step forward :D
Also, write_eeprom() is not the correct way to set the slave register data. You should study ex_modbus_slave.c to see how they deal with the registers.
(well it COULD be, but it's not the way the example does it. I would also not recommend it unless you only change the value every once in a while AND you want it to remember the value between power cycles.)
See that's the hard part... the modbus protocol is just a surface thing that specifies how the messages should be structured, which suggests how your data should be stored locally. But, beyond that, you can do whatever you want. |
okay, thanks |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19549
|
|
Posted: Tue Jun 04, 2019 12:27 pm |
|
|
Write_eeprom will give you issues:
1) EEPROM write life is very limited. Write it at all often and you can
kill the chip.
2) While writing, the chip stops for typically 4mSec. You would need to
design your master timings to stop while every write is performed.
Better to store in RAM, and design a supply shutdown that save the
values as the power goes off, or add an external battery backed RAM
(or FRAM), and save the data here. |
|
|
|