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

I am using interrupt to control external device
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
maiprog



Joined: 24 Mar 2014
Posts: 7

View user's profile Send private message

I am using interrupt to control external device
PostPosted: Tue Mar 25, 2014 7:01 am     Reply with quote

This is my code. I need to HIGH and LOW the pin_b2
so i need delay_us... my code is below:
Code:

#INT_RTCC
void inductor_firing_isr()
{
    if(enable_firing_interrupt == 1)
    {
    output_high(PIN_B2);
    delay_us(20);
    output_low(PIN_B2);
    set_timer0(0);
    enable_firing_interrupt = 0;
    }
}


Is their any way rather than using the delay in interrupts ?
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Mar 25, 2014 7:29 am     Reply with quote

yes, simply set a flag within the ISR then in main(), test that 'flag' and if set, do what you want with pin_b2.

You want ISRs to be small and fast, so NO delays, printf(), or math just simple set/clr flags.

hth
jay
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Tue Mar 25, 2014 7:48 am     Reply with quote

Timer 0 will be set to zero when the interrupt is taken.

Therefore you can look for a small count greater than zero as your delay,
based on the timer prescalar- master clock etc...

If latency for the pulse you make is critical after the int - then you will have to do it in the isr.

None of this gets around the question of ISR time hogging.

If you have no other foreground or overlapped #int handlers
that could be the alternative to using the ugly delay_us().

Without knowing the PIC - i don't know if you are reading an 8 or 16 bit register for the timer though.

Code:

# define mydelay 7
#INT_RTCC
void inductor_firing_isr()
{
    if(enable_firing_interrupt == 1)
    {
    output_high(PIN_B2);
    while(get_timer0()<mydelay){};
    output_low(PIN_B2);
    set_timer0(0);
    enable_firing_interrupt = 0;
    }
}
maiprog



Joined: 24 Mar 2014
Posts: 7

View user's profile Send private message

PostPosted: Tue Mar 25, 2014 9:07 am     Reply with quote

I am using pic18f4520 and int8
maiprog



Joined: 24 Mar 2014
Posts: 7

View user's profile Send private message

PostPosted: Tue Mar 25, 2014 9:08 am     Reply with quote

Why mydelay 7, any reason for that
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Tue Mar 25, 2014 10:49 am     Reply with quote

Because if you put the delay in the ISR, then any delays in your main code could cause interrupts to be disabled (depends on if the compiler inlines the delay or not).

Without knowing much about your hardware situations, some other thoughts:

If your clock is fast enough, you could do a small conditional in your ISR:

Code:


#INT_RTCC
void inductor_firing_isr()
{

   static BOOLEAN pulse = FALSE;

   if(enable_firing_interrupt){
      if(!pulse)
         output_high(PIN_B2);
         set_timer0(250);  //pick a value here that makes the interrupt happen 20us later
         pulse = TRUE;
      }else{
         output_low(PIN_B2);
         set_timer0(0);
         pulse = FALSE;
         enable_firing_interrupt = FALSE;
      }
   }
}



In this scenario, when you set enable_firing_interrupt to TRUE, the first IF happens setting the line high and the interrupt finishes. The set_timer0() call in the IF section should be selected to account for the time it takes for the interrupt to save registers, etc. The next time the interrupt fires, it goes to the ELSE section, which brings the line low and disables the section.
maiprog



Joined: 24 Mar 2014
Posts: 7

View user's profile Send private message

PostPosted: Tue Mar 25, 2014 12:47 pm     Reply with quote

K, and i am too getting errors such as:
interrupt disabled call to prevent re-entrancy:[lcd_send_nibble], [lcd_send_nibble] ,
[@mulff],[@delay_ms1] and [synchronize_on_rising_edge]
How to eliminate these errors ?
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Mar 25, 2014 1:33 pm     Reply with quote

You should have posted your entire program, not just the ISR, as I can see those 'errors' come from an LCD function or routine NOT in your original post.

You must understand that the PIC once in a delay function can not be called a second time.Usually you'll get this error with delay code inside an ISR.

If you post your entire code,others can better comment on what's going on....how to fix..

hth
jay
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Tue Mar 25, 2014 4:13 pm     Reply with quote

