Ynt: Pic to Pic Rs485 - 1 Master 2 slave

Başlatan WorldWideWeb, 06 Şubat 2014, 08:37:44

WorldWideWeb

Merhaba, Öncelikle bu projeye neden ihtiyacım olduğunu ve ne kadar PİC programlama bildiğimi anlatayım.
Projeyi Dmx512 veyahutta HMİ ve PLC kullanarak; evimin her yerine(yalnz yaşıyorum(bütün odalara)) ışıklar döşemek için kullanıcağım. Elimde neredeyse 7000'i geçik led var ve bir o kadarda yapılmış projeler var komürlükte(en az 1000 led) Bunların boşa gitmemesi, en azından bir işe yaraması için değerlendirmek istiyorum. Birde Elimde ışık masası var(arızalı) eğer tamir edebilirsem bu ışıkmasasınıda duvarın içine monte etme düşüncesindeyim. eeee yalnızlık zor..

Pic programlamada, Bu günüde sayarsak; 5'inci günümdeyim. Kodlara bakmadan; dc motor, pwm, lcd, glcd, display, rs232(pictopic ve pictopc) gibi basit projeleri rahatlıkla yazabiliyorum. Ben seçimimi yaparken Pic programlamayı eleyip, PLC'ye ağırlık verdim. dmx masasının ve elimdeki plcilerin baud değeri tutarda bu projeyi rahatlıkla yapabileceğime inaniyorum fakat PLC ile pic'in arasında fark var. Kendimi sınırlamak istemiyorum.

3 günden beri(bü gun dahil) rs485'e kafa patlatıyorum ve anlatılanlarda basit olduğunu gördüğüm gibi bir o kadarda uyuz bir şey olduğunu anladım. Ne kadar uğrassam(sabahlara kadar), bir türlü istediğim verimi alamadım. Sizlerin yardımıyla bunu başarıcağıma inaniyorum. Toplamda 2 gün boyunca kodların bir kısmını öğrendim. 3 gün boyuncada rs485'i çözmeye çalıştım.

Şuanlık rs485'ten Bilgisyara(PC) veri gönderebiliyorum, fakat bilgisayardan veriyi pic'e gönderemiyorum. Veyahutta picten pic'e veri gönderemiyorum. Bunların hepsini rs232'i ile yapabiliyorum. fakat evin, duvarlarının içinden kablo geçeceği için ve bütün evi saracağı için çok fazla kablo olacak ve iletişimin yetersiz kalacağını tahmin ediyorum. Rs485'i kullanmak zorunda olduğum için üzücü bir durum benim için.

İnternette gerçektende, acemilerin anlayacağı türden bir bilgi yok diyebilirim. Tam olarak program yapısını idrak edemediğimiz için, verilen kesik kesik bilgileri toparlayamıyoruz. Aslında internette var ama tecrübeli biri için var. Bizlere yol gösteren olduğu sürece bizlerinde bu projeyi yapabileceğine inaniyorum.

Kodlarımı, açıklamalı yaptım, Bu açıklamalarda yanlışlık varsa, beni uyarırsanız sevinirim. Hemde benden daha bilgili ama açıklama arayan arkadaşlara, fikir olabilmesi için böyle açıklama yapma gereği duydum.

verici(master)
#include <16f877a.h>
#fuses XT,NOBROWNOUT,NOPUT,NODEBUG,NOWDT,NOWRT,NOPROTECT,NOCPD,NOLvP
#use delay(clock=4000000)
#use fast_io(a)
#use fast_io(b)
#use rs232(baud=9600,xmit=pin_c7,rcv=pin_c7,enable=pin_c5,bits=9)
#define use_portb_lcd TRUE
#include <rs485.c>
#include <lcd.c>
#define TX PIN_C6   // Data gonderme pini
#define RX PIN_C7   // data alma pini
#define ENABLE PIN_C5   // Control Pini  RX low, TX high. Olursa Data gonderır, TX low, RX high, Control pinide low olursa daha alır
#define RS485_ID  0x10 
// Programın ana ayarları //
void main()
{
//GONDERME AYARI//
output_high(TX); // TX PİNİ HİGH OLARAK AYARLANDI
output_low(RX); // RX PİNİ LOW OLARAK AYARLANDI
output_high(ENABLE); // ENABLE PİNİ HİGH OLARAK AYARLANDI
// KULLANICAĞIM PORTLARIN, GİRİŞ ÇIKIŞ AYARI//
set_tris_a(0xFF);  // bütün pinler giriş yapıldı 1111 1111
set_tris_b(0x00);  // bütün pinler çıkış yapıldı 0000 0000
//rs485 ve lcd start ayarı//
rs485_init(); // rs485 protokolünü çalıştır
delay_ms(10);
lcd_init(); // lcd'yi çalıştır
printf(lcd_putc,"RS485-VERICI");
delay_ms(1000);
//yapılacak işlemler//
while(1) //sonsuza kadar devam et
{
if(input(pin_a0)) // buton 0 a basılırsa
{
printf(lcd_putc,"\fLED YAKMA KOMUTU\NGONDERILDI");
delay_ms(50);
putc('X'); //Kanal bilgisi yollandı
delay_us(50);
putc('Y');// yakma kodu yollandı
}
if(input(pin_a1)) // buton 1 e basılırsa
{
putc('X'); // kanal bilgisi yollandı
delay_us(50);
putc('S'); // sondurme kodu yollandı
printf(lcd_putc,"\fLED SONDURME KOMUTU\NGONDERILDI");
delay_ms(50);
}
}
}



