Gelen veriye göre pwm hesaplama ?

Başlatan makinahmet, 09 Mayıs 2014, 17:20:01

makinahmet

Herkese merhabalar. Yaptığım ufak bir çizgi izleyeni pwm ile çalıştırmak istiyorum. Kodlar aşağıdadır. Sorun şu ki "set_pwm_duty(value);" kodunun içindeki value değerini rakamsal olarak belirlediğimde pwm sorunsuz olarak çalışırken, aynı değeri değişkenlerle hesaplamaya çalıştığımda pwm çalışmıyor. Cevaplarınız için şimdiden teşekkürler.
#include <ders.h>

//qtr sensör siyahta output_high veriyor.

#use fast_io(b) 

#define s1 input(pin_b7)
#define s2 input(pin_b6)
#define s3 input(pin_b5)
#define s4 input(pin_b4)
#define s5 input(pin_b3)
#define s6 input(pin_b2)
#define s7 input(pin_b1)
#define s8 input(pin_b0)

#define solmotorileri output_high(pin_a2) //l293d'nin 2.bacağına bağlı
#define solmotorgeri  output_high(pin_a3) //l293d'nin 7.bacağına bağlı
#define sagmotorileri output_high(pin_a0) //l293d'nin 15.bacağına bağlı
#define sagmotorgeri  output_high(pin_a1) //l293d nin 10. bacagına baglı

#define solmotorilerix output_low(pin_a2) //l293d'nin 2.bacağına bağlı
#define solmotorgerix  output_low(pin_a3) //l293d'nin 7.bacağına bağlı
#define sagmotorilerix output_low(pin_a0) //l293d'nin 15.bacağına bağlı
#define sagmotorgerix  output_low(pin_a1) //l293d nin 10. bacagına baglı

int kosul;
float pwm = 250;
float hatasag;
float hatasol;
unsigned int solP;
unsigned int sagP;
float oran;

