CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Modbus master RTU issue with long distance
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
huynhhai



Joined: 04 Apr 2015
Posts: 39

View user's profile Send private message

Modbus master RTU issue with long distance
PostPosted: Tue May 04, 2021 8:30 am     Reply with quote

Hi Every one,

I had two boards, 1 master using PIC18F67K22 and 1 Slave using PIC16F887. To read input, i wrote code as example "ex_modbus_slave.c " and "EX_MODBUS_MASTER.C ", the master gets data from slave by command modbus_read_discrete_input(MODBUS_SLAVE_ADDRESS,0,8);. The issue with long distance (>500meter) the master transceiver data but slave no recived any data, but i tried with short distant (<10m) is ok.

With long distance i tried to test with software Modbus poll on PC is ok. Ii tried to change crystal master, pin transmit, please see code below.

Do i need to us library rs485.c to make get message??
Please refer it , thanks.
Code:

//slave code, id setting 239 to 247

#include <main.h>
#include "modbus.c"
#include "ds3231.c"
#include <2404.c>

//Khai bao phan cung ban phim
#define SELECT PIN_B0
#define INC    PIN_B1
#define DEC    PIN_B2
#define ENTER  PIN_B3

//Khai bao phan cung led 7 doan
#define led1 PIN_E0
#define led2 PIN_E1
#define led3 PIN_E2

//Khai bao phan cung input
#define input1 PIN_A0
#define input2 PIN_A1
#define input3 PIN_A2
#define input4 PIN_A3

char dataInput;
#bit input11 = dataInput.0
#bit input22 = dataInput.1
#bit input33 = dataInput.2
#bit input44 = dataInput.3

