CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

rotary encoder and printf....
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
asunca



Joined: 09 Sep 2005
Posts: 36

View user's profile Send private message

rotary encoder and printf....
PostPosted: Mon Sep 26, 2005 1:46 am     Reply with quote

i am building an encoder and nearly finished with it. but the problem is though i ve written the code well but the printf function doesnt show itself. the slotted optocoupler counts the number of the passing black lines on a circle and sends it out to lcd. speed is "hiz"

Code:


#include <16F877.h>
#device adc=8
#use delay(clock=4000000)
#fuses NOWDT,XT, PUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG

unsigned char sayac=0;
int16 count=0;
int8 hiz=0;
unsigned char sn=0;

#include <LCD.C>
#int_rtcc
void rtcc_isr()
{   
   sayac++;
   sn++;
   if(sayac==2)
   {
      sayac=0;
      hiz=count/6;
      count=0;
   }
   if(sn>=20)
   {
      sn=0;     
      printf(lcd_putc,"%d",hiz);
   }
}



void main()
{
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   set_timer0(0);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);

   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   lcd_init();
   set_tris_a(63);

   enable_interrupts(INT_rtcc);
   enable_interrupts(GLOBAL);

   while(1)
   {
      while(pin_A1==1);     //beyaz
      count++;             //artir
      while(pin_A1==0);    // siyah     
   }

}


"count" is incremented and according to timer0 interrupt speed (variable: hiz) is calculated. and displayed every seconds. interrupt is on the second count of timer0 (65.5*2 miliseconds).
MikeValencia



Joined: 04 Aug 2004
Posts: 238
Location: Chicago

View user's profile Send private message Send e-mail Yahoo Messenger

PostPosted: Mon Sep 26, 2005 7:13 am     Reply with quote

Don't know if it applies to the 8-bitters like the PIC, but i've always been advised in embedded systems programming not to attempt printf() in an ISR.
asunca



Joined: 09 Sep 2005
Posts: 36

View user's profile Send private message

PostPosted: Mon Sep 26, 2005 7:37 am     Reply with quote

i think you are right. i ve thought of it before but i had no choice. is there another way?? thanks
MikeValencia



Joined: 04 Aug 2004
Posts: 238
Location: Chicago

View user's profile Send private message Send e-mail Yahoo Messenger

PostPosted: Mon Sep 26, 2005 8:45 am     Reply with quote

I would guess you would put that printf in your while(1) loop. That is:

Code:

while(1)
{
...
    if (hiz != hiz_previous)
    {
        printf(...); // print out hiz
        hiz_previous = hiz;
    }
...
}


The reason why i introduced an "hiz_previous" variable is to avoid printf'ing hiz if it didnt change.

-Mike
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Mon Sep 26, 2005 9:45 am     Reply with quote

Always keep ISR's as short as possible. If some major function is needed, simply set a flag, in the ISR, and have that flag evaluated somewhere in the main body.

Ronald
asunca



Joined: 09 Sep 2005
Posts: 36

View user's profile Send private message

PostPosted: Mon Sep 26, 2005 10:40 am     Reply with quote

lets see if that will work. i ll inform you as soon as it is tried. thanks to every one
asunca



Joined: 09 Sep 2005
Posts: 36

View user's profile Send private message

PostPosted: Tue Sep 27, 2005 2:33 am     Reply with quote

i ve tried the new method but sorry to say that didnt work. in the main program while loop cannot terminate because of something i dont know. and when i print hiz for try "hiz++ " , the increment of it is like : 10, 20, 30.. an extra zero or integer near it. what is the reason for it?
here is the new one:
Code:


#include <16F877.h>
#device adc=8
#use delay(clock=4000000)
#fuses NOWDT,XT, PUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG

unsigned char sayac=0;
unsigned char count=0;
unsigned char hiz=0;
unsigned char sn=0;
int1 flag=0;


#include <LCD.C>
#int_rtcc
void rtcc_isr()
{
   sayac++;             //  count variable
   sn++;
   if(sayac==2)        //  65,5*2= 131 miliseconds passed
   {
      sayac=0;
      hiz=count*2;
      count=0;
   }
   if(sn>=20)          // say that one second passed
   {
      flag=1;           // printf flag set
      sn=0;     
   }   
}

void main()
{
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
   set_timer0(0);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   lcd_init();
   delay_ms(1);
   set_tris_a(63);
 
   printf(lcd_putc,"\fReady...");

   enable_interrupts(INT_rtcc);
   enable_interrupts(GLOBAL);
   
   while(1)
   {
      //while(pin_A1==0);     //  old ones
      //count++;                  //  old ones
      //while(pin_A1);          //  old ones
      if (pin_a1)
      {
         count++;
         while(pin_a1);
      }
      if (flag)
      {         
         printf(lcd_putc,"\fHIZ=%u",hiz);
         flag=0;
      }
   }

}


i have tried the hiz_previous logic that will probably do but for now no need to place it (thanks to mike)

itimer interrupt works but the program flow doesnt enter to inner loops of isr. as i told above, main loop is stuck somewhere...??
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Tue Sep 27, 2005 8:29 am     Reply with quote