void main()
{
   setup_timer_2 (T2_DIV_BY_16,255,1);
   setup_ccp1 (CCP_PWM);
   setup_ccp2 (CCP_PWM);
   set_pwm1_duty (0);
   set_pwm2_duty (0);
   

   while(1)
   {
   //sensör kurulumu*****
   set_tris_b(0x00); //bütün port output yani çıkış yapar
   output_b(255);    //bütün port high
   delay_us(10);     //sensörlerin dolması için gereken süre 10 mikrosn.
   set_tris_b(0xff); //bütün b portu giriş yapıldı.
   delay_us(500);    //500 mikrosn sensörlerin low olması için kalibrasyon süresi
   //********************
      
      sagP = pwm/hatasag; //sagmotor pwm hesabı. [b]Hesap yapmıyor mu ?[/b]
      solP = pwm/hatasol; //solmotor pwm hesabı  [b]Hesap yapmıyor mu ?[/b]
           
      // tek sensorluler
      if(s1 && !s2 && !s3 && !s4 && !s5 && !s6 && !s7 && !s8)
      {
       hatasol = 8;
       hatasag = 1;
       set_pwm1_duty(sagP);  // [b]sagmotor. pwm yapılan hesabı algılamıyor ?? [/b]
       set_pwm2_duty(solP);  // [b]solmotor. pwm  yapılan hesabı algılamıyor ??[/b]
       sagmotorileri;
       solmotorileri;
       sagmotorgerix;
       solmotorgerix;
      }
      
      if(!s1 && s2 && !s3 && !s4 && !s5 && !s6 && !s7 && !s8)
      {
       set_pwm1_duty (220);  // [b]sagmotor Direk rakam girince çalışıyor.[/b]
       set_pwm2_duty (200);  //[b] solmotor direk rakam girince çalışıyor.[/b]
       sagmotorileri;
       solmotorileri;
       sagmotorgerix;
       solmotorgerix;
      }
      
      if(!s1 && !s2 && s3 && !s4 && !s5 && !s6 && !s7 && !s8)
      {
       set_pwm1_duty (250);  // sagmotor
       set_pwm2_duty (220);  // solmotor
       sagmotorileri;
       solmotorileri;
       sagmotorgerix;
       solmotorgerix;
      }
      
      if(!s1 && !s2 && !s3 && s4 && !s5 && !s6 && !s7 && !s8)
      {
       set_pwm1_duty (250);  // sagmotor
       set_pwm2_duty (240);  // solmotor
       sagmotorileri;
       solmotorileri;
       sagmotorgerix;
       solmotorgerix;
      }
      if(!s1 && !s2 && !s3 && !s4 && s5 && !s6 && !s7 && !s8)
      {
       set_pwm1_duty (240);  // sagmotor
       set_pwm2_duty (250);  // solmotor
       sagmotorileri;
       solmotorileri;
       sagmotorgerix;
       solmotorgerix;
      }
   
      if(!s1 && !s2 && !s3 && !s4 && !s5 && s6 && !s7 && !s8)
      {
       set_pwm1_duty (215);  // sagmotor
       set_pwm2_duty (250);  // solmotor
       sagmotorileri;
       solmotorileri;
       sagmotorgerix;
       solmotorgerix;
      }
      
      if(!s1 && !s2 && !s3 && !s4 && !s5 && !s6 && s7 && !s8)
      {
       set_pwm1_duty (200);  // sagmotor
       set_pwm2_duty (250);  // solmotor
       sagmotorileri;
       solmotorileri;
       sagmotorgerix;
       solmotorgerix;
      }
      
      if(!s1 && !s2 && !s3 && !s4 && !s5 && !s6 && !s7 && s8)
      {
       set_pwm1_duty (175);  // sagmotor
       set_pwm2_duty (220);  // solmotor
       sagmotorileri;
       solmotorileri;
       sagmotorgerix;
       solmotorgerix;
      }
      
      //iki sensorluler
   
      if(!s1 && !s2 && !s3 && s4 && s5 && !s6 && !s7 && !s8)
      {
       set_pwm1_duty (250);  // sagmotor
       set_pwm2_duty (250);  // solmotor
       sagmotorileri;
       solmotorileri;
       sagmotorgerix;
       solmotorgerix;
      }
      
       if(!s1 && !s2 && s3 && s4 && !s5 && !s6 && !s7 && !s8)
      {
       set_pwm1_duty (225);  // sagmotor
       set_pwm2_duty (100);  // solmotor
       sagmotorileri;
       solmotorileri;
       sagmotorgerix;
       solmotorgerix;
      }
      
      
       if(!s1 && s2 && s3 && !s4 && !s5 && !s6 && !s7 && !s8)
      {
       set_pwm1_duty (225);  // sagmotor
       set_pwm2_duty (75);  // solmotor
       sagmotorileri;
       solmotorileri;
       sagmotorgerix;
       solmotorgerix;
      }
      
       if(s1 && s2 && !s3 && !s4 && !s5 && !s6 && !s7 && !s8)
      {
       set_pwm1_duty (225);  // sagmotor
       set_pwm2_duty (50);  // solmotor
       sagmotorileri;
       solmotorileri;
       sagmotorgerix;
       solmotorgerix;
      }
      
       if(!s1 && !s2 && !s3 && !s4 && s5 && s6 && !s7 && !s8)
      {
       set_pwm1_duty (150);  // sagmotor
       set_pwm2_duty (225);  // solmotor
       sagmotorileri;
       solmotorileri;
       sagmotorgerix;
       solmotorgerix;
      }
         
       if(!s1 && !s2 && !s3 && !s4 && !s5 && s6 && s7 && !s8)
      {
       set_pwm1_duty (100);  // sagmotor
       set_pwm2_duty (225);  // solmotor
       sagmotorileri;
       solmotorileri;
       sagmotorgerix;
       solmotorgerix;
      }
      
       if(!s1 && !s2 && !s3 && !s4 && !s5 && !s6 && s7 && s8)
      {
       set_pwm1_duty (70);  // sagmotor
       set_pwm2_duty (225);  // solmotor
       sagmotorileri;
       solmotorileri;
       sagmotorgerix;
       solmotorgerix;
      }
      
       if(s1 && !s2 && !s3 && !s4 && !s5 && !s6 && !s7 && !s8)
      {
       set_pwm1_duty (250);
       set_pwm2_duty (0);
       sagmotorileri;
       solmotorilerix;
       sagmotorgerix;
       solmotorgerix;
       kosul = 1;
      }
      
      if(!s1 && !s2 && !s3 && !s4 && !s5 && !s6 && !s7 && s8)
      {
       set_pwm1_duty (0);
       set_pwm2_duty (250);
       sagmotorilerix;
       solmotorileri;
       sagmotorgerix;
       solmotorgerix;
       kosul = 2;
      }
      
      //egerki hepsi beyazda ise
      if(!s1 && !s2 && !s3 && !s4 && !s5 && !s6 && !s7 && !s8)
      {
         if(kosul == 1)
         {
         set_pwm1_duty (250);
         set_pwm2_duty (100);
         sagmotorileri;
         solmotorgeri;
         sagmotorgerix;
         solmotorilerix;
         }
         
         if(kosul == 2)
         {
         set_pwm1_duty (100);
         set_pwm2_duty (250);
         sagmotorilerix;
         solmotorgerix;
         sagmotorgeri;
         solmotorileri;
         }
      }
   
   }//while  
}//main

           
DC, STEP, SERVO MOTOR -> www.sinematronik.com

