Measuring two resistors using a ADC channel

Discussion in 'Embedded Systems and Microcontrollers' started by kamarul amin, Jul 19, 2016.

  1. kamarul amin

    Thread Starter Member

    Dec 2, 2014
    62
    3
    Hi there...

    I use 18F4550 pic...

    how can I record two values of different resistors using one adc channel (AN2) ??
    I use the programming while loop and if loop, neither of them working.. whenever i run the program and write it to the pic, it don't follow the sequence of the program, it will execute the condition while loop even though it is wrong... I don't know what to do now. I'm really want to apologise because of this noob question. I am beginner in microprocessor.

    so this is my code
    Code (Text):
    1.  
    2. #include <18F4550.h>
    3.  
    4. #FUSES NOWDT                    //No Watch Dog Timer
    5. #FUSES HS      
    6. #FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
    7. #device ADC=10
    8.  
    9. #use delay(clock=20000000)
    10. #include <Flex_lcd.c>
    11. #USE FAST_IO(B)
    12.  
    13. void main()
    14. {
    15.    set_tris_b(0x0f);
    16.    unsigned int16 adcValue, adcValue1;
    17.    float volt;
    18.    float volt1;
    19.    float load1, load;
    20.    
    21.    
    22.    lcd_init();
    23.    setup_adc_ports(ALL_ANALOG);          // set all into analog
    24.    setup_adc(ADC_CLOCK_INTERNAL);        // Use internal ADC clock.
    25.    set_adc_channel(2);  
    26.    
    27.    while(1)
    28.    {
    29.       lcd_gotoxy(1,1);
    30.       output_low(PIN_B6);
    31.       delay_us(50);  
    32.       set_adc_channel(2);          
    33.       adcValue = read_adc();        // Get ADC reading
    34.       delay_us(50);                 // Delay for sampling cap to charge
    35.       volt=5.0*((float)adcValue/1023);      
    36.       volt=(5.00/volt)-1;
    37.       load1=(float)10000/volt;      
    38.       printf(lcd_putc,"Resistor : %f",load1);    
    39.       delay_ms(100);      
    40.      
    41.       while(input(pin_b1)!=1)
    42.        {
    43.                delay_us(50);
    44.                output_high(PIN_B6);
    45.                lcd_gotoxy(1,2);
    46.                delay_us(50);              
    47.                dcValue = read_adc();        // Get ADC reading
    48.                delay_us(50);                 // Delay for sampling cap to charge                  
    49.                volt=5.0*((float)adcValue/1023);                      
    50.                volt=(5.00/volt)-1;
    51.                load1=(float)10000/volt;      
    52.                printf(lcd_putc,"Resistor : %f",load1);  
    53.        }
    54.    }
    55.  
    56. }
    57.  
     
  2. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,889
    375
    If you mean that the line
    acts as if pin_b1 is never equal to 1 then I think that is because of the line
    This is setting all pins which have an analog function into analog mode - this would include pin_b1. The 'while' is doing a read of the pin as a digital input and pins set as analog will always read '0'.

    Note: You don't say which compiler you are using, and I don't recognise it from the code. I have not used whichever compiler you used, so I have to imagine what the compiler functions actually do, but I think the above is a likely interpretation.
     
    kamarul amin likes this.
  3. kamarul amin

    Thread Starter Member

    Dec 2, 2014
    62
    3

    ahhh I don't realize that thing... i should only declare only AN2 to be analog input, ryte? Now it's working well. firstly, the code will read the first resistor. then it will read the second resistor if i push the b1 button.. Thank you!!!!! If i'm lost again, I'll seek for your advice :)

    the compiler that I'm using right now is PIC C compiler..
     
  4. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,889
    375
    Yes. The PICs power up with all possible analog pins set as analog. Any pins you want to be digital input/output must be declared as digital.

    I use MPLAB-X with either MPASM for assembly or XC8 for C programs.
     
    kamarul amin likes this.
  5. kamarul amin

    Thread Starter Member

    Dec 2, 2014
    62
    3
    that is a good information. thank you!!!!
    so, you are doing some project using 18F4550???

    can I ask one more question ? I tried to write something on the lcd while having interrupt in the code, but nothing display on the lcd. I tried to make it as function, but nothing display on lcd.

    here is my code
    Code (Text):
    1.  
    2. #include <18f4550.h>
    3.  
    4. #USE DELAY(CLOCK=20000000)
    5. #FUSES HS,NOPROTECT,NOWDT,NOLVP
    6. #USE FAST_IO(B)
    7. #include <Flex_lcd.c>
    8. //The fast method of doing I/O will cause the compiler to perform I/O without programming of the direction register.
    9. //This directive takes effect until another #use xxxx_IO directive is encountered.
    10. //The user must ensure the direction register is set correctly using set_tris_X()
    11. //So, need to explicitly use set_trisx() command
    12.  
    13. int8 milisecs;
    14. int1 outs = 1;
    15.  
    16. void lcd();
    17.  
    18. #int_TIMER0
    19. void TIMER0_isr(void)
    20. {
    21.   int a=0;
    22.   set_timer0(100);  //100ms overflow
    23.   if(milisecs++ == 100)
    24.   {
    25.      milisecs = 0;  
    26.      outs = outs ^ 1;
    27.      output_bit(pin_b1, outs);
    28.      output_bit(pin_b0, outs);
    29.   }
    30. }
    31.  
    32. main()
    33. {
    34.    int a=0;        
    35.    set_tris_b(0x00);
    36.    
    37.    output_low(PIN_B0);
    38.    output_low(PIN_B1);
    39.    output_low(PIN_B2);
    40.    output_low(PIN_B3);
    41.      
    42.   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2); //timer 0 enebaled, pre-scaler of 2
    43.   enable_interrupts(INT_TIMER0); //unmask timer0 interrupt to respond to timer0 match
    44.   enable_interrupts(global);  //enable all unmasked interrupts
    45.   lcd_init();  
    46.   delay_ms(50);
    47.   lcd_putc("/f");
    48.   while(1)
    49.    {
    50.      lcd();
    51.    }
    52.   }
    53.  
    54. void lcd()
    55. {
    56.       int a=0;
    57.       a++;
    58.       delay_ms(50);
    59.       lcd_gotoxy(1,1);
    60.       delay_ms(50);
    61.       printf(lcd_putc,"Count %d", a);
    62. }
    63.  

    do i need to use special function or some code to make use of lcd while having interrupt? actually I'm still having a hard time to understand interrupt :(
     
  6. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    What kind of LCD are you using? It is rather unusual to use printf() for this as that function tends to be rather large for the work it needs to do.

    Also, which PIC C compiler are you using? There are many, and some may have LCD libraries as part of the package.
     
    kamarul amin likes this.
  7. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,889
    375
    Usually you have to clear the interrupt flag in the interrupt routine: TMR1IF = 0
    Once again I don't know your compiler, whether the compiler does this automatically for you.
    If the flag is not cleared, the interrupt will be called continuously - no other code will be executed.

    If you comment out the enable global interrupts line do you see the write to the LCD?
     
    kamarul amin likes this.
  8. kamarul amin

    Thread Starter Member

    Dec 2, 2014
    62
    3
    sorry for the not giving too much detail. okey, I use lcd 16x2 1602a with blue backlight.. and I use PIC C compiler and PicKit2... before this I use printf to display something on the LCD and it works fine.. but this time I don't know why it won't displaying.... the lcd libraries I got from my lecturer..
     
  9. kamarul amin

    Thread Starter Member

    Dec 2, 2014
    62
    3

    I use PIC C compiler and PicKit2.. I comment out it already but still nothing display :( to clear the interrupt flag, I should define it? Still confusing about this chapter (interrupt) !!!!!!!! T_T
     
  10. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,889
    375
    OK, so even with interrupts disabled you get nothing on the LCD. There are many, many possibilities for this.
    Somewhere you must tell the code which PIC pins you are using to connect to the LCD. You must make sure that the LCD is actually connected where the code expects it to be.

    Which company wrote the 'PIC C compiler' which you are using?
     
    kamarul amin likes this.
  11. kamarul amin

    Thread Starter Member

    Dec 2, 2014
    62
    3
    Yes, I connected it based on the library i use. Still working on how it won't display. So, the compiler is from PCWHD. I got it from internet and also my laboratory use it. so for the pins that were connected to the LCD were...

    1-GND
    2-VDD
    3-Con
    4-RB4
    5-GND
    6-RB5
    7 -> 14 (RD0-RD7)
    15-VDD
    16-Backlight
     
  12. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,889
    375
    Do you have RB4, RB5, RD0-RD7 set as digital I/O?
    When you adjust the contrast control can you make a line (or possibly two lines) of black (or possibly white) squares appear and disappear across the display?
     
    kamarul amin likes this.
  13. kamarul amin

    Thread Starter Member

    Dec 2, 2014
    62
    3
    set as digital I/O ? I never set it before this but it display words. it might be that whenever i use interrupt i need to set it ? Yeah right now I can see white squares boxes appears on the LCD..
     
  14. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,889
    375
    It's only RB4 you need to worry about. Like with original question at the top of this thread, at power up RB4 will be an analog input. You need to set it as digital I/O.

    If you've had words on the LCD before, what has changed since then?
     
    kamarul amin likes this.
  15. kamarul amin

    Thread Starter Member

    Dec 2, 2014
    62
    3

    Hm how to declare it as digital I/O ? As i know it can set only to analog ryte?
     
  16. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,889
    375
  17. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    No, many pins share both analog and digital functions. When they share each pin defaults to the analog function at power up, which keeps them safe no matter whatis connected to them. A digital only pin will similarly default to input again to keep things safe till the set up code is complete. As far as I know that is true across all microchip products.

    Port d is digital only. Most pins of port b also have analog functions. AN 2 is on port a, and the only way to make it analog is to also make an 1 & 0 analog; see ADCON1 description.

    You should be spending your time reading the spec sheet for your device. The documentation is very good and complete, so it is large. You can use the PDF table of contents to narrow down to the topics you need, such as I/O ports or A/D converter.
     
  18. dannyf

    Well-Known Member

    Sep 13, 2015
    1,771
    358
    It would be a miracle if you can compile your code using picc.
     
  19. kamarul amin

    Thread Starter Member

    Dec 2, 2014
    62
    3
    yes it is. I'm using that compiler.. I just follow the library that was built from my lecturer... so it might be that I should follow the default one for the compiler ?
     
  20. kamarul amin

    Thread Starter Member

    Dec 2, 2014
    62
    3
    why? Is it bad? This is my first time dealing with microcontroller. But got stuck at the interrupt!!! I am sad :(
     
Loading...