Autor Tema: sensor touch con pic 16f887 en ccs  (Leído 7948 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Superboy

  • PIC10
  • *
  • Mensajes: 23
sensor touch con pic 16f887 en ccs
« en: 24 de Agosto de 2018, 23:53:42 »
hola buena noche, soy nuevo en cuanto a la programacion y hace unas semanas me llamo la atencion lo de los sensores capacitivos que se pueden programar con el ADC de un pic como describe microchip en su app note AN1298.

Empece un programa con el pic 16f887 en pic c compiler sin embargo, como pueden ver el programa no esta muy bien hecho pero funciona; yo oprimo un sensor y eniende un led y se apaga al pasar un pequeño tiempo correspondiente a cada uno, el problema que tengo es que:
 
1) los sensores no me funcionan poniendoles una hoja de papel encima, no se a que se deba ese problema de sensibilidad ya que he visto otros experimentos del mismo y hasta con una placa delgada de acrilico siguen funcionando

2) cuando toco el primer sensor el led enciende pero cuando toco los demas sensores el led del primer sensor se queda clavado, se enciende y se queda asi prendido, mientras los demas leds de los otros sensores trabajan correctamente

me gustaria saber si alguien podria ayudarme a mejorar el programa y saber donde esta el error para todos los problemas que comente ya que como dije soy nuevo en esto de la programacion.

muchas gracias.

Dejo el link de mi programa en la parte de abajo.

Desconectado Superboy

  • PIC10
  • *
  • Mensajes: 23
Re:sensor touch con pic 16f887 en ccs
« Respuesta #1 en: 24 de Agosto de 2018, 23:55:41 »
 :)
« Última modificación: 24 de Agosto de 2018, 23:58:23 por Superboy »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:sensor touch con pic 16f887 en ccs
« Respuesta #2 en: 25 de Agosto de 2018, 08:40:51 »
Segun el programa deberia apagarse el led y no encenderse, no hay nada que haga encender al led 1 una ves que se detecte que el ADC esta con menos de 255, tal ves siga leyendo valores mayores a 255, y eso ya pasa por un problema de hardware

Desconectado Superboy

  • PIC10
  • *
  • Mensajes: 23
Re:sensor touch con pic 16f887 en ccs
« Respuesta #3 en: 25 de Agosto de 2018, 20:25:17 »
Segun el programa deberia apagarse el led y no encenderse, no hay nada que haga encender al led 1 una ves que se detecte que el ADC esta con menos de 255, tal ves siga leyendo valores mayores a 255, y eso ya pasa por un problema de hardware


hola, muchas gracias por responder y si no es molestia me podrias ayudar a hacer mas eficiente el programa?, ya que quiero usar switch para encender y apagar los leds pero no se como hacerlo bien.  :oops: :oops: :oops:

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:sensor touch con pic 16f887 en ccs
« Respuesta #4 en: 25 de Agosto de 2018, 23:01:20 »
Eficiente va a depender que estas buscando de tu codigo.

Usar un switch..case creo que seria complicarse la vida.Y no tendrias una mejora en ningun sentido.

Tal ves lo que buscas vos es "resumir" un poco el programa. Y pienso que lo podrías hacer con un for y un array, y tambien aprovechando que las salidas estan todas seguidas ( A0 a A4).. Ejemplo:

Código: C
  1. int8 canales[] = {13,11,9,8,10};
  2.  
  3.  
  4. void main() {
  5.        
  6.          // aca la configuracion del ADC como lo tenes
  7.  
  8.         while(1) {
  9.            
  10.             int8 i, valores;
  11.  
  12.             valores = 0;
  13.             for( i=0; i< sizeof canales ; i++) {
  14.                 valores <<= 1;  // Roto a la izquierda un lugar
  15.                 if ( adc(canales[i]) >= 255 ) valores |= 1;  // Si esta en 1, le hago una OR al bit0, asi pongo en 1 ese bit.
  16.             }
  17.  
  18.             output_a(valores);
  19.             delay_ms(100);
  20.         }
  21. }

Desconectado Superboy

  • PIC10
  • *
  • Mensajes: 23
Re:sensor touch con pic 16f887 en ccs
« Respuesta #5 en: 27 de Agosto de 2018, 20:28:18 »
Eficiente va a depender que estas buscando de tu codigo.

