Hi friends,
I am using the pic 16f877a for the RS 485 master slave communication, I want to see the status of the master chip in the slave boards output, I want logic high in one of the slave output, if some thing happend to the master side the slave side output should goes to the logic low, for this purpose which is the correct bit to be monitored from the master side.
in my application when press the master side PORTB,0 the output will be in the master side PORTD,0, the same output will be transmitted tho the slave side PORTD,0. If I off the master board then the master side PORTD,0 is OFF but in the slave side PORTD,0 is still ON.
how to avoide this, when ever the power off in the master I want to reflect in the slave side
how to do this
please advise me
thanks
Saran
Rs 485 communication status
-
- Posts: 61
- Joined: Thu Dec 20, 2007 4:23 pm
- Location: singapore
- Benj
- Matrix Staff
- Posts: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 times
- Contact:
Re: Rs 485 communication status
Hello Saran
I would do the following to get the functionality you require.
Master transmits a byte at a regular interval to state that it is still online. Eg 0.
If the slave device goes for a certain period without receiving this regular byte then it will switch off all of its outputs.
If you require values such as 0 to be sent via the master as data then you could use a array of bytes say 0x55, 0xAA to do the regular update.
I would use the timer interrupts to get this functionality so you get a dependable frequency of transmits and receives.
Hope this helps.
I would do the following to get the functionality you require.
Master transmits a byte at a regular interval to state that it is still online. Eg 0.
If the slave device goes for a certain period without receiving this regular byte then it will switch off all of its outputs.
If you require values such as 0 to be sent via the master as data then you could use a array of bytes say 0x55, 0xAA to do the regular update.
I would use the timer interrupts to get this functionality so you get a dependable frequency of transmits and receives.
Hope this helps.
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
-
- Posts: 61
- Joined: Thu Dec 20, 2007 4:23 pm
- Location: singapore
Re: Rs 485 communication status
Hi BENJ,
I have attached the master slave codes can you guide me where to modify to get the regular update (i am using the Micro C)
please
thanks
MASTER
SLAVE
I have attached the master slave codes can you guide me where to modify to get the regular update (i am using the Micro C)
please
thanks
MASTER
Code: Select all
unsigned int COUNT1, COUNT2, COUNT3, COUNT4, COUNT5, COUNT6, COUNTER_STATUS;
//unsigned int input;
//int test_bit;
//char oldinput;
char Output_Status , Output_Stat;
char dat[10]; // buffer for receving/sending messages
// global flegs and counters
char send = 0;
unsigned int SamplePeriod, timer1_count = 0;
// timer1 settings
const char timer1_prescaler = 3; // timer1 prescaler : real value | timer1_count value
// -----------+-------------------
// 8 | 3
// 4 | 2
// 2 | 1
// 1 | 0
const unsigned int ticks_per_second = 1000; // set timer1 overflow period : 10 -> 100msec
// 100 -> 10msec
// 1000 -> 1msec
// 10000 -> 100us
// 100000 -> 10us
// note : for values under 10 and over 100000
// user must make sure that timer1 supports them
// with settings in config_timer1() function
// and change these settings if neccessery
// communication protocol constants (user defined)
const char COMMAND = 0x0AA;
const char DATA = 0xF0;
const char LCD_WRITE = 0x55;
const char COMMANDD = 0x0AB;
// auxilary variables
unsigned int temp; // sampled value temporary storage variable
unsigned long tmr1_temp; // timer1 reload value storage variable
//-------------- Interrupt routine
void interrupt(){
if( PIR1.RCIF == 1 ) { // if uart interrupt
RS485master_receive(dat); // receive rs485 packets
// // Note : this is uneccessery in this example
// // considering that master does not expact
// // any kind of response from slave
}
else
if( PIR1.TMR1IF == 1 ) { // if timer1 interrupt
timer1_count++; // increment counter
if (timer1_count == SamplePeriod) { // if sample period is reached
timer1_count = 0; // clear counter
send = 1; // set send flag
}
TMR1H = tmr1_temp >> 8; // reload timer1 high
TMR1L = tmr1_temp; // reload timer1 low
PIR1.TMR1IF = 0; //clear timer1 interrupt flag
}
}//~
void Configure_timer1(char SamplePeriodMs){
SamplePeriod = SamplePeriodMs; // set sample period
T1CON = 0;
T1CON.TMR1CS = 0; // internal clock (Fosc/4)
T1CON |= timer1_prescaler << 4; // set timer1 prescaler
tmr1_temp = (Get_Fosc_kHz()*1000)/(4*(1 << timer1_prescaler)*ticks_per_second);
tmr1_temp = 65535 - tmr1_temp; // calc timer1 reload value (period = 1msec)
TMR1H = tmr1_temp >> 8; // load timer1 high
TMR1L = tmr1_temp; // load timer1 low
T1CON.TMR1ON = 1; // enable timer1
}
void configure_interrupts(){
PIE1.RCIE = 1; // enable uart receive interrupts
PIE1.TMR1IE= 1; // enable timer1 interrupt
INTCON.PEIE = 1; // enable periferal interrupts
INTCON.GIE = 1; // global interrupt enable
}
void main(){
ADCON1 |= 0x06; // set all pins as digita I/O
CMCON |= 0x07; // disable comparators
PORTD = 0;
TRISD = 0x00; // set PORTD as output
USART_init(19200); // initialize usart module
Delay_ms(1000);
Rs485master_Init(&PORTC, 2); // intialize mcu as master
Configure_timer1(1); // configure timer1 & set sample period in msec
Configure_interrupts(); // enable interrupts
STATUS = 0X03;
PORTA = 0X05;
PORTB = 0X06;
OUTPUT_STATUS = 0X21;
COUNT1 = 0X22;
COUNT2 = 0X23;
//COUNTER_STATUS = 0X24;
COUNT3 = 0X25;
COUNT4 = 0X26;
COUNT5 = 0X27;
//COUNT6 = 0X28;
//test_bit = 0X29;
Output_Stat = 0X30;
PORTA = 0x0;
TRISA = 0X00;
PORTB = 0X0;
TRISB = 0XFF;
PORTC = 0;
TRISC = 0x33; //30
PORTD = 0;
TRISD = 0;
PORTE = 0;
TRISE = 0;
Output_Status = 0;
Output_Stat = 0;
// input = PORTA;
// oldinput = input;
while (1) // endless loop
{
}
if (send == 1) { // if send fleg is set
dat[0] = COMMAND; // =
//dat[1] = LCD_WRITE; // |
dat[2] = PORTD; // | fill rs485 packet with appropriate values
dat[5] = 0; // |
dat[6] = 0; // =
Rs485master_Send(dat,3,160); // send packet
send = 0;
} //clear send flag
Delay_ms(30); //THIS TIMING TO ADJUST THE BUTTON SCANNING
if (send == 1) { // if send fleg is set
dat[0] = COMMANDD; // =
//dat[1] = LCD_WRITE; // |
dat[2] = PORTE; // | fill rs485 packet with appropriate values
dat[5] = 0; // |
dat[6] = 0; // =
Rs485master_Send(dat,3,160); // send packet
send = 0;
} //clear send flag
Delay_ms(30); //THIS TIMING TO ADJUST THE BUTTON SCANNING
if (send == 1) { // if send fleg is set
dat[0] = LCD_WRITE; // =
//dat[1] = LCD_WRITE; // |
dat[2] = PORTA; // | fill rs485 packet with appropriate values
dat[5] = 0; // |
dat[6] = 0; // =
Rs485master_Send(dat,3,160); // send packet
send = 0;
} //clear send flag
Delay_ms(30); //THIS TIMING TO ADJUST THE BUTTON SCANNING
asm {
goto Start
}
}
}//~!
SLAVE
Code: Select all
char dat[10]; // buffer for receving/sending messages
// communication protocol constants (user defined)
const char COMMAND = 0xAA;
const char DATA = 0xF0;
const char LCD_WRITE = 0x55; //initial 0x55
const char COMMANDD = 0xAB;
// auxilary variables
char txt[8]; // string for holding formated data for lcd display
//-------------- Interrupt routine
void interrupt(){
Rs485slave_Receive(dat); // received rs485 packet
}//~
void main() {
unsigned long temp;
ADCON1 |= 0xFF; // configure all pins as digital I/O
CMCON |= 0x07; // disable comparators
PORTD = 0;
TRISD = 0; // configure PORTD as output
PORTA = 0;
TRISA = 0; // configure PORTD as output
PORTB = 0;
TRISB = 0; // configure PORTB as output
PORTE = 0;
TRISE = 0;
USART_init(19200); // initialize usart module
Rs485slave_Init(&PORTC, 2, 160); // intialize mcu as slave, address 160
dat[4] = 0; //esure message reveived flag is zero
dat[5] = 0; // ensure that message received flag is 0
dat[6] = 0; // ensure that error flag is 0
PIE1.RCIE = 1; // enable interrupts
INTCON.PEIE = 1; // on byte received
PIE2.TXIE = 0; // via USART (RS485)
INTCON.GIE = 1; // global interrupt enable
while (1) { // endless loop
if (dat[4]) { // upon completed valid message receive
dat[4] = 0; // data[4] is set to 0xFF
if( dat[0] == COMMAND ) // if command is received
{
temp = dat[2] << 8; // load high byte of received data
temp |= dat[1]; // load low byte of received data
PORTD = (temp * 4) / 1024; // scale 10bit adc result to fit 8bit port
}
if( dat[0] == LCD_WRITE ) {
temp = dat[2] << 8; // load high byte of received data
temp |= dat[1]; // load low byte of received data
PORTA = (temp * 4) / 1024; // scale 10bit adc result to fit 8bit port
}
//if (dat[5]) { // if an error detected, signal it by
// PORTE = 0x01;
// } // setting portd to 0xAA
if( dat[0] == COMMANDD ) {
temp = dat[2] << 8; // load high byte of received data
temp |= dat[1]; // load low byte of received data
PORTE = (temp * 4) / 1024; // scale 10bit adc result to fit 8bit port
}
// Delay_ms(10);
}
}
}//~!
saran
-
- Posts: 61
- Joined: Thu Dec 20, 2007 4:23 pm
- Location: singapore
Re: Rs 485 communication status
hI Benj,
as you mention up i send a sequence of bits from master to slave for the regular update, when there is the communication breakdown in between the master and slave, the slave hollding the latest value from the master when the communication was good because after the breakdown the master cannot send the current value.
for example I am sending continious '1' from master to slave and the slave display the received bit in portE,0. when there is the breakdown the master cannot send the '1' to the slave but the slave still holding the previous value '1' even after the breakdown, it is not updated to the '0'.
i feel eventhough the master want to send the data because of the breakdown the data cannot be send to the slave
any way to solve it.
thanks
Saran
as you mention up i send a sequence of bits from master to slave for the regular update, when there is the communication breakdown in between the master and slave, the slave hollding the latest value from the master when the communication was good because after the breakdown the master cannot send the current value.
for example I am sending continious '1' from master to slave and the slave display the received bit in portE,0. when there is the breakdown the master cannot send the '1' to the slave but the slave still holding the previous value '1' even after the breakdown, it is not updated to the '0'.
i feel eventhough the master want to send the data because of the breakdown the data cannot be send to the slave
any way to solve it.
thanks
Saran
saran
- Benj
- Matrix Staff
- Posts: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 times
- Contact:
Re: Rs 485 communication status
Hello Saran
The UART will lock up if the buffer gets full. Performing a receive should remove the block and allow the UART to function again.
Here are things to look out for.
1) Is there any data going to the Master, Maybe you could do a dummy RS232 read somewhere through your program loop to avoid the incoming buffer becoming saturated.
2) Is the receive buffer becoming full. Eg if the receive buffer has 3 bytes and a 4th byte is sent then the module will go into its error mode. Performing a receive will clear the error but the receiver will still have 3 bytes in its buffer. Therefore maybe have a macro to clear out the buffer every so often. Alternatively transmit bytes less often to the slave.
The UART will lock up if the buffer gets full. Performing a receive should remove the block and allow the UART to function again.
Here are things to look out for.
1) Is there any data going to the Master, Maybe you could do a dummy RS232 read somewhere through your program loop to avoid the incoming buffer becoming saturated.
2) Is the receive buffer becoming full. Eg if the receive buffer has 3 bytes and a 4th byte is sent then the module will go into its error mode. Performing a receive will clear the error but the receiver will still have 3 bytes in its buffer. Therefore maybe have a macro to clear out the buffer every so often. Alternatively transmit bytes less often to the slave.
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel