Bueno ... tras unas cuantas horas perdidas debido a que el cable negro, el que tira a masa la resistencia R9, no hacía buen contacto y por consiguiente no había divisor de tensión ni nada que se le parezca, lo he solucionado y ya funciona.
He implementado una forma de leer que intenta minimizar los efectos aleatorios, y perversos, de las interferencias, transitorios y otras zarandajas.
Simplemente lo que hago es acumular n lecturas consecutivas y después calcular la media de todas ellas. Cuanto mas lecturas realice menor impacto pueden tener lecturas aleatorias esporádicas que puedan producirse.
Como leo con 10 bits de precisión, 1024 valores posibles, pero la menor y la mayor resistencia que puedo obtener son de 220R y 2760R que generan voltajes de 4,225V y 1,515V respectivamente, solo puedo obtener lecturas entre 865 y 310 aproximadamente.
Si es la mayor, 865, y acumulo sobre una variable de 16 bits solo podré acumular 75 lecturas (2^16/865) y después dividir por 75 para obtener la media de todas ... pero no es necesario ajustarse tanto al límite, con 32 lecturas tendremos mas que suficiente.
Asi que implementando que es gerundio:
void main(void){
int16 ANval;
int16 ANval_Acumuleitor=0;
int16 ANVal_Result;
int16 ANVAL_Minimun=255;
int8 CAN_count=0;
int8 CAN_maxcount=32;
setup_adc_ports(AN0 | VSS_VDD); // Configuro AN0 para lectura ADC, usando como referencia VSS y VDD
setup_adc(ADC_CLOCK_INTERNAL); // Configuro velocidad de muestreo la interna del PIC 2-6 us
set_adc_channel(0); // Configuro siguiente canal de lectura a AN0;
do{
ANVal = read_adc(); // Leo canal ACD y guardo en ANVal
ANval_Acumuleitor += ANVal; // Acumulo sucesivas lecturas sobre ANval_Acumuleitor
if(++Can_Count==CAN_maxcount){ // Si hago mas de CAN_maxcount lecturas ...
ANVal_Result = (int16) ANval_Acumuleitor/CAN_maxcount; // Calculo la media de las lecturas realizadas ...
if(ANVal_Result>ANVAL_Minimun){ // Que si resulta mayor que ANVAL_Minimun ...
printf("KeyScan %Lu\r\n",ANVal_Result); // La tomo en consideración, en este caso lo muestro,
// ya haremos la conversión a teclas por margen.
}
Can_Count=0; // Reinicio Can_Count, el contador de lecturas.
ANval_Acumuleitor=0; // Reinicio ANval_Acumuleitor, el acumulador de lecturas.
}
}while(1);
}
Asi el funcionamiento es claro y simple. Leo
CAN_maxcount veces (32) sobre
ANval, acumulando sobre
ANval_Acumuleitor, incrementando
CAN_count cada vez que leo. Cuando
CAN_count alcanza el valor de
CAN_maxcount lecturas calculo
ANVal_Result dividiendo
ANval_Acumuleitor por
CAN_maxcount. Si
ANVal_Result es mayor que
ANVAL_Minimun lo muestro, recordad que en nuestra tabla el menor resultado posible de una lectura correspondía a la mayor resistencia posible que nos daba una lectura de unos 310. Reinicio
CAN_count y
ANval_Acumuleitor y volvemos a empezar.
El resultado, mas abajo, tras pulsar la tecla Col4/Row4,
F4 en el teclado de la imagen:
Los resultados obtenidos son compatibles, en desviación, con el 5% de precisión de las resistencias usadas (las de la banda dorada). Con resistencias mas precisas, del 1% por ejemplo, podríamos afinar la lectura proporcionalmente.
Ahora ya solo queda identificar cada lectura con cada tecla, cosa que haremos teniendo en cuenta un margen de error de +-(mas, menos) ese 5%, disminuido a aproximadamente un 1% por la ponderación realizada, alrededor de cada valor teórico calculado, de forma que nuestra tecla
F4 que debería generar una lectura de 310 deberemos fijarla como 307>[F4]>313.