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 support@ccsinfo.com

Help with Table

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Srig007
Guest







Help with Table
PostPosted: Wed Jun 13, 2007 12:25 pm     Reply with quote

Hi All,
Currently I am working on a small program which takes three inputs from the ADC and immediately output the result obtained by the ADC to the PWM. I am trying to utilize three ADC channels because I have three temperature sensors that I want to control and then output the result to three separate FAN using PWM. Based on the reading of the ADC I want to either increase or decrease the revolution of the fan. Instead of using multiple If statements, I want to have all of the data logged into the lookup table and then just have three if statements one for each ADC-PWM values to control the fan. I know this is possible. My question is how to access the values that I have in each separate lookup table (Store_X, Store_Y, and Store_Z), and compare it to the value I receive from the ADC.

Here is what I have thus far, I have compiled the code but it gives me many syntax errors that I cannot fix. Any help with this is greatly appreciated, thanks.


--Srig



Code:
[size=18]#include   <18F6520.h>
#device    Adc = 10    //Number of bits the ADC will return is 10 bits
#fuses   HS, NOWDT, PUT, BROWNOUT, NOLVP
#use   delay(clock = 20000000)   //Using 20Mhz External Crystal


//Function Declaration
Void init_ADC0(void);
Void init_ADC1(void);
Void init_ADC2(void);




void main()
{
   int16   result_X, result_Y, result_Z, i;
   Setup_ADC_PORTS( ALL_ANALOG);
   Setup_ADC(ADC_CLOCK_DIV_16);
   
   Setup_CCP1(CCP_PWM);   //X
   Setup_CCP2(CCP_PWM);   //Y
   Setup_CCP3(CCP_PWM);   //Z

   While(1)
   {

      Init_ADC0();   //Reading ADC0
      result_X = read_Adc();   //Storing the value of the Read input to result0
       delay_ms(10);
      
      Init_ADC1();   //Reading ADC1
      result_Y = read_ADC();   //Storing the value of the Read input to result1
      delay_ms(10);

      Init_ADC2();    //Reading ADC2
      result_Z = read_ADC();   //Storing the value of the Read input to result2
      delay_ms(10);
      
      
     For(I = 0, I <= 10, I++)
     {   
      if(ResultX = Store_X[i] )   //Comparing Result_X
      {
         setup_PWM1_Duty( Store_X[i][1]);   /
         delay_ms(10);
           }
      else
      {
         Setup_PWM1_Duty(0);   //Turn Off the Fan
         delay_ms(10);
      }

      if(ResultY = Store_Y[i])    //Comparing Result_Y
      {
         setup_PWM2_Duty( Store_Y[i][1] );
         delay_ms(10);
      }
      else
      {
         Setup_PWM2_Duty(0);  //Turn Off the fan
         delay_ms(10);
      }
      

      if(ResultZ = Store_Z[i])   //Comparing result_Z
      {
         setup_PWM3_Duty(Store_Z[i][1]);
         delay_ms(10);
      }
      else
      {
         setup_PWM3_Duty(0);
         delay_ms(10);
      }
            }   


//      Setup_PWM1_Duty(result_x);   //Sending PWM to X
//      Setup_PWM2_DUTY(result_y);   //Sending PWM to Y
//      setup_PWM3_Duty(result_Z);   //Sending PWM to Z
      
      delay_ms(10);            
   }

}



/****************************************************************/
/******************* Changing the ADC Channel *******************/
Void init_ADC0(void)      //Setting up the ADC Channel0    //
{                              //
   Setup_Adc_Channel(0);               //
   delay_us(20);                  //
                        //
}                        //
                        //
Void init_ADC1(void)      //Setting up the ADC Channel1   //
{                        //
   Setup_Adc_Channel(1);               //
   delay_us(20);                  //
                        //
}                        //
                        //
Void init_ADC2(void)      //Setting up the ADC Channel2   //
{                        //
   Setup_Adc_Channel(2);               //
   delay_us(20);                  //
                        //
}                        //
/****************************************************************/


