Hot!Interfacing PIC18F24K40 with POT

Author
ajitnayak87
Super Member
  • Total Posts : 197
  • Reward points : 0
  • Joined: 2017/06/20 03:53:02
  • Location: 0
  • Status: offline
2018/08/08 01:28:22 (permalink)
0

Interfacing PIC18F24K40 with POT

Dear all,
 
I am looking for sample code which could display the  change the value from 0-1024 then convert that value into voltage . The value must be 16bit register. lower byte store in one address and higher byte in another. Is there example code.
#1

17 Replies Related Threads

    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re: Interfacing PIC18F24K40 with POT 2018/08/08 01:37:21 (permalink)
    0
    Sure there is Smile
     
    What have you already achieved by yourself? Hardware is ok?

    GENOVA :D :D ! GODO
    #2
    ajitnayak87
    Super Member
    • Total Posts : 197
    • Reward points : 0
    • Joined: 2017/06/20 03:53:02
    • Location: 0
    • Status: offline
    Re: Interfacing PIC18F24K40 with POT 2018/08/08 03:14:37 (permalink)
    0
    i m using RBO & Rb1 connected to 10k pot.  I would like to see change in value.
    my code look like below i cant see change is value
    unsigned int curr1;
    float curr[27] = 0;
    bit select = 0,Auto_flag = 0, curr1_min=0, curr2_min=0, curr3_min=0, curr4_min=0, curr5_min=0, curr6_min=0, curr7_min=0, curr8_min=0, curr9_min=0, curr10_min=0;


    void PIN_MANAGER_Initialize(void) {
     /**
     LATx registers
     */
     LATA = 0x00;
     LATB = 0x00;
     LATC = 0x00;

     /**
     TRISx registers
     */
     TRISA = 0x00;
     TRISB = 0x00;
     TRISC = 0x80;

     /**
     ANSELx registers
     */
     ANSELC = 0x00;
     ANSELB = 0x3F;
     ANSELA = 0x00;

     /**
     WPUx registers
     */
     WPUE = 0x00;
     WPUB = 0x00;
     WPUA = 0x00;
     WPUC = 0x00;

     /**
     ODx registers
     */
     ODCONA = 0x00;
     ODCONB = 0x00;
     ODCONC = 0x00;

     bool state = (unsigned char)GIE;
     GIE = 0;
     PPSLOCK = 0x55;
     PPSLOCK = 0xAA;
     PPSLOCKbits.PPSLOCKED = 0x00; // unlock PPS

     RC6PPS = 0x09; //RC6->EUSART:TX;
     RXPPSbits.RXPPS = 0x17; //RC7->EUSART:RX;

     PPSLOCK = 0x55;
     PPSLOCK = 0xAA;
     PPSLOCKbits.PPSLOCKED = 0x01; // lock PPS

     GIE = state;
    }




    float Adc12_Cha(unsigned char val) {
     unsigned char adc_hbit,adc_lbit;
     unsigned long adc_temp,adc_temp0,adc_val;
     ADCON2=0x95; //ADFM=1,adc_clk=FOSC/4
     adc_temp0=0;
     for(unsigned char j=0; j<10; j++) {
      ADCON0=val<<2;
      ADON=1;
      __delay_ms(5);
      GODONE =1;
      while(GODONE==1);
      adc_hbit=ADRESH;
      adc_lbit=ADRESL;
      adc_temp = adc_lbit + (256*adc_hbit);
      adc_temp0+=adc_temp;
     }
     adc_val=adc_temp0/10;
     return adc_val;
    }


    void ADC_Manipulation() {
     curr1 = (int)(curr[0]);
     if ((curr1<=102) ||(curr1>=502 && curr1<=514)||(curr1>=922)) {
      curr1=0;
      curr1_min=0;
     } else if (curr1>514) {
      if((curr1>514)||(curr1<540)) curr1= (((curr1-512)*74)/100);
      else curr1=(((curr1-512)*74)/100);
      curr1_min=0;
     } else {
      if((curr1>102)||(curr1<150)) curr1= (((511-curr1)*74)/100);
      else curr1=(((510-curr1)*74)/100);
      // curr1_min=1;
     }
    }


    void main(void) {
     while (1)

     {

      curr[0] = Adc12_Cha(10);
      ADC_Manipulation();

      __delay_ms(100);

     }

    }





     
    #3
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re: Interfacing PIC18F24K40 with POT 2018/08/08 03:31:25 (permalink)
    0
    You need to set those pins as inputs, and analog capable (and the others, digital).
     
    also, I'd avoid all of that averaging until you're sure you can read ADC correctly.

    GENOVA :D :D ! GODO
    #4
    ajitnayak87
    Super Member
    • Total Posts : 197
    • Reward points : 0
    • Joined: 2017/06/20 03:53:02
    • Location: 0
    • Status: offline
    Re: Interfacing PIC18F24K40 with POT 2018/08/08 03:58:25 (permalink)
    0
    I have attached config details here.
    I am using RB0 & RB1 as analog ports. If i am config as input it wont compile at all.
    even its warning it wont update in to chip.
     
     
    unsigned int ADCRead(unsigned char ch)
    {
       if(ch>13) return 0; //Invalid Channel

       ADCON0=0x00;

       ADCON0=(ch<<2); //Select ADC Channel

       ADON=1; //switch on the adc module

       GODONE=1; //Start conversion

       while(GODONE); //wait for the conversion to finish

       ADON=0; //switch off adc

       return ADRES;
    }
    void main(void) {

     unsigned char c=0;
     ADCON2=0b10001010;
     // ANSELH=0X3F;


     while (1)

     {
      val=ADCRead(12);
      __delay_ms(100);

     }

    //}

    }

    Attached Image(s)

    #5
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re: Interfacing PIC18F24K40 with POT 2018/08/08 04:04:50 (permalink)
    0
    I meant something like
     TRISB = 0x03;

    GENOVA :D :D ! GODO
    #6
    ajitnayak87
    Super Member
    • Total Posts : 197
    • Reward points : 0
    • Joined: 2017/06/20 03:53:02
    • Location: 0
    • Status: offline
    Re: Interfacing PIC18F24K40 with POT 2018/08/08 04:11:01 (permalink)
    0
    This is mcc generated file. Where i am config as input or output. In mcc if config as input & selected as Analog as show in previous thread i get an error. I dont know how to resolve this.
    i tried changing pin config in mcc genrated file. It allow you to change but there is no change in value.
    post edited by ajitnayak87 - 2018/08/08 04:12:43
    #7
    ajitnayak87
    Super Member
    • Total Posts : 197
    • Reward points : 0
    • Joined: 2017/06/20 03:53:02
    • Location: 0
    • Status: offline
    Re: Interfacing PIC18F24K40 with POT 2018/08/08 04:43:55 (permalink)
    0
    my main suspection intialization and this function
    The code i copied from PIC18F2420
    Where there is register ADCON2 in this i dont have adcon2
    ADCON register are differ from PIC18F24k40 &PIC18F2420
     
    I am not getting example for PIC16F886 since PINOUT & ADC config setting are same.
     

     
    unsigned int ADCRead(unsigned char ch)
    {
       if(ch>13) return 0;  //Invalid Channel

       ADCON0=0x72;

      // ADCON0=(ch<<2);   //Select ADC Channel

       ADON=1;  //switch on the adc module

       GODONE=1;  //Start conversion

       while(GODONE); //wait for the conversion to finish

       ADON=0;  //switch off adc

       return ADRES;
    }



    post edited by ajitnayak87 - 2018/08/08 04:45:16
    #8
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    Re: Interfacing PIC18F24K40 with POT 2018/08/08 05:25:05 (permalink)
    0
    ah ok, throw away MCC.

    GENOVA :D :D ! GODO
    #9
    A_MAK
    Junior Member
    • Total Posts : 27
    • Reward points : 0
    • Joined: 2014/08/05 10:45:57
    • Location: 0
    • Status: offline
    Re: Interfacing PIC18F24K40 with POT 2018/08/08 09:36:22 (permalink)
    0
    You can take a look at the example code on the webpage. There are several simple examples to work with.
    https://mplabxpress.microchip.com/mplabcloud/example/details/626
     
    Also, the K40 family has an ADC which can perform averaging in hardware. So you can set it up to take 2/4/8/16/32 samples and then average the result automatically without any CPU intervention. You can refer to this App Note for more details.
    http://www.microchip.com//wwwAppNotes/AppNotes.aspx?appnote=en584645
     
     
    #10
    davekw7x
    Entropy++
    • Total Posts : 1530
    • Reward points : 0
    • Joined: 2012/01/16 12:01:07
    • Location: Left Coast, USA
    • Status: offline
    Re: Interfacing PIC18F24K40 with POT 2018/08/08 15:35:14 (permalink)
    +2 (2)
    ajitnayak87
    i m using RBO & Rb1 connected to 10k pot.  I would like to see change in value.
    my code look like below i cant see change is value

     
    You can't measure the resistance of a pot by connecting it to RB0 and RB1.
     
    Here's a possibility: Connect one end of the pot to Vdd (PIC Supply voltage).  Connect the other end to Vss (Ground).  Connect the wiper of the pot to a PIC pin, say RB0.
     
    Now, sticking with MCC:
    Note that the GPIO selections in the MCC Pin Grid are for Digital Inputs and Outputs, so do NOT try to select RB0 there.  Really.
     
    Here's the way to get an Analog input:
     
    Activate the ADCC module in the MCC Resource Management window.  Set up appropriate TAD.  For my example, I'm running the chip at 64 MHz, so it takes Fosc/64 to give a 1 us TAD.  See the MCC_ADCC attachment.  If you erroneously select parameters that give TAD that is too short, there will be a significant Hint (should be a Warning) in the Notifications window.  See Footnote.
     
    Now you have ADCC selection possibilities in the Pin Manager Grid. Select RB0 to be the ANx input.
    Now, look at the Pin Module window on the MCC Resource Management window.  See the MCC_PIN_MODULE attachment
     
    You  see the default name, channel_ANB0, associated with pin RB0.  If you want to, you can change that name to anything that suits your fancy.  Use that name as the argument or base name to any of the MCC-generated functions that refer to a channel number.
     
    Now, after clicking on the Generate button of the Resource Management window, it's time to look at the functions described in mcc generated files  adcc.h and iimplemented in adcc.c to try to get a clue as to what to do next.
     
    Regards,

    Dave
     
    Footnote:
    Some people have found it to be a productivity time saver to read the Data Sheet before trying to implement the application using MCC-generated files.
     
    post edited by davekw7x - 2018/08/08 16:43:04

    Attached Image(s)


    Sometimes I just can't help myself...
    #11
    ajitnayak87
    Super Member
    • Total Posts : 197
    • Reward points : 0
    • Joined: 2017/06/20 03:53:02
    • Location: 0
    • Status: offline
    Re: Interfacing PIC18F24K40 with POT 2018/08/08 22:05:40 (permalink)
    0
    You can't measure the resistance of a pot by connecting it to RB0 and RB1.

     
    For me i can connect any analog port. Let me know which analog port i need to use to make it work. I have used ADCC function in MCC and Gen rated file . i have attached MCC file  for reference. the link attached in that its used adcc.c but dont have info how to use it.

     
     
     
    void main(void) {
        // Initialize the device
        SYSTEM_Initialize();

       while (1)
           
     {
      
           //val=ADCRead(12);
           val=ADCC_GetSingleConversion(10);
     //curr[0] = Adc12_Cha(10);
    //ADC_Manipulation();

    __delay_ms(100);

     }
          
     //}
        
    }

    post edited by ajitnayak87 - 2018/08/08 22:38:38

    Attached Image(s)

    #12
    qɥb
    Monolothic Member
    • Total Posts : 3329
    • Reward points : 0
    • Joined: 2017/09/09 05:07:30
    • Location: Jupiter
    • Status: offline
    Re: Interfacing PIC18F24K40 with POT 2018/08/08 22:52:57 (permalink)
    0
    ajitnayak87
    You can't measure the resistance of a pot by connecting it to RB0 and RB1.

     
    For me i can connect any analog port. Let me know which analog port i need to use to make it work.

    You can use any SINGLE port.
    His point was that you connect the wiper to one analog input, you don't use two analog inputs.

    This forum is mis-configured so it only works correctly if you access it via https protocol.
    The Microchip website links to it using http protocol. Will they ever catch on?
    PicForum "it just works"
    #13
    ajitnayak87
    Super Member
    • Total Posts : 197
    • Reward points : 0
    • Joined: 2017/06/20 03:53:02
    • Location: 0
    • Status: offline
    Re: Interfacing PIC18F24K40 with POT 2018/08/09 00:04:21 (permalink)
    0
    I have  used the example code from  StudentCompanion
    I have done setting shown. I have used ANO & AN1 port coding. it Still display 0000  there is no change in value.
    i used 2X10k pot . one end given to 5v another to gnd . Output given to ANO& AN1
    Both could not able read output. I am using Serial Monitor to display the value convertedValue
     

     
    void Serial_1_Send_byte(uint8_t trbuf1) {
        TX1REG = trbuf1;

        while (0 == PIR3bits.TXIF);

    //while (!TX1IF);

    }


    void Send_string_uart1(const unsigned char *string) {
        unsigned char i = 0;

        do {
            TX1REG = string[i++];
            while (0 == TX1STAbits.TRMT);
        } while (string[i] != '\0');
    }




    void Blink_Count() {
        if (PIR0bits.TMR0IF == 1) {
            PIR0bits.TMR0IF = 0;
            count = count + 1;

            if (count >= 10) {
                LED = !LED;
                count = 0;

                Send_string_uart1("ADC _Value");
                ser_data[0]=convertedValue;
                Serial_1_Send_byte(ser_data[0]);
            }
        }

    }


    void main(void) {
        // Initialize the device
        SYSTEM_Initialize();


        unsigned char c=0;

        while (1)

        {

            ADCC_StartConversion(channel_ANA1);
            while(!ADCC_IsConversionDone());
            convertedValue = ADCC_GetConversionResult();
            voltage = (convertedValue * 5.0)/1023;
            __delay_ms(100);

        }


    }





     
     
     
     
     


    void PIN_MANAGER_Initialize(void) {
     /**
     LATx registers
     */
     LATA = 0x00;
     LATB = 0x00;
     LATC = 0x00;

     /**
     TRISx registers
     */
     TRISA = 0x03;
     TRISB = 0x01;
     TRISC = 0x7F;

     /**
     ANSELx registers
     */
     ANSELC = 0x80;
     ANSELB = 0x00;
     ANSELA = 0x03;

     /**
     WPUx registers
     */
     WPUE = 0x00;
     WPUB = 0x00;
     WPUA = 0x00;
     WPUC = 0x00;

     /**
     ODx registers
     */
     ODCONA = 0x00;
     ODCONB = 0x00;
     ODCONC = 0x00;

     bool state = (unsigned char)GIE;
     GIE = 0;
     PPSLOCK = 0x55;
     PPSLOCK = 0xAA;
     PPSLOCKbits.PPSLOCKED = 0x00; // unlock PPS

     RXPPSbits.RXPPS = 0x16; //RC6->EUSART:RX;
     T0CKIPPSbits.T0CKIPPS = 0x08; //RB0->TMR0:T0CKI;
     RC7PPS = 0x09; //RC7->EUSART:TX;
     ADACTPPSbits.ADACTPPS = 0x08; //RB0->ADCC:ADACT;

     PPSLOCK = 0x55;
     PPSLOCK = 0xAA;
     PPSLOCKbits.PPSLOCKED = 0x01; // lock PPS

     GIE = state;
    }

    void ADCC_Initialize(void)
    {
        // set the ADCC to the options selected in the User Interface
        // ADDSEN disabled; ADGPOL digital_low; ADIPEN disabled; ADPPOL VSS;
        ADCON1 = 0x00;
        // ADCRS 0; ADMD Average_mode; ADACLR disabled; ADPSIS ADFLTR;
        ADCON2 = 0x02;
        // ADCALC First derivative of Single measurement; ADTMD disabled; ADSOI ADGO is cleared;
        ADCON3 = 0x08;
        // ADACT disabled;
        ADACT = 0x00;
        // ADAOV ACC or ADERR not Overflowed;
        ADSTAT = 0x00;
        // ADCS FOSC/8;
        ADCLK = 0x03;
        // ADNREF VSS; ADPREF VDD;
        ADREF = 0x00;
        // ADCAP Additional uC disabled;
        ADCAP = 0x00;
        // ADPRE 0;
        ADPRE = 0x00;
        // ADACQ 100;
        ADACQ = 0x64;
        // ADPCH ANA0;
        ADPCH = 0x00;
        // ADRPT 0;
        ADRPT = 0x00;
        // ADLTHL 0;
        ADLTHL = 0x00;
        // ADLTHH 0;
        ADLTHH = 0x00;
        // ADUTHL 0;
        ADUTHL = 0x00;
        // ADUTHH 0;
        ADUTHH = 0x00;
        // ADSTPTL 0;
        ADSTPTL = 0x00;
        // ADSTPTH 0;
        ADSTPTH = 0x00;
        
        // ADGO stop; ADFM right; ADON enabled; ADCONT enabled; ADCS FOSC/ADCLK;
        ADCON0 = 0xC4;
        
        // Clear the ADC interrupt flag
        PIR1bits.ADIF = 0;
        // Enabling ADCC interrupt.
        PIE1bits.ADIE = 1;
        
        ADCC_SetADIInterruptHandler(ADCC_DefaultInterruptHandler);

        // Clear the ADC Threshold interrupt flag
        PIR1bits.ADTIF = 0;
        // Enabling ADCC threshold interrupt.
        PIE1bits.ADTIE = 1;
        
        ADCC_SetADTIInterruptHandler(ADCC_DefaultInterruptHandler);
    }

    void ADCC_StartConversion(adcc_channel_t channel)
    {
        // select the A/D channel
        ADPCH = channel;
      
        // Turn on the ADC module
        ADCON0bits.ADON = 1;

        // Start the conversion
        ADCON0bits.ADGO = 1;
    }

    bool ADCC_IsConversionDone()
    {
        // Start the conversion
        return ((unsigned char)(!ADCON0bits.ADGO));
    }

    adc_result_t ADCC_GetConversionResult(void)
    {
        // Return the result
        return ((adc_result_t)((ADRESH << 8) + ADRESL));
    }

    adc_result_t ADCC_GetSingleConversion(adcc_channel_t channel)
    {
        // select the A/D channel
        ADPCH = channel;

        // Turn on the ADC module
        ADCON0bits.ADON = 1;
     
        //Disable the continuous mode.
        ADCON0bits.ADCONT = 0;

        // Start the conversion
        ADCON0bits.ADGO = 1;


        // Wait for the conversion to finish
        while (ADCON0bits.ADGO)
        {
        }
        
        // Conversion finished, return the result
        return ((adc_result_t)((ADRESH << 8) + ADRESL));
    }

    void ADCC_StopConversion(void)
    {
        //Reset the ADGO bit.
        ADCON0bits.ADGO = 0;
    }

    void ADCC_SetStopOnInterrupt(void)
    {
        //Set the ADSOI bit.
        ADCON3bits.ADSOI = 1;
    }

    void ADCC_DischargeSampleCapacitor(void)
    {
        //Set the ADC channel to AVss.
        ADPCH = 0x3C;
    }

    void ADCC_LoadAcquisitionRegister(uint8_t acquisitionValue)
    {
        //Load the ADACQ register.
        ADACQ = acquisitionValue;
    }

    void ADCC_SetPrechargeTime(uint8_t prechargeTime)
    {
        //Load the ADPRE register.
        ADPRE = prechargeTime;
    }

    void ADCC_SetRepeatCount(uint8_t repeatCount)
    {
        //Load the ADRPT register.
        ADRPT = repeatCount;
    }

    uint8_t ADCC_GetCurrentCountofConversions(void)
    {
        //Return the contents of ADCNT register
        return ADCNT;
    }

    void ADCC_ClearAccumulator(void)
    {
        //Reset the ADCON2bits.ADACLR bit.
        ADCON2bits.ADACLR = 1;
    }

    uint16_t ADCC_GetAccumulatorValue(void)
    {
        //Return the contents of ADACCH and ADACCL registers
        return ((uint16_t)((ADACCH << 8) + ADACCL));
    }

    bool ADCC_HasAccumulatorOverflowed(void)
    {
        //Return the status of ADSTATbits.ADAOV
        return ADSTATbits.ADAOV;
    }

    uint16_t ADCC_GetFilterValue(void)
    {
        //Return the contents of ADFLTRH and ADFLTRL registers
        return ((uint16_t)((ADFLTRH << 8) + ADFLTRL));
    }

    uint16_t ADCC_GetPreviousResult(void)
    {
        //Return the contents of ADPREVH and ADPREVL registers
        return ((uint16_t)((ADPREVH << 8) + ADPREVL));
    }

    void ADCC_DefineSetPoint(uint16_t setPoint)
    {
        //Sets the ADSTPTH and ADSTPTL registers
        ADSTPTH = setPoint >> 8;
        ADSTPTL = setPoint;
    }

    void ADCC_SetUpperThreshold(uint16_t upperThreshold)
    {
        //Sets the ADUTHH and ADUTHL registers
        ADUTHH = upperThreshold >> 8;
        ADUTHL = upperThreshold;
    }

    void ADCC_SetLowerThreshold(uint16_t lowerThreshold)
    {
        //Sets the ADLTHH and ADLTHL registers
        ADLTHH = lowerThreshold >> 8;
        ADLTHL = lowerThreshold;
    }

    uint16_t ADCC_GetErrorCalculation(void)
    {
     //Return the contents of ADERRH and ADERRL registers
     return ((uint16_t)((ADERRH << 8) + ADERRL));
    }

    void ADCC_EnableDoubleSampling(void)
    {
        //Sets the ADCON1bits.ADDSEN
        ADCON1bits.ADDSEN = 1;
    }

    void ADCC_EnableContinuousConversion(void)
    {
        //Sets the ADCON0bits.ADCONT
        ADCON0bits.ADCONT = 1;
    }

    void ADCC_DisableContinuousConversion(void)
    {
        //Resets the ADCON0bits.ADCONT
        ADCON0bits.ADCONT = 0;
    }

    bool ADCC_HasErrorCrossedUpperThreshold(void)
    {
        //Returns the value of ADSTATbits.ADUTHR bit.
        return ADSTATbits.ADUTHR;
    }

    bool ADCC_HasErrorCrossedLowerThreshold(void)
    {
        //Returns the value of ADSTATbits.ADLTHR bit.
        return ADSTATbits.ADLTHR;
    }

    uint8_t ADCC_GetConversionStageStatus(void)
    {
        //Returns the contents of ADSTATbits.ADSTAT field.
        return ADSTATbits.ADSTAT;
    }

    void ADCC_ISR(void)
    {
        // Clear the ADCC interrupt flag
        PIR1bits.ADIF = 0;

        if (ADCC_ADI_InterruptHandler)
                ADCC_ADI_InterruptHandler();
    }

    void ADCC_SetADIInterruptHandler(void (* InterruptHandler)(void)){
        ADCC_ADI_InterruptHandler = InterruptHandler;
    }

    void ADCC_ThresholdISR(void)
    {
        // Clear the ADCC Threshold interrupt flag
        PIR1bits.ADTIF = 0;

        if (ADCC_ADTI_InterruptHandler)
            ADCC_ADTI_InterruptHandler();
    }

    void ADCC_SetADTIInterruptHandler(void (* InterruptHandler)(void)){
        ADCC_ADTI_InterruptHandler = InterruptHandler;
    }

    void ADCC_DefaultInterruptHandler(void){
        // add your ADCC interrupt custom code
        // or set custom function using ADCC_SetADIInterruptHandler() or ADCC_SetADTIInterruptHandler()
    }



    }

    post edited by ajitnayak87 - 2018/08/09 01:17:21

    Attached Image(s)

    #14
    davekw7x
    Entropy++
    • Total Posts : 1530
    • Reward points : 0
    • Joined: 2012/01/16 12:01:07
    • Location: Left Coast, USA
    • Status: offline
    Re: Interfacing PIC18F24K40 with POT 2018/08/09 08:07:24 (permalink)
    +1 (1)
    Some observations:
     
    1. The code that you showed did not even call the function that sends the data over the serial port.  It is important to post the exact code that you are testing. You should tell us exactly what happens.  Also, assuming that you actually called the function, for example, does the LED blink at the rate you expected?  Or what?

      Furthermore

    2. To see anything meaningful on the serial port at the workstation, you must convert the 16-bit ADC value to a "string" of ASCII digits.    Sending a single (binary) byte from the 16-bit ADC value makes no sense.

    Other quibbles:
     
    Assuming Vdd is 5 Volts, the formula for calculating voltage from the ADC reading is
        voltage = (convertedValue * 5.0 ) / 1024   (Denominator is 1024, not 1023)
    Your function results in a very minor error, and may not make much difference in the grand scheme of things, but you might as well get it right.
     
    More significantly:
     
    The result of the calculation is a floating point number.  So, for example, if the reading is 0x177 (which is 375 decimal), the calculated value is 375 * 5.0 / 1024.0 = 1.83105... Volts.
     
    If you save this into an integer variable, the truncated result will be 1.  In fact, all readings whose calculated values are in the range of 1 Volt to 1.999999 Volts will be stored as 1.  Probably not what you have in mind.  Right?
     
    So, either store the value as floating point and convert the floating point value to a string of ASCII digits, or devise a scaling strategy that avoids calculating and printing floating point values.  There have been a lot of posts on this forum over the years that illustrate ways of doing this.  From a programming point of view, the simplest way, for starters, is just to use floating point calculations and variables and use printf or sprintf to convert to ASCII.  Later,  if you need to save time and/or program memory, try the integer scaling.  At least that is the way I would start out.
     
    [Edit]
    OOPs!  Upon closer inspection the function looks OK for sending a zero-byte terminated ASCII "string.".  Sorry.   I still say that I would use printf for starters and refine/optimize later if/when it becomes necessary.
     
    Finally, your function to send an ASCII "string" will send the terminating zero byte.  That's not recommended.  Change the loop so that it only stores the characters up to, but not including the zero byte.  Again, this may, or maybe not, make much difference, but transmission of non-ASCII stuff over serial ports sometimes has confusing consequences.  (I hate to repeat myself, but I would use printf and worry about the other stuff later.)
     
    I would eliminate everything except ADC, UART and an LED to keep things simple for starters.  In the UART setup I told MCC to "Redirect STDIO to EUSART"
    Here's my main():

    #include "mcc_generated_files/mcc.h"

    // Curiosity HPC Board:

    // Analog Input: Pot on RA0
    //
    // UART on mikroBUS 1:
    //   Rx on RC7
    //   Tx on RC6
    //
    // LEDs
    //   LED4 on RA4
    //   LED5 on RA5
    //

    #define VDD 3.3
    void main(void)
    {
        // Initialize the device
        SYSTEM_Initialize();
        __delay_ms(100); // Give things a little time to settle down.

        printf("\r\nCompiled on %s at %s UTC by XC8 version %d\r\n",
                __DATE__, __TIME__, __XC8_VERSION);

        printf("VDD  %.2f, sizeof(double) = %u\r\n\r\n", VDD, sizeof(double));
        double voltage;
        uint16_t adc_value;
        
        while (1) {
            LED4_Toggle();
            ADCC_StartConversion(channel_ANA0);
            while (!ADCC_IsConversionDone());
            adc_value = ADCC_GetConversionResult();
            voltage = (adc_value * VDD) / 1024.0;
            printf("ADC Value 0x%04X = %4u decimal ===> %.2f Volts\r\n",
                    adc_value, adc_value, voltage);

            __delay_ms(1000);
        } // End of main loop
    } // End of main()

     
    Output, showing effect of changing Pot settings between readings:
     
    Compiled on Aug  9 2018 at 16:27:03 UTC by XC8 version 1450
    VDD = 3.30, sizeof(double) = 3

    ADC Value 0x02ED =  749 decimal ===> 2.41 Volts
    ADC Value 0x02EC =  748 decimal ===> 2.41 Volts
    ADC Value 0x0248 =  584 decimal ===> 1.88 Volts
    ADC Value 0x01B8 =  440 decimal ===> 1.42 Volts
    ADC Value 0x00A3 =  163 decimal ===> 0.53 Volts
    ADC Value 0x0063 =   99 decimal ===> 0.32 Volts
    ADC Value 0x012C =  300 decimal ===> 0.97 Volts
    ADC Value 0x0300 =  768 decimal ===> 2.47 Volts
    .
    .
    .


    The LED blinks with a cadence of (approximately) one second on and one second off

    [/Edit
     
    Regards,

    Dave
     
     
    post edited by davekw7x - 2018/08/09 18:45:42

    Sometimes I just can't help myself...
    #15
    Aussie Susan
    Super Member
    • Total Posts : 3327
    • Reward points : 0
    • Joined: 2008/08/18 22:20:40
    • Location: Melbourne, Australia
    • Status: offline
    Re: Interfacing PIC18F24K40 with POT 2018/08/09 18:53:41 (permalink)
    #16
    ajitnayak87
    Super Member
    • Total Posts : 197
    • Reward points : 0
    • Joined: 2017/06/20 03:53:02
    • Location: 0
    • Status: offline
    Re: Interfacing PIC18F24K40 with POT 2018/08/10 03:49:59 (permalink)
    0
    I could able to achieve by changing MCC generated file.Now i have connected 2 ADC pot. I found data being same for both.i have attached code for reference.
     
    1) How to read multiple analog ports
    2) how to use full resolution currently below code display value from 0-3.9v i.e 0-255 count for max. i would like to use 10 bit resolution 0-5v i.e count 0-1024
    if change any pot the value changes same . even i keep voltage 1 v and another at max 3.9v . value remain same.
    Both uses common 5v and gnd , pot only varied
     

    void main(void) {
        // Initialize the device
        SYSTEM_Initialize();

        unsigned char c=0;
            while (1)

        {
            //convertedValue = 0;
            ADCC_StartConversion(channel_ANA0);
            
            while(!ADCC_IsConversionDone());
            convertedValue = ADCC_GetConversionResult();
            ADCC_StartConversion(channel_ANA1);
            while(!ADCC_IsConversionDone());
            convertedValue1 = ADCC_GetConversionResult();
            //convertedValue=convertedValue*1000;
            voltage = (convertedValue * 5.0)/1023;
            
            if ((RB0==1)||(RB1==1)||(RB2==1)||(RB3==1)||(RB4==1)||(RB5==1))
            {
               Pin_Status=1;
            }else
            {
                Pin_Status=0;
            }
                
        
        }

    }

    }


    adcc.c


    uint16_t ADCC_GetConversion(adcc_channel_t channel){
        return ADCC_GetSingleConversion(channel, 0);
    }

    void ADCC_SelectChannel(adcc_channel_t channel, uint8_t acquisitionDelay)
    {
        // select the A/D channel
        ADPCH = channel;  
        //Set the Acquisition Delay
        ADACQ = acquisitionDelay;
     
        // Turn on the ADC module
        ADCON0bits.ADON = 1;
    }

    void ADCC_StartConversion()
    {
        // Start the conversion
        ADCON0bits.ADGO = 1;
    }

    bool ADCC_IsConversionDone()
    {
        // Start the conversion
        return (!ADCON0bits.ADGO);
    }

    adc_result_t ADCC_GetConversionResult(void)
    {
        // Return the result
        return ((ADRESH << 8) + ADRESL);
    }
    adc_result_t ADCC_GetSingleConversion(adcc_channel_t channel, uint8_t acquisitionDelay)
    {
        // select the A/D channel
        ADPCH = channel;  

        //Set the Acquisition Delay
        ADACQ = acquisitionDelay;

        // Turn on the ADC module
        ADCON0bits.ADON = 1;
        
        //Disable the continuous mode.
        ADCON0bits.ADCONT = 0;    

        // Start the conversion
        ADCON0bits.ADGO = 1;

        // Wait for the conversion to finish
        while (ADCON0bits.ADGO)
        {
        }

        // Conversion finished, return the result
        return ((ADRESH << 8) + ADRESL) & 0x03FF;
    }

    void ADCC_StopConversion(void)
    {
        //Reset the ADGO bit.
        ADCON0bits.ADGO = 0;
    }

    void ADCC_SetStopOnInterrupt(void)
    {
        //Set the ADSOI bit.
        ADCON3bits.ADSOI = 1;
    }

    void ADCC_DischargeSampleCapacitor(void)
    {
        //Set the ADC channel to AVss.
        ADPCH = 0x3C;   
    }

    void ADCC_LoadAcquisitionRegister(uint8_t acquisitionValue)
    {
        //Load the ADACQ register.
        ADACQ = acquisitionValue;   
    }

    void ADCC_SetPrechargeTime(uint8_t prechargeTime)
    {
        //Load the ADPRE register.
        ADPRE = prechargeTime;  
    }

    void ADCC_SetRepeatCount(uint8_t repeatCount)
    {
        //Load the ADRPT register.
        ADRPT = repeatCount;   
    }

    uint8_t ADCC_GetCurrentCountofConversions(void)
    {
        //Return the contents of ADCNT register
        return ADCNT;
    }

    void ADCC_ClearAccumulator(void)
    {
        //Reset the ADCON2bits.ADACLR bit.
        ADCON2bits.ADACLR = 1;
    }

    uint16_t ADCC_GetAccumulatorValue(void)
    {
        //Return the contents of ADACCH and ADACCL registers
        return ((ADACCH << 8) + ADACCL);
    }

    bool ADCC_HasAccumulatorOverflowed(void)
    {
        //Return the status of ADSTATbits.ADAOV
        return ADSTATbits.ADAOV;
    }

    uint16_t ADCC_GetFilterValue(void)
    {
        //Return the contents of ADFLTRH and ADFLTRL registers
        return ((ADFLTRH << 8) + ADFLTRL);
    }

    uint16_t ADCC_GetPreviousResult(void)
    {
        //Return the contents of ADPREVH and ADPREVL registers
        return ((ADPREVH << 8) + ADPREVL);
    }

    void ADCC_DefineSetPoint(uint16_t setPoint)
    {
        //Sets the ADSTPTH and ADSTPTL registers
        ADSTPTH = setPoint >> 8;
        ADSTPTL = setPoint;
    }

    void ADCC_SetUpperThreshold(uint16_t upperThreshold)
    {
        //Sets the ADUTHH and ADUTHL registers
        ADUTHH = upperThreshold >> 8;
        ADUTHL = upperThreshold;
    }

    void ADCC_SetLowerThreshold(uint16_t lowerThreshold)
    {
        //Sets the ADLTHH and ADLTHL registers
        ADLTHH = lowerThreshold >> 8;
        ADLTHL = lowerThreshold;
    }

    uint16_t ADCC_GetErrorCalculation(void)
    {
        //Return the contents of ADERRH and ADERRL registers
        return ((ADERRH << 8) + ADERRL);
    }

    void ADCC_EnableDoubleSampling(void)
    {
        //Sets the ADCON1bits.ADDSEN
        ADCON1bits.ADDSEN = 1;
    }

    void ADCC_EnableContinuousConversion(void)
    {
        //Sets the ADCON0bits.ADCONT
        ADCON0bits.ADCONT = 1;
    }

    void ADCC_DisableContinuousConversion(void)
    {
        //Resets the ADCON0bits.ADCONT
        ADCON0bits.ADCONT = 0;
    }

    bool ADCC_HasErrorCrossedUpperThreshold(void)
    {
        //Returns the value of ADSTATbits.ADUTHR bit.
        return ADSTATbits.ADUTHR;
    }

    bool ADCC_HasErrorCrossedLowerThreshold(void)
    {
        //Returns the value of ADSTATbits.ADLTHR bit.
        return ADSTATbits.ADLTHR;
    }

    uint8_t ADCC_GetConversionStageStatus(void)
    {
        //Returns the contents of ADSTATbits.ADSTAT field.
        return ADSTATbits.ADSTAT;
    }



    #17
    qɥb
    Monolothic Member
    • Total Posts : 3329
    • Reward points : 0
    • Joined: 2017/09/09 05:07:30
    • Location: Jupiter
    • Status: offline
    Re: Interfacing PIC18F24K40 with POT 2018/08/10 03:58:17 (permalink)
    +2 (2)
    You're code is pretty much on the right track.
    I dislike using MCC calls, as it obscures how the hardware is being used. If the two pots are affecting each other. it indicates ther's not enough settling time/acquisition time being allowed, but we can't check as the register settings are hidden behind those MCC calls.
    You say that both pots affect the result, but you never reveal what that result is. Is it an average of the two pot settings?
     

    This forum is mis-configured so it only works correctly if you access it via https protocol.
    The Microchip website links to it using http protocol. Will they ever catch on?
    PicForum "it just works"
    #18
    Jump to:
    © 2018 APG vNext Commercial Version 4.5