uzun bir sayiyi printf(); ile gönderiyorum ama hep degisiyor

Başlatan Digimensch, 10 Mayıs 2014, 20:32:19

Digimensch

Arkadaslar  pic16f628 e bagladigm bir Infrorat Lede , aynen Serial iletisim seklinde örnegin su dezimal sayiyi
1319256238
int32 sayi=1319256238;
printf(sayi);

seklinde gönderiyorum. IR led bu sayiyi gönderiyor ama alici devre ilede gelen bu sinyali yakalayip PC de bir Software ile okuyorum,
her okumaamda 1319256238   sayi değilde baska sayilar olusuyor.
örnegin
1229376740
201234151
3009444038
2636705184
732313051
1319256238
1319256238
916961450
1319256238


acaba ben bu  1319256238  sayiyi gönderirken mi hata yapiyorum? Yoksa PC de alicidan Alan programmi yanlis aliyor, ama neden her defasinda degisik oluyor.

ben bu 1319256238 sayiyi aynen nasil alabilirim?

Pic devresine bagli IR Led var bu Infrorot Lede pic den bu sayiyi su sekilde gönderiyorum.
// internal oscilator icin
#fuses INTRC_IO, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP 
#use delay(CLOCK=4000000)

#use rs232 (baud=9600, xmit=PIN_B2, RCV=PIN_B1, parity=N, stop=1)
int32 b1=1319256238;
char temp=0;

#INT_RDA
void seri_kesme()
{  disable_interrupts(INT_RDA);
   temp=getc();
}

void main()
{  set_tris_b(0x02);
   set_tris_a(0x00);
   output_b(0x00);
   output_a(0x00);
   enable_interrupts(GLOBAL);
   
   
   while(true)
   {  
   
   enable_interrupts(int_rda);
   
      //YAKMAK ICIN
      if(temp=='x')
      {  
      temp=0X00;
      printf("%ld",b1);   ---->  b1 degiskenini burada gönderiyorum
      delay_ms(100);    
         output_bit(PIN_A0,1);
      }
}

}


acaba 31 bit oldugu icinmi sorun oluyor
1319256238  --> dez
1001110101000100100000010101110  --> binary

Salih

Gönderdiğin sayının önüne ve arkasına * , < gibi karakterler yerleştir.
Başlangıç karakterini görünce almaya başla, bitiş karakterini görünce dur.
Ve karakterleri sayıya çevir.

baran123

Sayıyı parçalayıp göndermeyi deneyebilirsiniz önce böler parça parça gönderir karşı tarafta toplayabilirsiniz.

Digimensch

Arkadaslar ccs de pek iyi sayilmam kisa bir örnek verirseniz sevinirim.

Salih

Alıntı yapılan: Digimensch - 10 Mayıs 2014, 22:05:26
Arkadaslar ccs de pek iyi sayilmam kisa bir örnek verirseniz sevinirim.

Aşağıda basit PC deki bir programla kullanılabilecek PIC'le yapılmış bir I/O kartının PIC Programı nı veriyorum.
Tarafımdan yapılmıştır ve denenmiştir.
Bu kart PC den veri almakta ve aynı zamanda PC'ye veri göndermekte.
PC tarafından Dijital çıkış port verisi ve kart daki pwm sinyal değeri gelmekte.
PC tarafına ise 5 adet analog giriş değeri ve portB nin değeri gönderilmekte.
Bu karta gelmesi gerekli veri paket formatı şöyle olmalı.

'>' + cikis + duty + chksum + '!'
Paket > karakteriyle başlıyor ! karakteriyle bitiyor.
cikis , duty , ve chksum verileri Hex formatında geliyor.
Sende sayını 4 bayta böl. Make8() ile.
a,b,c,d olsun bu baytlar.

Printf(">%X%X%X%X%X!",a,b,c,d,chksum); biçimde gönder.
Alıcı aşağıda programda var. kendine göre düzenle.
chksum basit bir veri kontrol baytı istersen sende kullan iyi olur.
Nasıl hesaplandığı aşağıda var. Sende gönderirken kendi verilerine göre uyarla.





#include <16F876.h>
#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES PUT                      //Power Up Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(clock=4000000)

#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,Stop=1,errors)

#BYTE PC = Getenv("SFR:PORTC")//PortC'nin adresini alıyoruz.

#BIT     D1=PC.0
#BIT     D2=PC.1
#BIT     D3=PC.3
#BIT     D4=PC.4
#BIT     D5=PC.5
#Define  D6  Pin_A4

int8  PortB,//PortB'nin içeriklerinin atanacağı değişken
      cikis;//PC'den gelen Röle konumlarını içerecek değişken
int16 ham0,ham1,ham2,ham3,ham4,//Analog giriş ham değerlerinin atanacağı değişkenler.(10 Bit)
      zaman,tmp;//Seri haberleşmede hata olduğunu gösterecek değişken.
      
char  gelen; 
int8  duty=0,x,Chksum=0;
char  dizi[10];
//PC'ye gönderilen ve PC'den alınan datalar büyük harfli Hexdesimal olarak yazıldığı için
//bu fonksiyon dönüştürme işlemlerinde kullanılacak
int8 hti(char a)//Hex to Int
{
 switch(a){
  case '0' : return(0);Break;
  case '1' : return(1);Break;
  case '2' : return(2);Break;
  case '3' : return(3);Break;
  case '4' : return(4);Break;
  case '5' : return(5);Break;
  case '6' : return(6);Break;
  case '7' : return(7);Break;
  case '8' : return(8);Break;
  case '9' : return(9);Break;
  case 'A' : return(10);Break;
  case 'B' : return(11);Break;
  case 'C' : return(12);Break;
  case 'D' : return(13);Break;
  case 'E' : return(14);Break;
  case 'F' : return(15);Break;
  default  : return(0); 
 } 
}
#INT_RDA
void seri_haber(){

  if ('>' == getc())
  { 
      x     = 0;
      zaman = 0;      
      output_toggle(D6);         
      while(zaman < 500)
         {
           if (Kbhit()) {           
               gelen   = getc();             
               dizi[x] = gelen;
               x++;
               zaman   = 0;
               if (gelen=='!') break;
            }                        
            zaman++;
         }
    
    if (!zaman){     
                cikis  = hti(dizi[1])+(hti(dizi[0])*16);  
                duty   = hti(dizi[3])+(hti(dizi[2])*16);
                chksum = hti(dizi[5])+(hti(dizi[4])*16);
                tmp    = cikis + duty;
                if (make8(tmp,0)!=chksum) 
                     {
                       cikis =0;
                       duty  =0;
                     }
                SET_PWM1_DUTY(duty);
               }else cikis = 0;  
//CCS 'de ASM komutlarının nasıl yazılacağının örnek kodları
//Bu kodlarda PC'den gelen çıkış bilgileri, ilgili röle çıkışlarına aktarılıyor.
#asm
BTFSS CIKIS,0
GOTO  SON11
BSF   D1
GOTO  SON
SON11:
BCF   D1
SON:
BTFSS CIKIS,1
GOTO  SON22
BSF   D2
GOTO  SON1
SON22:
BCF   D2
SON1:
BTFSS CIKIS,2
GOTO  SON33
BSF   D3
GOTO  SON2
SON33:
BCF   D3
SON2:
BTFSS CIKIS,3
GOTO  SON44
BSF   D4
GOTO  SON3
SON44:
BCF   D4
SON3:
BTFSS CIKIS,4
GOTO  SON55
BSF   D5
GOTO  SON4
SON55:
BCF   D5
SON4:
#endasm   
  }  
}