maiprog wrote:
K, and i am too getting errors such as:
interrupt disabled call to prevent re-entrancy:[lcd_send_nibble], [lcd_send_nibble] ,
[@mulff],[@delay_ms1] and [synchronize_on_rising_edge]
How to eliminate these errors ?


This not an error, it is a warning. However, you do need to pay attention to them. It says that you are using functions in your ISR (delay_ms, lcd_send_nibble. synchronize_on_rising_edge) and in your main code. You really should avoid doing this. It means that you cannot fire interrupts while these functions run because of how you placed them in the code. Avoid using ms delays or LCD functions or Floating point operations in your ISR. It can cause a lot of problems for you.
maiprog



Joined: 24 Mar 2014
Posts: 7

View user's profile Send private message

PostPosted: Wed Mar 26, 2014 12:30 am     Reply with quote

This is my code....
and i am using the LCD.c inbuilt driver of ccs compiler.
Code:
#include <18f4520.h>
//#fuses HS, NOWDT, NOPROTECT, NOPUT, NOBROWNOUT
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV25                   //Brownout reset at 2.5V
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES LVP                      //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES PBADEN                   //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOCPB                    //No Boot Block code protection
#FUSES NOLPT1OSC                //Timer1 configured for higher power operation
#FUSES MCLR                     //Master Clear pin enabled
//#FUSES XINST                    //Extended set extension and Indexed Addressing mode enabled
#use delay(clock=25M)
#include <LCD.C>

//#use standard_io(a)
//#use standard_io(b)
#zero_ram
 
#define ON 1
#define OFF 0
#define NUM_CAP_BANKS 3
#define TCR_LIMIT 10
#define LEADING_LIMIT -28
#define TURN_ON -1
 
// Unsigned INT (8 bit):   0   -> +256
// Signed INT (8 bit):   -128 -> +128
// CCS Compiler makes INTs unsigned by default
 
//-------------
//Fuzzy System
//-------------
//Input Membership Function
//                                -20  -15  -10   -5   0    5   10  15  20  25
signed int PhaseAngle_Input[10] = {40,  45,  50,  55,  60,  65, 70, 75, 80, 85};
 
//Output Membership Function
//                                           91  95  100  112  115  122  124  126 128 135
unsigned int FiringAngleChange_Output[10] = {1,  5,  10,  22,  25,  32,  34,  36, 38, 45};
 
//Fuzzy TSK Rules
unsigned int Rules[10] = {0, 1, 2, 3, 4, 5, 5, 7, 8, 9};
 
// One Input - One Output Fuzzy Function Prototype
unsigned int fuzzy_tsk(float);

//General Prototypes
void turn_capacitors_on();
void turn_capacitors_off();
void turn_inductor_on();
void turn_inductor_off();
signed long int round(float x);
void synchronize_on_rising_edge();
 
//Globals - little necessary
signed long ticks = 0;
//short int look_for_voltage = 1;
float phase_angle = 0.0;
unsigned long int firing_angle = 90;
short int voltage_state = 0;
short int current_state = 0;
short int bLagging = 0;
short int voltage_initial_state = 0;
short int current_initial_state = 0;
short int enable_firing_interrupt = 0;
float time_delay = -1.0;
int counter_set = 0;
signed long int interrupt_counter = 0;
 
/* -----------------------------------------------*/
/* Perform Capacitor Bank TSC Initialization Here */
/* -----------------------------------------------*/
int capacitor_banks[NUM_CAP_BANKS];
 
/* TSC Capacitor Bank Prototypes */
void set_capacitor_banks(void);
void control_capacitor_banks(int, int );
void turn_on_all_capacitor_banks(void);
void turn_off_all_capacitor_banks();
void control_capacitor_banks(int, int );
int find_number_of_cap_banks_on(void);
 
/* ------------- */
/* TCR Interrupt */
/* ------------- */
#INT_RTCC
void inductor_firing_isr()
{
    if(enable_firing_interrupt == 1)
    {
    output_high(PIN_B2);
    delay_us(20);
    output_low(PIN_B2);
    set_timer0(0);
    enable_firing_interrupt = 0;
    }
}
 