Alıcı codu(slave)

#include <16f877a.h>
#fuses XT,NOBROWNOUT,NOPUT,NODEBUG,NOWDT,NOWRT,NOPROTECT,NOCPD,NOLvP
#use delay(clock=4000000)
#use fast_io(b)
#use fast_io(d)
#use rs232(baud=9600,xmit=pin_c7,rcv=pin_c7,enable=pin_c5,bits=9)
#define use_portd_lcd TRUE
#include <rs485.c>
#include <lcd.c>
#define led PIN_B0
#define TX PIN_C6   // Data gonderme pini
#define RX PIN_C7   // data alma pini
#define ENABLE PIN_C5   // Control Pini  RX low, TX high. Olursa Data gonderır, TX low, RX high, Control pinide low olursa daha alır
#define RS485_ID  0x11 
char veri;
void main()
{
// rs485 data almaya ayarlandı//
output_high(RX);
output_low(ENABLE);
output_low(TX);
//giris-çıkış komutları//
set_tris_b(0x00);
set_tris_d(0x00);
output_b(0x00);
//rs485 ve lcd calıstırma komutları verildi//
rs485_init(); // rs485 calıstırıldı
delay_ms(50);
lcd_init(); // lcd calıstırıldı
printf(lcd_putc,"rs485-ALICI");
delay_ms(1000);
while(1)
{
if(getch()=='X')
{
veri=getch();
delay_ms(10);
}
if(veri=='Y')
{
output_high(led);
delay_ms(20);
printf(lcd_putc,"\fYak Verisi alındı\n   LED YANDI!!");
}
if(veri=='S')
{
output_low(led);
delay_ms(20);
printf(lcd_putc,"Son Verisi alındı\n   LED SONDU!!");
}
}
}
//  output_high(RS485_ENABLE_PIN);    //veri aktarımı var
// output_high(RS485_TX_PIN);   //'pic452 den max485'e veri gönderme izni iptal
// output_low(RS485_RX_PIN);    //'com dan max485'e veri gönderme izni verildi




mesaj birleştirme:: 06 Şubat 2014, 22:43:13


Buda benim fakir hane(çalışma odam)

Kutucukları daha önce gördüğünüzü umuyorum :)



mesaj birleştirme:: 06 Şubat 2014, 22:45:06

Birde unutmadan: Bu  kodların aynısı, rs485 çıkış pinleri olmadan, rs232'de başarılı ve sorunsuz bir biçimde çalışıyor.

memo333

öncelikle rs485 için direction pinini nerde ayarladığınızı göremedim. putch/getch komutlarının içinde ayarlıyor mu?
Gömülü Linux Notları --> http://linuxedu.xyz/

WorldWideWeb

Alıntı yapılan: memo333 - 06 Şubat 2014, 09:59:59
öncelikle rs485 için direction pinini nerde ayarladığınızı göremedim. putch/getch komutlarının içinde ayarlıyor mu?

Öncelikle yorumun için teşekkür ederim. Benim projemde Master sadece göndericek, Slave'de sadece alacak. Eğer gönderdiğim kanal bilgisi doğruysa slave diğer veriyi alıp işleyecek yani ayarladığım, gönderme ve alma ayarları şu şekilde,

//GONDERME AYARI//
output_high(TX); // TX PİNİ HİGH OLARAK AYARLANDI
output_low(RX); // RX PİNİ LOW OLARAK AYARLANDI
output_high(ENABLE); // ENABLE PİNİ HİGH OLARAK AYARLANDI


// rs485 data almaya ayarlandı//
output_high(RX);
output_high(ENABLE);
output_low(TX);


Slave'nin Enable(yön pini) Low fakat ben, veriyi almayınca böyle değiştirdim.

xoom

#use rs232(baud=9600,xmit=pin_c7,rcv=pin_c7,enable=pin_c5,bits=9)

Yukarıdaki satırda TX ve RX c7 pini olarak ayarlamışsınız burası yanlış.
birde isis şeması ekleseydiniz daha iyi olurdu. TX ve RX tanımlamalarınız nereleri?. max487 mi kullanıyorsunuz?
rs485 için kullanılan entegrelerin çoğunlukla
RO = Bu pin bir OUT pinidir. İşlemcinin RX bacağına bağlanır.
DI = Bu pin bir Input pinidir. İşlemcinin TX bacağına bağlanır.
RE/DE = Bu iki ucu birleştiriyorsun. Sonra bunu bir işlemci pinine bağlıyorsun.
RE/DE pinini bilgi göndermek için 1 (high) çekiyorsun
RE/DE pinini bilgi almak için 0 (low) çekiyorsun tabi bu low veya high çektikten sonra küçük bir bekleme yapmak gerekiyor.

