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

Solar tracking mechanism PIC16F877A

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



Joined: 28 Jul 2013
Posts: 6
Location: Malaysia

View user's profile Send private message

Solar tracking mechanism PIC16F877A
PostPosted: Sun Jul 28, 2013 5:21 am     Reply with quote

Hello guys. I'm doing a project about solar tracking mechanism and used PIC16F877A as my microcontroller. But I have troubles on the programming part.

Code:

#include <16F877A.h> //Include all the necessary variables available for PIC16F877A.
#device ADC=8 //Set the ADC as 8bit.
#fuses XT,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000) //As we are using 4MHz clock oscillator.

//#use fixed_io(b_outputs = PIN_B0, PIN_B1) //Set Port B as the output.

char vthreshold = 1; //Declare threshold value for voltage read from both LDR.

char readValue_0();
char readValue_1();

void main()
{
   char call_A0, call_A1;
   
   setup_adc_ports(ALL_ANALOG); //Set the ports to read analog input.
   setup_adc(ADC_CLOCK_INTERNAL); //Declared as we are using external clock.

   while(1) //To make an eternal loop.
   {   
   call_A0 = readValue_0();
   call_A1 = readValue_1();
   
   char sbtrc = call_A0-call_A1; //Subtraction value.
   
   if(call_A0 >= call_A1)
   {
      if(sbtrc <= vthreshold)
         {
            output_bit(PIN_B0,1); //The motor will
            output_bit(PIN_B1,0); //move clockwise.
         }
      else
      output_bit(PIN_B0,1); //The motor will
      output_bit(PIN_B1,0); //move clockwise.
   }
   else if(call_A0 <= call_A1)
   {
      output_bit(PIN_B0,0); //The motor will
      output_bit(PIN_B1,1); //move counterclockwise
   }
   else
   {
      output_bit(PIN_B0,0);
      output_bit(PIN_B1,0);
   }
   }
}

readValue_0()
{
   unsigned int8 adcValue; //Declare the variables.
   
   set_adc_channel(0); //Get the readings from the port connected to LDR1.
 
   delay_us(50); //Delay to give the circuit some buffer time to operate.
   adcValue = read_adc();//Read the voltage value from the LDR1.
   char adcV1 = (adcValue*5)/255; //Convert the digital value to analog.
   return adcV1;
}

readValue_1()
{
   unsigned int8 adcValue; //Declare the variables.
   
   set_adc_channel(1); //Get the readings from the port connected to LDR1.
   
   delay_us(50); //Delay to give the circuit some buffer time to operate.
   adcValue = read_adc(); //Read the voltage value from the LDR1.
   char adcV2 = (adcValue*5)/255; //Convert the digital value to analog.
   return adcV2;
}


I was hoping that the voltage value that the PinA0 and A1 read will act as the manipulative variable so that the output of Pin B0 and B1 will give high or low output. But unfortunately when I try it on my board, the output it gave is just the same, which is the Pin B0 will always be high no matter how much I vary the voltage value from Pin A0 and A1. Btw, I also not sure if how I read the input and output value is correct. So I'm hoping you guys can help me out on this. Thanks in advance![/code]
temtronic



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

View user's profile Send private message

PostPosted: Sun Jul 28, 2013 6:00 am     Reply with quote

You really don't need this line and it's mate...

char adcV1 = (adcValue*5)/255; //Convert the digital value to analog

...
Play 'computer' and see what happens when the adcValue is greater than say 52 bits.

Stick with the raw ADC data.You're only comparing which is bigger,so no 'fancy math' is reqired AND consider what happens when call_A0=call_A1 !
You should 'printout' the numbers to a PC or LCD if possible to give you feedback that the program is working as expected (or not).

Also be sure that the 'mechanical/electrical' section ( the LDR units) are reasonably 'matched' to give a proper response.

hth
jay
mpingu



Joined: 28 Jul 2013
Posts: 6
Location: Malaysia

View user's profile Send private message

PostPosted: Sun Jul 28, 2013 6:48 am     Reply with quote

temtronic wrote:
You really don't need this line and it's mate...

char adcV1 = (adcValue*5)/255; //Convert the digital value to analog

...
Play 'computer' and see what happens when the adcValue is greater than say 52 bits.

Stick with the raw ADC data.You're only comparing which is bigger,so no 'fancy math' is reqired AND consider what happens when call_A0=call_A1 !
You should 'printout' the numbers to a PC or LCD if possible to give you feedback that the program is working as expected (or not).

Also be sure that the 'mechanical/electrical' section ( the LDR units) are reasonably 'matched' to give a proper response.

hth
jay


thanks for the help jay Smile

How do I print it actually? Coz I won't be using LCD for the project & I don't quite sure how to printout the output value to the PC. And also then, my threshold value should be in binary number?
mpingu



Joined: 28 Jul 2013
Posts: 6
Location: Malaysia

View user's profile Send private message

PostPosted: Sun Jul 28, 2013 6:52 am     Reply with quote

Also, do I require this line? What is the effect of having this line actually?

Code:
//#use fixed_io(b_outputs = PIN_B0, PIN_B1) //Set Port B as the output.
temtronic



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

View user's profile Send private message

PostPosted: Sun Jul 28, 2013 7:04 am     Reply with quote

Do not use 'fixed_io...' unless you're a really good programmer !
Let the compiler handle what direction the I/O pins need to be for your programs.That's one of the great features of CCS C compiler..it'll do all the 'hidden' details for you.
If you improperly code an I/O pi for input when it's supposed to be an output, you will not get the result you're expecting.

