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

Long Distance communication with RS485
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ttelmah



Joined: 11 Mar 2010
Posts: 19609

View user's profile Send private message

PostPosted: Mon Mar 07, 2016 7:52 am     Reply with quote

It's difficult to know, but he is not talking 'long distances', only 20m. I can visualise a lot of things (like temperatures along a processing line), where such things would be ideal.

I think the PIC with a single jumper to allow ID to be programmed is a tidy, and small hardware solution, so if he is using CCS, come back and start talking software.
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Mon Mar 07, 2016 9:16 am     Reply with quote

Hi All,

Yes, I was also envisioning some sort of a 'process line' as a possible application.

I have a number of network connected sensor modules whose address is set with a single jumper. Some have LCD feedback, and some have a single LED. Here is how I do it with an LCD, but the LED case is simple as well....

Code:

   // Here we check the status of the configuration jumper. If not set, we obtain the Module
   // Number from the EEPROM. If it is set, we increment the Module Number until the jumper
    // is removed, and then store the new value in the EEPROM.
   if (!input(Config_Input)){
      ModuleNum = 0;
      while (!input(Config_Input)){
         lcd_gotoxy(1,1);
         printf(lcd_putc, "  Module Number: %i", ModuleNum);
         delay_ms(2000);
         if (!input(Config_Input))
            ModuleNum++;
         if (ModuleNum > 7)
            ModuleNum = 0;
      }
      // Here we write the module address to the EEPROM
         ModuleNum += 0x30;               //Convert to ASCII
         Write_EEPROM(0, ModuleNum);         //write the new Module Number to EEPROM
         lcd_init();
         delay_ms(1000);
   }
   else {
   // Here we read the Module Address from the EEPROM
      ModuleNum=Read_EEPROM(0);       //read the last saved Module Number from EEPROM
   }

_________________
John

If it's worth doing, it's worth doing in real hardware!
temtronic



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

View user's profile Send private message

PostPosted: Mon Mar 07, 2016 9:20 am     Reply with quote

hmm..rethinking this 'address' problem and it can be done without jumpers.
The technique is to power up one slave at a time, then have the master poll for 'new slaves'. It sees the new slave, assigns it an address and slave is now 'online.
Power up 2nd slave, same process.
Ditto for the 3rd.
Once all three have been 'programmed', master goes into 'regular' routine.
Did this 30 years ago for very high security products. Yes, problem is when the power fails, slaves lose their identity (address). There are hardware and software work arounds for this but really a couple of jumpers and extra I/O pins is easier !
The OP also never got into the 'power feed' aspects of the project which I'm curious about.

Jay
heavenlyrider



Joined: 04 Mar 2016
Posts: 7
Location: India

View user's profile Send private message

PostPosted: Thu Mar 17, 2016 7:05 am     Reply with quote

Hi,

I have started the project by using the modbus master/slave example program in CCS. For now, I am just using 1 master and 1 slave.

MASTER CODE:
Code:
#include <16F877A.h>
#FUSES XT PROTECT
#use delay(clock=4000000)
#include "flexlcd.c"

#BYTE TRISD=0X88
#BYTE PORTD=0x08

#define MODBUS_PROTOCOL MODBUS_PROTOCOL_SERIAL
#define MODBUS_TYPE MODBUS_TYPE_MASTER
#define MODBUS_SERIAL_TYPE MODBUS_RTU
#define MODBUS_SERIAL_RX_BUFFER_SIZE 64
#define MODBUS_SERIAL_BAUD 9600
#define MODBUS_SERIAL_TX_PIN PIN_C6   // Data transmit pin
#define MODBUS_SERIAL_RX_PIN PIN_C7   // Data receive pin
#define MODBUS_SERIAL_ENABLE_PIN PIN_C5
#define MODBUS_SERIAL_RX_ENABLE PIN_C4
#define MODBUS_SERIAL_INT_SOURCE MODBUS_INT_RDA
#define MODBUS_TIMER_USED MODBUS_TIMER_T1
#define MODBUS_TIMER_UPDATE MODBUS_TIMER_ISR

#include "modbus.c"

#define MODBUS_SLAVE_ADDRESS1 0x01

