PSoC 4S - CapSense ADC


Los PSoC 4S no cuentan con un ADC per se, pero los ingenieros encontrarón una forma de utilizar los componentes que forman el bloque de CapSense como ADC, aunque es un tanto limitado, resolución de 8 o 10 bits, y corre hasta los ~11.6 ksps (kilo samples per second / miles de muestras por segundo) maximo.

El primer problema que encontré es que para que funcione el CapSense ADC se tiene que añadir por lo menos un widget de CapSense (boton, slider, etc., acá perdemos un pin). Al principio trataba de usar este periférico sin crear widgets pero el programa se detenía al llamar la función _Start(), y este error se soluciona creando el widget.

Otro problema que encontré es que en la versión 3.3 de PSoC Creator no esta incluida la documentación de las funciones del bloque ADC en el Datasheet del CapSense_ADC, hay que bajarlas de este link. Si como yo estas trabajando en PSoC Creator 4 este error ya fue corregido.

El proyecto ejemplo será sencillo, el CapSense_ADC y una UART para imprimir el resultado de la conversión por el puerto serial.

Iniciamos agregando los componentes necesarios al esquematico:
Implementación en el esquemtico

Podemos ver la configuración de la UART:
Configuración de la UART

La configuracion del CapSense_ADC, como vemos en la primer imagen hay que agregar un widget para que funcione:
Dummy widget
Configuracion del ADC

La tarjeta 041-40xx tiene un potenciometro en una de las esquinas, este potenciometro esta conectado a un pin directamente.
Potenciometro en la tarjeta
Conexion del potenciometro
La tarjeta tambien tiene una conexión directa hacia el puente UART<->USB del kitprog.
Puente UART<->USB
Asignacion de pines, el tener que agregar un widget al funcionamiento del CapSense_ADC "desperdiciar" un pin (Button0_Sns0 en P1.2), además se asigna el Cmod, que esta ubicado en P4.1, el pin de entrada del potenciometro P2.4 y el Tx de la UART P0.5.
Asignación de pines
Y el main.c quedo asi:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include "project.h"
#include <stdio.h>

int main()
{
    uint16_t adcConvert = 0;
    char voltsStr[15] = {0};
    
    CyGlobalIntEnable; /* Enable global interrupts. */

    UART_Start();
    
    UART_PutString("\tPruebas con el CapSenseADC\r\n");
    
    /* Inicializamos el ADC */
    if(CYRET_SUCCESS != CapSense_ADC_Start()){
        UART_PutString("No se pudo inicializar el CapSenseADC.\r\n");
    }
    
    /* Calibramos el ADC */
    if(CYRET_SUCCESS != CapSense_ADC_AdcCalibrate()){
        UART_PutString("No se pudo calibrar el CapSenseADC.\r\n");
    }
    
    for(;;){
        
        /* Revisar si el ADC no se esta usando (IDLE) */
        if(CapSense_ADC_AdcSTATUS_IDLE == CapSense_ADC_AdcIsBusy()){
            /* Inicializamos una conversion en el Canal0 del ADC */
            if(CYRET_SUCCESS != CapSense_ADC_AdcStartConvert(CapSense_ADC_AdcCHANNEL_0)){
                UART_PutString("CapSenseADC no inicio una nueva lectura.\r\n");
            }

            /* Esperamos mientras el ADC esta realizando la conversion */
            while(CapSense_ADC_AdcSTATUS_CONVERTING == CapSense_ADC_AdcIsBusy());

            /* Checamos si el parametro de _AdcGetResult (Canal del ADC) es valido */
            adcConvert = CapSense_ADC_AdcGetResult_mVolts(CapSense_ADC_AdcCHANNEL_0);
            UART_PutString("Valor de la conversion: ");
            if(CapSense_ADC_AdcVALUE_BADCHANID != adcConvert){
                snprintf(voltsStr, sizeof(voltsStr), "%d mV", adcConvert);
                UART_PutString(voltsStr);
                UART_PutCRLF();
            }else{
                UART_PutString("El canal seleccionado no es valido.\r\n");
            }
        
        }

    }
}

/* [] END OF FILE */

Como se ve traté de hacer un poco de manejo de errores, en caso de que en alguna llamada de función se presente uno.
Para usar la función snprintf tenemos que aumenta el heap del proyecto además de agregar -u_printf_float a los comandos del linker, aqui esta documentado como hacerlo.

El proyecto (hecho en Creator 4.0) lo puedes encontrar aqui, más ejemplos hechos con PSoC 4000S los puedes encontrar aqui.

Saludos

Comentarios

Entradas más populares de este blog

PSoC Creator Tools

PSoC5LP Usando el SAR ADC y la señal EoS para manejar una LUT