/* ------------- */
/* LCD Interrupt */
/* ------------- */
#INT_TIMER2
void timer_2_isr()
{
    interrupt_counter++;
    if(interrupt_counter >= 100)
    {
       interrupt_counter=0;
       printf(LCD_putc,"\f%3.2f",phase_angle);
 
       lcd_gotoxy(0,1);
       printf(LCD_putc, "FA: %ld", firing_angle);
 
       lcd_gotoxy(0,2);
       printf(LCD_putc, "Cap: %d", find_number_of_cap_banks_on()); 
 
       //Synchronize Voltage Since Cycles Missed
       synchronize_on_rising_edge();
    }
}

/* ---------------*/
/* Main mSVC Code */
/* ---------------*/
void main()
{
    signed long int capacitor_counter = TURN_ON;
 
    //Set the LCD
    lcd_init();
 
    //Set Up Timer 0
    set_rtcc(0);
    setup_counters(RTCC_INTERNAL, RTCC_DIV_128);
    enable_interrupts(INT_RTCC);
 
    //Set Up Timer 2
    set_timer2(0);
    setup_timer_2(T2_DIV_BY_16, 0xFF, 16);
    enable_interrupts(INT_TIMER2);
 
    //Turn On All Interrupts
    enable_interrupts(GLOBAL);
 
    //Set up timer 1
    set_timer1(0);
    setup_timer_1( T1_INTERNAL | T1_DIV_BY_4);
    setup_timer_1( T1_INTERNAL | T1_DIV_BY_8);
 
    //Initialize Capacitor Banks to Off
//    turn_off_all_capacitor_banks();
 
    //Synchronize Voltage
    synchronize_on_rising_edge();
 
    //------------------------------
    //Main While Loop Controls PSVC
    //------------------------------
     while(ON)
    {
 
//Turn Off the LCD
 disable_interrupts(INT_TIMER2);
 
  //Update Capacitor Banks Once Every 5 Seconds
  if(capacitor_counter > 300 || capacitor_counter == TURN_ON)
 {
  //Reset Capacitor Counter
     capacitor_counter = 0;
 
  //Set Capacitor Banks Based On Previous phase_angle
   set_capacitor_banks();
 
  //Synchronize Voltage
  synchronize_on_rising_edge();
 }
 
//Increment Capacitor Counter
 capacitor_counter++;
//--------------------------
  //Continue Controlling mSVC
 //--------------------------
 //Determine Leading/Lagging
  voltage_state = input(PIN_A0);
  voltage_initial_state = voltage_state;
  while(voltage_initial_state == voltage_state)
 {
  voltage_state = input(PIN_A0);
 }
 
  //Start Inductor Countdown as Voltage Crosses Zero
  if(time_delay != -1.0)
 {
  set_timer0(counter_set);
  enable_firing_interrupt = 1;
 }
 
  //Take Current Reading
  current_state = input(PIN_A1);
 
  //Going from L->H
  if((voltage_initial_state == 0) && (voltage_state == 1))
 {
  if(current_state == 0)
  {
   bLagging = 1;
  }
  else
  {
   bLagging = 0;
  }
 }
 
 
  //Going from H->L
  else if((voltage_initial_state == 1) && (voltage_state == 0))
 {
  if(current_state == 0)
  {
   bLagging = 0;
  }
   
  else
  {
   bLagging = 1;
  }
 }
 
  if(bLagging == 1)
 {
  //Read Voltage First
    //Wait for Voltage Zero Crossing
  voltage_state = input(PIN_A0);
  while(voltage_state == input(PIN_A0))
  {
  }
 
    //Start Inductor Countdown as Voltage Crosses Zero
  if(time_delay != -1.0)
  {
   set_timer0(counter_set);
   enable_firing_interrupt = 1;
  }
  set_timer1(0);
 
   
//Read Current
    //Wait for Current Zero Crossing
  current_state = input(PIN_A1);
  while(current_state ==  input(PIN_A1))
  {
  }
 
  ticks = get_timer1();
 }
 
 else
 {
  //Read Current  First
    //Wait for Current Zero Crossing
  current_state = input(PIN_A1);
  while(current_state ==  input(PIN_A1))
  {
  }
 
  //Set the Timer
  set_timer1(0);
 
  //Read Voltage
    //Wait for Voltage Zero Crossing
  voltage_state = input(PIN_A0);
  while(voltage_state ==  input(PIN_A0))
  {
  }
 
  //Start Inductor Countdown as Voltage Crosses Zero
  if(time_delay !=  -1.0)
  {
   set_timer0(counter_set);
   enable_firing_interrupt = 1;
  }
   
  ticks = get_timer1();
  ticks = -ticks;
 }
 
  //Calculate Phase Angle from Ticks Counted
  phase_angle = ( ((float)ticks * (float)0.0000016) / (1.0 / 60.0)) * 360.0;
 
//Account for Rollover
  if((phase_angle <= -170.0) && (phase_angle >= -180.0 ))
 {
    phase_angle = -(180.0 + phase_angle);
 }
 
//Weed out False Signals
  if((phase_angle > -50.0) && (phase_angle < 130.0))
 {
 
  //Ensure Lower Bound is Met           
  if(phase_angle <=  -20)
  {
   phase_angle = -19;
  }
  if( phase_angle > -55 && phase_angle < 55 )
  {
 
   //Invoke Fuzzy System
      //Fuzzy System Returns Updated Firing Angle
   firing_angle = fuzzy_tsk(phase_angle);
 
      //Convert Desired Firing Angle to a Delay Time
      time_delay = (((float)firing_angle / 360.0) * (1.0 / 60.0));
      counter_set = round(time_delay / 0.0000256);
      counter_set = 255 - counter_set;
               }
 
    //Show the Phase on LCD
  enable_interrupts(INT_TIMER2);
 }
}
}
 