int i;
unsigned char deg=176;
unsigned int8 res_hl[]; //slave[0]-msb,slave[1]-lsb
unsigned int16 res16;
float temper;

void read_all_input_reg(unsigned int8 SLAVE_ADDR)
{
      lcd_gotoxy(1,1);
      printf(lcd_putc,"Input Registers:          ");
   if(!(modbus_read_input_registers(SLAVE_ADDR,0,8)))
   { 
      //Started at 1 since 0 is quantity of coils
      for(i=1; i < (modbus_rx.len)-1; ++i)  // for our use
      { 
         res_hl[i]=modbus_rx.data[i];                 
      }     
      lcd_gotoxy(7,2);
      printf(lcd_putc,"rx data: %X",modbus_rx.data[i]);
   }
   else
   {
         lcd_gotoxy(1,2);
         printf(lcd_putc,"<-**ExP %X**->        ",modbus_rx.error);         
   }
}

void main()
{   
   TRISD=0x00;           
   PORTD=0x00;
   
   lcd_init();
   lcd_putc("\f");
   delay_ms(200);
   lcd_gotoxy(1,1);
   printf(lcd_putc,"Initializing...");
   DELAY_MS(1000);
   
   modbus_init();
   delay_ms(500);
   WHILE(true)
   {
//!      DELAY_MS(5000);
         read_all_input_reg(MODBUS_SLAVE_ADDRESS1);
//!      DELAY_MS(5000);
   }
}



SLAVE CODE:
Code:

#include <16F877A.h>
#FUSES XT PROTECT
#use delay(clock=4000000)
#include "flexlcd.c"

#BYTE TRISD=0X88
#BYTE PORTD=0x08

#define MODBUS_PROTOCOL MODBUS_PROTOCOL_SERIAL
#define MODBUS_TYPE MODBUS_TYPE_SLAVE
#define MODBUS_SERIAL_TYPE MODBUS_RTU
#define MODBUS_SERIAL_RX_BUFFER_SIZE 64
#define MODBUS_SERIAL_BAUD 9600
#define MODBUS_SERIAL_TX_PIN PIN_C6   // Data transmit pin
#define MODBUS_SERIAL_RX_PIN PIN_C7   // Data receive pin
#define MODBUS_SERIAL_ENABLE_PIN PIN_C5  // Controls DE pin for RS485
#define MODBUS_SERIAL_RX_ENABLE PIN_C4   // Controls RE pin for RS485
#define MODBUS_SERIAL_INT_SOURCE MODBUS_INT_RDA
#define MODBUS_TIMER_USED MODBUS_TIMER_T1
#define MODBUS_TIMER_UPDATE MODBUS_TIMER_ISR

#include "modbus.c"

#define MODBUS_ADDRESS 0x01

void main()
{
   
   int16 input_regs[] = {0x3CAA,0x2200,0x3300,0x4400,0x5500,0x6600,0x7700,0x8800};
   TRISD=0X00;
   PORTD=0x00; 
   
   modbus_init();

   while(TRUE)
   {
      while(!modbus_kbhit());
      delay_us(50);
     
      //check address against our address, 0 is broadcast
      if((modbus_rx.address == MODBUS_ADDRESS) || modbus_rx.address == 0)
      {
         IF(modbus_rx.func == FUNC_READ_INPUT_REGISTERS){
               if(modbus_rx.data[0] || modbus_rx.data[2] ||
                  modbus_rx.data[1] >= 8 || modbus_rx.data[3]+modbus_rx.data[1] > 8)
                  modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
               else               
                  {
                     modbus_read_input_registers_rsp(MODBUS_ADDRESS,(modbus_rx.data[3]*2),input_regs+modbus_rx.data[1]);
                  }             
         }
       else    //We don't support the function, so return exception
               modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_FUNCTION);
         
      }
  }
}


Both codes gets compiled successful with same warning messages.

Quote:

WARNINGS!!
Interrupts disabled during call to prevent re-entrancy: (@GETCH_BIU_1)
Interrupts disabled during call to prevent re-entrancy: (modbus_calc_crc)
Interrupts disabled during call to prevent re-entrancy: (modbus_enable_timeout)


