Al conducir un LED con PWM, el brillo (como lo percibo) no se escala linealmente con el ciclo de trabajo. El brillo es lento para aumentar, luego aumenta exponencialmente con el ciclo de trabajo.
¿Alguien puede sugerir una regla general para usar como factor de corrección u otra solución?
Respuestas:
Para 16 niveles, es fácil hacer una tabla de búsqueda simple "a mano" y convertir el valor de 4 bits en un valor de 8 bits para pasar al controlador PWM: este es el componente que he usado en mi controlador de matriz de LED FPGA. Para un controlador de nivel de 8 bits, necesitará al menos una salida de 11-12 bits de la tabla de búsqueda.
fuente
1
En teoría, debería ser exponencial, pero obtuve los mejores resultados para el desvanecimiento mediante el uso de una función cuadrática.
También creo que lo tienes al revés. En el ciclo de trabajo bajo, el aumento percibido del brillo es mucho mayor que en el ciclo de trabajo casi completo, donde el aumento del brillo es casi imperceptible.
fuente
He estado investigando este tema en los últimos días ya que tengo el mismo problema ... tratando de atenuar los LED usando PWM de una manera visiblemente lineal, pero quiero una resolución completa de 256 pasos. ¡Intentar adivinar 256 números para crear una curva manualmente no es una tarea fácil!
No soy un matemático experto, pero sé lo suficiente como para generar algunas curvas básicas combinando algunas funciones y fórmulas sin saber realmente cómo funcionan. Me parece que usando una hoja de cálculo (usé Excel) puedes jugar con un conjunto de números del 0 al 255, poner algunas fórmulas en la siguiente celda y representarlas gráficamente.
Estoy usando pic assembler para hacer el desvanecimiento, por lo que incluso puede obtener la hoja de cálculo para generar el código del ensamblador con una fórmula (
="retlw 0x" & DEC2HEX(A2)
). Esto hace que sea muy rápido y fácil probar una nueva curva.Después de jugar un poco con las funciones LOG y SIN, el promedio de los dos y algunas otras cosas, realmente no pude obtener la curva correcta. Lo que está sucediendo es que la parte media del desvanecimiento fue más lenta que los niveles más bajos y más altos. Además, si un desvanecimiento es seguido inmediatamente por un desvanecimiento, hubo un fuerte aumento notable en la intensidad. Lo que se necesita (en mi opinión) es una curva en S.
Una búsqueda rápida en Wikipedia arrojó la fórmula necesaria para una curva en S. Lo conecté a mi hoja de cálculo e hice algunos ajustes para que se multiplique en mi rango de valores, y se me ocurrió esto:
Lo probé en mi plataforma y funcionó muy bien.
La fórmula de Excel que utilicé fue esta:
donde A2 es el primer valor en la columna A, que aumenta A3, A4, ..., A256 para cada valor.
No tengo idea si esto es matemáticamente correcto o no, pero produce los resultados deseados.
Aquí está el conjunto completo de 256 niveles que utilicé:
fuente
Encontré a este tipo que usa un método que él llama "Anti-Log Drive". Aquí está el enlace de descarga directa para su información.
fuente
Estaba usando un ATtiny para iluminar mi terraza. El brillo se controla usando una olla conectada al pin ADC.
Intentó la función exponencial y la salida PWM basada en eso parece estar dando un aumento lineal en el brillo percibido.
Estaba usando estas fórmulas:
Attiny85 @ 8MHz estaba tardando unos 210us en realizar el cálculo anterior. Para mejorar el rendimiento, hizo una tabla de búsqueda. Como la entrada era de ADC de 10 bits y la memoria ATtiny es limitada, también quería crear una tabla más corta.
En lugar de hacer una tabla de búsqueda con 1024 entradas, hizo una tabla de búsqueda inversa con 256 entradas (512 bytes) en la memoria del programa (PGMEM). Se escribió una función para realizar una búsqueda binaria en esa tabla. Este método solo requiere 28uS para cada búsqueda. Si uso una tabla de búsqueda directa, requeriría 2kb de memoria, pero la búsqueda tomaría solo 4 uS más o menos.
Los valores calculados en la tabla de búsqueda usan solo el rango de entrada 32-991, descartando el rango inferior / superior de ADC, en caso de que haya un problema con el circuito.
A continuación se muestra lo que tengo ahora.
fuente
Este PDF explica la curva necesaria, aparentemente una logarítmica. Si tiene un atenuador lineal (su valor PWM), entonces la función debe ser logarítmica.
Aquí puede encontrar una tabla de búsqueda para 32 pasos de brillo para PWM de 8 bits.
Aquí por 16 pasos.
fuente
Esto es lo que he hecho en base a esa respuesta del foro arduino . He calculado los valores de 0 a 255, por lo que es fácil de usar con pwm en arduino
Luego, para usar en Arduino, simplemente haga así:
Espero que sea útil para algunas personas;)
fuente
Estoy lidiando con esto ahora, y estoy tomando un enfoque ligeramente diferente. Quiero 256 niveles de brillo, pero el mapeo de un rango lineal de 0-255 a un rango no lineal de 0-255 termina, como puede ver en algunas de las otras respuestas, con muchas entradas duplicadas. (Es decir, varios de sus valores de entrada dan como resultado el mismo nivel de brillo).
Traté de modificar el algoritmo para asignar un rango de entrada 0-256 a un rango de salida 0-1023, pero incluso eso tenía varios valores de asignación a 0. Así que estoy intentando algo un poco diferente: estoy usando el nivel 0-255 para generar valores no lineales en el rango 0-769 (eso es 1023 menos 255) usando
sin()
, luego agregue eso al nivel de entrada para obtener una salida en el rango 0-1023 sin duplicados. Configuraré un temporizador para usar un contador de 1023 y estableceré el comparador para la salida PWM a los valores de la tabla de búsqueda en función del nivel de iluminación que quiero (0-255).Aquí está el programa C que usé para generar mi tabla de búsqueda:
Y aquí está la tabla:
Probablemente investigaré otras funciones (como
log()
) una vez que tenga esto en funcionamiento.fuente
Para mí, esta ley parece funcionar bastante bien: http://www.pyroelectro.com/tutorials/fading_led_pwm/theory2.html
fuente