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

ADCless POT reading using a 16F628

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



Joined: 31 May 2006
Posts: 2

View user's profile Send private message

ADCless POT reading using a 16F628
PostPosted: Wed May 31, 2006 9:57 pm     Reply with quote

Hello,

Long time lurker first time poster.....

I've been using higher end pics in the past, and now I'm playing with a MELABS x3 board. I've gotten everything to work except for the pot measurement. It appears to use the RC time constant to measure the change of resistence.

Circuit is a 5K pot in series with a .1 uF capacitor.

I've read in Myke Predko's book how to do it, but my code doesn't seem to work at all. The PIC basic hex file works, using the POT command so I know the hardware is fine.

Code:


#case      // case sensitive turned on
#include <16F628.h>   // Include device header file
#use delay(clock = 4000000)// Make compiler aware of osc frequency 4 @ MHz External
#fuses XT,NOLVP, NOWDT,         // Pre Directive of: External Oscil, No Low Voltage, No Watch Dog

#use rs232(baud = 9600, xmit = PIN_B2, rcv = PIN_B1)  // Setup the on boards USART
                                     

#byte port_b = 0x06      // Register For Bit Level Port_B
#byte port_a = 0x05      // Register For Bit Level Port_A
#byte LCD_DATA = 0x05

#bit BUTSTAT = port_b.7   // Port_B PIN_B7 aka Push Botton
#bit POTPIN = port_b.0   // Port_B PIN_B0 aka POT

// Function Prototype

int pot_read(void);

int potval;


   void main(void)
      {
         
         
         //int CharPresent;
                  

         port_b_pullups(TRUE);
         set_tris_a(0x00);
         set_tris_b(0b10000010);
         
         // set led's off
         BUTSTAT = 1;
         output_low(LED1);
         output_low(LED2);

         printf("TEST RS232\r\n");
         lcd_init();
         //enable_interrupts(INT_RB);   // Enable Status Chang on B Interrupt
         //enable_interrupts(GLOBAL);   // Enable Interrupts to be used.

         for (;;)
            {
               
               output_high(LED1);
               delay_ms(250);
               output_low(LED1);
               output_high(LED2);
               delay_ms(250);
               output_high(LED1);
               delay_ms(500);
               output_low(LED1);
               output_low(LED2);
               delay_ms(500);
               potval = pot_read();
               printf(putc_lcd,"%x",potval);
            }
         }

int pot_read (void)
   {
      int i = 0;      
      output_low(LED1);
      output_low(LED2);
      port_b_pullups(FALSE);    
      output_high(POT);
      delay_us(5);
      set_tris_b(0b10000011);         // Set port b0 to input.
      //output_low(POT);
      while (POTPIN == 1)
            i++;
      
      printf("Pot Val = %x",i);      
      return (i);
      

   }




So basically it just hangs in the while loop I assume. Now that I look at the code is it because I don't have a roll over for my int i? I thought it would automatically roll over....

Anyway, the way I coded the pot_read() function was that it put out a high on the B0 pin and delay 5 us for charging of the cap. Then I change my tris to make it an input, the capacitor should start to discharge to ground, then wait for the trigger point on the high to low transition. approx 2.5 or 1.5 V.

Any ideas? I'm sorta stumped.

Regards,

David.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed May 31, 2006 11:16 pm     Reply with quote

Look at the schematic for your board:
http://www.melabs.com/downloads/labx3sch.pdf
The trimpot and capacitor are in the top center of the schematic.
Note the values.

Now go to this explanation of the POT command, on the Piclist website:
http://www.piclist.com/techref/microchip/seepicsrc/psbpix/pot.htm
Near the top of the article, they explain how they calculate the
charging time for the capacitor. Compare the amount of time that
they charge the capacitor to the amount of time that you're using.
Plug the values of the cap and trimpot from the labx3 schematic
into their equation. What time value do you get ?

Also, do you have the trimpot set at some reasonable value ?
Make sure it's not set at 0. Initially, it's best to set it at max resistance.

Besides that problem, the rest of your pot_read() routine doesn't work
the way the Pot command does in PicBasic. If you want to translate
the PicBasic Pot command to C, one good way to do it is to compile
a Picbasic program which uses that command, and then look at the .LST
file. They put comments in there which explain what the ASM code is
doing. You may not understand all of it, but I think you should be
able to get the idea of how they do the measurement. Example:
Code:

POT
   call    CONVPIN   ; Convert pin to FSR and bit mask
