LusoRobótica - Robótica em Português

Sistemas específicos => Arduino / AVR => Tópico iniciado por: senso em 07 de Julho de 2010, 03:26

Título: Utilização de tabelas não lineares para controlar pwm em leds
Enviado por: senso em 07 de Julho de 2010, 03:26
  Boa noite a todos, aqui está uma pequena brincadeira que tenho vindo a fazer, é algo simples mas que volta e meia aparece nalgum forum, pois como sabemos a nossa visão não é linear, e já todos devem ter reparado que se usarmos pwm para controlar o brilho de um led, parece que o brilho do mesmo aumenta muito rapidamente até cerca de metade dos valores (em linguagem arduino isto quer dizer analogWrite(ledPin,150)) mais coisa menos coisa e que dai para cima variar o valor do pwm não parece surtir grande efeito, para corrigir isso podemos recorrer a fórmulas ou tabelas (look-up tables) para que o valor do pwm seja menos linear, regra geral aponta-se para valores exponenciais ou então para uma curva parabólica (do tipo Ax²+Bx + C), então escrevendo um pequeno programa em C, e usando uma fórmula retirada do forum AVRfreaks e uma outra que determinei, eis que tenho duas tabelas para experimentar no arduino com um led.
  Usar tabelas não lineares é ainda mais perceptivel quando se usa um led rgb, pois assim nota-se uma melhor distribuição cromática e não parece apenas branco com um brilho/intensidade variavel, pode-se dizer que as cores fica mais vivas.
A comparação entre linear, exponencial e parabólico:

(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fimg51.imageshack.us%2Fimg51%2F6268%2Fgraficoe.png&hash=a5c70f5dfb42379915431123949aeb8ac9453f5e)
A azul está o linear, a vermelho estão os valores da tabela parabólica e a amarelo estão os da tabela exponencial.

Aqui fica um pequeno video, a qualidade não é das melhores pois foi filmado com o telemovel e o pulsar dos led's no fim de cada ciclo é devido aos ajustes da camera em relação á luminosidade e não tem nada a ver com o pwm gerado pelo arduino.
Nos dois casos o led com pwm linear está á esquerda, estando o outro com a tabela não linear á direita:

Non linear look up tables to control led brightness using pwm (http://www.youtube.com/watch?v=aijhK3HX5qY#)

E aqui fica o programa em que gerou as duas tabelas, é só copiar e colar no vosso programa do arduino, são um pouco extensas sim, mas no final dos exames irei actualizar o programa para guardar essas mesmas tabelas na flash do arduino e talvez fazer um tutorial de como usar os atributos PROGMEM. Este programa compila sem erros usando o gcc 4.4.3.

Código: [Seleccione]
#include <stdio.h>
#include <math.h>

/*
Programa para gerar as duas tabelas usadas
Tiago Angelo
7/7/2010

Para compilar: gcc log.c -lm -o log
*/

int calc(int num){
return  (((1<<(num/32))-1) + ((1<<(num/32))*((num%32)+1)+15)/32);}

int calc2(int num){
return (num*num*0.00392);}

int main(void){
int i=0;

for(i=0;i<256;i++){
if(i==0){printf("uint8_t expn[256] = {%d,",calc(i));}
else if(i==255){printf("%d}; \n",calc(i));}
else {printf("%d,",calc(i));}}

printf("\n");

for(i=0;i<256;i++){
if(i==0){printf("uint8_t parab[256] = {%d,",calc2(i));}
else if(i==255){printf("%d}; \n",calc2(i)+1);}
else {printf("%d,",calc2(i));}}
}

E o programa que o arduino está a correr é o seguinte:

Citar
/*Demonstração de uso de tabelas de dados não lineares para controlo do brilho de leds via pwm
Tiago Angelo
7/7/2010
*/

uint8_t expn[256] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,30,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,65,67,69,71,73,75,77,79,81,83,85,87,89,91,93,95,97,99,101,103,105,107,109,111,113,115,117,119,121,123,125,127,131,135,139,143,147,151,155,159,163,167,171,175,179,183,187,191,195,199,203,207,211,215,219,223,227,231,235,239,243,247,251,255};

uint8_t parab[256] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,7,7,7,8,8,9,9,9,10,10,11,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,22,22,23,23,24,25,25,26,27,27,28,28,29,30,31,31,32,33,33,34,35,36,36,37,38,39,39,40,41,42,43,44,44,45,46,47,48,49,50,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,79,80,81,82,83,84,85,87,88,89,90,91,92,94,95,96,97,99,100,101,102,104,105,106,108,109,110,111,113,114,115,117,118,120,121,122,124,125,127,128,129,131,132,134,135,137,138,140,141,143,144,146,147,149,150,152,153,155,156,158,159,161,163,164,166,167,169,171,172,174,176,177,179,181,182,184,186,188,189,191,193,194,196,198,200,201,203,205,207,209,210,212,214,216,218,220,222,223,225,227,229,231,233,235,237,239,241,243,244,246,248,250,252,255};

