void setpixel(int x, int y, int z);
void clrpixel(int x, int y, int z);
unsigned char getpixel(int x, int y, int z);
unsigned char inrange(int x, int y, int z);
void negpixel(int x, int y, int z);
void alterpixel(int x, int y, int z, int state);
void setplane_z(int z);
void clrplane_z(int z);
void setplane_x(int x);
void clrplane_x(int x);
void setplane_y(int y);
void clrplane_y(int y);
void setplane(unsigned char plane, int i, int state);
void setline_z(int x, int y, int z1, int z2);
void setline_x(int z, int y, int x1, int x2);
void setline_y(int z, int x, int y1, int y2);
void clrline_z(int x, int y, int z1, int z2);
void clrline_x(int z, int y, int x1, int x2);
void clrline_y(int z, int x, int y1, int y2);
void drawline_plane(int x2, int y2, int x1, int y1,unsigned char anchor);
void fill (unsigned char pattern);
void rotcube(char axis, char direccion);
void tmp2cube(void);
void cube2tmp(void);A todo esto.. hablamos de una matriz monocromatica comun y corriente no?
Por ahi pinta hacer algo tricolor con control de intensidad jeje.
Universal, pero con CCS? :D Está muy buena la idea. Yo tengo una pero no la compartiria :P Porque sino es muy sencillo hacer un cartel, que se esfuercen :mrgreen:
Habria que definir bien el hardware como dice Gera. Yo armé una estructura en la memoria externa para configurar cada uno de los mensajes (Largo del mensaje, Animación de entrada, movimiento, velocidad, cantidad de pasadas, tipo de mensaje (Normal o negativo), animación de salida, caracteres especiales si se quiere mostrar hora, fecha, temperatura, ect .... ), y despues hice las funciones que cargan el mensaje, visualizan el mensaje, cargan la eeprom y blablabla :mrgreen:
Al subir los archivos, mejor sería en un rar :roll: :D :D Re pesado :P
Saludos!
Me parece pesima tu actitud amigo SUKY. Por si no te enteraste, este es un foro para compartir ideas, información y todo lo que tengamos con tal de ayudar a los demas. Si no pensas compartir lo que tenes, mejor ni digas que tenes algo, porque suena SUPER EGOISTA de tu parte.
Universal, pero con CCS? :D
Habria que definir bien el hardware como dice Gera. Yo armé una estructura en la memoria externa para configurar cada uno de los mensajes (Largo del mensaje, Animación de entrada, movimiento, velocidad, cantidad de pasadas, tipo de mensaje (Normal o negativo), animación de salida, caracteres especiales si se quiere mostrar hora, fecha, temperatura, ect .... ), y despues hice las funciones que cargan el mensaje, visualizan el mensaje, cargan la eeprom y blablabla :mrgreen:
Al subir los archivos, mejor sería en un rar :roll: :D :D Re pesado :P
A todo esto.. hablamos de una matriz monocromatica comun y corriente no?Saludos!
Por ahi pinta hacer algo tricolor con control de intensidad jeje.
Buenas.. ante todo quiero felicitar por la creacion de este hilo... te cuento que estoy armando un cartel y me estoy basando en tus aportes que me parecen que son muy buenos...
Mi pregunta es la siguiente... cuando definis la precarga del timer 0 lo haces mediante esta formula.
#define PRECARGA_TMR0 (256 - 1000000 / HERTZ / FILAS / 128 * (FOSC / 4000000))
Ahora bien... yo estoy trabajando con un PIC16F876A y a 20MHz... la pregunta es que tengo que tener en cuenta para adaptarlo a mi cartel ya que por las pruebas que hice los registros dependen mucho del tiempo de refresco entre cada frame. me puedes explicar un poco que es lo que debo tener en cuenta para calcular el valor exacto del timer?? ya que con tu definicion no logro que los refrescos se hagan de la manera correcta... es como si corriera las lineas hacia arriba (fila1 pasa a ser fila7)
espero tu comentario
saludos
carlos
void Mostrar_Frame (void){
//if(!inicio)
// j=Columnas-1;
//else
// j=inicio-1;
for (i = 0; i < Columnas; i++){ //Cargo las columnas
if ( Afuera[j] & mask2 )
output_low(Data_Fila);
else
output_high(Data_Fila);
output_high (Clock_Fila);
output_low (Clock_Fila);
if (!j)
j = Columnas -1;
else
j--;
}
aux = ~mask2; // Para complementar la logica debido a los TIP127 (PNP)
for ( i = 0 ; i < Filas ; i++ ){ //Cargo las filas al registro y voy rotando 1 bit
if ( bit_test(aux,Filas - 1) )
output_high(Data_Fila);
else
output_low(Data_Fila);
output_high(Clock_Fila);
output_low(Clock_Fila);
aux *= 2;
}
output_high (Latch);
output_low (Latch);
if (mask >= 0x80){
mask = 0x01;
//output_toggle(PIN_B4);
}
else
mask *= 2;
if (mask2>=0x80){
mask2 = 0x01;
Nuevo_Frame = TRUE; //Cuando llego aca es porque ya mostre el primer cuadro, entonces habilito para cargar otro.
}
else
mask2 *= 2;
}
hola,quiero comentarles que ya llevo un tiempo siguiendo sus comemtarios y aportes respecto a este tema,y tambien he desarrollado mi propia matriz (con algunos problemas de brillo,nada que no se pueda resolver :5]) que no esta terminada completamente, he usado los aportes de cryn que tiene en su hilo respecto al tema,de los cuales he aprendido bastante y en el entorno de mi hogar he modifcado el codigo muchas veces. Pero hay dudas que todavia dan vueltas en mi cabeza,como por ejemplo
- Consideraciones en la etapa de potencia.
- hasta que tamaño de matriz se podria hacer con un pic , me refiero a que cuando se declara una matriz va a depender de la capacidad de cada pic.
- es necesario recurrir a otros metodos en cuanto a programacion y diseño de hardware para matrices muy largas.
- en algunos casos he leido otros hilos en que solo lo manejan con un software (VB, VC,VC#),lo que da mas facilidad al tratamientos de los efectos para la matriz.
Saludos.
SE podra hacer uasando el puerto SPI letrero.
.... y hablando de animaciones como se puede ir empezando con este tema? apartando los desplazamientos ya que Bruno ya lo ha hecho en su codigo.
...
Hola. Teoricamente se enciende una fila por vez, por lo que la corriente maxima que demanda el panel(sin la controladora) es de la corriente de cada LED por la cantidad de LEDs por fila que utilices.
Con 35 LEDs a 0.02A por LED, el consumo debería ser de 0.7A RMS maximo asumiendo todo el panel encendido. Si notas un exceso de consumo en la linea,o bien un encendido leve de TODOS los LEDs a la vez, seguramente estas ante una mala configuración de esos dos parámetros.
En la simulación te funciona bien esa configuracion anodo/catodo? Hay señales ahi que no estan funcionando ademas en el simulador porque cambiaste su nombre(como CLK3,STB1,etc).
Podrias especificarme que tipo de hard estas usando? a la salida del 4094 que controla las filas, que pusiste? y a la salida de los 4094 que controlan las columnas? pusiste algun buffer(ULN o similar) por ejemplo?
También es importante respetar el cristal de 4Mhz. Si utilizas otro cristal, hay que reacomodar los FUSES y el valor de FOSC e el main.h.
Obviamente asumo que recompilaste antes de probar con esa nueva config de esos dos parámetros...
Saludos.
Muy bueno, Bruno!!
Gracias por responder amigo, muy agradecido.. si, en la simulación funciona perfectamente ese parámetro anodo/catodo.
En cuanto al tipo de hardware, estoy utilizando registros 74HS164 (no me di cuenta no se como no compre los 4094) pero no deberían funcionar? A las salidas de los registros para las columnas coloque resistencias de 150 Ohm. A la salida de las filas coloque unas de 22 Ohm a la base de un BC547 y su emisor a tierra por 1KOhm como en la imagen.
En cuanto al cristal... no era esto con oscilador interno a 48MHz? jajaja no me digas que es eso lo malo..
Y si, re-compilaba...
El 18FX550 no tiene cristal interno de 4Mhz. Obviamente necesita uno externo y con sus respectivos capacitores.otra pregunta, con la programacion que te envie:
Saludos.
bruno, una pregunta, en tu soft la configuracion de los fuses que tenes es para un cristal de 4 MHZ????? o uno de 20?? despues por PLL se va a 48 MHZ pero lo que me entro en duda es el cristal de entrada que va... supuestamente dice 20 MHZ input o le estoy errando??
Gracias, me di cuenta de que en el 74HS164 le agrego una compuerta NOT en el reset y enciende leds al azar.
No sabia la diferencia del strobe amigoEl 18FX550 no tiene cristal interno de 4Mhz. Obviamente necesita uno externo y con sus respectivos capacitores.otra pregunta, con la programacion que te envie:
Saludos.
¿supongo que va entre los pines 13 y 14 ese oscilador? ¿no debo hacer mas nada respecto a eso (fuses)?
Es que yo programo con MKB, es primera vez que trabajo con C
Muchisimas gracias, brother
Te hace falta definir el tipo de micro que usarás en tu proyecto.
Tienes que poner al principio de tu programa esto:
#defice 18F2550
Cambiando ese micro por el tuyo.
Hola Bruno y gracias nuevamente por tu tiempo.
Efectivamente compila sin problemas borrando el archivo. Además hice la prueba de cargar el hex en la simulación de proteus y la matriz de leds funciona ok. Así que dicho archivo publik.h no va en el paquete de la librería.-
Estoy estudiando todo el código con intenciones de migrar la librería a c18 y luego a xc8 Mplbab X. Y en el camino voy a comentar el código y trataré de hacer un mini tutorial al respecto.
Con las novedades volveré a postear.
te mando un abrazo.
Leo
Hola Amigos muy interesante este tema felicitaciones por el foro.
Mi pregunta es como puedo yo utilizar una cadena char definida por mi en el main sin necesidad de modificar la const char demo[] en el publik.c
esto seria util para utilizarla para diversas formas
Oscar, por lo general el buffer de entrada es sólo uno. En el ejemplo lo puse como const, por lo que no puede modificarse en tiempo de ejecución, pero removiendo el modificador const, se convierte en un arreglo modificable en ejecución y por ende libre para ser modificado a gusto. Si te interesa poder tener varios arrays y poder elegir cuál enviarle a las mísmas subrutinas, necesitarías modificar las subrutinas para que acepten y trabajen con un puntero a un arreglo de chars, para que de esa manera sea independiente del array original. Igualmente, sólo recomiendo hacerlo si aporta gran flexibilidad o característica pretendida al software, caso contrario, no es recomendable ya que en estos uC que tienen sólo un registro de trabajo, agregar parámetros a la funciones incrementa la cantidad de memoria RAM y ROM requerida por el programa para realizar las llamadas.
Saludos.
Oscar, por lo general el buffer de entrada es sólo uno. En el ejemplo lo puse como const, por lo que no puede modificarse en tiempo de ejecución, pero removiendo el modificador const, se convierte en un arreglo modificable en ejecución y por ende libre para ser modificado a gusto. Si te interesa poder tener varios arrays y poder elegir cuál enviarle a las mísmas subrutinas, necesitarías modificar las subrutinas para que acepten y trabajen con un puntero a un arreglo de chars, para que de esa manera sea independiente del array original. Igualmente, sólo recomiendo hacerlo si aporta gran flexibilidad o característica pretendida al software, caso contrario, no es recomendable ya que en estos uC que tienen sólo un registro de trabajo, agregar parámetros a la funciones incrementa la cantidad de memoria RAM y ROM requerida por el programa para realizar las llamadas.
Saludos.
Gracias amigo BrunoF, se podría utilizar una EEPROM para cargar un mensaje uno por uno definiendo la dirección de inicio y de entrada, ademas de utilizar una interrupción para cargar los datos a la EEPROM a través de USB.
Buen dato a tener en cuenta lo de "... sólo recomiendo hacerlo si aporta gran flexibilidad o característica pretendida al software, caso contrario, no es recomendable ya que en estos uC que tienen sólo un registro de trabajo, agregar parámetros a la funciones incrementa la cantidad de memoria RAM y ROM requerida por el programa para realizar las llamadas."
Gracias amigo BrunoF, se podría utilizar una EEPROM para cargar un mensaje uno por uno definiendo la dirección de inicio y de entrada, ademas de utilizar una interrupción para cargar los datos a la EEPROM a través de USB.
Claro que sí, se podría. Sólo te resta hacerlo! :)
char *demo=&text; //PUNTEROwhile(ejecutando) {
char text[]="Hola amigos";
Publik_Ejecutar();
}
Ahora mi pregunta como hago para calcular cuando el texto sea mostrado a su totalidad y para que este vuelva a hacer una lectura de la eeprom utlizando varias direcciones que podre definirlas en el inicio de la eeprom
#define FILAS_ANODO TRUE //establece si las FILAS controlaran los anodos en comun de los LEDs
#define COLUMNAS_CATODO TRUE //establece si las COLUMNAS controlaran los catodos en comun de los LEDs
void efecto_rota_izq()
{
if(ProximoElementoLetra()) //intentar obtener proximo elemento de la lectra actual...
{
if(++BufferInicio >= COLUMNAS) BufferInicio=0; //rotar...
if(BufferInicio>0) efAux1= BufferInicio-1; else efAux1=COLUMNAS - 1; //calcular la ultima columna actual...
buffer[efAux1] = letraData; //e inyectarle el valor leido
}else{
//buffer[efAux1] = 0; //inyectarle 0
if(!nuevoEfecto) archivoPosicionActual++;
nuevoEfecto = FALSE;
if(demo[archivoPosicionActual] == 0) archivoPosicionActual = 0;
CargarLetra(demo[archivoPosicionActual]);
// ESTO HE AGREGADO ///////////////////////////////////////////////////////////////////////////////////////////////////
if(++BufferInicio >= COLUMNAS) BufferInicio=0; //rotar...
if(BufferInicio>0) efAux1= BufferInicio-1; else efAux1=COLUMNAS - 1; //calcular la ultima columna actual...
buffer[efAux1] = 0;
}
}
void efecto_rota_izq()
{
if(ProximoElementoLetra()) //intentar obtener proximo elemento de la lectra actual...
{
if(++BufferInicio >= COLUMNAS)
BufferInicio=0; //rotar...
if(BufferInicio>0)
efAux1= BufferInicio-1;
else
efAux1=COLUMNAS - 1; //calcular la ultima columna actual...
buffer[efAux1] = letraData; //e inyectarle el valor leido
}
else
{//output_toggle(PIN_B1);
//buffer[efAux1] = 0; //inyectarle 0
if(!nuevoEfecto)
archivoPosicionActual++;
nuevoEfecto = FALSE;
if(demo[archivoPosicionActual] == 0)
archivoPosicionActual = 0;
CargarLetra(demo[archivoPosicionActual]);
// ESTO HE AGREGADO ///////////////////////////////////////////////////////
ProximoElementoLetra();
if(++BufferInicio >= COLUMNAS) BufferInicio=0; //rotar...
if(BufferInicio>0) efAux1= BufferInicio-1;
else efAux1=COLUMNAS - 1; //calcular la ultima columna actual...
buffer[efAux1] = letraData;
//////////////////////////////////////////////////////////////////////////////////
}
}