POTT
   movwf   RM1       ; Save bit mask
   call    HIGHT     ; Set pin high to charge cap

   movlw   10        ; Charge cap for 10ms
   call    PAUSE   
   movf    RM1, W    ; Get bit mask
   iorwf   INDF, F   ; Set pin to input
   bcf     FSR, 7    ; Point to port
   xorwf   INDF, F   ; Flip bit to low
   clrf    R0        ; Zero counter
   clrf    R0 + 1
potloop
   bsf     FSR, 7    ; Point to TRIS
   movf    RM1, W    ; Get bit mask
   xorwf   INDF, F   ; Set pin to output
                     ; Discharge a little (& clear Watchdog timer)
   clrwdt
   nop               ; Short delay
   nop
   
   xorwf   INDF, F   ; Set pin back to input
   bcf     FSR, 7    ; Point back to port
   andwf   INDF, W   ; Read pin
   btfsc   STATUS, Z ; Still high?
   goto    potdone   ; No
   movf    R2, W     ; Get scale factor
   addwf   R0, F     ; Increase count by scale
   btfsc   STATUS, C ; Check for roll to high
   incfsz  R0 + 1, F
   goto    potloop   ; Do some more
   decf    R0 + 1, F ; Overflow so set to max
potdone
   movf    R0 + 1, W ; Get result to W
DONE
Arlof



Joined: 31 May 2006
Posts: 2

View user's profile Send private message

PostPosted: Sat Jun 03, 2006 12:58 pm     Reply with quote

Hey, Great help thanks. Apprently the guy in the that wrote that book forgot to mention you needed to discharge the capacitor.

So if anyone else has this question the coded solution was:

Now I've got another question I did a delay_ms(2.5) ; And it put a delay of about 9.28 seconds. Whats the deal with that is that a bug or something? I've got compiler 3.42.

Thanks,

David

Code:


int pot_read (void)            // instruction = 1uS
   {
      int i = 0;      
      output_high(POT);
      delay_ms(3);             // Charge time 5x.1e-6x5k = 2.5 mS
      set_tris_b(0b10000011);      // Set port b0 to input.
      
      while (POTPIN == 1)            // Do loop will the storge charge is more than 2.5 Vdc
         {
            i++;               // Increment Counter 0hms = 01 hex
            output_low(POT);      // Set ouput to discharge cap a bit
            set_tris_b(0b10000010);   // set the i/o port to output
            delay_us(10);         // wait a bit for it to discharge some.
            set_tris_b(0b10000011);   // I/O to input to check for the switch point
         }
      
      set_tris_b(0b10000010);         // Set the i/o to output
      return (i);                  // return time it took to pull the RC to a 0.
   
   }

Leef_me



Joined: 14 Mar 2006
Posts: 45

View user's profile Send private message

PostPosted: Sat Jun 03, 2006 2:29 pm     Reply with quote

>>Arlof said:
>>Now I've got another question I did a delay_ms(2.5) ; And it put a >>delay of about 9.28 seconds. Whats the deal with that is that a bug or >>something? I've got compiler 3.42.
>>Thanks,
>>David

Hmm, according to the "Compiler Updates" webpage the latest versions are Version 3.249 & Version 3.236 . Perhaps you have a typo.

Check the parameter value for delay_ms() again; 2.5 is not within the allowed parameter ranges.

I did try 2.1, 2.2 ... 3.5 and only 2.5, 3 and 3.5 gave any ASM result.
I did not try to decipher the resulting delay. The values 2.1 and others caused the compiler to not generate any code.
------------------------------------------------------------------------------

Quoting from the help file:

Syntax:
delay_ms (time)

Parameters:
time - a variable 0-255 or a constant 0-65535





HTH,
Leef_me

Code:
#include "C:\Documents and Settings\Lee\My Documents\rc_signal\rc.h"


void main()
{
   delay_ms(100);
   
   output_float (PIN_A3);

   delay_ms(2.5);
   
   output_float (PIN_A3);
 
}
Ttelmah
Guest







PostPosted: Sat Jun 03, 2006 2:29 pm     Reply with quote

The 'delay' functions, accept _integer_ values only. My guess would be that 2.5, gets encoded by the compiler to a float, and then the first two bytes of this get taken and treated as an integer. This would be '0x2080', allowing for the byte order used in the float, which ought to give 8.32 seconds. However the behaviour with a float is completely undefined, so this is only a guess.
If you want to delay for 2.5mSec, then code this as delay_us(2500).

Best Wishes
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