Kodum Switch-Case içine girmiyor

Başlatan DaisysFox, 28 Mart 2022, 14:57:45

DaisysFox

Öncelikle daha önce açmış olduğum konulardaki yardımlarınızdan dolayı teşekkür ederim :) Saate göre Güneş takip sistemi yapmaya çalışıyorum ve bitmesine yaklaştığımı düşünüyorum. Fakat ayrı ayrı çalıştırmayı başarmış olduğum, RTC ve hesaplamalara bağlı Step Motor döndürme kodlarını birleştirdiğimde kodum çalışmıyor :/ Anladığım kadarıyla RTC'de sorun oluyor ve kodda da göreceğiniz switch-case içine girip d değerini if'in içine yazdıramıyor. Bu kodda nerde hata olabilir ve nasıl düzeltebilirim?

#include <16f877A.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD

#use delay (clock=4000000)

#use fast_io(b)
#use fast_io(c)
#use fast_io(d)

#define RTC_SCLK PIN_c1
#define RTC_IO PIN_c2
#define RTC_RST PIN_c0

#define use_portb_lcd_TRUE

#include <DS1302.c>
#include <math.h>
#include <lcd.c>

int saniye,dakika,ay,yil,haftanin_gunu;
int saat;
int gun;
int i=0, hiz=400;

int fi;
int w; // Saat açısı
long d=0;
float dec; // Deklinasyon açısı
float e; 
float a; 
float elev; // Altitude,elevasyon
float azi; // Azimuth
int b;

const int tam_adim[]={0x09,0x03,0x06,0x0C}; // Her adım 5.625 derece

void main () {

setup_psp(PSP_DISABLED);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);

set_tris_b(0x00);
set_tris_d(0x00);
output_d(0x00);

rtc_init();
lcd_init();

rtc_set_datetime(13,05,22,7,13,00); // Gün,ay,yil,haftanın günü,saat,dakika

while(1) {

rtc_get_time(saat,dakika,saniye);
rtc_get_date(gun,ay,yil,haftanin_gunu);
// Switch 1 ocaktan itibaren gün sayısını hesaplamak için kullanıldı.
// Ay'a göre case'e girip d'yi hesaplıyor.  
switch(ay) {

case 1: //ocak
d=gun; 
break;

case 2: //şubat
d=31+gun; 
break;

case 3: //mart
d=59+gun; 
break;

case 4: //nisan
d=90+gun; 
break;

case 5: //mayıs
d=120+gun; 
break;

case 6: //haziran
d=151+gun; 
break;

case 7: //temmuz
d=181+gun; 
break;

case 8: //ağutos
d=212+gun; 
break;

case 9: //eylül
d=243+gun; 
break;

case 10: //ekim
d=273+gun; 
break;

case 11: //kasım
d=304+gun; 
break;

case 12: //aralık
d=334+gun; 
break;

}

if ((saat>=6 && saat<=20)) { // Bu kısımda istenilen motorun b değişkeni kadar dönmesidir.
                             // Saat 6'dan 8'e kadar saat başı bu işlemi yapacak.
                             // Yani saat başı döngüye girip motoru kaldığı yerden döndürecek.
fi=41; 
// d=133 (RTC Tarihi için)
// w=15 (Saat 13 için) 
// dec. = 18.26
// elev=63.87
// azi=34
// b yaklaşık 6 adım
w=15*(saat-12); // Saat açısı
dec=23.45*sin((0.986*(284+d))*(PI/180)); // 7.48

e=(sin(dec*(PI/180))*sin(fi*(PI/180))+cos(dec*(PI/180))*cos(fi*(PI/180))*cos(w*(PI/180))); // -360 ile 360 
elev=asin(e);  //  -1 ile 1 
elev=(elev*180)/PI; // -16.77

a=(cos(dec*(PI/180))*sin(w*(PI/180))/cos(elev*(PI/180)));
azi=asin(a); // Azimuth
azi=(azi*180)/PI;

b=azi/5.625; // Motorun adım açısı 5.625 olduğu için bu sayıya bölüp kaç adım atması gerektiğini belirliliyor.
//z=elev/5.625;  
printf(lcd_putc,"\fB degeri=%d",b);

   for (i=0; i<=b; i++)
{
   if (i%4 ==0)
      output_d(tam_adim[0]);
      delay_ms(hiz);
   if (i%4 ==1)
      output_d(tam_adim[1]);
      delay_ms(hiz);
   if (i%4 ==2)
      output_d(tam_adim[2]);
      delay_ms(hiz);
   if (i%4 ==3)
      output_d(tam_adim[3]);
      delay_ms(hiz);
}
      if(i>b)
      {
         saat = 0;
         i=0;
         b=0;
         output_d(0x00); //akım çekmememsi için.
      }

   }

}}




z

Ay bilgisi nasil bir bilgi bir bakman lazim.

Ay degerini bir ogren. Print falan etmeyi dene.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

DaisysFox