Usar un switch..case creo que seria complicarse la vida.Y no tendrias una mejora en ningun sentido.

Tal ves lo que buscas vos es "resumir" un poco el programa. Y pienso que lo podrías hacer con un for y un array, y tambien aprovechando que las salidas estan todas seguidas ( A0 a A4).. Ejemplo:

Código: C
  1. int8 canales[] = {13,11,9,8,10};
  2.  
  3.  
  4. void main() {
  5.        
  6.          // aca la configuracion del ADC como lo tenes
  7.  
  8.         while(1) {
  9.            
  10.             int8 i, valores;
  11.  
  12.             valores = 0;
  13.             for( i=0; i< sizeof canales ; i++) {
  14.                 valores <<= 1;  // Roto a la izquierda un lugar
  15.                 if ( adc(canales[i]) >= 255 ) valores |= 1;  // Si esta en 1, le hago una OR al bit0, asi pongo en 1 ese bit.
  16.             }
  17.  
  18.             output_a(valores);
  19.             delay_ms(100);
  20.         }
  21. }


hola implemente tu código el cual agradezco bastante sin embargo no puedo saber como iniciar el adc en el código para que empiece a leer cuando yo toque los sensores ya que pongo el adc al principio del código que me diste y todos los leds encienden y empiezan a parpadear sin tocar los sensores, me podrías ayudar con eso???


Código: C++
  1. #INCLUDE <16F887.h>
  2. #DEVICE adc=8
  3.  
  4. #Fuses INTRC_IO,NOWDT,MCLR,NOPROTECT
  5.  
  6. #use delay (internal=4M)
  7.  
  8. #BYTE TRISA=0x85
  9. #BYTE TRISB=0x86
  10.  
  11.  
  12. #define LED1 PIN_A0
  13. #define LED2 PIN_A1
  14. #define LED3 PIN_A2
  15. #define LED4 PIN_A3
  16. #define LED5 PIN_A4
  17.  
  18. int8 canales[] = {13,11,9,8,10};
  19.  
  20. char adc(char canal)
  21. {
  22.  
  23.      char dato=0;
  24.      
  25.      set_adc_channel(canal);
  26.      delay_us(20);
  27.      dato=read_adc();
  28.      delay_us(100);
  29.      return dato;
  30.      
  31. }
  32.  
  33.  
  34. void main()
  35.  
  36. {
  37.    
  38.    TRISA=0X00;
  39.    TRISB=0xFF;
  40.    
  41.    
  42.    setup_adc_ports(sAN8|sAN9|sAN10|sAN11|sAN13);  
  43.    setup_adc(ADC_CLOCK_INTERNAL);
  44.      
  45.  
  46.    set_tris_b(0b00000000);
  47.    output_high(pin_b0);
  48.    set_adc_channel(0);
  49.    
  50.    
  51.    output_a(0);
  52.    output_b(0);
  53.  
  54.    
  55.    
  56.    while (TRUE)
  57.    {
  58.  
  59.    output_low(pin_b1|pin_b2|pin_b3|pin_b4|pin_b5);
  60.    set_tris_b(0b00111110);
  61.      
  62.    adc(10);adc(8);adc(9);adc(11);adc(13);
  63.      
  64.      
  65.         int8 i, valores;
  66.  
  67.        valores = 0;
  68.        for( i=0; i< sizeof canales ; i++)
  69.          {
  70.            valores <<= 1;  // Roto a la izquierda un lugar
  71.            if ( adc(canales[i]) >= 255 ) valores |= 1;  // Si esta en 1, le hago una OR al bit0, asi pongo en 1 ese bit.
  72.          }
  73.  
  74.             output_a(valores);
  75.             delay_ms(50);
  76.      
  77.        
  78.      
  79.    }  
  80. }

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:sensor touch con pic 16f887 en ccs
« Respuesta #6 en: 27 de Agosto de 2018, 23:01:54 »
Aclaremos un par de puntos:

- Yo resumi tu programa, hace casi lo mismo que el tuyo.
- Cuando tocas no dispara el ADC, vos lees el ADC para determinar si es que hay un toque.
- La forma de implementar la nota de aplicacion me parece incorrecta.
- El sensor es importante.

La nota de aplicacion especifica:

Necesitas un canal analogico que lo unico que va a servir es para referenciarlo a VDD (Si es que no posee VDD como referencia). Mas los canales de los sensores. Ese canal va a estar a VDD siempre.

Y los pasos a seguir son:
- Pongo todos los canales como salida y en 0. Excepto el que me da referencia de VDD. Esto es para que el capacitor que es el sensor este descargado.
- Selecciono el canal ( sin leer) que posee VDD y espero que se cargue el capacitor de S/H ( cambiar de canal y un pequeño delay )
- Procedo a poner como entrada el canal que deseo leer y cambio de canal.
- Inicio la conversion
- Vas a tener un valor en "alto", queriendo decir que no se detecto nada. Y un valor "bajo" que significa que se detecto algo.

Los valores que obtenes tocando o no, vas a tener que observarlo y definir cual es el limite que conviene para que sea fiable la deteccion del toque.
Por que va a depender de la capacidad del sensor tambien, no podes pensar que si o si el valor quede perfecto en VDD.

Desconectado Superboy

  • PIC10
  • *
  • Mensajes: 23
Re:sensor touch con pic 16f887 en ccs
« Respuesta #7 en: 28 de Agosto de 2018, 23:00:45 »
Aclaremos un par de puntos:

- Yo resumi tu programa, hace casi lo mismo que el tuyo.
- Cuando tocas no dispara el ADC, vos lees el ADC para determinar si es que hay un toque.
- La forma de implementar la nota de aplicacion me parece incorrecta.
- El sensor es importante.

La nota de aplicacion especifica:

Necesitas un canal analogico que lo unico que va a servir es para referenciarlo a VDD (Si es que no posee VDD como referencia). Mas los canales de los sensores. Ese canal va a estar a VDD siempre.

Y los pasos a seguir son:
- Pongo todos los canales como salida y en 0. Excepto el que me da referencia de VDD. Esto es para que el capacitor que es el sensor este descargado.
- Selecciono el canal ( sin leer) que posee VDD y espero que se cargue el capacitor de S/H ( cambiar de canal y un pequeño delay )
- Procedo a poner como entrada el canal que deseo leer y cambio de canal.
- Inicio la conversion
- Vas a tener un valor en "alto", queriendo decir que no se detecto nada. Y un valor "bajo" que significa que se detecto algo.

Los valores que obtenes tocando o no, vas a tener que observarlo y definir cual es el limite que conviene para que sea fiable la deteccion del toque.
Por que va a depender de la capacidad del sensor tambien, no podes pensar que si o si el valor quede perfecto en VDD.


ok, lo que sucede es que me guie por un codigo que encontre aqui mismo en el foro y el programa es el siguiente...

Código: C++
  1. #include <16F877a.h>
  2. #fuses XT,NOWDT,NOPROTECT,NOLVP,PUT
  3. #DEVICE ADC=10
  4. #use delay(clock=4M)
  5. #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
  6.  
  7.  
  8. void main(){
  9.    unsigned long value=0;
  10.    delay_ms(10);
  11.    setup_adc_ports(AN0);
  12.    setup_adc(ADC_CLOCK_INTERNAL);
  13.    
  14.    while(TRUE){
  15.       set_tris_a(0b11111100); //Drive secondary channel to VDD as digital output.
  16.       output_high(PIN_A1);
  17.       set_adc_channel(1); //Point ADC to the secondary VDD pin (charges CHOLD to VDD)
  18.      
  19.       output_low(PIN_A0); //Ground sensor line.
  20.       set_tris_a(0b11111101); //Turn sensor line as input (TRISx = 1).
  21.       set_adc_channel(0);//Point ADC to sensor channel (voltage divider from sensor to CHOLD).
  22.      
  23.       value=read_adc();//Begin ADC conversion.
  24.       printf("%lu\n",value);
  25.       delay_ms(50);
  26.    }  
  27. }

y lo que hice o trate es de hacer lo mismo que el el ya que lee el adc del pin como sensor

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:sensor touch con pic 16f887 en ccs
« Respuesta #8 en: 28 de Agosto de 2018, 23:11:34 »
Si lees los pasos que te doy (que es lo que copie del AN) vas a ver que es casi lo mismo, lo voy a copiar y numerar, para que veas la similitud:

Citar
1 - Pongo todos los canales como salida y en 0. Excepto el que me da referencia de VDD. Esto es para que el capacitor que es el sensor este descargado.
2 - Selecciono el canal ( sin leer) que posee VDD y espero que se cargue el capacitor de S/H ( cambiar de canal y un pequeño delay )
3 - Procedo a poner como entrada el canal que deseo leer y cambio de canal.
4 - Inicio la conversion
5 - Vas a tener un valor en "alto", queriendo decir que no se detecto nada. Y un valor "bajo" que significa que se detecto algo.

Código: C
  1. set_tris_a(0b11111100); // Paso 1, pongo la entradas de los sensores a leer como salida. Observa que el canal 1 (A1) es quien esta en VDD y A0 el que quiero leer.
  2.       output_high(PIN_A1);                    // Ya lo puse como salida, le pongo un nivel alto o VDD
  3.       set_adc_channel(1);                      //Paso 2, selecciono el canal que posee VDD
  4.      
  5.       output_low(PIN_A0);                     // Esto es parte del paso 1, ya que ademas de ponerlo como salida, exigue que se ponga a GND el sensor de interes.
  6.       set_tris_a(0b11111101);                // Paso 3, pongo como entrada el sensor que quiero leer. Y selecciono el canal que quiero leer
  7.       set_adc_channel(0);                       //
  8.      
  9.       value=read_adc();                        // Paso 4, inicio la conversion


Desconectado Superboy

  • PIC10
  • *
  • Mensajes: 23
Re:sensor touch con pic 16f887 en ccs
« Respuesta #9 en: 28 de Agosto de 2018, 23:57:42 »
Si lees los pasos que te doy (que es lo que copie del AN) vas a ver que es casi lo mismo, lo voy a copiar y numerar, para que veas la similitud:

Citar
1 - Pongo todos los canales como salida y en 0. Excepto el que me da referencia de VDD. Esto es para que el capacitor que es el sensor este descargado.
2 - Selecciono el canal ( sin leer) que posee VDD y espero que se cargue el capacitor de S/H ( cambiar de canal y un pequeño delay )
3 - Procedo a poner como entrada el canal que deseo leer y cambio de canal.
4 - Inicio la conversion
5 - Vas a tener un valor en "alto", queriendo decir que no se detecto nada. Y un valor "bajo" que significa que se detecto algo.

Código: C
  1. set_tris_a(0b11111100); // Paso 1, pongo la entradas de los sensores a leer como salida. Observa que el canal 1 (A1) es quien esta en VDD y A0 el que quiero leer.
  2.       output_high(PIN_A1);                    // Ya lo puse como salida, le pongo un nivel alto o VDD
  3.       set_adc_channel(1);                      //Paso 2, selecciono el canal que posee VDD
  4.      
  5.       output_low(PIN_A0);                     // Esto es parte del paso 1, ya que ademas de ponerlo como salida, exigue que se ponga a GND el sensor de interes.
  6.       set_tris_a(0b11111101);                // Paso 3, pongo como entrada el sensor que quiero leer. Y selecciono el canal que quiero leer
  7.       set_adc_channel(0);                       //
  8.      
  9.       value=read_adc();                        // Paso 4, inicio la conversion


Ahora lo que tengo duda es que es lo sucede en el codigo que explica esta persona en su blog, el lee los 2 adc a diferencia del codigo anterior que solo lee el adc del sensor que se quiere leer, lo que el hace es saber la diferencia entre las 2 lecturas?

http://pictrance.blogspot.com/2014/03/apagador-touch-usando-el-modulo-adc-de.html

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:sensor touch con pic 16f887 en ccs
« Respuesta #10 en: 29 de Agosto de 2018, 07:30:42 »
Lo que pasa es lo siguiente, Te explico burdamente como funciona.

El ADC tiene un pequeño capacitor, que al momento de estar conectado al canal, se carga con la tension del canal analogico, luego al momento de la conversion se desconecta de los pines analogicos y pasa a convertirse la señal, este pequeño capacitor es el capacitor de Sample and Hold ( Muestreo y Retencion) De esa forma al operar el ADC, opera sobre la tension "adquirida" por este capacitor y no sobre el pin de entrada que es varaible con el tiempo.