pea

Değişkenleri float olarak tanımlamışsınız. Tam sayı girmeniz gerekiyor.

makinahmet

#2
Açıkçası onuda denedim. pwm modüül 16 yada 8 bit sabit yada değişken sayıları okuyor. "value may be an 8 or 16 bit constant or variable." compilerdeki açıklamadır.

int16 pwm = 250; // ve diğer değişkenleri int16,int8 olarakda tek tek denedim.
float olan bir değişkeni int değişkene bölmedim...

set_pwm1_duty((int16)sagP) //denedim.

sagP = ceil(pwm/hatasag);  // ceil ile tam sayıya çevirdim.
set_pwm1_duty(sagP);  //denedim olmadı.

"Bir satırda bir hesap" denedim olmadı.
İnternette araştırdım herkes benim yaptığım gibi hesaplamış oysaki.
DC, STEP, SERVO MOTOR -> www.sinematronik.com

Salih

Alıntı yapılan: makinahmet - 09 Mayıs 2014, 18:26:04
Açıkçası onuda denedim. pwm modüül 16 yada 8 bit sabit yada değişken sayıları okuyor. "value may be an 8 or 16 bit constant or variable." compilerdeki açıklamadır.

int16 pwm = 250; // ve diğer değişkenleri int16,int8 olarakda tek tek denedim.
float olan bir değişkeni int değişkene bölmedim...

set_pwm1_duty((int16)sagP) //denedim.

sagP = ceil(pwm/hatasag);  // ceil ile tam sayıya çevirdim.
set_pwm1_duty(sagP);  //denedim olmadı.

"Bir satırda bir hesap" denedim olmadı.
İnternette araştırdım herkes benim yaptığım gibi hesaplamış oysaki.
Büyük ihtimal derleyiciniz de problem var.
Dediğin komut zaten genelde  değişkenle kullanılır.

makinahmet

Alıntı yapılan: salih - 09 Mayıs 2014, 19:29:55
Büyük ihtimal derleyiciniz de problem var.
Dediğin komut zaten genelde  değişkenle kullanılır.

Derleyici olarak PIC C compiler kullanmaktayım. 4.068 versiyonunda olmadı. Sonra versiyonu yükselttim yine olmadı. Şu an ki versiyon ise 5.007 dir.
DC, STEP, SERVO MOTOR -> www.sinematronik.com

Salih

Alıntı yapılan: makinahmet - 09 Mayıs 2014, 20:17:21
Derleyici olarak PIC C compiler kullanmaktayım. 4.068 versiyonunda olmadı. Sonra versiyonu yükselttim yine olmadı. Şu an ki versiyon ise 5.007 dir.
aşağıda ki kodları denermisin. Bende derleniyor.

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

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOPROTECT                //Code not protected from reading

#use delay(clock=500000)
 int16 agir;

void main()
{
   setup_adc_ports(AN0);
   setup_adc(ADC_CLOCK_INTERNAL);
   set_adc_channel(0);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DIV_BY_16,255,1);// 50.08 Hz
   setup_ccp1(CCP_PWM);
   setup_oscillator(OSC_31KHZ);
   Set_Tris_A(0X01);
   Set_Tris_B(0);
   Output_B(0X00);
   
While(true){
 agir = Read_adc();
 Delay_ms(10);
 set_pwm1_duty((agir));
}
}

makinahmet

Alıntı yapılan: salih - 09 Mayıs 2014, 21:09:56
aşağıda ki kodları denermisin. Bende derleniyor.

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

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOPROTECT                //Code not protected from reading

#use delay(clock=500000)
 int16 agir;

void main()
{
   setup_adc_ports(AN0);
   setup_adc(ADC_CLOCK_INTERNAL);
   set_adc_channel(0);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DIV_BY_16,255,1);// 50.08 Hz
   setup_ccp1(CCP_PWM);
   setup_oscillator(OSC_31KHZ);
   Set_Tris_A(0X01);
   Set_Tris_B(0);
   Output_B(0X00);
   
