Página 1 de 1

Calibração touch screen. {SOLVED}

MensagemEnviado: 23 Mar 2011 12:56
por fabim
Pessoal.
Estou utilizando um display de 7" x800y480, junto com um touch screem de 4 fios.
Estou utilizando um chip dedicado com pino de interrupt com ADC de 12 bits para fazer a leitura XY.

Acontece que o touch não apresenta qualquer tipo de simetria resistiva em sua mecanica. Desta forma é necessario um tipo de calibração, o a mesma calibração efetuada em tablets ou celulares.

Até o momento eu tinha achado o erro deste display, e estava fazendo os grids pixel xy, fazendo o acerto na unha para um touch, o que não batia no outro..
E chegou a hora de fazer o negocio da forma correta, e to levando um baile.

O touch em questão, me apresenta o valor de X crescendo da direita para a esquerda, e o valor de y crescendo de cima para baixo.

Alguém ja fez algo do tipo, e poderia me dar um auxilio para entender a sistematica do calculo ?

Fabim

MensagemEnviado: 23 Mar 2011 13:10
por fabim
http://www.raymundodeoliveira.eng.br/Simpson.htm

desculpem os loucos, mais não entendo caraionenhum disso ai.

MensagemEnviado: 23 Mar 2011 17:38
por cortex
integralzinha baba!! ja sofri muito com isso!!

Re: Calibração touch screen.

MensagemEnviado: 23 Mar 2011 20:02
por Rodrigo_P_A
fabim escreveu:Pessoal.
Estou utilizando um display de 7" x800y480, junto com um touch screem de 4 fios.
Estou utilizando um chip dedicado com pino de interrupt com ADC de 12 bits para fazer a leitura XY.

Acontece que o touch não apresenta qualquer tipo de simetria resistiva em sua mecanica. Desta forma é necessario um tipo de calibração, o a mesma calibração efetuada em tablets ou celulares.

Até o momento eu tinha achado o erro deste display, e estava fazendo os grids pixel xy, fazendo o acerto na unha para um touch, o que não batia no outro..
E chegou a hora de fazer o negocio da forma correta, e to levando um baile.

O touch em questão, me apresenta o valor de X crescendo da direita para a esquerda, e o valor de y crescendo de cima para baixo.

Alguém ja fez algo do tipo, e poderia me dar um auxilio para entender a sistematica do calculo ?

Fabim


dá uma lida nesta AN

http://www.atmel.com/dyn/resources/prod ... oc8091.pdf

MensagemEnviado: 23 Mar 2011 21:44
por msamsoniuk

MensagemEnviado: 24 Mar 2011 07:48
por fabim
Pessoal.
Obrigado pelas indicações. Eu ja havia visto os dois APP´s, e ja tinha implementado algo..
Mas não sei se>:
- Os touch screen chinezes baratos são uma bosta com absoluta simetria alguma.
- Eu talvez esteja precisando relembrar um pouco de matemática interpretativa..

F***.

Os algoritmos dizem erro menor que 10%, e qualquer um erra abundantemente.... WTF ?

MensagemEnviado: 24 Mar 2011 10:14
por fabim
Pessoal, soldev.

Fiz com 4 pontos , 5 pontos , 6 pontos..

4 pontos o erro foi reduzido a algo entre 0.25 e 1.6%.
5 e 6 pontos eu não vi nada de diferente..

Segue algoritmo e esplanações dos calculos.

