|
|
View previous topic :: View next topic |
Author |
Message |
musti463
Joined: 19 Sep 2013 Posts: 66
|
RS485 between two PIC problem! |
Posted: Sun Aug 17, 2014 7:27 am |
|
|
Hello i am trying to communicate two pic. Its works on PROTEUS correctly. But this system didn't work in real. What's the problem please help me!
System doing this job:
From Master PIC to Slave PIC;
when d2 high, send 82.34 to Slave
when d3 high send 25.36 to Slave
when d4 high send 12.56 to Slave
Slave PIC is add 10.00 to comming data and show total data on the GLCD. Example: Master 82.34 send, we will see 92.34 on the GLCD. But when i operate the system, GLCD shows 0.00. So when Master's d2,d3,d4 pins anyone be high by me, GLCD shows 10.00
Sorry about my english
MASTER PIC: 16F877A
Code: | #include <16f877.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay (clock=4000000) // Gecikme fonksiyonu için kullanılacak osilatör frekansı belirtiliyor.
#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,enable=pin_c5,stop=1,parity=n)
#include <input.c>
#use fast_io(b)
#use fast_io(d)
#use fast_io(c)
#define use_portb_lcd TRUE
#include <lcd.c> // lcd.c dosyası tanıtılıyor
#define enable pin_c5
//
float a=82.34,b=25.36,c=12.56;
void main ( )
{
setup_psp(PSP_DISABLED); // PSP birimi devre dışı
setup_spi(SPI_SS_DISABLED); // SPI birimi devre dışı
setup_timer_1(T1_DISABLED); // T1 zamanlayıcısı devre dışı
setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
setup_adc_ports(NO_ANALOGS); // ANALOG giriş yok
setup_adc(ADC_OFF); // ADC birimi devre dışı
setup_CCP1(CCP_OFF); // CCP1 birimi devre dışı
setup_CCP2(CCP_OFF); // CCP2 birimi devre dışı
set_tris_b(0x00);
output_b(0x00);
output_d(0x00);
output_high(enable);
delay_ms(50);
lcd_init();
delay_ms(50);
printf(lcd_putc,"\fBilgi: ");
while(1) // Sonsuz döngü
{
if(input(pin_d2))
{
delay_ms(10);
printf(lcd_putc,"\fBilgi:%f ",a);
while(input(pin_d2));
printf("%f",a);
delay_ms(50);
}
if(input(pin_d3))
{
delay_ms(10);
printf(lcd_putc,"\fBilgi:%f ",b);
while(input(pin_d3));
printf("%f",b);
delay_ms(50);
}
if(input(pin_d4))
{
delay_ms(10);
printf(lcd_putc,"\fBilgi:%f ",c);
while(input(pin_d4));
printf("%f",c);
delay_ms(50);
}
}
}
|
SLAVE PIC: 18F4685
Code: | #INCLUDE <18F4685.H>
#USE DELAY (CLOCK=4000000)
#INCLUDE <T6963C.c>
#INCLUDE <stdlib.h>
#USE rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,enable=pin_c5,stop=1,parity=n)
#INCLUDE <input.c>
#USE fast_io(d)
#USE fast_io(c)
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES PUT //Power Up Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOPBADEN //PORTB pins are configured as digital I/O on RESET
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#DEFINE fast_glcd
#DEFINE enable pin_c5
char gelen_bilgi[10],x_str[10];
int sayac;
float x=0;
void main()
{
set_tris_d(0x00);
output_d(0x00);
output_low(enable);
glcd_init(240,128);
glcd_WriteByte(1, (LCDModeSet|LCDMode_XOR)); // Grafik LCD ekran XOR moda göre ayarlanıyor
glcd_WriteByte(1, (LCDDispMode|LCDDisp_TXT|LCDDisp_GRH)); // Grafik LCD ekran hem metin hem grafik modunda çalışacak şekilde ayarlanıyor
delay_ms(50);
sprintf(x_str,"Bilgi: %f",x);//float to string işlemi gerçekleştiriliyor
glcd_text57(60,55,x_str,2,1);//voltaj_str değeri ekrana yazdırılıyor
while (1)
{
for(sayac=0;sayac<5;sayac++)
{
gelen_bilgi[sayac]=getc();
}
x = atof(gelen_bilgi);
x=x+10;
glcd_init(240,128); // Grafik LCD ektran hazırlanıyor
glcd_WriteByte(1, (LCDModeSet|LCDMode_XOR)); // Grafik LCD ekran XOR moda göre ayarlanıyor
glcd_WriteByte(1, (LCDDispMode|LCDDisp_TXT|LCDDisp_GRH)); // Grafik LCD ekran hem metin hem grafik modunda çalışacak şekilde ayarlanıyor
sprintf(x_str,"Bilgi: %f",x);//float to string işlemi gerçekleştiriliyor
glcd_text57(60,55,x_str,2,1);//voltaj_str değeri ekrana yazdırılıyor
}
}
|
CIRCUIT SCHEMATIC:
DURING SIMULATION:
_________________ M.Emir SADE
Last edited by musti463 on Fri Aug 22, 2014 6:40 am; edited 3 times in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19358
|
|
Posted: Sun Aug 17, 2014 8:35 am |
|
|
One screaming problem at the start.
How large is an int?.
Can it hold 9876?......
As further comments though:
1) Have you got a pull-up resistor on the receive inputs to each chip?. This is needed, otherwise when you turn the receive buffers 'off' the line can float 'low' and give random received data. Proteus _won't_ simulate this, but it is a problem on real chips.
2) When using the hardware UART, you should always have 'ERRORS' in the RS232 declaration, unless you are adding your own code to handle errors. Without this the UART can become hung.
3) The bus requires termination at each end, and to be biased when undriven, unless you are using a transceiver that warrants what is seen when this happens. You show termination, but no biasing.
4) Looking at your circuit, it can't work.
You have both chips permanently driving the bus. Your code operates lines to control the transceivers, but on the transceiver, these are directly wired to the power rail, not the PIC.....
You also don't tell the compiler to use the internal oscillator. Proteus will ignore this, but a real chip would not.
I gave up here. |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Sun Aug 17, 2014 2:40 pm |
|
|
IMHO
No. 1 problem; PROTEUS/ISIS.
End of.
Mike |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9168 Location: Greensville,Ontario
|
|
Posted: Mon Aug 18, 2014 6:47 am |
|
|
Mr. T and Mike are right 100%. That 'project' could never ,ever work in the real world. I counted over 27 errors that Proteus didn't care about... If you'd handed that in for me to grade, it'd be an 'F'..failure.
As for your code...
IF you're gong to use RS485 drivers properly(well, what they're for...) you need to add the 'enable=' option to the uses RS232(....) options and obviously rewire the circuit to 'standard' RS485 specs.
Nothing prepares YOU for the real world better than using real PICs and pieces and seeing how they work. |
|
|
musti463
Joined: 19 Sep 2013 Posts: 66
|
|
Posted: Thu Aug 21, 2014 8:41 am |
|
|
I changed something. Please look my codes and circuit now. Why dont work? :( _________________ M.Emir SADE |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9168 Location: Greensville,Ontario
|
|
Posted: Thu Aug 21, 2014 9:30 am |
|
|
obvious errors...
1) RS-485 configuration is totally wrong. You need to download the datasheet for the transceiver and look at the correct biasing and control wiring.
2) you should configure the uses rs232(...options...) to include the ENABLE option for RS485 as well as reconfigure the hardware. Currently though you're trying to use RS485 devices, you aren't allowing the PIC to use them. A MAX232 device would work for you as long as there is only 1 master and one slave.
3) the delay before calling lcd_init(); is too small.Generally a delay of 500ms is 'about right'.This time is dependent on the LCd module used and the spec will be in the datasheet of the LCD module.
there's 3 things to work on
recode/recompile/retest/report back
Jay |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Thu Aug 21, 2014 9:33 am |
|
|
Hi,
Ttelmah already pointed out a glaring problem with your circuit - you are configuring each RS485 Bus tranceiver to drive the bus simultaneously!
Here is what you need to do:
1. On each MAX487 you need to disconnect Pins 2/3 from GND, and instead connect these pins to an I/O pin of the PIC, say 'RC5'. This will allow the PIC to control whether the MA487 is 'listening' to the RS485 bus, or 'talking to' the RS485 bus.
2. You need to add the 'Enable' keyword to the #use 232 directive, and specify the PIC pin you used in #1:
Code: |
#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7, Enable = Pin_c5, errors)
|
John |
|
|
musti463
Joined: 19 Sep 2013 Posts: 66
|
|
Posted: Sat Aug 23, 2014 10:00 am |
|
|
i did it now working correctly thank for all. I wanna ask this. I can send messsage with this code:
Code: | void main() {
char data[10]="123456789";
int *pointer;
pointer=&data[0];
rs485_init(); //Initialize RS485 Communication
while(1)
{
rs485_wait_for_bus(FALSE);
rs485_send_message( 1, 9, pointer );
delay_ms(100);
}
} |
but i cant send message with this code:
Code: | void main() {
int data[10]={1,2,3,4,5,6,7,8,9};
int *pointer;
pointer=&data[0];
rs485_init(); //Initialize RS485 Communication
while(1)
{
rs485_wait_for_bus(FALSE);
rs485_send_message( 1, 9, pointer );
delay_ms(100);
}
} |
Why i cant send? Can you tell me? _________________ M.Emir SADE |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Aug 23, 2014 10:33 am |
|
|
You have noticed a problem occurs when you declare the data a different way.
Strip your program down to almost nothing and make a little test program.
Code: |
#include <18F4520.h>
#fuses INTRC_IO, BROWNOUT, PUT, NOWDT
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)
//========================================
void main()
{
char data[10]="123456789";
int *pointer;
int data2[10]={1,2,3,4,5,6,7,8,9};
int *pointer2;
pointer = &data[0];
pointer2 = &data2[0];
while(1);
} |
Now compile that and look at the .LST file. Look at how the data is being
written to the two arrays. Look at the data. You'll see that it's different.
Then think about the reason why. |
|
|
musti463
Joined: 19 Sep 2013 Posts: 66
|
|
Posted: Sun Aug 24, 2014 6:13 am |
|
|
.LST Files Results
PROTEUS Simulation Results
But still i cant understand why i couldnt sent int datas.
So you can see at the PROTEUS results, there is no values while sending int( only . . . .) Why? _________________ M.Emir SADE |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9168 Location: Greensville,Ontario
|
|
Posted: Sun Aug 24, 2014 7:00 am |
|
|
you ARE sending data ! The right column clearly shows you are sending
SOH, STX, ETX, EOT, ENQ, ACK, BEL, BS, TAB.
These are the ASCII names for the decimal data of 1 through 9.
You seem to misunderstand that an INT '1' is NOT a CHAR '1'. Oddly enough Proteus actually does display 100% correctly that a CHAR '1' is an ASCII 31 which does produce the visible number '1'. An INT '1' is a control code, namely SOH or Start Of Heading.
You should consult an ASCII table. One can be downloaded from www.LookupTables.com or consult almost any 'computer' book.
BTW 'displaying' an INT 7 ( CTRL G ) should ring a 'BELL' on the PC IF the emulation is correct.
hth
jay |
|
|
musti463
Joined: 19 Sep 2013 Posts: 66
|
|
Posted: Sun Aug 24, 2014 7:17 am |
|
|
ok i think we can't send integer datas directly, we have to use chars? Right? _________________ M.Emir SADE |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9168 Location: Greensville,Ontario
|
|
Posted: Sun Aug 24, 2014 7:31 am |
|
|
No... you can send INTeger data directly and you are, as seen in the right column.
You're missing the point that INTEGER data are the 'values' from 0 to 255 NOT ASCII visible 'numbers' like 'one', two, three' etc.
To display NUMBERS like 'one' you need to send the 'value' of 49 decimal or 31 hex.
Again, either download an ASCII table/chart, or Google 'ASCII table'.
hth
jay |
|
|
musti463
Joined: 19 Sep 2013 Posts: 66
|
|
Posted: Sun Aug 24, 2014 10:54 am |
|
|
Why i get this message i cant solve this problem.
When i simulate my code with proteus its working! But when i compile again same code (no changes). My code didnt work on proteus.
I get this messages when compile again:
_________________ M.Emir SADE |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Aug 24, 2014 11:02 am |
|
|
Use a text search program and search the CCS \drivers directory for
RS485_ID. A text search program is essential for finding things.
In rs485.c, you find this code:
Code: | #ifndef RS485_ID
#define RS485_ID 0x10 // The device's RS485 address or ID
#endif |
It says, if RS485_ID is not already defined, then define it now, as 0x10.
So if you want to use your own defined value for RS485_ID, you must
place it above the line for #include <rs485.c>. You placed the
#define statement below the #include, and that's why it gives the error
message. Doing things this way is an essential part of programming
knowledge.
The other error messages says "String Truncated". A string is an array
that has space for the data, and a final 0x00 placed at the end by the
compiler. Your array length is too short. There is no room for the
final 0x00, so you get the error. Again, the fact that a string ends with
a 0x00 (placed by the compiler), is an essential part of programming
knowledge. |
|
|
|
|
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
|