unsigned int8 sodem[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned int8 ledData1,ledData2,ledData3,ledNumber=1;
unsigned int8 MODBUS_SLAVE_ADDRESS; //khai bao bien dia chi SLAVE

unsigned int8 data_rtc[15],data_inputs[8],data_history[64],inputs;
unsigned int16 checkComStatus=0,event_count = 0;
int1 offLed=0;

//Ds3231 real time....
unsigned short hr_format = _24_hour_format,am_pm = 1;
unsigned int8 seconds=0,minute=0,hour=0,day=0,date=0,month=0,year=0;
unsigned int8 cmdSetRtc1=0,cmdSetRtc2=0,cmdSetRtc3=0,cmdSetRtc4=0;

//history eeprom set up
unsigned int8 eepromAddr=0,countReadTime=0;
int8 coGhi=0,enableWriteEeprom=0;

//KHAI BAO CAC HAM SU DUNG
void write_history_eeprom();
void read_history_eeprom();
void modbus_interface();
void set_time_ds3231();
char read_input();
void readtime_ds3231();
int8 swap_bits(int8 c);
void clearEeprom();
void slaveIDSet();
void resetHistoryAddr();
void testKey();

//-----------------------------------------------------------------------------
//su dung de quet led 7 doan
#INT_TIMER2
void  TIMER2_isr(void)
{
   if(ledNumber==4) ledNumber=1;
   switch(ledNumber)
   {
      case 1:
      {
        output_low(led2);
        output_low(led3);
        output_high(led1);
        output_d(ledData1);
        ledNumber++;
        break;
      }
      case 2:
      {
        output_low(led1);
        output_low(led3);
        output_high(led2);
        output_d(ledData2);
        ledNumber++;
        break;
      }
           
      case 3:
      {
        output_low(led1);
        output_low(led2);
        output_high(led3);
        output_d(ledData3);
        ledNumber++;
        break;
      }
   }
}

//-----------------------------------------------------------------------------
void main()
{
   //Khai bao ngat cho timer2
   enable_interrupts(INT_TIMER2);
   enable_interrupts(GLOBAL);
   setup_timer_2(T2_DIV_BY_16,218,1);      //700 us overflow, 700 us interrupt
   set_timer2(0);
   
   i2c_init(100000);
   ds3231_init();      //khai bao real time
   init_ext_eeprom();  //khai bao su dung rom ngoai
   modbus_init();      //khai bao su dung modbus
   port_b_pullups (TRUE);  //keo gia tri portB len
   set_tris_b (0x0f);      //4 bit thap input, 4 bit cao output
   setup_adc_ports(NO_ANALOGS);
   
   //cau hinh watch dog
   setup_wdt(WDT_ON);
   setup_wdt(WDT_2304MS|WDT_DIV_2);      //~1.1 s reset
   
   //Doc dia chi phan cung SLAVE
   MODBUS_SLAVE_ADDRESS=read_ext_eeprom(254);
   ledData1=sodem[(MODBUS_SLAVE_ADDRESS/100)%10];
   ledData2=sodem[(MODBUS_SLAVE_ADDRESS/10)%10];
   ledData3=sodem[(MODBUS_SLAVE_ADDRESS%10)];
   delay_ms(1000);
   
   
   clearEeprom(); //chuong trinh xoa toan bo Rom ngoai ve 0
   slaveIDSet();  // cai dat dia chi slave
   resetHistoryAddr();   //reset lai dia chi dau tien trong history
 
//=============================================================================
//Chuong trinh chinh
   while(TRUE)
   {
       countReadTime++;    //10 lan moi doc ds3231 va input
       if(countReadTime>=50)
       {
          readtime_ds3231();
          countReadTime=0;
       }
       modbus_interface(); //truyen du lieu ve master
       set_time_ds3231();// cai dat thoi gian rtc
       delay_ms(10);   //gia tri ban dau 10m
//!    testKey();
   }
}

//-----------------------------------------------------------------------------
//Dao trang thai bit
int8 swap_bits(int8 c)
{
   return ((c&1)?128:0)|((c&2)?64:0)|((c&4)?32:0)|((c&8)?16:0)|((c&16)?8:0)
          |((c&32)?4:0)|((c&64)?2:0)|((c&128)?1:0);
}

//-----------------------------------------------------------------------------
//Doc thoi gian tu DS3231
void readtime_ds3231()
{
   getTime(hour,minute,seconds,am_pm,hr_format);
   getDate(day, date, month,year);
   data_inputs[1] = seconds;
   data_inputs[2] = minute;
   data_inputs[3] = hour;
   data_inputs[4] = date;
   data_inputs[5] = month;
   data_inputs[6] = year;
   data_inputs[7] = 0;
   inputs=read_input();   //doc gia tri input
   data_inputs[0] = inputs;
}

//-----------------------------------------------------------------------------
//Doc gia tri inputs va hien thi trang thai loi, ghi eeprom ngoai
char read_input()
{
   dataInput=0x0f;
   input11=input(input1);
   if(input11==0)
   {
      if(offLed==0)
      {
       ledData1=0x92; //'S'
       ledData2=0x87; //'t'
       ledData3=0xc0; //'O'
      }
   }
   if(input11==0 && coGhi==0)
   { enableWriteEeprom=1;  //bat chuc nang ghi loi
     coGhi=1;
   }
   //----------------------------
   input22=input(input2);
   if(input22==0)
   {
      if(offLed==0)
      {
        ledData1=0x88; //'A'
        ledData2=0xc7; //'L'
        ledData3=0xaf; // 'r';
      }
   }
   if(input22==0 && coGhi==0)
   { enableWriteEeprom=1;  //bat chuc nang ghi loi
     coGhi=1;
   }
   //----------------------------
   input33=input(input3);
   if(input33==0)
   {
       if(offLed==0)
       {
         ledData1=0x88; //'A'
         ledData2=0xc7; //'L'
         ledData3=0xaf; // 'r';
       }
      }
   if(input33==0 && coGhi==0)
   { enableWriteEeprom=1;  //bat chuc nang ghi loi
     coGhi=1;
   }
   //----------------------------
   input44=input(input4);
   if(input44==0)
   {
       if(offLed==0)
       {
         ledData1=0x88; //'A'
         ledData2=0xc7; //'L'
         ledData3=0xaf; // 'r';
       }
    }
   if(input44==0 && coGhi==0)
   { enableWriteEeprom=1;  //bat chuc nang ghi loi
     coGhi=1;
   }
   
   if(dataInput==0x0f) //cho phep ghi 1 lan dau tien khi van con loi
   {
     coGhi=0;
     if(offLed==0)
     {
       ledData1=0xaf;   // 'r';
       ledData2=0xc1;   // 'U'
       ledData3=0xab;   // 'n'
     }
   }
   
   if(enableWriteEeprom==1)
   {
     write_history_eeprom(); //tam tat chuc nang viet history
   }
   return dataInput;
 }
 
//-----------------------------------------------------------------------------
//cai dat thoi gian sau khi chinh - dung data tu master
void set_time_ds3231()
{
  cmdSetRtc1= data_rtc[11]; //0x11 = 17
  cmdSetRtc2= data_rtc[12]; //0x22 = 34
  cmdSetRtc3= data_rtc[13]; //0x33 = 51
  cmdSetRtc4= data_rtc[14]; //0x44
 
  //Kiem tra dung dieu kien lenh moi cho ghi du lieu vao DS3231
  if(cmdSetRtc1==0x11 && cmdSetRtc2==0x22 && cmdSetRtc3==0x33 && cmdSetRtc4==0x44)
  {
  date   = data_rtc[5];
  month  = data_rtc[6];
  year   = data_rtc[7];
  hour   = data_rtc[8];
  minute = data_rtc[9];
  seconds= data_rtc[10];
 
  setTime(hour,minute,seconds,am_pm,hr_format);
  setDate(day,date,month,year);
  delay_ms(1);
  //xoa lenh sau khi thuc hien xong
  data_rtc[11]=0; //0x11 = 17
  data_rtc[12]=0; //0x22 = 34
  data_rtc[13]=0; //0x33 = 51
  data_rtc[14]=0; //0x44
       
  //thong tin cai dat thoi gian tu xa
  ledData1=0x92; // 'S'
  ledData2=0x86; // 'E'
  ledData3=0x87; // 't'
  delay_ms(500);
  }
}

//-----------------------------------------------------------------------------
//Chuong trinh viet so thuc vao EEPROM ngoai
void write_history_eeprom() // 1 chua dia chi vi tri nho
{
    eepromAddr = read_ext_eeprom(1);              //doc vi tri dia chi can luu
    write_ext_eeprom(eepromAddr++,dataInput);     //ghi trang thai loi input tu vi tri thu 2
    delay_ms(5);
    write_ext_eeprom(eepromAddr++,data_inputs[4]);         //ghi ngay
    delay_ms(5);
    write_ext_eeprom(eepromAddr++,data_inputs[5]);        //ghi thang
    delay_ms(5);
    write_ext_eeprom(eepromAddr++,data_inputs[6]);         //ghi nam
    delay_ms(5);
    write_ext_eeprom(eepromAddr++,data_inputs[3]);         //ghi gio
    delay_ms(5);
    write_ext_eeprom(eepromAddr++,data_inputs[2]);       //ghi phut
    delay_ms(5);
    eepromAddr++;
    if(eepromAddr>251) eepromAddr=0;
    enableWriteEeprom=0;  //bao da ghi history xong
    write_ext_eeprom(1,eepromAddr);
    delay_ms(5);
}   
//-----------------------------------------------------------------------------
//chuong trinh doc lich su 10 lich su gan nhat
void read_history_eeprom()   // 0x0000 chua dia chi vi tri nho       
{
    int8 j=0;
    unsigned int8 temp=0;
    eepromAddr=read_ext_eeprom(1);
    eepromAddr=eepromAddr-7;         // giam xuong 1 gia tri
    temp=eepromAddr;
       
    for(int8 i=0;i<8;i++)  //chuyen ma 8 lich su
    {   
       data_history[j]=read_ext_eeprom(temp);        //Doc trang thai loi input
       data_history[j++]=read_ext_eeprom(temp++);    //Doc ngay
       data_history[j++]=read_ext_eeprom(temp++);    //Doc thang
       data_history[j++]=read_ext_eeprom(temp++);    //Doc nam
       data_history[j++]=read_ext_eeprom(temp++);    //Doc gio
       data_history[j++]=read_ext_eeprom(temp++);    //Doc phut
       data_history[j++]=read_ext_eeprom(temp++);    //Doc giay
       if(eepromAddr<7) eepromAddr=252;
       eepromAddr=eepromAddr-7;
       temp=eepromAddr;
    }
 }
 
//-----------------------------------------------------------------------------
void modbus_interface()
{
  if(modbus_kbhit()==1)
 {
      delay_us(50);
      checkComStatus=0; //reset bao loi truyen thong COM PORT
      offLed=0;         //cho phep hien thi tat ca trang thai input
      //check address against our address, 0 is broadcast
      if(modbus_rx.address == MODBUS_SLAVE_ADDRESS)
      {       
         switch(modbus_rx.func)
         {
            case FUNC_READ_COILS: 
                 read_history_eeprom();  //doc data tu eeprom+   
                 
                  modbus_read_coils_rsp(MODBUS_SLAVE_ADDRESS,64,&data_history);
                  event_count++;
            break;
            //-----------------------------------------------------------------
            case FUNC_READ_DISCRETE_INPUT:     //read inputs ---> chuong trinh nay chi su dung ham nay
                  modbus_read_discrete_input_rsp(MODBUS_SLAVE_ADDRESS, 8,&data_inputs);
                  event_count++;
            break;
            //-----------------------------------------------------------------   
            case FUNC_WRITE_SINGLE_COIL:      //write coil;

                  modbus_write_single_coil_rsp(MODBUS_SLAVE_ADDRESS,modbus_rx.data[1],((int16)(modbus_rx.data[2]))<<8);
                  event_count++;
            break;
            //-----------------------------------------------------------------
            case FUNC_WRITE_MULTIPLE_COILS:          // ---> chuong trinh nay chi su dung ham nay 
                 //modbus_rx.data[0]; --> dia chi bat dau muc cao
                 //modbus_rx.data[1]; --> dia chi bat dau muc thap
                 //modbus_rx.data[3]; --> so bit goi tu master
                 //modbus_rx.data[4]; --> chieu dai cua du lieu can goi
                 //modbus_rx.data[5]; --> noi dung du lieu goi tu master

                 //luu du lieu vao trong bo nho
                 for(int8 temp=0;temp<15;temp++)
                 { data_rtc[temp] = modbus_rx.data[temp];} 
 
                  modbus_write_multiple_coils_rsp(MODBUS_SLAVE_ADDRESS,0,10);
                  event_count++;   
                     
             break;
               //--------------------------------------------------------------
             default:    //We don't support the function, so return exception
             modbus_exception_rsp(MODBUS_SLAVE_ADDRESS,modbus_rx.func,ILLEGAL_FUNCTION);
         }
      }
  }
  else
  {
    if(checkComStatus>=200)  //sau 2s ko nhan duoc tin hieu bao loi COM PORT
    {
    checkComStatus=0;
    offLed=1;    //tat hien thi cac trang thai khac, chi hien thi loi COM PORT
    ledData1=0x86; // 'E'
    ledData2=0xaf; // 'r'
    ledData3=0xaf; // 'r';
    }
    else checkComStatus++;
  }
}

//chuong trinh xoa toan bo Rom ngoai ve 0
//--------------------------------------------------------------------------
void clearEeprom()
{
   if(input(SELECT)==0 && input(INC)==0 && input(DEC)==0 && input(ENTER)==0)
   {
      unsigned int8 clearEEpromExternal;
            //Hien thi thong tin clear eeprom
      ledData1=0xC6; // 'C'
      ledData2=0xc7; // 'L'
      ledData3=0xaf; // 'r';
      delay_ms(1000);
      for(clearEEpromExternal=0;clearEEpromExternal<254;clearEEpromExternal++)
      {
         write_ext_eeprom(clearEEpromExternal,0);
         delay_ms(10);
      }
   }
}

//--------------------------------------------------------------------------
//Cai dat dia chi moi khi tac dong cung luc 2 nut nhan luc bat nguon
void slaveIDSet()
{
   if(input(INC)==0 && input(DEC)==0)
   {
   do{
      if(input(INC)==0)
      {
      delay_ms(10);
      if(MODBUS_SLAVE_ADDRESS>=254) {MODBUS_SLAVE_ADDRESS=0;}
      else MODBUS_SLAVE_ADDRESS++;
      }
     
      if(input(DEC)==0)
      {
      delay_ms(10);
      if(MODBUS_SLAVE_ADDRESS<=0)   {MODBUS_SLAVE_ADDRESS=254;}
      else MODBUS_SLAVE_ADDRESS--;
      }
      //tao chuong trinh chop tat led
      ledData1=sodem[(MODBUS_SLAVE_ADDRESS/100)%10];
      ledData2=sodem[(MODBUS_SLAVE_ADDRESS/10)%10];
      ledData3=sodem[(MODBUS_SLAVE_ADDRESS%10)];
      delay_ms(300);
      ledData1=0xff;
      ledData2=0xff;
      ledData3=0xff;
      delay_ms(300);
      }while(input(ENTER));
      write_ext_eeprom(254,MODBUS_SLAVE_ADDRESS);
      delay_ms(1000);
   }
}

//--------------------------------------------------------------------------
//Gan dia chi vi tri lich su dau tien vao Eeprom
void resetHistoryAddr()
{
   if(input(SELECT)==0 && input(ENTER)==0)
   {
      //Hien thi thong tin reset
      ledData1=0xaf; // 'r';
      ledData2=0x92; // 'S'
      ledData3=0x87; // 't'
      delay_ms(1000);
      eepromAddr=0;
      write_ext_eeprom(255,eepromAddr);
      delay_ms(5);
   }
}

//Test key---------------------------------------------------------------------
void testKey()
{
   if(input(SELECT)==0)
   ledData3=sodem[1];

   if(input(INC)==0)
   ledData3=sodem[2];

   if(input(DEC)==0)
   ledData3=sodem[3];
   
   if(input(ENTER)==0)
   ledData3=sodem[4]; 
   
   delay_ms(100);
   ledData1=sodem[0];
   ledData2=sodem[0];
   ledData3=sodem[0];
}


Code:

//slave h file

#include <16F887.h>
#device ADC=10

#FUSES WDT                      //Watch Dog Timer
#FUSES HS
#FUSES PROTECT   //code protect
#FUSES NOBROWNOUT

#use delay(crystal=11059200,restart_wdt)
#use i2c(master, sda=PIN_C4, scl=PIN_C3)

#define MODBUS_BUS SERIAL
#define MODBUS_TYPE MODBUS_TYPE_SLAVE
#define MODBUS_SERIAL_TYPE MODBUS_RTU
#define MODBUS_SERIAL_INT_SOURCE MODBUS_INT_RDA
#define MODBUS_SERIAL_RX_BUFFER_SIZE 64
#define MODBUS_SERIAL_BAUD 9600

//------------------------------------------------------------------

master code:

h. file
Code:

#FUSES NOWDT                      //use Watch Dog Timer
#FUSES VREGSLEEP_SW             //Ultra low-power regulator is enabled
#FUSES SOSC_DIG                 //Digital mode, I/O port functionality of SOSCI and SOSCO pins turned on i/o pin c0 & c1
#FUSES NOBROWNOUT               //No brownout reset
#FUSES PROTECT                  //code protect
#FUSES HSM       

#use delay(crystal=11059200)

//SERIAL PROTOCOL
#define MODBUS_PROTOCOL MODBUS_PROTOCOL_SERIAL
#define MODBUS_TYPE MODBUS_TYPE_MASTER
#define MODBUS_SERIAL_TYPE MODBUS_RTU             //use MODBUS_ASCII for ASCII mode
#define MODBUS_SERIAL_INT_SOURCE MODBUS_INT_RDA   //hardware- TX: PIN_C6 / RX: PIN_C7
#define MODBUS_SERIAL_BAUD 9600
#define MODBUS_SERIAL_RX_PIN       PIN_C7   // Data receive pin
#define MODBUS_SERIAL_TX_PIN       PIN_C6   // Data transmit pin
#define MODBUS_SERIAL_ENABLE_PIN   0   // Controls DE pin.  RX low, TX high.
#define MODBUS_SERIAL_RX_ENABLE    0   // Controls RE pin.  Should keep low.
#define MODBUS_PARITY "EVEN"
#define MODBUS_SERIAL_RX_BUFFER_SIZE 64

in c file the code for read data
Code:

void read_inputs_and_data_rtc(unsigned int8 slaveID2)

   modbus_read_discrete_input(slaveID2,0,64);  //dia chi 8 byte input
   delay_ms(1);
//!   simulink_display();  //test thong tin nhan tu slave
   
   inputs_data[0]=modbus_rx.error;    //trang thai loi
   inputs_data[1]=slaveID2;           // dia chi Slave
   inputs_data[2]=modbus_rx.data[1];  // inputs data system
   inputs_data[3]=modbus_rx.data[2];  // giay
   inputs_data[4]=modbus_rx.data[3];  // phut
   inputs_data[5]=modbus_rx.data[4];  // gio
   inputs_data[6]=modbus_rx.data[5];  // ngay
   inputs_data[7]=modbus_rx.data[6];  // thang
   inputs_data[8]=modbus_rx.data[7];  // nam
   
   //Giai ma tin hieu tu slave
   switch (slaveID2)
   {
      case 247:  //station1
      {
          station1=0;
          outputAlarm1=0;
          if(inputs_data[2]==0x0e) {outputAlarm1=1;
          station1=1;}
          if(inputs_data[2]<0x0e)  {outputAlarm1=1;
          station1=2;}
          if(inputs_data[0]!=0)    {outputAlarm1=1;
          station1=3;}
      }
      break;
     
      case 246:  //station2
      {
          station2=0;
          outputAlarm2=0;
          if(inputs_data[2]==0x0e) {outputAlarm2=1;
          station2=1;}
          if(inputs_data[2]<0x0e)  {outputAlarm2=1;
          station2=2;}
          if(inputs_data[0]!=0)    {outputAlarm2=1;
          station2=3;}
      }
      break;
     
      case 245:  //station3
      {
          station3=0;
          outputAlarm3=0;
          if(inputs_data[2]==0x0e) {outputAlarm3=1;
          station3=1;}
          if(inputs_data[2]<0x0e)  {outputAlarm3=1;
          station3=2;}
          if(inputs_data[0]!=0)    {outputAlarm3=1;
          station3=3;}
      }
      break;
     
      case 244:  //station4
      {
          station4=0;
          outputAlarm4=0;
          if(inputs_data[2]==0x0e) {outputAlarm4=1;
          station4=1;}
          if(inputs_data[2]<0x0e)  {outputAlarm4=1;
          station4=2;}
          if(inputs_data[0]!=0)    {outputAlarm4=1;
          station4=3;}
      }
      break;
     
      case 243:  //station5
      {
          station5=0;
          outputAlarm5=0;
          if(inputs_data[2]==0x0e) {outputAlarm5=1;
          station5=1;}
          if(inputs_data[2]<0x0e)  {outputAlarm5=1;
          station5=2;}
          if(inputs_data[0]!=0)    {outputAlarm5=1;
          station5=3;}
      }
      break;
     
      case 242:  //station6
      {
          station6=0;
          outputAlarm6=0;
          if(inputs_data[2]==0x0e) {outputAlarm6=1;
          station6=1;}
          if(inputs_data[2]<0x0e)  {outputAlarm6=1;
          station6=2;}
          if(inputs_data[0]!=0)    {outputAlarm6=1;
          station6=3;}
      }
      break;
     
      case 241:  //station7
      {
          station7=0;
          outputAlarm7=0;
          if(inputs_data[2]==0x0e) {outputAlarm7=1;
          station7=1;}
          if(inputs_data[2]<0x0e)  {outputAlarm7=1;
          station7=2;}
          if(inputs_data[0]!=0)    {outputAlarm7=1;
          station7=3;}
      }
      break;
     
      case 240:  //station8
      {
          station8=0;
          outputAlarm8=0;
          if(inputs_data[2]==0x0e) {outputAlarm8=1;
          station8=1;}
          if(inputs_data[2]<0x0e)  {outputAlarm8=1;
          station8=2;}
          if(inputs_data[0]!=0)    {outputAlarm8=1;
          station8=3;}
      }
      break;
     
      case 239: //station9
      {
          station9=0;
          outputAlarm9=0;
          if(inputs_data[2]==0x0e) {outputAlarm9=1;
          station9=1;}
          if(inputs_data[2]<0x0e)  {outputAlarm9=1;
          station9=2;}
          if(inputs_data[0]!=0)    {outputAlarm9=1;
          station9=3;}
      }
      break;
   } 
}
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue May 04, 2021 9:32 am     Reply with quote

What interface devices and wiring have to designed for the >500 meter distance ?
Usually MODBus uses RS-485 devices, so yes, you'd need the RS485.c 'driver' but, that code 'may' be already included in the MODBus programs.
As this is a serial communications network, you do need to design based upon speed of the network, number of devices, the type/make of interface chips, type of cabling. The datasheet of the interface device should have 'design recommendations' for most of this

Since your project works fine for short distance, the 'code' is OK, it's the 'hardware' you need to fix.

Jay
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Tue May 04, 2021 9:43 am     Reply with quote

When you have long cables, the cables themselves and the terminations
become more important.

Do you have the 120 ohm terminators at the end of the lines at the master
and the last slave? Are you using a daisy chain configuration like RS485
standard suggests?

How about the cable itself? Is it twisted pair and shielded? How about the
environment? Are there high power AC machinery around?

As a quick test, maybe try dropping the baud rate. What happens if you try
that?
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Tue May 04, 2021 10:01 am     Reply with quote

What RS485 transceivers are you using (some low power designs have
limited range)?. What terminations on the bus?. What wire?.
As distance goes up everything conspires to make things more and more
important.
huynhhai



Joined: 04 Apr 2015
Posts: 39

View user's profile Send private message

PostPosted: Tue May 04, 2021 10:03 am     Reply with quote