Rtc kodunu tek başına çalıştırdığımda ay normal bir şekilde yazılıyor ekrana. 1,2,3,4,.. diye girilen değere göre. Ayrıca saat, dakika ve saniye de düzgün bir şekilde çalışıyor. Fakat kodu motor koduyla birleştirince çalışmıyor.
Rtc Kodu:

#include <16f877A.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD

#use delay (clock=4000000)

#define use_portb_lcd TRUE

#define RTC_SCLK PIN_c1
#define RTC_IO PIN_c2
#define RTC_RST PIN_c0

#include <DS1302.c>
#include <lcd.c>
#include <math.h>

long d;
float dec;
int saniye,dakika,saat,ay,yil,haftanin_gunu;
int gun=0;
void main () {

setup_psp(PSP_DISABLED);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);

lcd_init();
rtc_init();

rtc_set_datetime(30,10,6,2,22,52);

while(1) {

rtc_get_time(saat,dakika,saniye);
rtc_get_date(gun,ay,yil,haftanin_gunu);
//printf(lcd_putc,"\fT :%02d/%02d/20%02d",gun,ay,yil);

switch(ay) {

case 1: //ocak
d=gun; 
printf(lcd_putc,"\fGun=%Ld",d);
delay_ms(500);
break;

case 2: //şubat
d=31+gun; 
printf(lcd_putc,"\fGun=%Ld",d);
delay_ms(500);
break;

case 3: //mart
d=59+gun; 
printf(lcd_putc,"\fGun=%Ld",d);
delay_ms(500);
break;

case 4: //nisan
d=90+gun; 
printf(lcd_putc,"\fGun=%Ld",d);
delay_ms(500);
break;

case 5: //mayıs
d=120+gun; 
printf(lcd_putc,"\fGun=%Ld",d);
delay_ms(500);
break;

case 6: //haziran
d=151+gun; 
printf(lcd_putc,"\fGun=%Ld",d);
delay_ms(500);
break;

case 7: //temmuz
d=181+gun; 
printf(lcd_putc,"\fGun=%Ld",d);
delay_ms(500);
break;

case 8: //ağutos
d=212+gun; 
printf(lcd_putc,"\fGun=%Ld",d);
delay_ms(500);
break;

case 9: //eylül
d=243+gun; 
printf(lcd_putc,"\fGun=%Ld",d);
delay_ms(500);
break;

case 10: //ekim
d=273+gun; 
printf(lcd_putc,"\fGun=%Ld",d);
delay_ms(500);
break;

case 11: //kasım
d=304+gun; 
printf(lcd_putc,"\fGun=%Ld",d);
delay_ms(500);
break;

case 12: //aralık
d=334+gun; 
printf(lcd_putc,"\fGun=%Ld",d);
delay_ms(500);
break;
}
printf(lcd_putc,"\f    Saat=%d",saniye);
delay_ms(1000);
printf(lcd_putc,"\nSaat:%02d:%02d:%02d",saat,dakika,saniye);
delay_ms(1000);

}}



ziyaretci

'd' long türünde, "gun" int. gun değişkeni 'd'nin LSB kısmına yerleştirilip, diğer MSB kısımlar ram bellekteki rastgele bir sayıyla dolduruluyor olabilirler. Aslında case'e girer ama 'd' değeri hatalıdır. Bir de RTC çıktıları unsigned olması lazım. Buna da dikkat etmek gerekir.

Önce 'd' ye, düzgün çalışırsa "ay"-a elle değer girip deneyin. Veri türleriyle alakalı bir problem var gibi.

sin fonksiyonunun içinde kullandığınız long türündeki değişkeni sin'nın parametre türüne çevirmeniz gerekebilir.


d=(long)(gun);
switch(ay)
{
case 2:
d+=31
break;
//bla bla...

}

Ek olarak; sürekli RTC okumak sistemi yavaşlatır. Sistem ilk enerjilendiğinde ve belli aralıklarla denetleyicide oluşturacağınız yerel zaman sayacını senkronize etmeniz daha sağlıklı ve performanslı olur.

Tavsiye: Aşama aşama gidin.
-Öncelikle ay değerleri için 'd' düzgün alınıyor mu?
-'d' ye bağlı açılar düzgün hesaplanıyor mu?
-Hesaplanan değer ve açılar motoru döndürecek olan for döngüsünün değişkenine istenilen duyarlılikta aktarılıyor mu?

**Gördüğüm kadarıyla paydada cos fonksiyonu var. Fonksiyonun 90 ve 270 derecelik açılarında tanımsız durum oluşacak, bunun önlemi harici bir parametre ile alınmalı.
(bkz. Run-Time hatası)



Epsilon

CCS bilmiyorum ama
Select Case de neden label kullanmıyorsunuz
Yani d=1 ise case in içinde "goto BIR " deyin BIR de ona ait hesaplamaları yaptırın(1-7 ye kadar olan)sonrada alt satırında bütün değerleri ekrana yazdırın