View previous topic :: View next topic |
Author |
Message |
micro_man
Joined: 05 Jun 2013 Posts: 14
|
modbus ascii and rtu selection. |
Posted: Wed Nov 25, 2015 6:08 am |
|
|
Hi
I am using PIC18f46k22
My ccs compiler version is 4.124
I am communicating two devices (based on Modbus) with my microcontroller.
One device is based on RTU and second one is based on ASCII.
when i want to read the data from device based on RTU method i define it as
Code: |
#define MODBUS_SERIAL_TYPE MODBUS_RTU
|
compile the program and burn it into microcontroller.
when i want to read the data form device based on ASCII method i define it as
Code: |
#define MODBUS_SERIAL_TYPE MODBUS_ASCII
|
compile the program and burn it into microcontroller.
Every time i change the device, i have to reprogram it.
Can i make a selection using dip switch to select the device like
Code: |
if(input(Pin no))
{
#define MODBUS_SERIAL_TYPE MODBUS_RTU
}
else #define MODBUS_SERIAL_TYPE MODBUS_ASCII
|
and place this code in very starting of main loop.
Will it work? or there is some other method to do this. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Wed Nov 25, 2015 8:46 am |
|
|
Yes a version of that idea will work for you..
Another is to cut code that automatically figures out what Modbus method the remote device is using. Fairly simple to implement.For reference lookup 'auto baud rate'. Similar in that code decides how fast the 'remote' is going and the 'host' adjusts as required.
Jay |
|
|
micro_man
Joined: 05 Jun 2013 Posts: 14
|
|
Posted: Wed Nov 25, 2015 10:51 pm |
|
|
thanks temtronic
I tried a little code but it is not working as i want
Code: |
#include <18f46k22.h>
#fuses HSH,PUT,NOWDT,NOBROWNOUT
#use delay(crystal=20M)
#use RS232(baud=38400, UART2, parity=N, stream=PC_PORT)
void main()
{
int16 a;
if(!input(PIN_E0))
{
#define VALUE 300
}
else
{
#define VALUE 150
}
a = VALUE;
fprintf(PC_PORT,"%Lu",a);
while(TRUE)
{
}
}
|
The result is always 150.
What should be done? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Thu Nov 26, 2015 3:29 am |
|
|
Would be.....
#defines are _not_ code lines.
#defines are 'pre-processor directives'. All done at compile time, before the chip even starts running. The second one overrides the first, so result is always 150....
Code: |
#include <18f46k22.h>
#fuses HSH,PUT,NOWDT,NOBROWNOUT
#use delay(crystal=20M)
#use RS232(baud=38400, UART2, parity=N, stream=PC_PORT)
int8 value;
void main()
{
int16 a;
if(!input(PIN_E0))
{
value=300;
}
else
{
value=150;
}
a = value;
fprintf(PC_PORT,"%Lu",a);
while(TRUE)
{
}
}
|
|
|
|
micro_man
Joined: 05 Jun 2013 Posts: 14
|
|
Posted: Thu Nov 26, 2015 4:55 am |
|
|
Thanks Ttelmah
So what would be the possible way to do a selection between MODBUS ASCII and MODBUS RTU...
I am seeing in the modbus driver file all these initialization are pre-processor directives and can't be changed as i want. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Thu Nov 26, 2015 5:53 am |
|
|
Exactly as I just did for the single #define, you'd have to re-write the modbus code to use variables, rather than #defines. Obvious problem will be that both copies of the code will then be loaded (so it'll grow in size massively). This is why the #define approach is used, since most users would not mix protocols...
It is actually in breach of the ModBus spec, to do so:
"The Modbus over Serial spec states in section 2.5 of ver 1.0, that the transmission mode MUST be the same for all devices on a Modbus serial line".....
Generally, though (for example) some PC master's do support either protocol, they run 'one or the other' on a particular connection. Mixing on a connection gets even more problematical, since the transmitted character length also changes RTU uses 8bits/character, while ASCII uses 7bits.
Honestly safer and easier really to have two RS485 connections and build one to use RTU, and the other ASCII. I suspect you will find that 'mixed mode' is going to be a very nasty can of worms. :( |
|
|
|