|
|
View previous topic :: View next topic |
Author |
Message |
Ttelmah
Joined: 11 Mar 2010 Posts: 19609
|
|
Posted: Mon Mar 07, 2016 7:52 am |
|
|
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
|
|
Posted: Mon Mar 07, 2016 9:16 am |
|
|
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
|
|
Posted: Mon Mar 07, 2016 9:20 am |
|
|
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
|
|
Posted: Thu Mar 17, 2016 7:05 am |
|
|
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
|
|
Posted: Thu Mar 17, 2016 8:06 am |
|
|
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
|
|
Posted: Thu Mar 17, 2016 10:44 am |
|
|
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
|
|
Posted: Thu Mar 17, 2016 10:44 am |
|
|
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
|
|
Posted: Thu Mar 17, 2016 11:51 am |
|
|
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
|
|
Posted: Fri Mar 18, 2016 5:53 am |
|
|
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
|
|
Posted: Fri Mar 18, 2016 6:16 am |
|
|
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
|
|
Posted: Fri Mar 18, 2016 6:22 am |
|
|
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 |
|
|
|
|
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
|