//------------------------------
//Set Number of Capacitor Banks
//------------------------------
void set_capacitor_banks()
{
    int i=0;
 
    //Check if Phase is Lagging - Only Add More Capacitors
    //If Phase Is Lagging
    if (phase_angle > 0)
    {
  //Only Add More Capacitors If Phase > TCR_LIMIT Degrees
  //10 Degrees Is the Current Span of the TCR Branch
  if (phase_angle > TCR_LIMIT)
    {
    //Add the Next Available Capacitor Bank
    for(i=0; i<NUM_CAP_BANKS; i++)
  {
   if (capacitor_banks[i] == OFF)
   {
    //Turn On Capacitor Bank
    control_capacitor_banks(i,ON);
    break;
   }
  }
 }
    }
 
 
    //Remove a Capacitor Bank If Leading Too Much
    else if (phase_angle < LEADING_LIMIT)
    {
  for(i=NUM_CAP_BANKS-1; i>=0; i--)
    {
    if (capacitor_banks[i] == ON)
   {
       //Turn Off Capacitor Bank
   control_capacitor_banks(i,OFF);
   break;
  }
 }
   }
}
 
//-----------------------------------------
//Returns the Number Of Capacitor Banks On
//-----------------------------------------
int find_number_of_cap_banks_on(void)
{
   int i=0;
   int banks_turned_on = 0;
   for(i=0; i<NUM_CAP_BANKS; i++)
   {
       if (capacitor_banks[i] == ON)
       {
           banks_turned_on++;
       }
   }   
 
   return (banks_turned_on);
}
 
//----------------------------
//Control Capacitor Banks
//Individual PIC Pins Needed
//----------------------------
void control_capacitor_banks(int bank, int mode)
{
 
//Wait for Current to Cross Zero Before Switching Capacitor
  current_state = input(PIN_A1);
  current_initial_state = current_state;
  while(current_initial_state == current_state)
 {
  current_state = input(PIN_A1);
 }
 
  //1st Capacitor Bank
  if (bank == 0) 
 {
    if (mode == OFF)
  {
        output_low(PIN_B1);
        capacitor_banks[bank] = OFF;
        }
  else
  {
        output_high(PIN_B1);
        capacitor_banks[bank] = ON;
  }
 }
 
  //2nd Capacitor Bank
  else if (bank == 1)   
 {
    if (mode == OFF)
  {
        output_low(PIN_B3);
        capacitor_banks[bank] = OFF;
  }
  else
  {
        output_high(PIN_B3);
        capacitor_banks[bank] = ON;
  }
 }
 
  //3rd Capacitor Bank
        else if (bank == 2)
 {
    if (mode == OFF)
  {
        output_low(PIN_A2);
        capacitor_banks[bank] = OFF;
  }
  else
  {
        output_high(PIN_A2);
        capacitor_banks[bank] = ON;
  }
 }
}
 
