Trying to get ADC SAR to work

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
CuTh_2099391
Level 2
Level 2
First like received First like given

I'm trying to acquire the voltage from a potentiometer so I can use it as a rotary switch.  I'm using the CY8CKIT--059 PSoC 5LP Prototyping Kit.  The pot is connected to 5VDC and the wiper is connected to P1.7.  I can see the voltage go from 0 to 5VDC at P1.7 as seen with an o'scope.  I've dropped an analog pin and ADC_SAR into the design and connected them.

Here is my main():

int main(void)

{

    volatile int8 pot_in;

    CyGlobalIntEnable; /* Enable global interrupts. */

    /* Place your initialization/startup code here (e.g. MyInst_Start()) */

    ADC_SAR_1_Start();

    for(;;)

    {

        /* Place your application code here. */

        if (ADC_SAR_1_IsEndConversion(ADC_SAR_1_RETURN_STATUS) != 0)

        {

            pot_in =  ADC_SAR_1_GetResult8();

            (void) pot_in;

        }

    }

}

It never seems to end the conversion and get to ADC_SAR_1_GetResult8().  I know I'm missing something simple.

The project is attached.

Curtis

0 Likes
1 Solution
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted

Curtis,

You forgot to add ADC_StartConvert:

  ADC_SAR_1_Start();

  ADC_SAR_1_StartConvert();

Other thing is that ADC reading rate should be capped to e.g. 100 Hz, which is sufficient for manual control. Either use a timer event to read ADC or simply add a delay in the loop

CyDelay(10); // 10ms delay

Alternatively, you may consider using rotary encoder for manual input as shown here

Quad Decoder with Button Switch component for rotary shaft encoders

/odissey1

View solution in original post

5 Replies
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted

Curtis,

You forgot to add ADC_StartConvert:

  ADC_SAR_1_Start();

  ADC_SAR_1_StartConvert();

Other thing is that ADC reading rate should be capped to e.g. 100 Hz, which is sufficient for manual control. Either use a timer event to read ADC or simply add a delay in the loop

CyDelay(10); // 10ms delay

Alternatively, you may consider using rotary encoder for manual input as shown here

Quad Decoder with Button Switch component for rotary shaft encoders

/odissey1

Odissey1,

That's it.  Thanks for the help.

I will throttle the acquisition rate to a reasonable value.

I'm using the pot because I had one laying around.  A rotary encoder would be better.

Curtis

lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

Wow, /odissey1-san is so fast!

Anyway adding to /odissey1-san's answer, I touched up your project.

To view the result I added UART and changed ADC from free running to software trigger.

Schematic

002-schematic.JPG

ADC_SAR_1 configuration

001-ADC_Setting.JPG

Pin (added P12_6, P12_7 for UART)

003-Pins.JPG

main.c

=================

#include "project.h"

#include "stdio.h"

#define STR_LEN 64

char str[STR_LEN+1] ;

void print(char *str)

{

    UART_PutString(str) ;

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */

   

    UART_Start() ;

   

    ADC_Start() ;

}

void cls(void)

{

    print("\033c") ; /* reset */

    CyDelay(20) ;

    print("\033[2J") ; /* clear screen */

    CyDelay(20) ;

}

void splash(void)

{

    cls() ;

    print("CY8CKIT-059 ADC TEST ") ;

    snprintf(str, STR_LEN, "(%s %s)\n", __DATE__, __TIME__) ;

    print(str) ;

}

   

int main(void)

{

    uint16_t adc_count ;

    int16_t mV ;

   

    init_hardware() ;

   

    splash() ;

    for(;;) {

       

        ADC_StartConvert() ;

        ADC_IsEndConversion(ADC_WAIT_FOR_RESULT) ;

        adc_count = ADC_GetResult16(0) ;

        mV = ADC_CountsTo_mVolts(adc_count) ;

       

        if (mV < 0) {

            mV = -mV ;

            print("-") ;

        }

        snprintf(str, STR_LEN,  "%d.%03d V (0x%04X) \n", mV/1000, mV%1000, adc_count) ;

        print(str) ;

       

        CyDelay(1000) ;

    }

}

=================

Tera Term output

000-TeraTerm-log.JPG

moto

Moto,

Very nice and complete solution.  Thanks.

Curtis

MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Oops, I pasted a wrong "main.c" in my previous response!

Although it also should work, following is the main.c using ADC_SAR_1_GetResult8()

========================

#include "project.h"

#include "stdio.h"

#define STR_LEN 32

char str[STR_LEN+1] ;

void print(char *str)

{

    UART_PutString(str) ;

}

void cls(void)

{

    print("\033c") ; /* reset */

    CyDelay(20) ;

    print("\033[2J") ; /* clear screen */

    CyDelay(20) ;

}

void splash(void)

{

    cls() ;

    print("CY8CKIT-059 ADC TEST ") ;

    snprintf(str, STR_LEN, "(%s %s)\n", __DATE__, __TIME__) ;

    print(str) ;

}

int main(void)

{

    volatile uint8 pot_in;

   

    CyGlobalIntEnable; /* Enable global interrupts. */

    /* Place your initialization/startup code here (e.g. MyInst_Start()) */

    ADC_SAR_1_Start();

    UART_Start() ;

   

    splash() ;

    for(;;)

    {

        ADC_SAR_1_StartConvert() ;

        ADC_SAR_1_IsEndConversion(ADC_SAR_1_WAIT_FOR_RESULT) ;

        pot_in = ADC_SAR_1_GetResult8() ;

        snprintf(str, STR_LEN, "%d\n", pot_in) ;

        print(str) ;

        CyDelay(1000) ;

    }

}

========================

moto

0 Likes