Const int16 Store_X [10][1] = {1, 10      //ADC VALUE = 1, PWM OUTPUT = 10
            ,2, 45      //ADC VALUE = 2, PWM OUTPUT = 45
            ,3, 50      //ADC VALUE = 3, PWM OUTPUT = 50
            ,10, 100   //ADC VALUE = 10, PWM OUTPUT = 100
            ,15, 125   //ADC VALUE = 15, PWM OUTPUT = 125
            ,25, 250   //ADC VALUE = 25, PWM OUTPUT = 250
            ,35, 300   //ADC VALUE = 35, PWM OUTPUT = 300
            ,40, 350   //ADC VALUE = 40, PWM OUTPUT = 350
            ,50, 500   //ADC VALUE = 50, PWM OUTPUT = 500
            ,75, 600   //ADC VALUE = 75, PWM OUTPUT = 600
            ,100, 1023   //ADC VALUE = 100, PWM OUTPUT = 1023
            };

Const int16 Store_Y [10][1] = {1, 10      //ADC VALUE = 1, PWM OUTPUT = 10
            ,10, 45
            ,45, 50
            ,50, 100
            ,65, 200
            ,75, 300
            ,90, 400
            ,100, 550
            ,125, 650
            ,325, 1000
            ,400, 1023   //ADC VALUE = 400, PWM OUTPUT = 1023
            };

Const int16 Store_Z [10][1] = {4, 25      //ADC VALUE = 4, PWM OUTPUT = 25
            ,20, 75
            ,45, 100
            ,50, 200
            ,85, 225
            ,122, 350
            ,175, 500
            ,325, 550
            ,487, 600
            ,650, 750
            ,750, 1023   //ADC VALUE = 750, PWM OUTPUT = 1023
            };[/size]
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jun 13, 2007 3:58 pm     Reply with quote

You have a few undeclared variables, you have mis-spelled several
CCS function names, and you are using commas instead of semi-colons
in some places. You need to study C and then go through the program
and clean up all these problems.
Srigopal007



Joined: 13 Jun 2005
Posts: 11

View user's profile Send private message

PostPosted: Thu Jun 14, 2007 7:33 am     Reply with quote

Thanks for pointing these mistakes out, I had gone back to the compiler manual and fixed the necessary mistakes. Can you please help me with accessing the values that I have in each separate lookup table (Store_X, Store_Y, and Store_Z), and compare it to the value I receive from the ADC.


Here is the modified code. Any help on this is greatly apprciated, thanks.

-Srig

Code:
#include   <18F6520.h>
#device    Adc = 10    //Number of bits the ADC will return is 10 bits
#fuses   HS, NOWDT, PUT, BROWNOUT, NOLVP
#use   delay(clock = 20000000)   //Using 20Mhz External Crystal


//Function Declaration
Void init_ADC0(void);
Void init_ADC1(void);
Void init_ADC2(void);




void main()
{
   int16   result_X, result_Y, result_Z, i;
   Setup_ADC_PORTS(ALL_ANALOG);
   Setup_ADC(ADC_CLOCK_DIV_32);
   
   Setup_CCP1(CCP_PWM);   //X
   Setup_CCP2(CCP_PWM);   //Y
   Setup_CCP3(CCP_PWM);   //Z

   While(1)
   {

      Init_ADC0();   //Reading ADC0
      result_X = read_Adc();   //Storing the value of the Read input to result0
       delay_ms(10);
       
      Init_ADC1();   //Reading ADC1
      result_Y = read_ADC();   //Storing the value of the Read input to result1
      delay_ms(10);

      Init_ADC2();    //Reading ADC2
      result_Z = read_ADC();   //Storing the value of the Read input to result2
      delay_ms(10);
       
       
     For(I = 0; I <= 10; I++)
     {   
      if(Result_X = Store_X[i] )   //Comparing Result_X
      {
         Set_PWM1_Duty( Store_X[i][1]);   /
         delay_ms(10);
           }
      else
      {
         Set_PWM1_Duty(0);   //Turn Off the Fan
         delay_ms(10);
      }

      if(Result_Y = Store_Y[i])    //Comparing Result_Y
      {
         set_PWM2_Duty( Store_Y[i][1] );
         delay_ms(10);
      }
      else
      {
         Set_PWM2_Duty(0);  //Turn Off the fan
         delay_ms(10);
      }
       

      if(Result_Z = Store_Z[i])   //Comparing result_Z
      {
         set_PWM3_Duty(Store_Z[i][1]);
         delay_ms(10);
      }
      else
      {
         set_PWM3_Duty(0);
         delay_ms(10);
      }
            }   


//      Set_PWM1_Duty(result_x);   //Sending PWM to X
//      Set_PWM2_DUTY(result_y);   //Sending PWM to Y
//      set_PWM3_Duty(result_Z);   //Sending PWM to Z
       
      delay_ms(10);             
   }

}