WorldWideWeb

#4
Alıntı yapılan: xoom - 06 Şubat 2014, 21:18:15
#use rs232(baud=9600,xmit=pin_c7,rcv=pin_c7,enable=pin_c5,bits=9)

Yukarıdaki satırda TX ve RX c7 pini olarak ayarlamışsınız burası yanlış.
birde isis şeması ekleseydiniz daha iyi olurdu. TX ve RX tanımlamalarınız nereleri?. max487 mi kullanıyorsunuz?
rs485 için kullanılan entegrelerin çoğunlukla
RO = Bu pin bir OUT pinidir. İşlemcinin RX bacağına bağlanır.
DI = Bu pin bir Input pinidir. İşlemcinin TX bacağına bağlanır.
RE/DE = Bu iki ucu birleştiriyorsun. Sonra bunu bir işlemci pinine bağlıyorsun.
RE/DE pinini bilgi göndermek için 1 (high) çekiyorsun
RE/DE pinini bilgi almak için 0 (low) çekiyorsun tabi bu low veya high çektikten sonra küçük bir bekleme yapmak gerekiyor.

Bu bilgilere dikkat etmiştim, isistende hiç şüphe etmesem de içime kurt düştü, hemen sanal makineyi(virtual-terminal) koydum. Bir hata gördüm fakat o da programsal bir hata sanırsam. Slave(alici)'yi alma moduna almışken, nasıl olurda sanal makineye ve master picine kod gönderebilir.

bahsettiğiniz baud,xmit,rcv ayarları düzeltildi.


Alıcı moduna almak için tx,rx ve enable pinlerini. Low-high olarak gösterebilir misiniz?
örnek;
TX=low
RX=high
ENABLE=low
gibi


rx-tx-enable pinlerim define'da atandı
#define TX PIN_C6   // Data gonderme pini
#define RX PIN_C7   // data alma pini
#define ENABLE PIN_C5   // Control Pini  RX low, TX high. Olursa Data gonderır, TX low, RX high, Control pinide low olursa daha alır
#define RS485_ID  0x11 


Not; isiste RX Ayakları "SARI" yanıyor





------------------------------------------------------------------------------------------------------------------------------------------------------------

yazılan programda ufak tefek değişiklikler uyguladım. Şuanda master ve slave ayarını yapabiliyorum. 2 pici ilk olarak master yapıp, veri göndermelerini istedim ve düzgün bir şekilde yaptılar. 1 pici master 1 pici slave olarak ayarladım fakat slave'e kod gittiğinde slave işlemini yapmıyor.

Sonrasında alma ve gönderme kodlarımda sorun olduğunu düşünüp, yazdığım master-slave programını rs232'ye uygun hale getirip denediğimde. güzel ve sorunsuz çalıştığını gördüm. Sonrasında tekrardan rs485'e uyarlayıp denediğimde, Slave kodu alıyor fakat işleme dökmediğini anladım.



Umarım açıklayıcı olmuşumdur. Slave'e kod gittiğinden eminim fakat slave o kodları işlemiyor. rs232'de işliyor.


Slave kodları;

#include <16f877a.h>
#fuses XT,NOBROWNOUT,NOPUT,NODEBUG,NOWDT,NOWRT,NOPROTECT,NOCPD,NOLVP
#use delay(clock=4000000)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,bits=9)
#define use_portd_lcd TRUE
#include <rs485.c>
#include <lcd.c>
#define led PIN_B0
#define TX PIN_C6   // Data gonderme pini
#define RX PIN_C7   // data alma pini
#define ENABLE PIN_C5   // Control Pini  RX low, TX high. Olursa Data gonderır, TX low, RX high, Control pinide low olursa daha alır
#define RS485_ID  0x11 
int veri;
void main()
{
// rs485 data almaya ayarlandı//
//giris-çıkış komutları//
set_tris_b(0x00);
set_tris_d(0x00);
set_tris_c(0x00);
output_b(0x00);
output_low(RX);
output_low(TX);
output_low(ENABLE);
delay_ms(75);
//rs485 ve lcd calıstırma komutları verildi//
rs485_init(); // rs485 calıstırıldı
delay_ms(50);
lcd_init(); // lcd calıstırıldı
printf(lcd_putc,"rs485-ALICI");
delay_ms(1000);
while(1)
{
if(getch()=='X')
{
veri=getch();
delay_ms(10);
}
if(veri=='Y')
{
output_high(led);
delay_ms(20);
printf(lcd_putc,"\fYak Verisi alındı\n   LED YANDI!!");
}
if(veri=='S')
{
output_low(led);
delay_ms(20);
printf(lcd_putc,"Son Verisi alındı\n   LED SONDU!!");
}
}
}
//  output_high(RS485_ENABLE_PIN);    //veri aktarımı var
// output_high(RS485_TX_PIN);   //'pic452 den max485'e veri gönderme izni iptal
// output_low(RS485_RX_PIN);    //'com dan max485'e veri gönderme izni verildi