After programming the codes to my IC's, the LCD simply displays "EXCEPTION 0C". The circuit connection includes two 120R between MASTER and slave's MAX485. I have rechecked my wiring connections, but the problem still persists. Please give me some suggestions.
_________________
Thanks & Regards,
Heavenlyrider.
temtronic



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

View user's profile Send private message

PostPosted: Thu Mar 17, 2016 8:06 am     Reply with quote

Well for starters using MODBUS for master/4 slaves is way overkill in the serial RS485 world.
NEVER use the 'protect' fuse until you have a final 'market ready' product.
Those warnings are just warnings, they do NOT stop the program from working.
NOW you're using a bigger PIC, so get back to square one, use the RS485 examples....


Jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Mar 17, 2016 10:44 am     Reply with quote

Your 'res_hl' doesn't have any RAM allocated to it. Your for() loop will
overwrite RAM in an undesired address range. Your program will run
erratically or crash. You need to specify the number of bytes for the array.
Quote:
unsigned int8 res_hl[];

for(i=1; i < (modbus_rx.len)-1; ++i) // for our use
{
res_hl[i]=modbus_rx.data[i];
}


Last edited by PCM programmer on Thu Mar 17, 2016 10:45 am; edited 1 time in total
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Thu Mar 17, 2016 10:44 am     Reply with quote

Cables? What is this contraption you all speak off?

I would have ESP8266'ed the hell out of this.
_________________
CCS PCM 5.078 & CCS PCH 5.093
temtronic



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

View user's profile Send private message

PostPosted: Thu Mar 17, 2016 11:51 am     Reply with quote

Well I'm confused....again... OP starts out with 8 pin PICs now with costly 877s and HUGE overhead of MODBUS for what amounts to a very simple 'network'. Whole project could be done with $8 worth of PICs(4*2) and 100 lines of PCM C code and be 'up and running' in 1/2 day.


Jay
heavenlyrider



Joined: 04 Mar 2016
Posts: 7
Location: India

View user's profile Send private message

PostPosted: Fri Mar 18, 2016 5:53 am     Reply with quote

Hi,

Quote:


Your 'res_hl' doesn't have any RAM allocated to it. Your for() loop will
overwrite RAM in an undesired address range. Your program will run
erratically or crash. You need to specify the number of bytes for the array.
Quote:
unsigned int8 res_hl[];

for(i=1; i < (modbus_rx.len)-1; ++i) // for our use
{
res_hl[i]=modbus_rx.data[i];
}



Thanks @PCM programmer its working now. i do have slightly changed those codes and hardwired the whole circuit neatly in a dot matrix board.


@temtronic

Quote:


Well I'm confused....again... OP starts out with 8 pin PICs now with costly 877s and HUGE overhead of MODBUS for what amounts to a very simple 'network'. Whole project could be done with $8 worth of PICs(4*2) and 100 lines of PCM C code and be 'up and running' in 1/2 day.



Actually i have a plan to complete the project with PIC16LF1936. But I just started it with my two PIC16f877A boards. Now my next move is to add 3 more slaves. Thanks for your time and your "PROTECT FUSES" suggestion.
_________________
Thanks & Regards,
Heavenlyrider.
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Fri Mar 18, 2016 6:16 am     Reply with quote

Quote:
Now my next move is to add 3 more slaves.


That's often the time when everything falls apart... If the RS485 hardware is not right, proper bias and terminating resistors, you might get a simple pair (master & slave) to work, but it won't with multiple slaves. Obviously this applies to MODBUS too when using RS485.
temtronic



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

View user's profile Send private message

PostPosted: Fri Mar 18, 2016 6:22 am     Reply with quote

One potential issue you may have is with power supplies. The 877 is a 5 volt only device, the LF1936 a 3 volt only one. Also there are 5V and 3 V sensors, so you better be very,very careful when selecting and wiring the PICs and sensors. Those sensors can't be cheap, hate to see 'magic smoke' come out of one !
I was interested in the sensor but the mfr website REQUIRES me to setup an account, harvest my information BEFORE I can download the PDF of the sensor! NOT happening, went to a vendor of the device, got it from there.

Jay
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 Previous  1, 2
Page 2 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