Código: Selecionar todos
   
  void calibra_touchXY(void){
   int temp;               
   //desenha xy1
   put_line(20,0,20,40,WHITE ); //linha do eixo x
   put_line(0,20,40,20,WHITE ); //linha do eixo y
   //enquanto não for precionado
   while (!precionado){
   //faz leitura analogica do touch screem
   for(temp=0;temp<12000000;temp++);
   SamplePoint[0][0] = touch_x;
   SamplePoint[0][1] = touch_y;
   };
   //precionou então apaga linha xy1
   put_line(20,0,20,40,BLACK ); //linha do eixo x
   put_line(0,20,40,20,BLACK ); //linha do eixo y
   
 
   while (precionado){;};
   //desenha xy2
   put_line(780,0,780,40,WHITE ); //linha do eixo x
   put_line(760,20,800,20,WHITE); //linha do eixo y   
   //enquanto não for precionado
   while (!precionado){
   for(temp=0;temp<12000000;temp++);
   SamplePoint[1][0] = touch_x;
   SamplePoint[1][1] = touch_y;   
   };
   //precionou então apaga linha xy1
   put_line(780,0,780,40,BLACK ); //linha do eixo x
   put_line(760,20,800,20,BLACK); //linha do eixo y
 
   
   
   while (precionado){;};
   //desenha xy3
   put_line(0,460,40,460,WHITE ); //linha do eixo x
   put_line(20,440,20,480,WHITE); //linha do eixo y   
   //enquanto não for precionado
    while (!precionado){
   for(temp=0;temp<12000000;temp++);
   //faz leitura analogica do touch screem
   SamplePoint[2][0] = touch_x;
   SamplePoint[2][1] = touch_y;
   };
   put_line(20,440,20,480,BLACK);  //linha do eixo x   
   put_line(0,460,40,460,BLACK ); //linha do eixo y


 
   while (precionado){;};
   //desenha xy3
   put_line(760,460,800,460,WHITE ); //linha do eixo x
   put_line(780,440,780,480,WHITE); //linha do eixo y   
   //enquanto não for precionado
    while (!precionado){
   for(temp=0;temp<12000000;temp++);
   //faz leitura analogica do touch screem
   SamplePoint[3][0] = touch_x;
   SamplePoint[3][1] = touch_y;
   };
   put_line(760,460,800,460,BLACK ); //linha do eixo x
   put_line(780,460,780,480,BLACK); //linha do eixo y



   

   //0terceiro ponto para teste
   while (precionado){;};



 //  Depois de capturados os 4[x,y] valores analogicos, e colocados na matriz   //em seus respectivos lugares.

 // Chama calibração para calculos lineares, para descobrir os polinomios de //correção
   
   //the FUCK FUNCTIONAL BAGACEITION CALIBRATIONS TABAJARA
   Get_Calibration_Coefficient();
   } 

   
 
#define N 4 // numero de pontos para calibração do touch screen


//valores de referencia dos pontos adjacentes no display.
//são N pontos de (X,Y) representados no valor real de pixel
//o valor deve ser inicializado manualmente nas posições existentes no display
short ReferencePoint[N][2]={{0,0},{760,0},{0,440},{760,440}}; // ponto de referencia ideal
/* exemplo
 ReferencePoint[0]={20,20}; x1-y1
 ReferencePoint[1]={780,20};x2-y2
 ReferencePoint[2]={20,460};x3-y3
*/
 

//valores medidos de grandeza analogica no touch screen posicionado sobre o display
//são N pontos de (x,y) representados no valor real de pixel
//o valor é capturado da interface de leitura do touch screen
short SamplePoint[N][2]; // amostras analogicas sobre sobre os pontos de pixels ideais
/* exemplo
 SamplePoint[0]={3100,318}; valores analogicos referente as posições x1-y1
 SamplePoint[1]={70,254};valores analogicos referente as posições x2-y2
 SamplePoint[2]={3020,3040};valores analogicos referente as posições x3-y3
*/



//estas variaveis são utilizadas para fatorização de coeficientes.
float KX1, KX2, KX3, KY1, KY2, KY3; // coefficients para o algoritmo de calibração



//procedimento chamado com valor analogico medido em px e px, e sobrescrito pelo valor proporcional ao pixel
//chamada da seguinte forma
//do_calibration(&amostra x, &amostra y, &resultado pixel x, &resultado pixel y)

void Do_Calibration(short *Px, short *Py, short *Ry, short *Rx)
{
*Rx=( short )(KX1*(float)(*Px)+KX2*(float)(*Py)+KX3+0.5);
*Ry=( short )(KY1*(float)(*Px)+KY2*(float)(*Py)+KY3+0.5);
}