//----------------------------------------
//Synchronize on Rising Edge of Voltage
//Set Capacitor Banks
//---------------------------------------
void synchronize_on_rising_edge()
{
    //Determine Leading/Lagging
    voltage_state = input(PIN_A0);
    voltage_initial_state = voltage_state;
 
    //Wait for Voltage to Change State
    while(voltage_initial_state == voltage_state)
    {
    voltage_state = input(PIN_A0);
    }
 
    //Take Current Reading
    current_state = input(PIN_A1);
 
    //Going from L->H
    if((voltage_initial_state == 0) && (voltage_state == 1))
    {
  if(current_state == 0)
 {
  bLagging = 1;
 }
 else
 {
  bLagging = 0;
 }
    }
 
  //Going from H->L
  else if((voltage_initial_state == 1) && (voltage_state == 0))
  {
  if(current_state == 0)
 {
  bLagging = 0;
 }
 else
 {
  bLagging = 1;
 }
  }
 
//Wait for Rising Edge of Voltage
 if(bLagging == 1)
 {
  if(input(PIN_A0) == 0)
 {
  while(input(PIN_A0) ==  0)
  {
    //Just Wait for Voltage to Go from H->L
  }
 }
 
 else
 {
  if(input(PIN_A1) == 0)
 {
  while(input(PIN_A1) ==  0)
  {
    //Just Wait for Current to Go from H->L
  }
 }
}
 }}
//-----------------------------
//Rounding Function on a Float
//-----------------------------
signed long int round(float x)
{
    //float decimal = 0.0;  //Commented to Save RAM
    int return_rounded = 0;
 
    if((x - ((signed long int)x)) < 0.5)
    {
        return_rounded = ((signed long int)x);  //This is the floor function
    }
    else
    {
  return_rounded = ((signed long int)(x+1));  //This is the ceil function
    }
 
    return (return_rounded);
}
//----------------------------------
//One input-output TSK Fuzzy Engine
//---------------------------------
unsigned int fuzzy_tsk(float crisp_in)
{
   float fired[2] = {0,0};
   int rules[2] = {0,0};
   unsigned int out = 0;
   signed int a = 0;
   signed int b = 0;
   signed int c = 0;
   signed int d = 0;
   signed int e = 0;
   signed int f = 0;
   signed int g = 0;
   signed int h = 0;
   signed int i = 0;
   signed int j = 0;
 
   a = PhaseAngle_Input[0];  // -40       
   b = PhaseAngle_Input[1];  // -30       
   c = PhaseAngle_Input[2];  // -12       
   d = PhaseAngle_Input[3];  // -5       
   e = PhaseAngle_Input[4];  // 0       
   f = PhaseAngle_Input[5];  // 5       
   g = PhaseAngle_Input[6];  // 12       
   h = PhaseAngle_Input[7];  // 30       
   i = PhaseAngle_Input[8];  // 40       
   j = PhaseAngle_Input[9];
 
   //Scale to Fit Fuzzy Rules
   crisp_in += 60.0;
 
   //----------------
   //Start Fuzzy TSK 
   //----------------
   if ((crisp_in >= a) && (crisp_in < b))
   {
         fired[0] = (-1.0) * ( crisp_in / (float)a ) + 1.0;
    rules[0] = 0;
    rules[1] = 1;
   }
 
   else if ((crisp_in >= b) && (crisp_in < c))
   {
    fired[0] = ((-1.0 )* crisp_in + (float)c) /((float)(c-b));
    rules[0] = 1;
    rules[1] = 2;
   }
 
   else if ((crisp_in >= c) && (crisp_in < d))
   {
    fired[0] = ((-1.0)* crisp_in + (float)d) / ((float)(d-c));
    rules[0] = 2;
    rules[1] = 3;
   }
 
   else if ((crisp_in >= d) && (crisp_in < e))
   {
    fired[0] = ((-1.0)* crisp_in+ (float)e) / ((float)(e-d));
    rules[0] = 3;
    rules[1] = 4;
   }
 
   else if ((crisp_in >= e) && (crisp_in < f))
   {
    fired[0] = ((-1.0)* crisp_in + (float)f) / ((float)(f-e));
    rules[0] = 4;
    rules[1] = 5;
   }
 
   else if ((crisp_in >= f) && (crisp_in < g))
   {
    fired[0] = ((-1.0)*crisp_in+ (float)g) / ((float)(g-f));
    rules[0] = 5;
    rules[1] = 6;
   }
 
   else if ((crisp_in >= g) && (crisp_in < h))
   {
    fired[0] = ((-1.0)*crisp_in+(float)h) / ((float)(h-g));
    rules[0] = 6;
    rules[1] = 7;
   }
 
   else
   {
       rules[0] = 7;
       rules[1] = 8;
   }
 
   fired[1] = 1 - fired[0];
 out = (unsigned int)(FiringAngleChange_Output[Rules[rules[0]]]*fired[0] +
FiringAngleChange_Output[Rules[rules[1]]]*fired[1]);
 
  // Scale Firing Angle from Fuzzy Rules
   out += 90;
   return out;
}
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Wed Mar 26, 2014 6:45 am     Reply with quote