void main()
{
   setup_adc_ports(ALL_ANALOG);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_timer_2(T2_DIV_BY_4,249,1);//992 Khz'lik PWM elde ediliyor
   setup_ccp1(CCP_PWM);
   SETUP_SPI(SPI_DISABLED);   
   port_B_pullups(True);
   output_C(0);//PortC bütün pinleri çıkış olarak ayarlanıyor ve sıfırlanıyor
   input(Pin_C7);//RS232 haberleşmede giriş pini olarak kullanılacağı için, giriş olarak ayarlanıyor.   
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_RDA);
   SET_PWM1_DUTY(0);
   while(TRUE)
   {                       
            set_adc_channel( 0 );
            Delay_us(100);
            ham0 = Read_adc();
            set_adc_channel( 1 );
            Delay_us(100);
            ham1 = Read_adc();
            set_adc_channel( 2 );
            Delay_us(100);
            ham2 = Read_adc();
            set_adc_channel( 3 );
            Delay_us(100);
            ham3 = Read_adc();
            set_adc_channel( 4 );
            Delay_us(100);
            ham4 = Read_adc();
            //PortB Girişleri Pullup olduğu içinde normalde Lojik 1 oluyor.
            //Butona basıldığında Lojik 0 Oluyor
            //Onun için tersini alıyoruz.
            PortB = ~input_B();          
            //Basit bir veri kontrol mekanizması oluşturuyoruz
            tmp    = ham0+ham1+ham2+ham3+ham4+portb;
            chksum = make8(tmp,0);            
            Printf("#%LX%LX%LX%LX%LX%X%X$",ham0,ham1,ham2,ham3,ham4,portb,chksum);            
            delay_ms(50);
   }
}

Digimensch

@salih
tesekkür ederim Dostum.Bu kodlarla bir deneme yapacagim fakat benim alici tarafindaki yazilimla oynama imkanim yok.
kisacasi söyle.
Ben bir IR kumandanin gönderdigi sinyalin hex , dez veya binary sayilarini hangisini istersek aliyorum.
Bu hex sayilari yaptigim bir pic16f628 ve buna bagli IR led üzerinden göndermek istiyorum.
Alici kisim bir Aydinlatma aleti ve bir cok funksiyonu var, anlayacagin alici icindeki yazilim ve microkontrol hakkinda bir bilgim yok.
ben sadece uzaktan kumandanin gönderdigi sinyalin(Hex data) aaynisini yani off fonksiyonu icin 1319256238 sayisini yaptigim devreden göndermek istiyorum.

Yaptigim bu devrenin yazilimini CCS ile yukardaki gibi yaptim, veri gidiyor , giden veriyide bilgisayara bagladigim bir IR alici ile alip PC de görebiliyrum.
her defasinda ayri hex data geliyor.
int32 sayi=1319256238;  gönderiyorum
ama PC ekraninda
1229376740
201234151
3009444038
2636705184
732313051
1319256238
1319256238
916961450
1319256238   seklinde degisime ugramis olarak görünüyor.

oysa 1319256238  sayisini aynen yaptigim devreden gönderebilsem islem tamam,
ama bir türlü beceremedim.

Salih

Belki 32 bit göndermek problem oluşturuyordur. Siz tespit ettiğiniz sayıları ki, bayt bayt tespit etmişsinizdir.
Sizde aynı şekilde baytları aynı sırada arka arkaya gönderin.

Yani,


a,b,c,d gibi 4 baytınız(tespit ettiğiniz) var.
Bunu
putc(a);
putc(b);
putc(c);
putc(d); gibi gönderin.

Digimensch


Digimensch

Arakadaslar ne yaptiysam ayni,
sanirim kullandigim devrede bir sorun var.
su Devreyi kullaniyorum.
[IMG]http://img495.yukle.tc/thumbs/5477verici.JPG[/img]

acaba pic 616f84 veya pc16f628 ile yapilmis buna benzer(button falan olmasi sart degil) calisacak  IR verici devre varmi bu ccs kodlariyla istedigim sayiyi gönderebilecek.
varsa sunarsaniz sevinirim.

Salih

IR sistemlerde 38Khz lik modülasyon kullanılır. Sizin devredeki RB3 ucunda 38Khz pwm çıkışı olması gerekir.
Bunun için programında ilgili ucdan 38Khz pwm çıkacak şekilde kod ekle.
Daha önce dediğim gibi baytları gereken sırada ard arda gönder.