//executa calculo para os coeficientes de calibração do display
//esta rotina deve ser chamada com os valores previamente postados    ReferencePoint e SamplePoint.
// calcula coeficientes lineares de KX1, KX2, KX3, KY1, KY2, KY3
int Get_Calibration_Coefficient(void)
{
int i;
int Points=N;
float a[3],b[3],c[3],d[3],k;

if(Points<3)
{
return 0;
}


else
{
if(Points==3)
{
for(i=0; i<Points; i++)
{
a[i]=(float)(SamplePoint[i][0]);
b[i]=(float)(SamplePoint[i][1]);
c[i]=(float)(ReferencePoint[i][0]);
d[i]=(float)(ReferencePoint[i][1]);
}
}
else if(Points>3)
{
for(i=0; i<3; i++)
{
a[i]=0;
b[i]=0;
c[i]=0;
d[i]=0;
}
for(i=0; i<Points; i++)
{
a[2]=a[2]+(float)(SamplePoint[i][0]);
b[2]=b[2]+(float)(SamplePoint[i][1]);
c[2]=c[2]+(float)(ReferencePoint[i][0]);
d[2]=d[2]+(float)(ReferencePoint[i][1]);
a[0]=a[0]+(float)(SamplePoint[i][0])*(float)(SamplePoint[i][0]);
a[1]=a[1]+(float)(SamplePoint[i][0])*(float)(SamplePoint[i][1]);
b[0]=a[1];
b[1]=b[1]+(float)(SamplePoint[i][1])*(float)(SamplePoint[i][1]);
c[0]=c[0]+(float)(SamplePoint[i][0])*(float)(ReferencePoint[i][0]);
c[1]=c[1]+(float)(SamplePoint[i][1])*(float)(ReferencePoint[i][0]);
d[0]=d[0]+(float)(SamplePoint[i][0])*(float)(ReferencePoint[i][1]);
d[1]=d[1]+(float)(SamplePoint[i][1])*(float)(ReferencePoint[i][1]);
}
a[0]=a[0]/a[2];
a[1]=a[1]/b[2];
b[0]=b[0]/a[2];
b[1]=b[1]/b[2];
c[0]=c[0]/a[2];
c[1]=c[1]/b[2];
d[0]=d[0]/a[2];
d[1]=d[1]/b[2];
a[2]=a[2]/Points;
b[2]=b[2]/Points;
c[2]=c[2]/Points;
d[2]=d[2]/Points;
}
k=(a[0]-a[2])*(b[1]-b[2])-(a[1]-a[2])*(b[0]-b[2]);
KX1=((c[0]-c[2])*(b[1]-b[2])-(c[1]-c[2])*(b[0]-b[2]))/k;
KX2=((c[1]-c[2])*(a[0]-a[2])-(c[0]-c[2])*(a[1]-a[2]))/k;
KX3=(b[0]*(a[2]*c[1]-a[1]*c[2])+b[1]*(a[0]*c[2]-a[2]*c[0])+b[2]*(a[1]*c[0]-a[0]*c[1]))/k;
KY1=((d[0]-d[2])*(b[1]-b[2])-(d[1]-d[2])*(b[0]-b[2]))/k;
KY2=((d[1]-d[2])*(a[0]-a[2])-(d[0]-d[2])*(a[1]-a[2]))/k;
KY3=(b[0]*(a[2]*d[1]-a[1]*d[2])+b[1]*(a[0]*d[2]-a[2]*d[0])+b[2]*(a[1]*d[0]-a[0]*d[1]))/k;
return Points;
}
}

MensagemEnviado: 24 Mar 2011 13:44
por fanl
TS Resistivo é um saco as vezes! Por isso que frequentemente o pessoal usa um chip que faz a análise do toque e envia para o uC por um protocolo serial.

A calibração é um saco sempre. Porque varia com a temperatura ambiente.

Eu fiz um algoritmo que tenta unir performance e precisão num TS de malha resistiva de 4 fios, bolei um detector de toque/não toque, um sistema anti debounce. Não cheguei a usar filtros, só calculei média simples.

Se quiseres está no meu blog no demo do Finger Drawning.
[youtube]http://www.youtube.com/watch?v=mLf1j28Pgl0[/youtube]

MensagemEnviado: 24 Mar 2011 21:54
por fabim
cara, pensa num troço sem nexo...

Pensou ?

Então.
O display é de 7" e o touch tambem, etc...

Acontece que o touch é linear no meio quase chegando nas beiradas onde ainda esta dentro do display, o touch não tem nenhum tipo de simetria.... Como se quando voce clicasse ele dava contato em outro lugar...
Desmontei um s3c2440 aqui com display de 7, e o touch dele é bem maior, tipo da uns 1.5CM maior que o que eu tenhoi,,,
Faz sentido, o cara fugiu da não linearidade das beiradas,..... F***

MensagemEnviado: 25 Mar 2011 14:03
por fabim
Nossa.
Eu estou fazendo a confirmação de click fisico no display sobre os botões através de.

Se maior que X1 e menor que X2, e maior que Y1 e menor que Y2.

Onde cada botão tem o seu X1X2Y1Y2.

Isto da um puto de um trabalho de fazer.

Existe alguma técnica super secreta de matriciassão ou algo parecido, que eu consigo derivar um valor comparativo pra saber qual botão foi precionado ?
Tipo, como o fuck SO gerencia isto ?

MensagemEnviado: 25 Mar 2011 18:18
por tcpipchip
Talvez esta fudamentação matemática te ajude!

http://embedded-systems.com/story/OEG20 ... table=true

Tem aqui codigo fonte das rotinas de TOUCH do CIRCLE OS do STM32...

http://www.stm32circle.com/circleos_doc ... ource.html

Eu vi funcionando...

Abraços

TCPIPCHIP