char var;

void setup() {
  Serial.begin(9600);
  Serial.write("Envia s para tabela exponencial e S para tabela parabolica");
}

void loop() {

  if(Serial.available()){
    var=Serial.read();

    if(var=='s'){
      for(int i=0; i<256; i++){
        analogWrite(6,expn);
        analogWrite(5,i);
        delay(100);
        Serial.print(i);
        Serial.print("  ");
        Serial.println(expn,DEC);
      }
    }

    if(var=='S'){
      for(int i=0; i<256; i++){
        analogWrite(6,parab);
        analogWrite(5,i);
        delay(100);
        Serial.print(i);
        Serial.print("  ");
        Serial.println(expn,DEC);
      }
    }
  }
}

Digam o que acham  ;)
Título: Re: Utilização de tabelas não lineares para controlar pwm em leds
Enviado por: TigPT em 07 de Julho de 2010, 17:12
Muito interessante e também com grande aplicação. Vou colocar na primeira página ;)

Acho que é uma excelente leitura para qualquer membro. Obrigado por partilhares senso.
Título: Re: Utilização de tabelas não lineares para controlar pwm em leds
Enviado por: norbanvs em 07 de Julho de 2010, 19:30
Realmente, no exemplo a diferença entre os valores lineares e não lineares é ENORME. Notem só como o led da esquerda ficou logo brilhante...
Título: Re: Utilização de tabelas não lineares para controlar pwm em leds
Enviado por: preytender em 08 de Julho de 2010, 00:08
Parabens, aqui esta um artigo muito interessante.

Já agora sabes se é possivel fazer o processo inverso ou seja tendo a tabela obter a formula ou função ??? 
A pergunta pode parecer estupida mas imagina dois motores DC, não rodam a mesma velocidade e a sua diferenca(desvio) tambem não é linear era bom conseguir, tendo alguns pontos de referencia, uma formula para calcular mais correctamente esse desvio.

Abraço.
Título: Re: Utilização de tabelas não lineares para controlar pwm em leds
Enviado por: senso em 08 de Julho de 2010, 00:40
Se souberes a rotação de cada um deles e qual o valor de pwm que estás a aplicar para obter essa rotação, metes esses valores no excel, fazes um gráfico e pedes para ele te calcular uma formula de ajuste, quer seja uma y=m*x+b ou uma polinomial, logaritmica, etc.
O pior é ler o valor de rotação com um erro muito muito reduzido.
Título: Re: Utilização de tabelas não lineares para controlar pwm em leds
Enviado por: preytender em 08 de Julho de 2010, 01:02
Obrigado, não sabia que o excel fazia isso. :o e é bastante facil o meu excel esta em ingles por isso a opção é "trendline".

Com relação aos motores, tens razão para alem de ser muito dificil medir as rotações com precisão existem ainda outras variaveis tais como carga das baterias, atrito etc.. que são impossiveis de medir mas... tal como muito bem exemplificado no teu artigo existem varias situações em que são uteis e foi muito bom aprender a fazer isto.

Abraço.
Título: Re: Utilização de tabelas não lineares para controlar pwm em leds
Enviado por: _ze_pedro_ em 08 de Julho de 2010, 19:42
muito interessante ;)

por acaso eu tenho um problema no meu projecto com um led secalhar aqui alguem me consegue ajudar

quando mando acender o led no meu projecto o led aparece com muito pouco brilho custa-se a ver

eu ja experimentei em fazer um programa so para por aquele pin activo e o led tem muito brilho mas depois quando ponho o programa todo e mando acender ele nao tem brilho

isto sera do programa?


cump.
ze pedro
Título: Re: Utilização de tabelas não lineares para controlar pwm em leds
Enviado por: amando96 em 08 de Julho de 2010, 20:17
Declaraste o pino onde tens o LED como output?

é um erro comum...
ia mandar PM para não contribuir para o offtopic, mas tens mensagens bloqueadas...
Título: Re: Utilização de tabelas não lineares para controlar pwm em leds
Enviado por: senso em 08 de Julho de 2010, 20:26
Ou isso ou estás a acender e a apagar o led dentro de um loop pequeno e estás efectivamente a fazer pwm por software.
Título: Re: Utilização de tabelas não lineares para controlar pwm em leds
Enviado por: _ze_pedro_ em 08 de Julho de 2010, 21:46
pois eu acho que esta a acontecer isso ele apaga e acende dentro do loop mas o que è faço é por o pin high nao é por pwn
Título: Re: Utilização de tabelas não lineares para controlar pwm em leds
Enviado por: _ze_pedro_ em 08 de Julho de 2010, 21:51
ja resolvi foi isso mesmo esqueci.me de declarar como output

obrigado ;)

cump.
ze pedro