Digimensch

#10
salih
asagidaki örnekte Timer2 yi 38khz icin ayarladim ve öyle gönderiyorum simdi.
ama hala gönderdigim su binary sayi degsmis olarak aliyorum.

#include <16F628A.h>
#fuses XT
#use delay (clock=4000000)

#use rs232 (baud=1200, xmit=pin_b2, parity=N, stop=1)


int b1=0b01100001;   


void main()
{
   
   while(true){  
     setup_timer_1(T1_DISABLED);      // T1 zamanlayýcýsý devre dýþý
     setup_timer_2(T2_DIV_BY_1,25,1); // Timer2 ayarlarý yapýlýyor, PWM sinyali frekansý=~38Khz olacak þekilde
     set_pwm1_duty(12);               // PWM sinyalinin görev saykýl oraný belirleniyor
     setup_CCP1(CCP_PWM);             // CCP modülü PWM çýkýþý için ayarlanýyor
      
 
      if(input(pin_b4)==0){  //
         putc(b1);
         
         output_high(pin_a1);
         delay_ms(50);
         output_low(pin_a1);
         

      }
    
   }
   
}


yukarda buttona basilinca 01100001 veya hex karsiligi değil  baska sayilar ekrana cikiyor.
oysa ekrana (0b01100001 binäry)  veya (97 desimal)  veya (61 heximal) almam gerek

Salih

     setup_timer_1(T1_DISABLED);      // T1 zamanlayýcýsý devre dýþý
     setup_timer_2(T2_DIV_BY_1,25,1);   // Timer2 ayarlarý yapýlýyor, PWM sinyali frekansý=~38Khz olacak þekilde
     set_pwm1_duty(12);                         // PWM sinyalinin görev saykýl oraný belirleniyor
     setup_CCP1(CCP_PWM);
     output_high(Pin_B2);// B2 ve B3'ün çıkış olarak ayarlanmasını garantiye alıyoruz.
     output_high(Pin_B3);


Bu satırları while'dan önceye al.
Bir daha dene.

Digimensch

#12
aldim su sekilde;
#include <16F628A.h>
#fuses XT
#use delay (clock=4000000)

#use rs232 (baud=1200,uart,xmit=pin_b2, parity=N, stop=1)


int b1=0b01100001;  



void main()
{
     setup_timer_1(T1_DISABLED);      // T1 zamanlayýcýsý devre dýþý
     setup_timer_2(T2_DIV_BY_1,25,1); // Timer2 ayarlarý yapýlýyor, PWM sinyali frekansý=~38Khz olacak þekilde
     set_pwm1_duty(12);               // PWM sinyalinin görev saykýl oraný belirleniyor
     setup_CCP1(CCP_PWM);             // CCP modülü PWM çýkýþý için ayarlanýyor
      
   
   while(true){  
 
      if(input(pin_b4)==0){  //
         putc(b1);

         

      }
    
   }
   
}


kod icinde görüldügü gibi
int b1=0b01100001; 
putc(b1);   seklinde gönderiyorum,

PC'de
FCABFFBF   veya binary olarak 11111100101010111111111110111111 bu sekilde aliyorum.

Salih

Öncelikle, verici devren den gerekli modüleli sinyal çıkıyormu?
İmkanın varsa osiloskop la bakarmısın.
Bende yarın işyerin de devre üzerinde deneme yapıp sana bildireyim.

Digimensch

#14
sinyal cikiyor, ama alici olarak kullandigim ARDUINO devresi PC ye degisik veriyor.

Kullandigim ARDUINO baglanti semasi ve kullandigim kod(PC de görmek icin) su linkteki

http://sn0wmax.wordpress.com/2012/10/04/ir-empfanger-apple-remote/

bu devre herhangi bir infrarotlu vericiden gelen sinyali PC ekraninda gösteriyor.
tabiki Arduinonun PC icin kendi yazilimiyla.