Thank you very much,

For cable i used Altek cable 22AWG 1 pair shield, about 9 slaves (read status run-stop) and 1 master.
The master read step by step from slave 1 to slave 9, the time for read two slaves is 100ms, in the case i was only test 1 master connect to 1 slave.

But i didn't understand what is the reason why?, with this slave hardware i used Modbus poll pc software( at modbus.org ) to tested ok, and tested with 3 slave at the same time ok

I don't know before read "discrete_input". Do i need to send message to make the slave ready for transfer data ?

RS485 Master and slave module boards i used isolate by opto and i checked signal by oscilloscope OK.

The network connect look like below:


Slave1|--------+--------+----------+---...----+-----------| slave9
| | | |
| | | |
slave2 master slave3.... slave8

Would you please show me Modbus RTU protocol to read data from any slave? Because i thought incorrect with my code from master.

thanks,
huynhhai
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Tue May 04, 2021 10:16 am     Reply with quote

Your master is in the middle of the string?

I think that modbus/rs485 suggests putting your master at the end.
huynhhai



Joined: 04 Apr 2015
Posts: 39

View user's profile Send private message

PostPosted: Tue May 04, 2021 10:22 am     Reply with quote

Dear dluu13, Ttelmah

For network i used "backbone with stubs" about 9 slave and 1 master.
I connected with two resistors 120 ohm the end of two lines.
I tested the baudrate to 1200bps master and slave but the same issue.