/****************************************************************/
/******************* Changing the ADC Channel *******************/
Void init_ADC0(void)      //Setting up the ADC Channel0    //
{                              //
   Setup_Adc_Channel(0);               //
   delay_us(20);                  //
                        //
}                        //
                        //
Void init_ADC1(void)      //Setting up the ADC Channel1   //
{                        //
   Setup_Adc_Channel(1);               //
   delay_us(20);                  //
                        //
}                        //
                        //
Void init_ADC2(void)      //Setting up the ADC Channel2   //
{                        //
   Setup_Adc_Channel(2);               //
   delay_us(20);                  //
                        //
}                        //
/****************************************************************/


Const int16 Store_X [10][1] = {1, 10      //ADC VALUE = 1, PWM OUTPUT = 10
            ,2, 45      //ADC VALUE = 2, PWM OUTPUT = 45
            ,3, 50      //ADC VALUE = 3, PWM OUTPUT = 50
            ,10, 100   //ADC VALUE = 10, PWM OUTPUT = 100
            ,15, 125   //ADC VALUE = 15, PWM OUTPUT = 125
            ,25, 250   //ADC VALUE = 25, PWM OUTPUT = 250
            ,35, 300   //ADC VALUE = 35, PWM OUTPUT = 300
            ,40, 350   //ADC VALUE = 40, PWM OUTPUT = 350
            ,50, 500   //ADC VALUE = 50, PWM OUTPUT = 500
            ,75, 600   //ADC VALUE = 75, PWM OUTPUT = 600
            ,100, 1023   //ADC VALUE = 100, PWM OUTPUT = 1023
            };

Const int16 Store_Y [10][1] = {1, 10      //ADC VALUE = 1, PWM OUTPUT = 10
            ,10, 45
            ,45, 50
            ,50, 100
            ,65, 200
            ,75, 300
            ,90, 400
            ,100, 550
            ,125, 650
            ,325, 1000
            ,400, 1023   //ADC VALUE = 400, PWM OUTPUT = 1023
            };

Const int16 Store_Z [10][1] = {4, 25      //ADC VALUE = 4, PWM OUTPUT = 25
            ,20, 75
            ,45, 100
            ,50, 200
            ,85, 225
            ,122, 350
            ,175, 500
            ,325, 550
            ,487, 600
            ,650, 750
            ,750, 1023   //ADC VALUE = 750, PWM OUTPUT = 1023
            };
RossJ



Joined: 25 Aug 2004
Posts: 66

View user's profile Send private message

PostPosted: Thu Jun 14, 2007 8:56 am     Reply with quote

Hi Srig,

A few things stand out which you should consider...

1. Your lookup tables are incorrectly dimensioned as 10 x 1 instead of 11 x 2. The dimension is the number of items, even though you access them using index values of 0-10 and 0-1.

2. When you are searching the table, your if statement uses '=' instead of '=='. So you are attempting to perform an assignment instead of a comparison. A better solution would be '<', since this would deal with the range of ADC values between the table entries. This works because your table is sorted.

