TODOPIC
Mecatrónica => DMX512 - Diseños y Proyectos => Mensaje iniciado por: oscar diaz en 05 de Julio de 2009, 00:55:38
-
Hola a migos de todopic soy nuevo en el foro y en el tema de los microcontroladores pic pero en realidad los descubri y estoy muy interesado en aprender a aplicarlos. Tengo una pequeña empresa de sonido e iluminacion y ultimamente empece a incursionar sobre ls leds y su gran variedad de utilidades. Para empezar me gustaria construir un tacho de leds (es decir, en vez de tener una parabola comun y corriente agregarle leds y manejarla a traves de DMX), ya tengo lista la parabola de leds (30 rojos, 30 verdes y 30 azules). El diseño lo tome de uno comprado (en el siguiente post agrego las fotos de la parabola). Lo que me gustaria que me ayuden es a diseñar un circuito que reciba e interprete la trama dmx y genere 3 señales pwm para manejar los tres colores para poder estandarizar todo mi equipamiento. La idea es utilizar un pic, un dip switch de 10 para setear la direccion y un CI que decodifique la señal (no recuerdo su numeracion ahora). Desde ya muchas gracias y saludos desde San Juan Argentina.
-
Hola Óscar. ¿Solicitas ayuda o quieres que te lo hagan?
Si es lo primero deberías poner lo que llevas hecho para que podamos resolver dudas y colaborar con ideas.
Si es lo segundo, deberías publicarlo en el subforo Empleo (ofertas/demandas) (http://www.todopic.com.ar/foros/index.php?board=57.0)
Cuando nos lo aclares ya vemos si tenemos que mover el mensaje de sitio. Un saludo y bienvenido.
-
Hola nocturno como te va te hago una consulta estoy en la contruccion de algo precido a lo que quiere el amigo te adjunto el esquema, el control es dmx y me gustaria adicionarle un dip switch para seleccionar la direccion dmx sera que me podes ayudar gracias
-
Lo ideal es que liberes el pin RB5 del led RGB; lo puedes conectar a cualquier otro pin libre. Con los 8 pines del PORTB y uno adicional ya tendrías el dipswitch conectado.
Para averiguar la dirección sólo tendrías que leer PORTB y multiplicar por dos si el pin adicional está a 1.
-
Hola, acá posteo lo que llevo hecho hasta ahora, y lo que conseguí para hacer lo del sistema DMX. En realidad el circuito lo tengo clarísimo, lo que necesito es saber si alguien tiene un programa que me pueda servir (aunque tenga que cambiar algunas conexiones), o que pueda ayudarme a hacerlo, ya que la programación en el entorno de mplab me cuesta bastante, y más aun con el sistema dmx.
El sistema consta de 90 leds, 30 rojos, 30 verdes y 30 azules. Van conectados en paralelo, es decir, cada uno recibe una tensión de 12v, que es reducida con una resistencia de 1kΩ.
CONTROL
El control consta de un interruptor que selecciona entre el sistema DMX y el sistema manual. El último cuenta con 3 potenciómetros que varían la tensión/corriente que se le entrega a cada color. Sé que este sistema no es el ideal para dimmerizar los leds, ya que varia la temperatura del color y cada led responde de una manera diferente, pero funciona bastante bien y es de gran simpleza.
DMX
La señal DMX ingresa y es trasladada al integrado MAX481CPA que decodifica la señal dmx y la envía a l pic a través del dip switch que setea la dirección DMX. El pic lee los datos recibidos y genera 3 señales PWM que varían según la información enviada desde el controlador DMX externo. Desde allí, se dirigen hacia los tres amplificadores de potencia (uno por color). Eso es todo el sistema que maneja la luminaria pero tengo un problema muy importante: NO TENGO ABUNDANTES CONOCIMIENTOS EN PROGRAMACIÓN Y NO SE COMO CONSTRUIR UN PROGRAMA PARA QUE EL PIC SE COMPORTE COMO YO QUIERO. CUALQUIER AYUDA, POR MÁS MINIMA QUE SEA SIRVE Y DESDE YA LES AGRADEZCO SU COLABORACIÓN.
AGRADEZCO ESPECIALMENTE A EL ADMINISTRADOR DE TODOPIC QUE ME PERMITEN A MI Y A MUCHA GENTE EXPRESARME A TRAVES DE ESTE FORO APORTANDO Y RECIBIENDO APORTES DE GENTE QUE DESEA AYUDAR. TAMBIEN GRACIAS A RAFAEL GIMENEZ POR APORTAR EL CIRCUITO DMX UTILIZADO ANTERIORMENTE Y A FRANK MOERSEN POR EL CIRCUITO AMPLIFICADOR DE POTENCIA.
Saludos desde San Juan, Argentina… Oscar Diaz
-
yo tenia entendido que DMX es un protocolo que envia solo 1 byte de manera serie y eso regulaba el duty cicle de una señal PWM, como puede ser tan dificil...?
-
No es solo un byte, es una trama de hasta 512 bytes, donde cada uno, corresponde a un dato de un canal dmx, y es ciclico... :mrgreen:
Norberto
-
Hola amigos del foro, ante todo gracias por la ayuda, dejo cerrado el proyecto porque ya lo termine y quedo muy bn.... Si a a lguien le interesa posteo todo..
Salu2 desde San Juan, Argentina.
Oscar Diaz
-
claro un videito no caeria nada mal...
saludos
-
Claro que nos interesa, eso ni se pregunta hombre :D
-
hola, estimado oscar, en que quedo tu proyecto, yo tambien estoy averiguando como empezar un receptor dmx
-
Lo ideal es que liberes el pin RB5 del led RGB; lo puedes conectar a cualquier otro pin libre. Con los 8 pines del PORTB y uno adicional ya tendrías el dipswitch conectado.
Para averiguar la dirección sólo tendrías que leer PORTB y multiplicar por dos si el pin adicional está a 1.
disculapa amigo estoy realizando algo similar y no logro entender el como funciona los dipswitch y esto k explicas puedes ayudarme el como funciona..
ja_02_da@hotmail.com
-
Hola Jahir, como te he comentado en el otro hilo, te sugiero que hagas la modificación y publiques el código modificado concretando tu duda.
-
Hola, acá posteo lo que llevo hecho hasta ahora, y lo que conseguí para hacer lo del sistema DMX. En realidad el circuito lo tengo clarísimo, lo que necesito es saber si alguien tiene un programa que me pueda servir (aunque tenga que cambiar algunas conexiones), o que pueda ayudarme a hacerlo, ya que la programación en el entorno de mplab me cuesta bastante, y más aun con el sistema dmx.
El sistema consta de 90 leds, 30 rojos, 30 verdes y 30 azules. Van conectados en paralelo, es decir, cada uno recibe una tensión de 12v, que es reducida con una resistencia de 1kΩ.
CONTROL
El control consta de un interruptor que selecciona entre el sistema DMX y el sistema manual. El último cuenta con 3 potenciómetros que varían la tensión/corriente que se le entrega a cada color. Sé que este sistema no es el ideal para dimmerizar los leds, ya que varia la temperatura del color y cada led responde de una manera diferente, pero funciona bastante bien y es de gran simpleza.
DMX
La señal DMX ingresa y es trasladada al integrado MAX481CPA que decodifica la señal dmx y la envía a l pic a través del dip switch que setea la dirección DMX. El pic lee los datos recibidos y genera 3 señales PWM que varían según la información enviada desde el controlador DMX externo. Desde allí, se dirigen hacia los tres amplificadores de potencia (uno por color). Eso es todo el sistema que maneja la luminaria pero tengo un problema muy importante: NO TENGO ABUNDANTES CONOCIMIENTOS EN PROGRAMACIÓN Y NO SE COMO CONSTRUIR UN PROGRAMA PARA QUE EL PIC SE COMPORTE COMO YO QUIERO. CUALQUIER AYUDA, POR MÁS MINIMA QUE SEA SIRVE Y DESDE YA LES AGRADEZCO SU COLABORACIÓN.
AGRADEZCO ESPECIALMENTE A EL ADMINISTRADOR DE TODOPIC QUE ME PERMITEN A MI Y A MUCHA GENTE EXPRESARME A TRAVES DE ESTE FORO APORTANDO Y RECIBIENDO APORTES DE GENTE QUE DESEA AYUDAR. TAMBIEN GRACIAS A RAFAEL GIMENEZ POR APORTAR EL CIRCUITO DMX UTILIZADO ANTERIORMENTE Y A FRANK MOERSEN POR EL CIRCUITO AMPLIFICADOR DE POTENCIA.
Saludos desde San Juan, Argentina… Oscar Diaz
hola que tal amigo una molestis podrias publicar tu codigo lo que pasa que soy nuevo en esta del dmx
y todavia tengo algunas dudas ademas veo k tu ya lo acavaste bueno espero y se pueda saludos..
-
Hola Jahir, como te he comentado en el otro hilo, te sugiero que hagas la modificación y publiques el código modificado concretando tu duda.
tengo eso para agregar los dips espero m puedas ayudar o decir en que estoy mal..
#include <16F887.h>
#FUSES WDT //Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz)
#FUSES PUT //Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#use delay(clock=20000000,RESTART_WDT) // Utilizo clock de 20MHz porque me facilita la elección exacta del baudrate a 250k y tenia el cristal
/************************************************************************
* Registros USART *
************************************************************************/
#byte SPBRG= 0x99 // Registros para el pic 16F628
#byte RCSTA= 0x18 // Aqui se han modificado las direcciones correspondientes para el 628
#byte TXSTA= 0x98
#byte RCREG= 0x1A
#byte PIR1= 0x0C
#byte PIE1= 0x8C
#bit SPEN= RCSTA.7
#bit RX9= RCSTA.6
#bit SREN= RCSTA.5
#bit CREN= RCSTA.4
#bit ADDEN= RCSTA.3
#bit FERR= RCSTA.2
#bit OERR= RCSTA.1
#bit RX9D= RCSTA.0
#bit BRGH= TXSTA.2
#bit SYNC= TXSTA.4
#bit RCIF= PIR1.5
#bit RCIE= PIE1.5
//*******************************MI DESMADRE*****************************************
#byte TRISC = 0x87
#byte TRISD = 0x88
#byte PORTC = 0x07
#byte PORTD = 0x08
// 5 bits para conseguir la direccion del dispositivo (Midireccionreal)
#bit RD0 = PORTD.0
#bit RD1 = PORTD.1
#bit RD2 = PORTD.2
#bit RD3 = PORTD.3
#bit RD4 = PORTD.4
#bit RD5 = PORTD.5
#bit RD6 = PORTD.6
#bit RD7 = PORTD.7
#bit RC4 = PORTC.4
//************ACAVA MI DESMADRE*****************************************************
/************************************************************************
* Estados protocolo DMX *
************************************************************************/
#define DMX_ESPERA_BYTE 0
#define DMX_ESPERA_BREAK 1
#define DMX_ESPERA_START 2
#define DMX_ESPERA_DATO 3
#define DMX_RECEPCION_DATOS 4
/************************************************************************
* Variables globales y constantes *
************************************************************************/
//--------------------Se han quitado las variables que no utilizo--------------------------------------
int8 DMX_Estado = DMX_ESPERA_BREAK; // Estado de la máquina de estados
int8 DatoRX; // Dato genérico recibido en USART
//int8 DMX_Indice = 0; // Apuntador a una posición de la trama DMX
int8 Ticks = 0;
//***********************************************************************
int16 CanalDMX ; // Canal DMX seleccionado para visualizar, de 1 a 512
int8 DatoDMX; // Dato que contiene el canal seleccionado
int8 DMX_Indice = 0; // Apuntador a una posición de la trama DMX
//char buffer[128];
//int8 CaracteresRecibidos = 0;
int8 Midireccion;
int1 ComandoRecibido;
//*********************************************************************
//!int16 CanalDMX; // Canal DMX seleccionado para visualizar, de 1 a 512
//!int8 DatoDMX; // Dato que contiene el canal seleccionado
//!int16 DMX_Indice = 0; // Apuntador a una posición de la trama DMX
//#define TotalCanales 512 // Total canales a almacenar
//int8 TramaDMX[TotalCanales]; // Trama completa de valores DMX
#define TotalCanales 12 // Total canales a almacenar en este caso solo interesan los 3 primeros
int8 TramaDMX[TotalCanales] = {0,0,0,0,0,0,0,0,0,0,0,0}; // Trama completa de valores DMX
int8 r1,g1,b1,r2,g2,b2,r3,g3,b3,r4,g4,b4;
union // Estructura para hacer una copia del registro RCSTA
{
unsigned char registro;
struct {
unsigned char RX9D:1;
unsigned char OERR:1;
unsigned char FERR:1;
unsigned char ADDEN:1;
unsigned char CREN:1;
unsigned char SREN:1;
unsigned char RX9:1;
unsigned char SPEN:1;
} bits ;
}Copia_RCSTA;
void Cojedireccion (void);
/************************************************************************
* Interrupción Timer 0: *
************************************************************************/
#int_Timer0
TIMER0_isr()
{
Ticks++;
if (Ticks==0)
{
r1 = TramaDMX[0];
g1 = TramaDMX[1];
b1 = TramaDMX[2];
r2 = TramaDMX[3];
g2 = TramaDMX[4];
b2 = TramaDMX[5];
r3 = TramaDMX[6];
g3 = TramaDMX[7];
b3 = TramaDMX[8];
r4 = TramaDMX[9];
g4 = TramaDMX[10];
b4 = TramaDMX[11];
// r5 = TramaDMX[12];
//g5 = TramaDMX[13];
//b5 = TramaDMX[14];
output_high(pin_B0);
output_high(pin_B1);
output_high(pin_B2);
output_high(pin_B3);
output_high(pin_B4);
output_high(pin_B5);
output_high(pin_B6);
output_high(pin_B7);
output_high(pin_A1);
output_high(pin_A2);//r4
output_high(pin_A3);//g4
output_high(pin_A0);//b4
}
if(Ticks==r1)
output_low(pin_A2);
if(Ticks==g1)
output_low(pin_A3);
if(Ticks==b1)
output_low(pin_B3);
if(Ticks==r2)
output_low(pin_B4);
if(Ticks==g2)
output_low(pin_B5);
if(Ticks==b2)
output_low(pin_B6);
if(Ticks==r3)
output_low(pin_B7);
if(Ticks==g3)
output_low(pin_A0);
if(Ticks==b3)
output_low(pin_A1);
if(Ticks==r4)
output_low(pin_B0);
if(Ticks==g4)
output_low(pin_B1);
if(Ticks==b4)
output_low(pin_B2);
// set_timer0(256);
set_timer0(128);
}
void Cojedireccion (void){
Midireccion = 0;
if (RD0 == 1)
Midireccion = Midireccion +1;
if (RD1 == 1)
Midireccion = Midireccion +2;
if (RD2 == 1)
Midireccion = Midireccion +4;
if (RD3 == 1)
Midireccion = Midireccion +8;
if (RD4 == 1)
Midireccion = Midireccion +16;
//!
if (RD5 == 1)
Midireccion = Midireccion +32;
if (RD6 == 1)
Midireccion = Midireccion +64;
if (RD7 == 1)
Midireccion = Midireccion +128;
if (RC7== 1)
Midireccion = Midireccion +256;
}
/************************************************************************
* Interrupción RDA: dato recibido por la USART *
* Esta interrupción se activa cada vez que se recibe un dato en la *
* USART. Mediante el control de una máquina de estados se determina *
* la validez y el significado del dato recibido, y se obra en *
* consecuencia. *
************************************************************************/
//--------La interrupción de la USART no se ha modificado, esta tal cual el receptor de Nocturno----------------
//--------solo cambia el hecho de que TotalCanales vale 3 en lugar de 512----------------------------------------
#int_rda
void Dato_Recibido_USART(void)
{
while (RCIF) // ejecutamos mientras haya un dato pendiente de procesar
{
// Hacemos una copia del registro RCSTA porque sus bits cambian de valor
// al leer RCREG y modificar CREN
Copia_RCSTA.registro = RCSTA;
// En RCREG está el dato que acaba de recibir la USART
DatoRX = RCREG;
// Si se reciben más de 3 bytes sin haberlos procesado, se produce un error
// de Overrun. En este caso, se borra el error reiniciando CREN y dejamos
// la interrupción preparada para procesar la siguiente trama DMX
if (Copia_RCSTA.bits.OERR)
{
CREN=0;
CREN=1;
DMX_Estado = DMX_ESPERA_BYTE;
return;
}
// Máquina de estados
switch (DMX_Estado)
{
case DMX_ESPERA_BYTE: // si estamos en este estado y hay error FRAME
// es que nos ha pillado en medio de un Byte. Hay que seguir esperando
// hasta que desaparezca el error.
if (!Copia_RCSTA.bits.FERR)
// Ha llegado un byte. Ahora esperaremos la señal Break
DMX_Estado = DMX_ESPERA_BREAK;
break;
case DMX_ESPERA_BREAK: // estamos esperando la señal Break
// Esta señal se identifica porque aparece el error de Frame
if (Copia_RCSTA.bits.FERR)
// Tras recibir el error de Break, hay que esperar un byte de valor 0
if (!DatoRX)
DMX_Estado = DMX_ESPERA_START;
break;
case DMX_ESPERA_START: // ya hemos recibido el Break y ahora hay que
// esperar un Byte con valor 0, que será la señal de Start
// Mientras tanto, si recibimos un error de Frame, hay que volver a
// empezar para recibir la señal de comienzo de trama.
if (Copia_RCSTA.bits.FERR)
DMX_Estado = DMX_ESPERA_BYTE;
else {
if (!DatoRX)
{
// Llegados a este punto, ya hemos recibido el Byte Start=0
// y comenzamos la trama de valores DMX.
DMX_Indice = 0;
DMX_Estado = DMX_RECEPCION_DATOS;
} else
// Si el dato recibido no es 0, volvemos a empezar
DMX_Estado = DMX_ESPERA_BREAK;
}
break;
case DMX_RECEPCION_DATOS:
// En este estado estamos recibiendo la trama de datos DMX
// Si se detecta un error de Frame es que ha habido un error y estamos
// al principio
if (Copia_RCSTA.bits.FERR)
if (!DatoRX)
DMX_Estado = DMX_ESPERA_START;
else
DMX_Estado = DMX_ESPERA_BYTE;
else
{
// Almacenamos el dato recibido en nuestro array
TramaDMX[DMX_Indice++] = DatoRX;
// Si ha llegado al final de la capacidad, cambiamos al estado de espera
// de nueva trama
if (DMX_Indice >= TotalCanales)
DMX_Estado = DMX_ESPERA_BREAK;
}
break;
}
}
return;
}
void main()
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_wdt(WDT_18MS);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_oscillator(False);
//**********************************************************************************
set_tris_d(0xFF); //Se configura para 8 entradas
set_tris_c(0x0F); //Se configuran los pines de los Leds como salidas y el resto como entradas
CanalDMX=1; // Por defecto, el canal seleccionado es el primero
//**********************************************************************************
// Configuración de la USART
SPBRG=4; // A 20Mhz el baudrate es 250.000, sale de la tabla de la hoja de datos del 16F628
BRGH=1; // Seleccionamos high speed
SYNC=0; // Transmisión asíncrona
SPEN=1; // Activamos la USART
RX9=1; // 9 bit para la recepcion
SREN=0; // Desactiva recepción de un byte
CREN=1; // Recepción activada
ADDEN=0; // Desactivada la autodetección de dirección
FERR=0; // No hay error de frame con 1 se activa
OERR=0; // No hay error de overrun con 1 se activa
// Activamos las interrupciones de recepción de la USART y del Timer0
enable_interrupts(INT_RDA);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
//-----------------------------------------------------------
set_timer0(128);
//set_timer0(255);
while(true)
{
delay_ms(5000);
}
}