All the issue not come hardware because i used this slave to test them with modbus poll tool (tool modbus master) was ok.[/url]
huynhhai



Joined: 04 Apr 2015
Posts: 39

View user's profile Send private message

PostPosted: Tue May 04, 2021 10:28 am     Reply with quote

Thanks dluu13,

The Master i put middle of the string,
and i used module usb to rs485 to tested at the same position with pc modbus poll tool is ok.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Tue May 04, 2021 11:32 am     Reply with quote

Comment still applies about what transceivers you are using on the PIC
board, since these are different when you are using the USB to 485
board.
huynhhai



Joined: 04 Apr 2015
Posts: 39

View user's profile Send private message

PostPosted: Tue May 04, 2021 11:55 am     Reply with quote

please see module rs485

1. USB module
https://1drv.ms/u/s%21AlOlL_PaiWSVj5MB2oLId4VypF93oQ?e=xtltKy

2. rs485 module on PIC board
https://1drv.ms/u/s%21AlOlL_PaiWSVj5MCEyX0VSC9GF9AoQ?e=rvbcqm
huynhhai



Joined: 04 Apr 2015
Posts: 39

View user's profile Send private message

PostPosted: Wed May 05, 2021 12:10 am     Reply with quote

Today, i tried to increase the time timeout =100ms reponse to connect master and slave, and the time read data between two slaves is 10ms.
At the time i used delay to read data from master to slaves everytime 100ms,
Do i need using interrupt for this?
Do you know how to check baudrate actual in PIC board?
How to use Modbus RTU with synchronized mode in RS232?
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Wed May 05, 2021 12:27 am     Reply with quote