While(true){
 agir = Read_adc();
 Delay_ms(10);
 set_pwm1_duty((agir));
}
}


Evet adc okumada bende de çalışmakta. Güneş izleyen bi sistemde ldr dirençleri adc ile okuyup motora ona göre pwm verdirmiştim daha önce.Sonrasında 200 adım bipolar step kullandım. Pwm değerinin atandığı değişken sayısal değer olunca sıkıntı vermiyor. Ancak iki veya daha fazla değişkenle pwm değerini hesaplamaya çalıştığımızda ise sonuç alamamaktayız. Gerçekten de PIC C compilerda problem olduğunu düşünmeye başladım.
DC, STEP, SERVO MOTOR -> www.sinematronik.com

ferdem

CCS C de bazen ilginç problemler olabiliyor, eski versiyonlarda problemler olabiliyor. Sizin problem böyle bir problem olabilir, değişken tipleriyle ilgili de olabilir. Değişken tipleriyle oynayın, pwm hesabının olduğu satırda değişken tipini özellikle belirtin ("type casting").
Debug yapacaksınız hocam, set_pwm1_duty(sonuc);
sonuc size göre 100 olması lazım ama öyle olmuyor, peki ne oldu? Bunu görmenin çeşitli yolları var... putc(sonuc), printf(lcd_putc, ) en basitinden
if(sonuc>90 && sonuc<110)output_high(led); yazıp nelerin yolunda gitmediğini görebilirsiniz.

makinahmet

Alıntı yapılan: ferdem - 10 Mayıs 2014, 15:31:44
CCS C de bazen ilginç problemler olabiliyor, eski versiyonlarda problemler olabiliyor. Sizin problem böyle bir problem olabilir, değişken tipleriyle ilgili de olabilir. Değişken tipleriyle oynayın, pwm hesabının olduğu satırda değişken tipini özellikle belirtin ("type casting").
Debug yapacaksınız hocam, set_pwm1_duty(sonuc);
sonuc size göre 100 olması lazım ama öyle olmuyor, peki ne oldu? Bunu görmenin çeşitli yolları var... putc(sonuc), printf(lcd_putc, ) en basitinden
if(sonuc>90 && sonuc<110)output_high(led); yazıp nelerin yolunda gitmediğini görebilirsiniz.
Aslında dediğinizi denedim. 18f2550 de b portunun tamamını kullandığım için lcd2'yi "A" portuna bağlamaya çalıştım ancak ayarları yapamadım. Dediğiniz gibi led ile kontrol yaptım. Buraya konuyu daha sonra açtım zaten. Pwm bacaklarına bağladığım belli değerlerde yanmasını sağladığım ledlerden tepki alamadım. Sıfır tepki. 3 ayrı PIC'te denedim aynı.
DC, STEP, SERVO MOTOR -> www.sinematronik.com

Salih

Kodların hepsini verin, birde biz derlemeye çalışalım.

vatandas30

selamlar. konunun üzerinden bayağı geçmiş ama benimde şöyle bir sorunum var. main içine kodları aşağıdaki gibi yazıyorum. bazen enerji verdiğimde motorlardan birisi tam gaz çalışıyor. sebebini bulamadım.

void main()
{
   setup_timer_2 (T2_DIV_BY_16,255,1);
   setup_ccp1 (CCP_PWM);
   setup_ccp2 (CCP_PWM);
   set_pwm1_duty (0);
   set_pwm2_duty (0);

Salih

verdiğin kodlara göre, pwm ler sıfırdan başlaması gerekir.
Mümkünse kodların tamamını ve şemayı göster.

vatandas30

16f887 nin ccp pinleri l293 ün enable uçlarına bağlı. klasik motor sürme bağlantısı yani.
bu kodlardan sonra led yakıyorum gecikme vs. var deneme amaçlı. o süre zarfında normalde motorların dönmemesi lazım. fakat bazen ilk anda son hız motorlardan bir tanesi dönüyor.

dursuncemal

olcu aletiyle veya osiloskopla bir gozle hatta uclari ayir da bak pic mi, kaciriyo l293 de mi bir kararsizlik var? gerisi ayiklanir yavas yavas.
:=

vatandas30

donanımsal bir hata olacağı aklıma gelmemişti. ben derleyiciden şüpheleniyordum. bir deneneyim .tşk.