Merhaba
arkadaşlar güvenlik sistemlerinde kullanılan kameralardaki PELCO-D protokolü ile uğraşan oldumu bunu pic ile nasıl çözebilirim.
burada sanırım C# için örnek verilmiş
http://www.codeproject.com/KB/cs/PelcoPDinC.aspx
Speeddome kameraları kontrol etmek için bir çok protokol mevcut.
pelco-d, pelco-p 'de speeddome kameraları kontrol etmek için kullanılan bir protokoldür, rs-485 üzerinden haberleşir.
protokol hakkında ayrıntılı bilgi almak isteyen arkadaşlar
daha sade ve anlaşılır olan aşağıdaki linki inceleyebilirler.
http://www.commfront.com/RS232_Examples/CCTV/Pelco_D_Pelco_P_Examples_Tutorial.HTM#1
Arkadaşlar merhaba.
RS485 üzerinden PelcoD protokolü ile haberleşen bir PAN-TILT güvenlik kamerası var. Bu kamerayı RS485 üzerinden kontrol etmek istiyorum birşey aklıma takıldı.
Kameranın PelcoD protokolüne göre standart komut yapısı bu şekilde
(http://imagizer.imageshack.us/v2/800x600q90/910/p1ARoL.jpg)
Burada Synch Byte olarak sürekli FF gönderiliyor. Sonrasında adres komut ve data şeklinde sıralanıyor. En sondaki 7. Byte'da ise CheckSum byte'ı yollanıyor. Bunu anlayamadım. Checksum Hesaplaması yapmam gerekiyor. Bunun hesabı nasıldır?
Önceki baytlarin toplamı olabilir. Sync byte hariç .
Yukarıdaki linkte bahsedilmis. Sadece toplama değil başka yöntemler de varmış.
Elinizde gerçek bir data varsa hangisi uyuyorsa onu kullanabilirsiniz
o sayfada bahsedilen Checksum Calculator programı ile deneme yapılır.
sync hariç hepsinin toplamı mod 256,
yani 8 bitlik eldesiz toplama yapman yeterli.
http://www.commfront.com/RS232_Examples/CCTV/Pelco_D_Pelco_P_Examples_Tutorial.HTM#2 (http://www.commfront.com/RS232_Examples/CCTV/Pelco_D_Pelco_P_Examples_Tutorial.HTM#2)
Bendeki pelcod protokolünün anlatıldığı pdf de checksum hesabina değinilmemiş. Ben bulamadım en azından. Şimdi meseleyi anladım. T2 nin dediği gibi sync hariç gönderilen tüm değerler and işlemine tabi tutulup checksum verisi elde ediliyor.
Selamlar. STM32 ile bir tane speeddome kamerayı RS485 üzerinden kontrol etmeye çalışıyorum. Kameranın video çıkışına ufak bir video monitör bağladım. Kamera çalışıyor. Baudrate Adress gibi parametreleri görebiliyorum. Kamera ile STM32 arasındaki bağlantıları yaptım. Kamera 2400 Baudrateye ayarlı olduğu için bende STM32 de usart ayarlarını 2400 baudrate olarak ayarladım.
Kameraya PelcoD protokolüne göre veri gönderiyorum. Kamera buna Video çıkışına bağladığım monitör üzerinden yazılı olarak tepki veriyor.
Kameraya hang komutu gönderirsem göndereyim farketmiyor. Veri gönderdiğim zaman Monitörde PROTOCOL AND BAUD IS DETECTING... Yazıyor. Veri göndermeyi kesince,
SELF BAUD 2400
CONTROL BAUD UNKNOW
Yazıyor. Yani baudrate farklı gibi birşey demek istiyor. Ama Ben STM32'nin Usart TX çıkışına Logic analyser bağlayıp 2400 baudratede veri gittiğini doğrulayabiliyorum. Hatta Gelen verileri analiz edip gönderdiğim dataların doğru bir şekilde STM32'den çıktığını görebiliyorum.
Acaba Senkronizasyon felanmı tutmuyor. PelcoD için Sync Byte 0xFF verilmiş. Buda karşıya gidiyor. Başka ne olabilirki?
Fikri olan varmı? Acaba protokol dışında yanlış birşeylermi yapıyorum?
Eğer cihazı PC'ye bağlayabiliyorsan ve PC yazılımı var ise iletişimi izleyip analiz edebilirsin.
Elimde oyle bir yazılım yok ama araştırayım. Arkadaşımda bunları kontrol edebilen bir joystick vardı. Onu alıp çıkışını logic analyzer ile takip edersem gelen data paketlerini çözebilirim diye düşünüyorum.
http://www.serialporttool.com/sptblog/?tag=usb (http://www.serialporttool.com/sptblog/?tag=usb)
İyi Bayramlar.
Dün tekrardan kameranın kartına baktım. Donanımda problem var sanırım. Kamera bana geldiğinde RS485 hattı yanmıştı. Kart üzerinde RS485 hattının A ve B uclarına seri iki adet 100R direnç ve SP485 isimli RS485 transreciever entegresi yanmıştı. Ben yanan malzemeleri değiştirdim. Ama RS485 çevirici düzgün çalışmıyor anladığım kadarıyla. Çıkışında datalar bozuluyor. İlk 2-3 byte düzgün gidiyor ama sonrasında bozuyor. Bunu RS485 çipinin data çıkışı ile Benim mikroişlemcimin TX pinin aynı anda Logic analyser'a bağlayarak görüyorum. Acaba RS485 transreciever çipi mi arızalı?
Bu çipleri test etmek atla deve değil. Scopun yokmu?
Öncelikle tüm foruma iyi bayramlar.
Bu transceiver testi konusu digital elektroniğe bile girmez onun öncesi olan bildiğimiz dijital logic'in konusu sayılır. (Three-state buffer gibi). O zamanlar çok dersten kaçtın galiba.
(https://arduino-info.wikispaces.com/file/view/max485Pin-256.jpg/329202540/max485Pin-256.jpg)
Şekildeki transceiver'ın RE'sini logic low yap, DE'sini logic high yap, DI'den datanı gir , RO'dan izle, doğru geliyorsa transceiver çalışıyordur.
Karşılıklı (karşı devre) test etmek istiyorsan karşıyıda aynı şekilde logic kontrollerle , bozuk mu, sağlam mı veya bozuksa hangisi bozuk anlayabilirsin.
Skop Logic analyser felan var hocam. Çipler SMD tipte karta lehimli. Gönderici taraf Benim deney kartım. Üzerinde RS485 çipi var. Ama şimdiye kadar hiç kullanmamıştım. Bozuk olacağını sanmıyorum. Alıcı tarafın 485 çipini ise bir kere değiştim. Değişmeden önce çok kötü bir şekilde yanmıştı.
Ben en iyisi kameranın anakartı üzerindeki RS485 çipini çipi yerinden söküp doğrudan MCU'lar arasında TX-RX yapayım. Dün akşam bir anlık kamera hareket eder gibi oldu. Büyük ihtimal taktığım çipte arızalı. Sonrasında Tekrar çipi yerine takıp duruma bakarım.
Evet arkadaşlar Yine Saçma sapan bir sorunla karşı karşıyayım.
Sorunu çözdüm aslında kamerayı yönlendirebiliyorum. Donanımda problem yokmuş. Sorun Gönderici tarafında Transreciever entegresinin DIR pininde. STM32 ile ilgili başka bir problem var. Şöyle anlatayım.
RS485 üzerinden PelcoD protokolünde veri gönderirken SyncByte>>Adress>>Comman0>>Command1>>Data0>>Data1>>CheckSum olmak üzere 7 byte'dan oluşan paket göndermek gerekiyor.
Ben uarttan yukarıda yazdığım sıralamada SyncByte'ı göndermeden önce RS485_DIR pinini Lojik 1 yapıyorum. CheckSum'un tamamı gittikten sonrada Lojik sıfır yapıyorum. Bu iş için aşağıdaki kodları kullandım.
GPIO_SetBits(GPIOB,GPIO_Pin_2); //Enable DIR
RS485_SendByte(PelcoD_Command->SyncByte); //Write SyncByte
RS485_SendByte(PelcoD_Command->Adress); //Write Adress
RS485_SendByte(PelcoD_Command->Command1); //Write Command1
RS485_SendByte(PelcoD_Command->Command2); //Write Command2
RS485_SendByte(PelcoD_Command->Data1); //Write Data1
RS485_SendByte(PelcoD_Command->Data2); //Write Data2
RS485_SendByte(CheckSum); //Write CheckSum
GPIO_ResetBits(GPIOB,GPIO_Pin_2); //Disable DIR
RS485_SendByte Fonksiyonumda aşağıdaki gibi.
void RS485_SendByte(u16 Data)
{
USART3->DR = (Data & (uint16_t)0x00FF);
while (!USART_GetFlagStatus(USART3,USART_FLAG_TXE)){}
}
Lojik analyserdan herşeyi izliyorum. Benim üzerinde çalıştığım mcu nun tx pini ile Kamera üzerinde bulunan işlemcinin(oda stm32f103) RX pinini lojik analyser'a bağladım. Aynı zamanda benim veri gönderdiğim taraftaki RS485_DIR Pinini de lojik analyser'a bağladım.
Sonuç aşağıdaki gibi.
(http://s15.postimg.cc/fuaxe1sjf/Ekran_Al_nt_s.jpg)
gönderilen verilerde sıkıntı yok. SyncByte>>Adress>>Comman0>>Command1>>Data0>>Data1>>CheckSum sırasında göre 7 byte data gidiyor. fakat Karşı tarafa CheckSum gitmeden RS485_DIR Pini 0 yapılıyor. Bu yüzden CheckSum karşıya gidemiyor. Giden veri anlaşılmıyor. Yani 1 byte önceden DIR Pini 0 yapılıyor. Bu her zaman böyle.
Bende CheckSumdan sonra DIR Pinin 0 yapmadan hemen önce 0xFF gönderdim.
GPIO_SetBits(GPIOB,GPIO_Pin_2);
RS485_SendByte(PelcoD_Command->SyncByte); //Write SyncByte
RS485_SendByte(PelcoD_Command->Adress); //Write Adress
RS485_SendByte(PelcoD_Command->Command1); //Write Command1
RS485_SendByte(PelcoD_Command->Command2); //Write Command2
RS485_SendByte(PelcoD_Command->Data1); //Write Data1
RS485_SendByte(PelcoD_Command->Data2); //Write Data2
RS485_SendByte(CheckSum); //Write CheckSum
RS485_SendByte(0xFF); //gereksiz veri.
GPIO_ResetBits(GPIOB,GPIO_Pin_2);
Toplamda 8 byte data gitmiş oldu ama dir pini en sonki datayı gönderirken 0 olduğu için en son göndermiş olduğum 0xFF karşıya gitmedi dolayısıyla protokole uyumlu bir paket göndermiş oldum. Kamera böyle çalışıyor.
Dediğim durum aşağıdaki gibi.
(http://s18.postimg.cc/dwl682rnd/Ekran_Al_nt_s_2.jpg)
Durumu daha iyi anlamak için debug yapıyorum. Paketleri teker teker gönderiyorum. Ve her göndermeden sonra lojik analyser ile RX TX ve DIR pinine bakıyorum. Debug yapınca sıkıntı yok gibi görünüyor. Bütün paket gidiyor en sonda DIR 0 yapılıyor.
Duruma anlam veremedim gerçekten Debugda düzgün çalışıp normalde düzgün çalışmamasını nasıl yorumlayabiliriz. Sankide RS485_SendByte(CheckSum); komutu ile GPIO_ResetBits(GPIOB,GPIO_Pin_2); komutu normal çalışmada yer değiştiriyor!
Varmı yorumlayabilecek olan. Kamerayı çalıştırdım. STM32 niye böyle davranıyor?
hocam durum cok basit.
GPIO_SetBits(GPIOB,GPIO_Pin_2); //Enable DIR
RS485_SendByte(PelcoD_Command->SyncByte); //Write SyncByte
RS485_SendByte(PelcoD_Command->Adress); //Write Adress
RS485_SendByte(PelcoD_Command->Command1); //Write Command1
RS485_SendByte(PelcoD_Command->Command2); //Write Command2
RS485_SendByte(PelcoD_Command->Data1); //Write Data1
RS485_SendByte(PelcoD_Command->Data2); //Write Data2
RS485_SendByte(CheckSum); //Write CheckSum
GPIO_ResetBits(GPIOB,GPIO_Pin_2); //Disable DIR
buradaki codelarinizda ornegin su code unuz RS485_SendByte(PelcoD_Command->SyncByte); bu mantikla calisiyor.
uart birimi musaitmi? hayir değil. oyleyse musait olana kadar bekleyelim. musait olunca. (PelcoD_Command->SyncByte) bu bilgiyi uart tan gonderelim. ama gonderim baslayinca isi peripheral birim halletsin. biz bir alt satira gecelim.
simdi code unuzu daha simple bir hale getirelim. yukaridaki codeunuz aslinda soyle
set_dir;
while(!birseyler); send_birseyler;
while(!birseyler); send_birseyler;
while(!birseyler); send_birseyler;
while(!birseyler); send_birseyler;
while(!birseyler); send_birseyler;
while(!birseyler); send_birseyler;
reset_dir;
simdi zurnanin zirt dedigi yere geldik.
en sondaki su code RS485_SendByte(CheckSum); icin microcontroller uart birimi musaitmi diye bakiyor. tamam musait diyor. DR registerina CheckSum degerini basip gondermeyi baslatiyor. hop bir alt satira geciyor ve DIR pinini disable ediyor. bakin daha karsi tarafa start biti gitmeye baslar baslamaz rs485 entegresi tranmitter ozelliginden receiver ozelligine geciyor.
logic analyzer ekranindan bunu basitce gozlemleyip yorumlayabilirsiniz.
sorunu olusturan ve durumu sacma sapan yapan sey library. yani library boyle calisiyor. siz icerideki while i goremediginiz ve systemin register seviyesini incelemediginiz icin aldaniyorsunuz. yada bunu ihmal ediyorsunuz. debug yaparken son veri sak diye uarttan ciktigi ve daha sonra DIR ucu disable edildigi icin sorunu goremiyorsunuz.
boyle yapmayin:
GPIO_SetBits(GPIOB,GPIO_Pin_2);
RS485_SendByte(PelcoD_Command->SyncByte); //Write SyncByte
RS485_SendByte(PelcoD_Command->Adress); //Write Adress
RS485_SendByte(PelcoD_Command->Command1); //Write Command1
RS485_SendByte(PelcoD_Command->Command2); //Write Command2
RS485_SendByte(PelcoD_Command->Data1); //Write Data1
RS485_SendByte(PelcoD_Command->Data2); //Write Data2
RS485_SendByte(CheckSum); //Write CheckSum
RS485_SendByte(0xFF); //gereksiz veri.
GPIO_ResetBits(GPIOB,GPIO_Pin_2);
gereksiz veri yerine 1 byte lik veri gonderimi suresi kadar delay koyun. CheckSum karsi tarafa gidince rs485 entegresi receiver olsun. sorun ortadan kalkar.
STM32 yanlış davranmıyor, düzgün çalışıyor. Problem senin gönderme fonksiyonunda.
İyide Ben zaten RS485_SendByte Fonksiyonunun içerisinde TX_Bufferinin boşalmasını bekliyorum.
void RS485_SendByte(u16 Data)
{
USART3->DR = (Data & (uint16_t)0x00FF);
while (!USART_GetFlagStatus(USART3,USART_FLAG_TXE)){}
}
while (!USART_GetFlagStatus(USART3,USART_FLAG_TXE)){} Burada buffer boşalması bekleniyor. TX Buffer boşalmadan diğer byte gönderilmiyor.
Hatta yukarıdaki fonksiyonda fonksiyondan çıkmadan önce GPIO lardan birini toggle yapıp logic analyserde TX pini ile birlikte izledim. Hiçbir sıkıntı yok görünüyor. Tam olarak 1 byte veri gönderildikten sonra çıkış toggle yapılıyor. Bekleme olmasa eğer paketin başında vs toggle yapılırdı.
@Karamel senin dediğin mantıkta çalışıyor zaten program.
Muhtemelen gözümden kaçan birşey var.
@CLR Sen problemi gördün gibi. Neyi eksik yapıyorum?
Alıntı yapılan: Mucit23 - 21 Temmuz 2015, 10:40:42
İyide Ben zaten RS485_SendByte Fonksiyonunun içerisinde TX_Bufferinin boşalmasını bekliyorum.
void RS485_SendByte(u16 Data)
{
USART3->DR = (Data & (uint16_t)0x00FF);
while (!USART_GetFlagStatus(USART3,USART_FLAG_TXE)){}
}
while (!USART_GetFlagStatus(USART3,USART_FLAG_TXE)){}
Burada buffer boşalması bekleniyor. TX Buffer boşalmadan diğer byte gönderilmiyor.
Hatta yukarıdaki fonksiyonda fonksiyondan çıkmadan önce GPIO lardan birini toggle yapıp logic analyserde TX pini ile birlikte izledim. Hiçbir sıkıntı yok görünüyor. Tam olarak 1 byte veri gönderildikten sonra çıkış toggle yapılıyor. Bekleme olmasa eğer paketin başında vs toggle yapılırdı.
@Karamel senin dediğin mantıkta çalışıyor zaten program.
Muhtemelen gözümden kaçan birşey var. @CLR Sen problemi gördün gibi. Neyi eksik yapıyorum?
Single byte communication
The TXE bit is always cleared by a write to the data register.
The TXE bit is set by hardware and it indicates:
• The data has been moved from TDR to the shift register and the data transmission has
started.
• The TDR register is empty.
• The next data can be written in the USART_DR register without overwriting the
previous data.
This flag generates an interrupt if the TXEIE bit is set.
hocam USART_SR registerin da TC bitini test ederek yapabilirmisiniz?
soyle yani.
while(USART_SR->TC == 0);
mesaj birleştirme:: 21 Temmuz 2015, 14:05:04
bu arada yukaridaki code u direk copy paste yapmayin. keil da declaring nasil bilmiyorum. onu biz o bit 0 iken bekleyecegiz i anlatmak icin yazdim.
birde usart peripheral birim cok uzun. bunu okuyup tam anlamiyla anlamak icin 5-6 saat gerekli.
İlgin için teşekkürler. Ben gönderme fonksiyonlarında problem olduğunu sanmıyorum. Çünkü normal çalışmada
while (!USART_GetFlagStatus(USART3,USART_FLAG_TXE)){} satırından sonra GPIO pinin toggle yapıyorum. Daha önce demiştim paket bittiği anda Toggle işlemi oluyor. Yani Yukarıdaki satırda buferin boşalması bekleniyor.
Ciddi anlamda artık anlamakta zorlanıyorum. Çok basit bir yazım hatası vs olabilir diye düşünüyorum ama defalarca kodu inceledim.
@CLR nerde hata yapıyorum?
Alıntı yapılan: Mucit23 - 21 Temmuz 2015, 16:19:25
İlgin için teşekkürler. Ben gönderme fonksiyonlarında problem olduğunu sanmıyorum. Çünkü normal çalışmada
while (!USART_GetFlagStatus(USART3,USART_FLAG_TXE)){} satırından sonra GPIO pinin toggle yapıyorum. Daha önce demiştim paket bittiği anda Toggle işlemi oluyor. Yani Yukarıdaki satırda buferin boşalması bekleniyor.
Ciddi anlamda artık anlamakta zorlanıyorum. Çok basit bir yazım hatası vs olabilir diye düşünüyorum ama defalarca kodu inceledim.
@CLR nerde hata yapıyorum?
Ben
@CLR degilim ama, sorununuz transmission bitmesini degil, TX registerin bos olmasini bekliyorsunuz.
TXE biti degil TC bitini test edin gonderme bittimi diye(en sonda)
Denemedim ama sanırım haklısınız. TXE enable bitini bekleyince son bytte buffere yazıp beklemeden çıkıyordu fonksiyondan. hemen DIR disable yapılıyor. TC bitini bekleyince while içerisinde işlemci beklemek zorunda kalır. Hemen deneyeceğim.
Ben cevabı basit olduğu için hedef gösterip, kendin bulasın diye yazmamıştım ama
@mufitsozen ve
@Karamel cevabı yazmışlar. Müfit bey zaten biliyordur ama Karamel kendi işi olmadığı halde gidip registeri okuyup bulmuş. Zaten sadece bir status registerine bakmak gerekiyordu.
Bir küçük donanım ayrıntısını hatırlatayım.
Her iki taraf dinlemede (RX) iken
MAX485 için
nRE = 0 , DE = 0 => A-B = High-Z
Bu durumda RO = 1 gösteriyor (MCU ya bağlı RX ucu) ancak A-B'nin High-Z durumu (hat yüzer halde) hat boyunca oluşabilecek elektriksel girişimler sebebi ile RO çıkışında belirsiz pulse lara sebep olabilir.
MAX485'in fonksiyon tablosu biraz daha güvenilir görünüyor, 75176 kullanırsanız bahsettiğim belirsiz durum daha yuksek ihtimal gibi.
Bunun önüne gecmek için A,B uçları pullup ve pulldown yapılıp, A-B arasına da bir kapatma direnci koyulur. Bakınız RS485 app notes.
Ben uygulamalarımda RO pinini de (MCU ya bağlı RX ucu) pullup yapıyorum.
MAX 485
(https://i.ibb.co/2n4gdtt/Ekran-Al-nt-s.png) (https://ibb.co/smYyqww)
(http://s17.postimg.cc/kknbstjfz/Ekran_Al_nt_s.png) (http://postimg.cc/)
resim yüke (http://postimg.cc/index.php?lang=turkish)
SN75176
(https://i.ibb.co/qR3v52M/Ekran-Al-nt-s-1.png) (https://ibb.co/7Gdq40J)
(http://s12.postimg.cc/4e5zd4i4d/Ekran_Al_nt_s.png) (http://postimg.cc/)
resim yükleme servisi (http://postimg.cc/index.php?lang=turkish)
Aslında daha önce rs232 için sürekli kullandığım bir kütüphaneydi. Test için RS485 İçin kodları çevirmiştim. Bende baska bir yerde almıştım. Demek en baştan hatalıymış.
Alıntı yapılan: Mucit23 - 21 Temmuz 2015, 20:37:38
Aslında daha önce rs232 için sürekli kullandığım bir kütüphaneydi. Test için RS485 İçin kodları çevirmiştim. Bende baska bir yerde almıştım. Demek en baştan hatalıymış.
Ne farkeder ki, protokol aynı, donanıma doğru hitap ettikçe aynı işler yapılıyor.
Yok hocam protokolü biliyorum. TXE Bitini beklemek hatalıymış.
Alıntı yapılan: Mucit23 - 21 Temmuz 2015, 21:07:00
Yok hocam protokolü biliyorum. TXE Bitini beklemek hatalıymış.
demek ki karamel gibi yapip datasheet okumak lazimmis. Ne kadar biliyoruz zannetsekde yada yazdigimiz program bir sekilde daha once calisiyor gibi gozuksede, hata varsa referansimiz datasheet.
Şuan çalıştı. Haklısınız... Okuduğumu anlamakta zorlanıyorum.