The timer interrupt is your issue. Printing to the LCD and also calling find_number_of_cap_banks_on() will cause most if not all those. It's not a very safe or stable design. Your timer will prevent your other interrupt from firing and causes the disabling of interrupts in the main.

A better approach would be to set a flag in the ISR and handle monitoring that flag in your main, updating as you are able.
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Mar 26, 2014 7:40 am     Reply with quote

These two fuse settings are wrong and can cause a lot of headaches!

#FUSES LVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
//#FUSES XINST //Extended set extension and Indexed Addressing mode enabled



99% of programmers do NOT use LVP. so select NOLVP

commenting out the XINST does not necessarily select NOXINST.

You're always best to configure them yourself, do not rely on 'wizards' or 'defaults'. With PICs having more fuses and instructions , always confirm from the listing what the fuses really are.Even compiler versions might change them as well...

Interesting to see 'fuzzy' logic ! I thought it dies 2 decades ago !

hth
jay
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Mar 26, 2014 12:48 pm     Reply with quote

there are a number of other time wasting features in the program. this one jumped out at me:
Code:
 if(time_delay != -1.0)


rather than a floating point test -it would be simpler to do the test ONCE when you assign a new value to time_delay and use a flag such as :

int1 TDnot1

then you are setting it to zero or one as the present assignment of time_delay might require.
testing IT repeatedly uses VERY few precious clock cycles
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Mar 26, 2014 1:21 pm     Reply with quote

floats in general are a HUGE waste of time and processing power..

also printf()s inside ISRs is very,very bad programming.

jay
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Mar 26, 2014 1:48 pm     Reply with quote

let me reinforce what Jay means :
Code:
 //Calculate Phase Angle from Ticks Counted
  phase_angle = ( ((float)ticks * (float)0.0000016) / (1.0 / 60.0)) * 360.0;
 
//Account for Rollover
  if((phase_angle <= -170.0) && (phase_angle >= -180.0 ))
 {
    phase_angle = -(180.0 + phase_angle);
 }
 
//Weed out False Signals
  if((phase_angle > -50.0) && (phase_angle < 130.0))
 {



phase_angle need not be a float, since it's underlying "value" is derived from less than half of timer 1's register maximum and after more tedious floating point math to get to be "degrees" -minus your error limit test -the working resolution is less than 16000 counts of timer1!!!

ie: the BEST resolution of the 'float' you are likely to get is one part is
about 16000

using your own phase_angle integer coordinate space could be done with a signed int16 and the math would be so MUCH faster ..
THAT could be converted if need be when it changes for LCD display..

as a rule ONLY use floats when the precision of integers won't do.
HINT: 16 bit signed is all you need for your app!

in your case- INTeger math could do it all, even the LCD display with a bit of creativity .
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