En esta aplicacion, necesitas pensar que tu sensor es un capacitor pero mucho mas pequeño que el interno al ADC.
Entre los primeros pasos es cargar ese capacitor a VDD y dejar el sensor como salida y en 0. Esto es para que... el capacitor de Sample and Hold ( S/H ) tenga un voltaje igual a VDD, y la capacidad del sensor no posea carga, y este a una tension GND.
Al momento de cambiar de canal vas a tener 2 capacidades en paralelo. Uno cargado y otro no, entonces el capacitor del S/H va a cargar esa pequeña capacidad del sensor. Es tan poco que queda proximo a VDD. PERO si hay un dedo sobre el sensor, es otro camino mas para la carga del capacitor, y entonces el capacitor de S/H se va a vaciar mas rapido, como consecuencia vas a tener una "carga" o resultado en el ADC menor.

Entonces siempre antes de convertir el canal, tenes que cargar tu capcitor de S/H a VDD, para que este pueda dar carga y asi detectar si esta solo el sensor o hay algo mas.

PD: El link que me pasas para mi esta mal. En realidad no hay necesidad de leerlo.
PD2: Asi como esta este metodo, hay otros mas, como el de detectar el momento que supera el treshold del pin. con una resistencia en serie grande, como para que  detectar el tiempo que necesita cargarse la capacidad el sensor + capacidad que le proveemos.
« Última modificación: 29 de Agosto de 2018, 07:47:26 por KILLERJC »

Desconectado Superboy

  • PIC10
  • *
  • Mensajes: 23
Re:sensor touch con pic 16f887 en ccs
« Respuesta #11 en: 20 de Octubre de 2018, 00:40:05 »
HOLA BUENA NOCHE, me surgio una nueva duda sobre esto de los sensores capacitivos, como le hago si lo que quiero es sensar valga la redundancia sensores de otro puerto?? es decir que no solo sense el convertidos analogico del puerto b como el ejemplo que puse arriba y me quiera mover al puerto a y e para ocupar los otros posibles sensores capacitivos.

como tal me refiero a este punto del codigo:

Código: C++
  1. set_tris_a(0b11111100); //Drive secondary channel to VDD as digital output.
  2.       output_high(PIN_A1);
  3.       set_adc_channel(1); //Point ADC to the secondary VDD pin (charges CHOLD to VDD)


pues solo esta usando todo el puerto a y los analogicos que se encuentran ahi para hacer el sensor capacitivo, pero y si quiero sensores en otros puertos, como le tendria que hacer?.

muchas gracias de antemano.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:sensor touch con pic 16f887 en ccs
« Respuesta #12 en: 20 de Octubre de 2018, 13:42:52 »
Citar
pues solo esta usando todo el puerto a y los analogicos que se encuentran ahi para hacer el sensor capacitivo, pero y si quiero sensores en otros puertos, como le tendria que hacer?.

Los unicos pines que vas a poder usar para estos casos son aquellos que son analogicos. Por ejemplo en el PIC16F887 DIP40 , tenes RA0 a RA3, RA5, RB0 a RB5 y RE0 a RE2 (que corresponden de AN0 a AN13). Esos serian tus unicos pines que podrias ponerle "sensores" por mas que sean de otro puerto. El procedimiento es igual que en con los del PORTA solamente.

Desconectado Superboy

  • PIC10
  • *
  • Mensajes: 23
Re:sensor touch con pic 16f887 en ccs
« Respuesta #13 en: 20 de Octubre de 2018, 16:14:24 »
entonces solo declaro lo mismo, solo que lo hago para el puerto que yo quiero usar los analogicos?
por ejemplo algo asi, para el puerto a y b

Código: C++
  1. set_tris_a(0b00000000); //Drive secondary channel to VDD as digital output.
  2.       output_high(PIN_A1);
  3.       set_adc_channel(1); //Point ADC to the secondary VDD pin (charges CHOLD to VDD)
  4.  
  5. set_tris_b(0b00000000); //Drive secondary channel to VDD as digital output.
  6.       output_high(PIN_b1);
  7.       set_adc_channel(10); //Point ADC to the secondary VDD pin (charges CHOLD to VDD)

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:sensor touch con pic 16f887 en ccs
« Respuesta #14 en: 20 de Octubre de 2018, 16:57:55 »
Exactamente algo asi, y es obvio que hay que cambiar los valores de los bits en set_tris_a y b