MensagemEnviado: 26 Mar 2011 00:47
por msamsoniuk
entao velho, volta naquilo que te falei semanas atras e vc ignorou sumariamente: botoes nao sao apenas desenhos bmp na tela. aquela porrada de lindos botoes o iphone/ipad/osx/android/etc sao objetos em uma grande lista de objetos e, quando qualquer evento ocorre no display, essa lista eh varrida, de modo que as areas sao comparadas e, se baterem, funcoes de tratamento e callback sao ativadas.

nao tem nem milagres de geometria: quando eu passo a seta do mouse em uma caixa de texto com bordas redondas no OSX, mesmo passando na area que supostamente faz parte do cortorno interno, o cursor de texto nao aparece. mapeando os pontos onde ele aparece ou nao, percebe-se claramente que apesar de ter bordas arredondadas, a area efetiva de ativacao eh uma area quadrada. e isso eh algo bem logico: nao tem pq perder tempo fazendo verificacoes pixel a pixel! o objeto pode ser qq formato, o que vale eh a area quadrada consideravel dele... eh algo da vida real mesmo: qdo vc quer ativar um botao, vc clica numa area consideravel dele. ateh a minha capainha da rua nao toca se apertar o botao de "relance" hehehe

sabendo disso, a coisa eh simples. um botao, um label, etc sao elementos em listas linkadas. o cara gera um evento (uma dedada no display) e vc tem a coordenada do evento, daih vc varre a olhando os x,y,w,h para ver se o evento esta dentro da area de algum elemento. se estiver, vc chama o respectivo callback que faz alguma coisa... tem que ser sistematico! :)

uma coisa que vc pode fazer para acelerar o processamento eh montar as estruturas de forma hierarquica. por exemplo, a tela de um browser eh composta de varios objetos segundo uma hierarquia. a hierarquia de maior nivel eh a janela principal do browser. se um evento ocorrer fora dessa janela principal, vc nem testa o que estiver abaixo na hierarquia. se ocorrer dentro, vc tem varios elementos: barra de menu, barra de icones, barra de localizacao, barra de status, tabs e janela de visualizacao. se o evento ocorrer na barra de icones, vc nem varre a hierarquia adiante para os outros elementos, varre apenas a barra de icones e entao localiza o icone onde o evento ocorreu.

afinal, como vc acha que maquinas com 68000 de 8MHz rodando com menos de 1MIPS tinham interfaces graficas avancadas jah em 1984 ? hehehe :D

http://www.youtube.com/watch?v=C_7ehvepzhU

fabim escreveu:Nossa.
Eu estou fazendo a confirmação de click fisico no display sobre os botões através de.

Se maior que X1 e menor que X2, e maior que Y1 e menor que Y2.

Onde cada botão tem o seu X1X2Y1Y2.

Isto da um puto de um trabalho de fazer.

Existe alguma técnica super secreta de matriciassão ou algo parecido, que eu consigo derivar um valor comparativo pra saber qual botão foi precionado ?
Tipo, como o fuck SO gerencia isto ?

{SOLVED}

MensagemEnviado: 28 Mar 2011 10:15
por tcpipchip
{SOLVED}

Mudou o status para {SOLVED}

TCPIPCHIP

MensagemEnviado: 28 Mar 2011 10:48
por fabim
Á intão não gem outra forma mesmo. :0-( ...

Poisé SAM, é exatamente desta forma que eu imaginei no inicio e fiz tudo.

Eu tenho a area de botões de set point, a area de telas de tendencia, a area de botões de configuração.
Eu faço X1Y1X2Y2, pra saber em qual das 3 areas está, se não for na primeira nem testa nada, se não for na segunda nem testa nada, é na terceira /?^sim, então entra.

eu sei onde foi o X, ai vou testando pra saber de qual X ele é menor, pois antes era sempre maior, e o Y mesma coisa. Ficou rapidão, mais não quanto eu queria..

Acredito que no pc seja a mesma coisa.

bom, valew intão tio!! Brigado e solved...

MensagemEnviado: 28 Mar 2011 16:05
por fabim
Pessoal.
Agora sim consegui uma precisão menor do que +/- 4pixels.

Acontece que este algoritmo tanto quanto os outros, são lineares e necessitam de valores constantes, os quais são traçados e derivadas suas constantes de conversão.

Agora imaginem se the fuck ADS7843 estivesse funcionando a 6mhz, e pegando um ruido em 12 bits 4096 e o ruido fosse de +/- 30 decimal, e isto variando nos 4 cantos...
O algoritmo traça o erro proporcionalmente!!! E Fica uma nhaca de pitibiriba.

Eu diminui o clock para 750khz, e fiz media de 3 amostragens em 100ms. Ficou simplesmente perfeito, eu fiz para 20hz tambem e 30 e não vi diferença alguma.

:) Now relity solved!!! Com thinner !!!