You are evaluating PIN_A1 incorrectly. It should be:

Code:

while(1)
   {
      //while(pin_A1==0);     //  old ones
      //count++;                  //  old ones
      //while(pin_A1);          //  old ones
      if (input(pin_a1))      // NOTE the input() function here
      {
         count++;
         while(input(pin_a1));  // NOTE the input() function here too
      }
      if (flag)
      {         
         printf(lcd_putc,"\fHIZ=%u",hiz);
         flag=0;
      }
   }


The funcion input() looks at the status of the Input pin. Give that a try now.

Also, on a side note, the ISR will probably be entering and exiting multiple times while the printf() statement does it's thing. The value of your variable might be changing while the printf() is printing.

Ronald
asunca



Joined: 09 Sep 2005
Posts: 36

View user's profile Send private message

PostPosted: Tue Sep 27, 2005 8:49 am     Reply with quote

i ve had a quick try and that seemed to work.. ronald thank you.. i am doing the details now.. i ll come back.. bysss
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Tue Sep 27, 2005 9:30 am     Reply with quote

Some comments:

1) Style notation
This is not a good style to define IO pins.
set_tris_a(63); // At first glance doesn´t have any meaning.

using:
set_tris_a(0x3F); // you can know which bit is H and wich is L.

using
set_tris_a(0b0111111);// you can see which bit is H and wich is L.


2) Test against zero for shortest code.
Remember to initilize your variables before using them.
Code:

#int_rtcc
void rtcc_isr()
{     
   sayac--;
   if( !sayac )
     { sayac=2;   
       hiz=count*2;
       count=0;
     }
   
   sn--;
   if( !sn )     
     { sn=20;
       flag=1;               // printf flag set
     }
}


3) In the Mike´s suggestion I would add:
Code:

...
    if(hiz != hiz_previous)
      {
        disable_interrupts(INT_rtcc);
        printf(...); // print out hiz
        enable_interrupts(INT_rtcc);
        hiz_previous = hiz;
      }
...


Humberto
asunca



Joined: 09 Sep 2005
Posts: 36

View user's profile Send private message

PostPosted: Wed Sep 28, 2005 4:48 am     Reply with quote

i did all you told ,it works ok but has a little problem. when the rotor gives up turning, the lcd is stuck at a number sometimes and sometimes it shows zero as expected. what is missing ??
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Wed Sep 28, 2005 6:57 am     Reply with quote

Pls could you post the whole code that demostrate the problem ?

Humberto
asunca



Joined: 09 Sep 2005
Posts: 36

View user's profile Send private message

PostPosted: Wed Sep 28, 2005 7:22 am     Reply with quote

Code:


#include <16F877.h>
#device adc=8
#use delay(clock=20000000)
#fuses NOWDT,HS, PUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG

unsigned char sayac=0;
unsigned char sayim=0;
unsigned char hiz_previous=0;
unsigned char hiz=0;
unsigned char sn=0;
int1 flag=0;

#include <LCD.C>
#int_rtcc
void rtcc_isr()
{
   sayac++;
   sn++;
   if(sayac==2)
   {
      hiz=sayim*2;
      sayim=0;
      sayac=0;
   }
   if(sn>=20)
   {
      flag=1;
      sn=0;
   }

}

void main()
{
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);

   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
   set_timer0(0);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   lcd_init();
   delay_ms(1);
   set_tris_a(0b00111111);

   printf(lcd_putc,"\fReady...");

   enable_interrupts(INT_rtcc);
   enable_interrupts(GLOBAL);

   while(1)
   {
      //while(input(pin_A1==0));     
      //sayim++;             
      //while(input(pin_A1));   
      if (input(pin_a1))
      {
         sayim++;
         while(input(pin_a1));
      }
      if (flag)
      {
         disable_interrupts(INT_rtcc);
         if (hiz != hiz_previous)
            {
               printf(lcd_putc,"\fHIZ=%u",hiz);
               hiz_previous=hiz;
            }
         sayim=0;
         flag=0;
         enable_interrupts(INT_rtcc);
      }

   }

}

Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Wed Sep 28, 2005 7:34 am     Reply with quote

Code:

unsigned char sayac=0;
unsigned char sayim=0;
unsigned char hiz_previous=0;
unsigned char hiz=0;
unsigned char sn=0;


By default in CCS variables are unsigned integers.


Just disable the RTCC while using the LCD, test this way:

Code:

   if (flag)
      {
        if (hiz != hiz_previous)
           {
             disable_interrupts(INT_rtcc);
             printf(lcd_putc,"\fHIZ=%u",hiz);
             enable_interrupts(INT_rtcc);
             hiz_previous=hiz;
           }
        sayim=0;
        flag=0;
      }


Humberto
sseidman



Joined: 14 Mar 2005
Posts: 159

View user's profile Send private message

PostPosted: Wed Sep 28, 2005 10:20 am     Reply with quote

Humberto wrote:


Just disable the RTCC while using the LCD, test this way:



For many apps, it would be ill advised to give up the ghost on your count to update a display. The count should be inviolate.

Scott
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group