TODOPIC
Mecatrónica => DMX512 - Diseños y Proyectos => Mensaje iniciado por: stk500 en 26 de Febrero de 2010, 10:56:46
-
Hola amigos!
Ya que tengo mi placa de Easypic6 y con ella puedo experimentar abro este hilo para aquellos que no conocen este Protocologo o para aquellos que deseen hacer un control de Luces,LED,Motores,Musica con Efectos etc etc, bien como ya habia publicados en mis primero mensaje la funcion de este protocolos voy a resumir algunas cosas, ante todos llevos varios meses leyendos libros,Tutoriales acerca del Compilador CCS,buscando informaciones alli y alla y no solo eso le doy la gracias a nuestros queridos amigo Nocturno por ofrecer su codigo, al tambien amigo Suky por ayudarme en dudas , al gran Jefe Todopic por tener en mi su confianza de estar con ustedes y a muchos amigos aqui que me apoyan pero sobre todos tambien doy la gracia a Mark de CCS por brindar su codigo como ejemplo. en fin doy la gracias a todos aquellos que me animaron para estar aqui :mrgreen:
Para comenzar quiero ir por parte esperando que algunos me corrijan mis fallos, el codigo que quiero implementar lo quiero hacer por partes.
Aqui empleareamos el pic16f627 aunque se puede usar cualquier pic que tengan a mano con CCP y claro USART, porque es la
unica forma menos complicada de hacerlos.
/**************************************************************************
* PRACTICA DMX512
*Ejemplo DMX512 para generar 1 canal PWM, en este caso un LED, aqui usamos
*el Pic16F627, con 2 CCP *
*USART modo Asincrono,recibe en 9bit modo *
*Canal PWM de 0 a 255,0%...100% *
#include <16F627.h>
#fuses HS, NOLVP, NOWDT, NOPUT, NOPROTECT, NOBROWNOUT, MCLR, /// este Fuse es para los PWM CCPB3
#use delay(clock=20000000)
#include <string.h>
#include <stdio.h>
/************************************************************************
* Puertos I/O *
************************************************************************/
struct PA_pin_map {
boolean unusedRA0; //no usamos bit 0
boolean test_osc; // aqui emplearemos diversos cristales
boolean unusedRA2; //no usamos bit 3
boolean unusedRA3; // no usamos bit 4
boolean unusedRA4; //no usamos bit 5
boolean unusedRA5; //no usamos bit 6
} Puerto_A;
#byte Puerto_A = 5
struct PB_pin_map {
boolean unusedRB0; //no usamos bit 0
boolean unusedRB1; //no usamos bit 1
boolean rx; // Recibiendo DMX
boolean test_osc; // Testeando cristal
boolean unusedRB4; //no usamos bit 4
boolean unusedRB5; // no usamos bit 5
boolean unusedRB6; // no usamos bit 6
boolean unusedRB7; //no usamos bit 8
} Puerto_B;
#byte Puerto_B = 6
#CASE
#byte porta=0x05
#byte portb=0x06
bien estos es un trazducion de los que comprendo para configurar el micro, lo que creo que asi desactivamos muchas memorias de pic , espero opniones de ustedes.
el paso siguiente sera la configuracion de USART
-
Rafael, ¿qué versión de CCS C utilizarás para tus ejemplos?
(Pregunto, y así de camino me suscribo a tu nuevo hilo :mrgreen:)
-
Rafael, ¿qué versión de CCS C utilizarás para tus ejemplos?
(Pregunto, y así de camino me suscribo a tu nuevo hilo :mrgreen:)
:D :D gracias Sr. Diego!
para mi seria un orgullo tenerte por estos Lares, pues bien la version que uso son varias, de momentos estoy con la version 3.249
y haciendo el ejemplo que me paso el Sr. Mark para controlar solo 1PWM me va.
yo hire posteando y trazduciendos todos lo que el me puso, para que sea mas comprensible por aqui, pero me falta la tecnica para escribir , asi que eso te lo dejo a ti :mrgreen:
un gran abrazo Don Diego
-
Conmigo ya tiene dos seguidores del hilo, Señor Rafael!! :mrgreen: :mrgreen:
-
Aqui me anoto!
Ando en estas de aprender DMX.
Saludos!
-
Yo también me asomo para
dar un poco por el culo molestar por aquí :lol:
-
Lo decía porque al ver el código que has puesto aparece boolean que imagino será un bit ó int1 y creía que CCS C no podía usar este tipo de variable para las struct :shock:
-
Yo también me asomo para dar un poco por el culo molestar por aquí :lol:
Aqui nadie se baja los pantalone, asi que te equivocaste de cama :D :D :D
broma aparte :mrgreen:
Para mi es un grana honor tenerte por aqui amigo mio :P
Vaya vacaciones te esta pegando macho, deja un poco de ron debajo de la cama :D :D
-
Conmigo ya tiene dos seguidores del hilo, Señor Rafael!! :mrgreen: :mrgreen:
Marcos, a ti te digo lo mismo, un Honor verte por aqui :-/ :-/
-
Aqui me anoto!
Ando en estas de aprender DMX.
Saludos!
Venga Akenafab a ver si te hace un control :mrgreen:
Saludote amigos
-
Me apunto ... de DMX no se nada de nada ... asi que ha aprender!!!!
Saludos
-
Otro que se anota :mrgreen: Quiero aprender este protocolo :-/
En el mensaje inicial dices que usando estructuras ahorras memoria...mmm...no creo que sea el caso de manejo de solo bits, que colocando #use fast_io lo logras. Puede ser mucho más cómodo cuando usas un nible (también menos o más bits ) del puerto como variable y te ahorrarías de andar haciendo mascaras y ese tipo de cosas.
Saludos!
-
:-/ :-/ Pues muchas gracias a todos Ustedes por tenerlo por aqui, que alegria me dan :-/ :-/
Pues bien continuamos, llevo todas la semana buscando informaciones sobre registros de la UART porque la verdad no es facil saberla todas sin estar leyendo, donde como va cada cosas, ya duermos con el ejemplo que me mandaron y el codigo de nuestro estimado amigo Nocturno :oops: y decir verdad , cada dia esto me fascina, porque ? muy simple, en el mundo del espectaculos tantos en sonido como iluminacion se usa este protocolo, este protocolo fue hecho pues para eso, ya tambien lo estan usando en DMX512 Domotica y seguridad,no me gustaria poner ningun link de otros proyectos o empresa que se dedican a estos, eso se lo dejos a ustedes.
El problema que se pueden encontrar muchos es , tener los modulos, osea un Emisor DMX512 que (Consola DMX,paneles de mando DMX,USBD DMX, o algunos simple que se podia encontrar en la Web, yo me monte ya uno de 6 canales, ¿porque? teniendo un USB DMX y estar probando en mi experimento es horroroso tener todos periferico conectados a una PC y claro es tener un modulo emisor a mano para experimentar es mas comodo.
Bien aqui os pongo algunas caracteristica para que muchos vean su funcion:
UNIVERSES CHANNELS
1 1-512
2 513-1024
3 1025-1536
4 1537-2048
5 2049-2560
6 2561-3072
Etc. en un Bus de linea se pueden conectar hasta 32 universos
estos nunca lo he probado yo, yo solo he usado hasta 4 universo y fue en un proyecto en un campo de Football hace 7 años. claro hay consola muy compleja que te memorizan en tiempo real todas las ecenas, puede programa grupos de canales, renombrandos y jugar con ellos de acuerdos a tu gustos y no solo eso cambiar cosas en vivo claro esta consola tan compleja son carisima.
Pero para aquello que quieran descorar su casa e instalando sistema economico como es hoy en dia el tema de los LEDs y luce convencionales,Moviemientos de motores,cortinas etc..
aqui una imagen del TIMING CHART
(http://img169.imageshack.us/img169/4947/timingchat.gif)
y siguiendo con el codigo de ejemplo os pongo 2 tipo de comparaciones
esta primera es la que yo tengo
/************************************************************************
* Configuracion de los registros USART para DMXtoLED 1 canal PWM *
************************************************************************/
#byte SPBRG = 0x99 //Registro de Baudios
#byte RCSTA = 0x18 //Registro de recepcion de la usart
#byte TXSTA = 0x98 //Registro de emision de la Usart
#byte RCREG = 0x1a //Registro donde se guarda el paquete Buffer
#byte PIR1 = 0x0c //Registro de interrupciones de perifericos
#byte PIE1 = 0x8c //Registro de activaciones de los perifericos
#byte INTCON = 0x0b //Registro asociado a la interrupciones
#bit SPEN = RCSTA.7 //Serial port enable bit
#bit RX9 = RCSTA.6 // 9-bit receive enable
#bit SREN = RCSTA.5 //En modo asyncrono no se tiene en cuenta
#bit CREN = RCSTA.4 // Continuos receive enable bit
#bit ADDEN = RCSTA.3 // Autodeteccion de direccion
#bit FERR = RCSTA.2 //Frame error bit
#bit OERR = RCSTA.1 //Overrun error bit
#bit RX9D = RCSTA.0 //El noveno bit
#bit BRGH = TXSTA.2 //Seleccion de alta velocidad de baudios
#bit SYNC = TXSTA.4 // Selecion de modo sincro o asincrono
#bit RCIF = PIR1.5 //Señalizador de bzte recibido USART
#bit RCIE = PIE1.5 //Activacion de la interrupcion USART
#bit GIE = INTCON.7 //Activacion globar de interrupcion
#bit PEIE = INTCON.6
este codigo trazducí solamente los comentarios ya que venian como es claro en ingles, por favor corregirme si tengo algun fallo,
/************************************************************************
* Registros USART ReceptorDmx de Nocturno *
************************************************************************/
#byte SPBRG= 0xFAF // Registros para establecer la velocidad
#byte SPBRGH=0xFB0 // de la USART
#byte RCSTA= 0xFAB // Registro de recepcion de la usart
#byte TXSTA= 0xFAC // Registro de emisión de la usart
#byte RCREG= 0xFAE // Aquí se recibe el dato de la usart
#byte PIR1= 0xF9E // Estado de interrupciones de periféricos
#byte PIE1= 0xF9D // Activación de interrupciones de periféricos
#byte BAUDCON= 0xFB8 // Control de la velocidad en baudios
#bit SPEN= RCSTA.7 // Bit activación puerto serie
#bit RX9= RCSTA.6 // Activación de recepción de 9 bits
#bit SREN= RCSTA.5 // Se activa para recibir un sólo byte
#bit CREN= RCSTA.4 // Se activa para recepción continua
#bit ADDEN= RCSTA.3 // Autodetección de dirección
#bit FERR= RCSTA.2 // Error de Frame
#bit OERR= RCSTA.1 // Error de Overrun
#bit RX9D= RCSTA.0 // El noveno bit
#bit BRGH= TXSTA.2 // Selección de alta velocidad
#bit BRG16= BAUDCON.3 // Uso de un valor baudrate de 16 bits
#bit SYNC= TXSTA.4 // Selección de modo síncrono o asíncrono
#bit RCIF= PIR1.5 // Señalizador de byte recibido en USART
#bit RCIE= PIE1.5 // Activación de la interrupción USART
y este aqui es de nuestros amigos Nocturno, como pueden ver hay cosas diferente al mio, pero el Sr. Nocturno solo hizo una monitor para ver los valores de cada canales en un display.
El proximo tema sera Variables globales.
por favor espero comentarios y el que tenga mas informacion que nos de mas detalle, asi este tutorial estarias mas completo, se agradece muchos todas vuestras colaboraciones.
Gracias amigos por estar aqui.
Un gran saludos
-
Aqui estoy otras vez, pero con mala noticias, estoy muy desilucionado ya que haciendo prueba con el programa no me salen los numeros,cambie varias cosas intentando comprende el codigo y por muchos que cambiará el codigo me funcionaba igual, quite la configuracion de los puertos arriba donde esta los boolean , lo quite todos compiler esperando error y borre todos los del pic y volvi a programar sin la configuracion de los puerto y me funciona igual.
Aqui pongo el programa completo , creo que dejare borrare todos el tema y os pido disculpa a todos, lo sientos muchos amigos, me confie pensando que era facil jugar con ese programa y me siento impotente.
#include <16F88.h>
#fuses HS, NOLVP, NOWDT, NOPUT, NOPROTECT, NOBROWNOUT, MCLR
#use delay(clock=20000000)
#include <string.h>
#include <stdio.h>
/************************************************************************
* Puertos I/O *
************************************************************************/
//struct PA_pin_map {
//boolean unusedRA0; //bit 0
//boolean test_osc;
//boolean unusedRA2;
//boolean unusedRA3;
//boolean unusedRA4;
//boolean unusedRA5; //bit 4
// } Puerto_A;
//#byte Puerto_A = 5
//struct PB_pin_map {
//boolean unusedRB0; //bit 0
//boolean unusedRB2;
//boolean rx; // aqui RB1
//boolean test_osc;
//boolean unusedRB4;
//boolean unusedRB5;
//boolean unusedRB6;
//boolean unusedRB7; //bit8
//} Puerto_B;
//#byte Puerto_B = 6
#CASE
//#byte porta=0x05
//#byte portb=0x06
/************************************************************************
* Registros USART *
************************************************************************/
#byte SPBRG = 0x99 // Generador de Baudios rate que debe ser 250000Kbit
#byte RCSTA = 0x18 //Registro de recepcion de la usart
#byte TXSTA = 0x98
#byte RCREG = 0x1a
#byte PIR1 = 0x0c
#byte PIE1 = 0x8c
#byte INTCON = 0x0b
#bit SPEN = RCSTA.7 //Serial port enable bit
#bit RX9 = RCSTA.6 // 9-bit receive enable
#bit SREN = RCSTA.5 //En modo asyncrono no se tiene en cuenta
#bit CREN = RCSTA.4 // Continuos receive enable bit
#bit ADDEN = RCSTA.3
#bit FERR = RCSTA.2 //Frame error bit
#bit OERR = RCSTA.1 //Overrun error bit
#bit RX9D = RCSTA.0 // noveno bit
#bit BRGH = TXSTA.2
#bit SYNC = TXSTA.4
#bit RCIF = PIR1.5
#bit RCIE = PIE1.5
#bit GIE = INTCON.7
#bit PEIE = INTCON.6
/************************************************************************
* Variables globales *
************************************************************************/
#define MAX_PWMS 1 // aqui definimos 1 canal PWM
int8 Rx_Buffer[MAX_PWMS];
int8 DMX_Levels[MAX_PWMS];
int1 Check_levels=1;
void Interrupt_USART_Rx(void);
#int_rda
void Interrupt_USART_Rx(void)
{
#define ESPERAR_POR_SIGUIENTE_BYTE 0
#define ESPERAR_POR_BREAK 1
#define ESPERAR_PARA_INICIAR 2
#define RECIBIMOS_DATOS 3
/* State machine for determining the begining of the DMX stream */
static int8 Rx_ESTATUTO = ESPERAR_POR_BREAK;
/* Data that we are receiving */
int8 data;
union
{
unsigned char byte;
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 ;
}rcsta;
static int8 *ptr_Rx;
/*mantenemos leyendo la data hasta que este presente */
while (RCIF)
{
/* lee los datos y el estado de registros RX */
rcsta.byte = RCSTA;
data = RCREG;
/* Check for buffer overrun error */
if (rcsta.bits.OERR)
{
CREN = 0;
CREN = 1;
/* we just received a buffer overrun so lets wait
for a good data byte before we look for the break signal. */
Rx_ESTATUTO = ESPERAR_POR_SIGUIENTE_BYTE;
return;
}
switch (Rx_ESTATUTO)
{
case ESPERAR_POR_SIGUIENTE_BYTE:
if (!rcsta.bits.FERR)
Rx_ESTATUTO = ESPERAR_POR_BREAK;
break;
case ESPERAR_POR_BREAK:
/* Check for a framing error */
if (rcsta.bits.FERR)
{
/* If we did receive a framing error, make sure that the data is 0.
This means that we did Rx the break signal for at least 44us. */
if (!data)
Rx_ESTATUTO = ESPERAR_PARA_INICIAR;
}
break;
case ESPERAR_PARA_INICIAR:
/* Check for a framing error. If we receive one then we need to wait
until we receive a good data byte before we begin looking for our
Break signal */
if (rcsta.bits.FERR)
Rx_ESTATUTO = ESPERAR_POR_SIGUIENTE_BYTE;
/* The start code for our data packet should always start with 0. */
else
{
if (!data)
{
ptr_Rx = Rx_Buffer;
Rx_ESTATUTO = RECIBIMOS_DATOS;
}
}
break;
case RECIBIMOS_DATOS:
/* comprobamos error de Frame - si recibimos un Error de Frame esto puede ser el comienzo
del siguiente paquete o verdadero Error del Frame */
if (rcsta.bits.FERR)
{
/* si esto es el comienzo del proximo Frame data debe ser = 0
sino lo es sera Error de Frame */
if (!data)
Rx_ESTATUTO = ESPERAR_PARA_INICIAR;
else
Rx_ESTATUTO = ESPERAR_POR_SIGUIENTE_BYTE;
}
else
{
/* guardamos los datos recibidos en el buffer RX */
*ptr_Rx=data;
ptr_Rx++;
/* comprobamos si recibimos todos nuestros datos */
if(ptr_Rx > &Rx_Buffer[MAX_PWMS-1] )
{
Check_levels=1;
Rx_ESTATUTO= ESPERAR_POR_BREAK;
}
}
break;
// default:
/* desconocido codigo de inicio */
}
}
return;
}
/************************************************************************
* Programa Principal *
************************************************************************/
void main (void) {
set_tris_a(0x00);
set_tris_b(0b00000000);
SPBRG=0x04; // SPBRG=0 implica que a 20Mhz el baudrate=250.000
BRGH=1; // BRGH=1 implica High speed.
SYNC=0; // habialitar recepcion asincronos
SPEN=1; // habilitar puerto serial - rc7/rx/dt , rc6/tx/ck pins as serial port pins
RX9=1; // 9 bit recepcion
CREN=1; // enable recepcion
ADDEN=0;
FERR=1;
OERR=1;
delay_ms(3000);
///////////////////////////////////////////////////////////////////
//// Configuramos PWM ////
///////////////////////////////////////////////////////////////////
setup_ccp1(CCP_PWM); //Configuracion CCP1 como PWM
setup_timer_2(T2_DIV_BY_16,266,1); //(T2_DIV_BY_16,255,1)
set_pwm1_duty(0);
delay_ms(1000);
/////////////////////////////////////////
GIE=1; // Habilitamols todos los interrupts
PEIE=1; // Habilitamos periferico interrupts
RCIE=1; // Habilitamos receptor interrupt
// output_high(PIN_A1);
// delay_ms(1000);
// output_low(PIN_A1);
// delay_ms(1000);
// output_high(PIN_A1);
// delay_ms(1000);
// output_low(PIN_A1);
while (1)
{
if (Check_levels)
{
Check_levels=1;
DMX_Levels[0]=Rx_Buffer[0];
set_pwm1_duty(DMX_Levels[0]);
}
}
}
La verdad lo siento muchos y perdonad por confiar en mi.
-
No desanimes porque la única forma de sacarlo es ir superando barreras. Mientras más trabajo te cueste mayor será luego la alegría.
-
No, no! No hay que rendirse así de fácil! No te imaginas las horas que he pasado para hacer que funcione algo como yo quiero :? Vamos a seguir dando batalla!
-
Gracias muchacho por los animos.
Bien dandole vuelta al programa quizas Vds. me ayuden a encontarle la rueda, es decir quitandos las configuracion de los Puetos
arriba, me funciona el CCP1 osea el canal PWM1, pero tengo un incoveniente y es que al reiniciar el pic el canal con un led ya me sale encendido, y creo que el problema esta aqui
/*******************************************************************************
* programa principal *
*******************************************************************************/
void main (void) {
set_tris_a(0x00; / que aqui claro esta difinido el puerto A que no lo uso para.
set_tris_b(0b00000000; / aqui creo es el problema, no?
aunque configurando el Timer2 y poniendo set_pwm1_dusty(1); y variando a mas hasta 255 el canal PWM1 me reinicia siempre a 100%(256) todas esta prueba sin poner el Emisor, estuve Testeando con el Emisor dmx512 cada canales, a ver si mezclaba otros canales y nada, osea cuando pongo el Emisor estando el canal 1 a cero el LED se apaga, poniendo a Dimmar ese canal y sale muy limpio todos, yo observo la señales con el Oscilocopio, otro caso es que el Pin_TX me sale señal, pero eso lo puedo cambiar en la configuracion de los puertos.
yo que me deseo es saber como manipular el canal, lo que me creo tambien que despues de la interrupciones PEIE=1 donde luego habilitamos el RCIE=1 el interruptor de recepcion hasta aqui segun mis calculo creo es donde se deberia configurar la Salida PWM1 para que vaya fino.
a ver que opinan ustedes?
aqui os pongo el esquema como lo tengo en el Easypic6
(http://img35.imageshack.us/img35/5081/16f881pwm.jpg)
-
El tema de la señal PWM, dependiendo de la frecuencia con la cual estás trabajando y la frecuencia seleccionada del PWM tendrás cierta resolución, y dependiendo de esta resolución tendrás un valor para el 100% del ciclo de trabajo. Por ejemplo si la resolucion que te da es de 8.5, para obtener el 100% habría que cargar 362 :?
Luego si es necesario llevar a nivel bajo la linea Tx durante un tiempo, habría que: deshabilitar el módulo, llevar el pin a 0 lógico durante el tiempo necesario, y luego habilitar el módulo.