3. You should access 2 dimensional arrays using two indexes, you do 'Store_Y[i]' which returns a pointer to 'Store_Y[i][0]'. If you want the actual value, you must do 'Store_Y[i][0]'.

4. In the for loops you might consider using (sizeof(Store_Y) / 4) so you avoid coding the size of your arrays in multiple places (which is prone to error). If you don't understand how the sizeof() function works, it's in the manual.

/Ross.
Srigopal007



Joined: 13 Jun 2005
Posts: 11

View user's profile Send private message

PostPosted: Thu Jun 14, 2007 11:24 am     Reply with quote

thanks RossJ and PCM programmer for your great advise,

I always tend to make silly mistakes like the ones you pointed out. I pretty sure that the sizeof(Store_Y)/4) expression will make things easier and error-free, but I have read it but was not able to get as much info on why it is used nor what errors I can potentially get myself into if I did not use it.

I would like to ask some questions since I am trying to implement ADC into my design. I know that there are certain crucial parameters in designing an ADC system, and that is to select the appropriate reference voltage for the device. I do not want to damage the microcontroller by setting a reference voltage that is below the actual operating voltage of the temperature sensor, nor do I want to select a reference voltage that is too high. What and how do I select the appropriate voltage reference for the ADC? Also since I am using the PIC18F6520 microcontroller, do I simply connect the reference voltage to the RA3 pin?


Here is what I have changed based on the recommendations from Ross. Can you please check to see if I have fixed the errors correctly. thanks

--Srig

Fix to Question 1:
Code:
Const int16 Store_Y [11][2] = {1, 10      //ADC VALUE = 1, PWM OUTPUT = 10
            ,10, 45
            ,45, 50
            ,50, 100
            ,65, 200
            ,75, 300
            ,90, 400
            ,100, 550
            ,125, 650
            ,325, 1000
            ,400, 1023   //ADC VALUE = 400, PWM OUTPUT = 1023
            };


Fix to Question2 and Question3:

Code:
      if(Result_X == Store_X[i][0] )   //Comparing Result_X
      {
         Set_PWM1_Duty( Store_X[i][1]);   /
         delay_ms(10);
           }
      else
      {
         Set_PWM1_Duty(0);   //Turn Off the Fan
         delay_ms(10);
      }
RossJ



Joined: 25 Aug 2004
Posts: 66

View user's profile Send private message

PostPosted: Thu Jun 14, 2007 8:40 pm     Reply with quote

Hi Srig,

The reason to use sizeof() is to let the compiler determine how big the array is rather than hard coding it. That way you can't get it wrong. If in the future you add one extra pair of values to the table, the loop will still work correctly. The 'divide by 4' bit is because sizeof() return the number of bytes, but the loop iterates through the rows (4 bytes each).

I think you have a logic problem with your loop and table lookup. My guess is that you want to read the sensor, and use that value to run the fan at some appropriate speed in response. The table defines the relationship between temperature and speed.

The problem is that the ADC can return values in between the ones in your table. Since you are using '==' and not '<' (or similar) in the if statement, you will end up stopping the fan just becuase there is not exact match in the table (which will be most of the time, since you only have 11 entries). I suggest you do something like this...
Code:

for (i = 0; i < sizeof(Store_X) / 4; ++i)
{
   if (Result_X <= Store_X[i][0])   //Comparing Result_X
   {
      Set_PWM1_Duty(Store_X[i][1]);   /
      delay_ms(10);
   }
}

This will work as long as Store_X[i][0] is in increasing order in the table, and you have table rows to cover the boundary conditions. This means you need to cover all possible ADC values. At the very least this means one extra row at the end of the table.

As for the ADC reference voltage... You wont damage the PIC if the input voltage exceeds the reference, so long as you don't exceed VCC (see datasheet for exact voltages). However, the reference determines the voltage which will be reported by the ADC as the highest value (which depends on the resolution you use, i.e. 1023 (10 bits) or 4095 (12 bits).

What voltage range do you expect to get from the sensor?

/Ross.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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