Show us a link to where you buy the module you are using with the PIC?.
Hopefully this may have some data.
This module 'worries' me, since it has no direction control pin, implying
it is turning the transceivers round itself. This will be baud rate critical,
and if wrong would explain a lot.
Using 'undocumented' parts is a sure way to have problems.
huynhhai



Joined: 04 Apr 2015
Posts: 39

View user's profile Send private message

PostPosted: Wed May 05, 2021 1:26 am     Reply with quote

Dear Ttelmah,

This module i got from supplier of china,
https://shopee.vn/Module-TTL-to-RS485-i.104103144.4673294905

At the moment in my boards i used TTL to RS485 ( mean no pin DE and RE ) when finished send data it will be become received mode, only use two pin RX and TX look like RS232 what is difference between them?
For the USB Module, i checked hardware inside as below

PC-->USB --> CH314 ---> MAX485 (DE and RE the same TTL to RS485 my module, but with Modbus poll tool them ok
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Wed May 05, 2021 1:49 am     Reply with quote

Seriously don't use stuff like this with no data available. Doing so just wastes
your and our time....

There is no data that I can see on how this actually handles the bus reversal.
I'd suspect it just goes to transmit when there is activity on the TX input,
but if so it needs some form of timer to prevent it dropping to receive in
the bus idle periods that MODBUS _requires_. Mistiming of this will result
in the packets failing. So this module may well be causing your problems.

When you are using the USB to 485 module, this has proper DE control so
works. This module does not, so fails.

Get yourself a proper TTL to 485 module with DE control, like:

https://protosupplies.com/product/max485-ttl-to-rs-485-interface-module/
alan



Joined: 12 Nov 2012
Posts: 357
Location: South Africa

View user's profile Send private message

PostPosted: Wed May 05, 2021 2:05 am     Reply with quote

You do realize the board comes with its own 120 terminating resistor. Try removing it or place at the beginning of the bus.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group