For 'printing to a PC', just look at the 'help' files( press F11 when project is open) and lookup 'printf'. Also, check some of the example programs CCS supplies. TONS of great information on how to do it!
Yes, it'll take a bit of time to scan and read, but you'll be a better programmer that just 'cutandpaste'.
hth
jay
mpingu



Joined: 28 Jul 2013
Posts: 6
Location: Malaysia

View user's profile Send private message

PostPosted: Sun Jul 28, 2013 7:55 am     Reply with quote

temtronic wrote:
Do not use 'fixed_io...' unless you're a really good programmer !
Let the compiler handle what direction the I/O pins need to be for your programs.That's one of the great features of CCS C compiler..it'll do all the 'hidden' details for you.
If you improperly code an I/O pi for input when it's supposed to be an output, you will not get the result you're expecting.

For 'printing to a PC', just look at the 'help' files( press F11 when project is open) and lookup 'printf'. Also, check some of the example programs CCS supplies. TONS of great information on how to do it!
Yes, it'll take a bit of time to scan and read, but you'll be a better programmer that just 'cutandpaste'.
hth
jay


Thank you very much for your help jay, it worked! Very Happy
mpingu



Joined: 28 Jul 2013
Posts: 6
Location: Malaysia

View user's profile Send private message

PostPosted: Sun Jul 28, 2013 11:41 am     Reply with quote

ok, now i've encountered another problem. I'm expecting it to stop when input the value from Pin A0 and A1 is equal but it doesn't stop. What should I do?
temtronic



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

View user's profile Send private message

PostPosted: Mon Jul 29, 2013 7:04 am     Reply with quote

your code...
Code:

if(call_A0 >= call_A1)  ////// !!!!!
   {
      if(sbtrc <= vthreshold)
         {
            output_bit(PIN_B0,1); //The motor will
            output_bit(PIN_B1,0); //move clockwise.
         }
      else
      output_bit(PIN_B0,1); //The motor will
      output_bit(PIN_B1,0); //move clockwise.
   }
   else if(call_A0 <= call_A1)  ////// !!!!!
   {
      output_bit(PIN_B0,0); //The motor will
      output_bit(PIN_B1,1); //move counterclockwise

'play computer'...

what happens when call_A0 = call_A1 ???
what will the PIC do when this condition is true ???

answer...
the PIC will command the motor to go cw, then ccw, cw, then ccw, as long as the condition is met.

possible cure...
one is to have 3 conditions, a0<a1, a0>a1, a0=a1 setting motor control bits as required.

also..
you should add some 'hysterisis' to your conditions, something like ...
if a0<a1-2 then move cw
if a0>a1+2 then move ccw
this allows for a smoother response to the inputs, reduces motor 'jerk',etc.
what value (2 in this example) you use is best determined in 'real life' testing, a bit depends upon the 'damping' of the photocell output and desired response time.


hth
jay
mpingu



Joined: 28 Jul 2013
Posts: 6
Location: Malaysia

View user's profile Send private message

PostPosted: Tue Jul 30, 2013 5:24 am     Reply with quote

thanks again jay! that really help.

Also, for my code, I done some backup programming using PIC16F84A (which does not have the ADC function) just in case, and I wanted it to work exactly like how the PIC16F877A do, but it didn't work.

Here's the code.

Code:
#include <16F84A.h>
#device ADC=8
#fuses XT,NOWDT,NOPROTECT,NOPUT
#use delay(clock=4000000)

#include <stdlib.h>

char vthreshold = 1; //Declare threshold value for voltage read from both LDR.

char readValue_0();
char readValue_1();

void main()
{
   set_tris_a(0x0f); //set as input
   set_tris_b(0x00); //set as output
   
   char call_A0, call_A1;
   
   call_A0 = readValue_0();
   call_A1 = readValue_1();
   
   while(1) //To make an eternal loop.
   {
   char sbtrc = call_A0-call_A1; //Subtraction value.
   
   if(abs(sbtrc) < vthreshold) //When the absolute value of the subtraction is higher than threshold value.
   {
      output_low(PIN_B0); //The motor will
      output_low(PIN_B1); //not move.
   }
   else if(abs(sbtrc) > vthreshold) //When the absolute value of the subtraction is lower than threshold value.
   {
      if(call_A0 > call_A1)
      {
         output_high(PIN_B0); //The motor will
         output_low(PIN_B1); //move clockwise.
      }
      else
      {
         output_low(PIN_B0); //The motor will
         output_high(PIN_B1); //move counterclockwise
      }
   }
   else
   {
         output_low(PIN_B0); //The motor will
         output_low(PIN_B1); //not move.
   }
   }
}

readValue_0()
{
   unsigned int8 Value0; //Declare the variables.
   
   delay_us(50); //Delay to give the circuit some buffer time to operate.
   Value0 = input(PIN_A0); //Read the voltage value from the LDR1.

   return(Value0);
}

readValue_1()
{
   unsigned int8 Value1; //Declare the variables.
   
   delay_us(50); //Delay to give the circuit some buffer time to operate.
   Value1 = input(PIN_A1); //Read the voltage value from the LDR1.

   return(Value1);
}


Just ignorre the if else statement, I haven't updated it yet coz I can do it later. I would very much appreciate if you guys can help me to fix this thing. Thanks in advance guys Smile
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