PDA

Ver la versión completa : Dmx



Josefe17
31/03/2015, 11:27
A raíz de tu comentario Aunolosé sobre el Dmx abro este hilo para no desvirtuar el otro. Mi idea es: tengo un dimmer analógico casero y otro al que le he puesto la entrada. Luego quiero hacerme un demux dmx con un pwm dmx para leds con un LPF. Ahora quiero hacerme un generador dmx para el pc. Tengo 3 caminos que quiero probar: Software Freestyler con un hw usb que crea un puerto COM (FT232RL) que el sw me reconoce y al escribir sobre el marcandolo como cierto adaptador comercial de dmx, tengo sobre el RS232 los bits del dmx. Bastaria con meter el transceptor de Rs485 y dmx. Otro camino es escribir sobre el COM de mi pc los bits de dmx y con hw convertirlos en dmx. El problema de esto es el código a usar y sobre todo, la marca de 88us. La tercera opcion es el Arduino, que tiene librerías ya hechas. En cualquier caso quiero tener claros los timings del protocolo. Por lo que se es normalmente alto, 88us minimo de marca en bajo, 8 us de MAB, luego el primer canal de prueba y luego los 512 de señal. Cada canal 11 bits, 1 de inicio, 8 de datos y 2 de fin. Eso sí, no se si en alto o en bajo. 1 bit=4us. Me gustaría contrastar esto a ver si es correcto o no para tener la base sólida.
JF

Aunolose
31/03/2015, 12:27
¡Ostras! que recuerdos... soltero y to' que estaba... trabajando 11 horas y media, una hora para comer y llegar de un trabajo a otro... luego más relajado pero con menos dinero y casado... Hice una placa ISA-DMX y varios cacharros que funcionaban con ella, incluso una "mesa" DMX en ensamblador, que feliz era... uf, mejor dejarlo.

Como te decía en el otro hilo, el timing con el 8051 "sale solo", pues le pones un reloj de 16Mhz, creo que era, y dividiendo ya.

Pero no leo que el 8051 sea una de tus opciones, así que vamos al grano. El Arduino sería lo fácil, si ya tienes la librería, pues ala, pero si quieres meterte en más fregaos, un PIC con USB usado como puerto RS232. El programa en el PC solo tiene que preocuparse de los datos que tiene que mandar, no tiene sentido que en el RS232 uses ese protocolo, puede ser otro más sencillo de implementar, el que se ocuparía de la temporización DMX sería el PIC.

Problema, si quieres controlar los 512 bytes que admite el DMX512, tendrás que buscar un PIC que tenga memoria RAM para hacerlo, y sencillos no hay muchos. Si solo quieres controlar 64, que no lo parece, pero es un montón, "cualquiera" con 128 bytes de RAM bien estudiado te vale. Si no te importa "saturar" el USB, puedes ir mandando bloques de 64 bytes hasta los 512, y el PIC tendría que gestionar la posición de esos bloques dentro de los 512, así "todo" estaría en la memoria del PC.

Muchas mesas profesionales apenas gestionan los 64 canales que digo, solo las gordas controlan los 512, por que acaba siendo complicado aclararse al humano que tiene que controlar todos los cacharros. aunque hoy se tira de PC y tema resuelto...

La temporización crítica es la de los 250kb/s, la de los 88us no tanto y la que hay entre trama y trama, mientras no supere el segundo, creo que era, no hay problema. Si no ha cambiado la norma, cuando estás unos segundos sin mandar nada, el aparato hace un reset. Si no era una norma, al menos así lo hacíamos nosotros, era una manera de reiniciar el cacharro sin tener que subir hasta donde estuviera colgado, que a veces era muy alto...

Josefe17
31/03/2015, 15:39
A ver, de momento programar micros pues como que aun no llego (llegaré), pero bueno. De momento la idea es primero ver si me llega el arduino y luego probar con el, y segundo esperar que me llegue esto: http://www.ebay.com/itm/291043914266?_trksid=p2060353.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT y probar con el y el FreeStyler. Si le pongo el Entec open DMX dicen que lo reconoce y manda sobre el puerto COM directamente el DMX=>SN75176 y listo. Y si no pues nada y a otra cosa.

Y respecto al 75176, mi amiguete se pilló una mesa dmx de segunda mano por 70€-48ch. Cuando la probamos con el estroboscopio no iba, no mandaba señal. Tras pensar que era por la carga fantasma y al ponerla seguia sin hacer nada, la abrimos, metemos osci y una de las salidas del transceptor estaba quemada. Estoy casi convencido que fue porque el anterior dueño usó un cable de micro no balanceado a la salida, que tienen el pin 3 cortocircuitado a masa=> uno de los canales diferenciales en corto. Cambiamos el trasnceptor y listo.

Y otra pregunta, ¿cómo hacer el through? La señal viene como RS-485, pasa por el transceptor, saca los bits y los mete en el chisme N. Luego si yo quiero mandar los bits de nuevo cómo lo hago, ¿con otro transceptor en modo send conectado a la salida del otro? ¿Y las cargas fantasmas dónde irían?

Y si quiero optoacoplar serían en la entrada, ¿no? ¿Hay algún modelo de optoacoplador ya probado para esto? Seguro.

Finalmente, el cable a usar valdría cualquiera compatible con el RS-485 (el de micro incluído ;-), que tiene muuuucho ancho de banda)

Muchas gracias.

Aunolose
31/03/2015, 16:30
Si la tirada no es muy larga el 75176 funciona con solo dos cables, comprobado. Puedes poner A y masa, A y B, o B y masa... son peores los rebotes ¿has llegado a eso ya? son la leche, muy curiosos de explicar/entender. A ver si lo consigo.

Cuando cierras un circuito empiezan a fluir los electrones, pero ¿cuantos? es cierto que todo es muy rápido para nosotros, pero no para ellos ¿cuantos electrones tienen que salir? ¿1A, 2A? bueno, pues el caso es que los electrones salen "a lo bruto", la primera resistencia que se encuentran es la del cable, como está inmediatamente cerca, eso se corrige enseguida, cuanto tienes una tirada de metros tardan algo más, cuando llegan se encuentran con la impedancia del circuito destino, si esa impedancia no es la misma del cable, ya tienes un problema, por que todos los electrones que han salido "no caben" y rebotan, literalmente como una ola, esos electrones "hacía atrás", mezclados con los que vienen hacen que las señal cambie, a veces mucho y a veces poco. Si lo veis como una ola (de electrones) se entiende mejor, se producen valles y crestas, es los valles puede resultar que la tensión llegue a 0, cuando debería ser 5V (o 9, o 12) y al revés 10 en vez de 5V. Si en vez de ser una señal continua, que se estabiliza en milisegundos, es una señal que cambia a razón de 250kps tienes un mejunje divertido :D añade también distintos circuitos conectados uno aquí, otro dos metros más p'allá, otro 6m, y tienes un caos de señales bastante bueno :D

Esto ¿por que te lo cuento? por que me ha pasado (en las piscinas de Marina D'Or) hacer una tirada larga y tener señal suficiente al final, pero justo en medio no... a ver como se lo explicas a un profano... como los conectores son macho y una hembra, soltabas la salida y funcionaba, soltabas los dos y los juntabas y dejaba de funcionar la de "dos más p'allá" :D divertido ahora que lo cuento, pero explícaselo a "tu abuela", que además es la que te tiene que pagar :D el caso es que es muy importante la terminación del cable... el último aparato debe llevar una resistencia de 120 ohm en paralelo con A y B. Por cierto que todas las tiradas eran con manguera de 3x1.5mm... y funcionaba "sin problemas" al menos cuando solucionamos el problema de los rebotes. Aquí es cuando me meto en lo que preguntas. Lo solucionamos poniendo repetidores, ¿como funciona un repetidor? a nosotros no nos importaba que estuviera aislado así que hice uno con cuatro 75176, uno recibía y lo pasaba a los otros tres, los otros tres tenían salidas normales otra vez. Para ser aislado podrías poner un optoacoplador en medio, en la señal TTL, pero necesitarás dos alimentaciónes ¿y entre A y B? cuando se polarice al revés es un 0... sí, supongo que también se podría hacer, pero ojo, la carga total deben ser 120ohm, o generarás rebotes potencialmente "impertinentes".

No acabo de entender lo de "llega en formato 485" la norma 485 es una norma eléctrica, solo define tensiones, diferenciales y cosas así, el 75176 se encarga de convertir la señal TTL a 485 y al revés. ¿A que te refieres con el through? ¿a que empiece la trama? no sé si es eso, ya digo que los repetidores los hicimos tontos. Si te refieres a pillarlos con el micro, el primer byte que llega es 255, si no lo es, no es DMX (aunque creo que esto lo iban a cambiar para tener más canales) si es 255 hay que mirar el siguiente, que creo que es 0 con el noveno bit a uno, luego no me acuerdo :scratch: puf, ¿donde tendré toda la documentación? hablamos de tiempos de disquetes... me suena un pen usb de 128MB... creo que la he perdido :( el caso es que si se cumplen esas condiciones, ya te pones a recibir llevando la cuenta de los bytes recibidos y cuando sea "el tuyo", haces lo que toque con la información.


¿70 € una mesa...? nosotros la vendíamos nueva bastante más barata, aunque era muy orientada a lo nuestro y difícil de manejar, por mucho que dijera el jefe, se empeñó en hacer las cosas "así" y "así" pasó que no vendimos apenas y las teníamos que regalar cuando compraban cosas...


Ah, lo del RS232, cómo le pases la información al emisor de DMX es independiente de lo que sale después por el bus DMX Te sugiero que hagas por un lado la recepción (RS232 o como sea), pongas los datos a mandar en un sitio y por otro lado hagas la emisión (DMX) por otro, cogiendo los datos de ese sitio donde los habías puesto. Con interrupciones de emisión/recepción se puede hacer fácilmente, bueno, no sé como tratan las interrupciones en arduino, pero no debe ser complicado ¿no?

No sé si te he aclarado algo, me lanzo a hablar y...

Josefe17
31/03/2015, 17:27
Me acabo de levantar de siesta y me lo tendré que volver a leer como un examen de programación.

Lo de la impedancia lo entiedo. El sistema ha de tener la misma impedancia entre cada uno de los pares y masa puesto que es una tensión diferencial antisimétrica y para que esté balanceado, según el teorema de barlett, la impedancia que vea un canal respecto a masa ha de ser la misma que respecto al otro. Y como los cables tienen cierta impedancia, para que la carga sea la misma, se pone el terminador en el último elemento. Y si mi teoría no se equivoca la resistencia en paralelo entre A y B del terminador equivaldría, en teoría, a una resistencia entre A y masa de 60 ohm y otroa entre B y masa de 60 ohm. En la práctrica, R entre A y B de 120 ohm sin tocar masa.

Los repetidores serían lo típico integrado en el dispositivo: llega el cable con la señal, 75176 en modo reader, señal TTL, 75176 en modo driver, salida de señal. Digamos que tras la salida de este 75176 tenemos una nueva etapa limpia que mandaríamos al siguiente equipo. ¿Entonces en este equipo haría falta una carga? Lo que no se debería hacer, o a lo mejor estoy confundido y es lo que se hace, es hacer el through de un dispositivo puenteando a pelo la señal que entra al xlr de entrada al xlr de salida.

Respecto a usar cable de 3x1.5, ¿te refieres a cable de AC, como el de alimentar la caravana? En caso afirmativo :yaya:.

Por curiosidad, lo tuyo eran los LED's, ¿no?

Aunolose
31/03/2015, 18:24
Me acabo de levantar de siesta y me lo tendré que volver a leer como un examen de programación.

Lo de la impedancia lo entiedo. El sistema ha de tener la misma impedancia entre cada uno de los pares y masa puesto que es una tensión diferencial antisimétrica y para que esté balanceado, según el teorema de barlett, la impedancia que vea un canal respecto a masa ha de ser la misma que respecto al otro. Y como los cables tienen cierta impedancia, para que la carga sea la misma, se pone el terminador en el último elemento. Y si mi teoría no se equivoca la resistencia en paralelo entre A y B del terminador equivaldría, en teoría, a una resistencia entre A y masa de 60 ohm y otroa entre B y masa de 60 ohm. En la práctrica, R entre A y B de 120 ohm sin tocar masa.

Los repetidores serían lo típico integrado en el dispositivo: llega el cable con la señal, 75176 en modo reader, señal TTL, 75176 en modo driver, salida de señal. Digamos que tras la salida de este 75176 tenemos una nueva etapa limpia que mandaríamos al siguiente equipo. ¿Entonces en este equipo haría falta una carga? Lo que no se debería hacer, o a lo mejor estoy confundido y es lo que se hace, es hacer el through de un dispositivo puenteando a pelo la señal que entra al xlr de entrada al xlr de salida.

Respecto a usar cable de 3x1.5, ¿te refieres a cable de AC, como el de alimentar la caravana? En caso afirmativo :yaya:.

Por curiosidad, lo tuyo eran los LED's, ¿no?

Lo del color no lo pillo, claro que se puede puentear la entrada y salida, los aparatos "cuelgan" del bus, en paralelo. En nuestro caso, incluso los que no fabricábamos nosotros, todos llevaban los 75176, y solo poníamos la resistencia del final. Es decir, al lado de las direcciones del aparato, había otro microinterruptor que conectaba o no la resistencia, según ese aparato fuera el último o no lo fuera.

"Lo mío" fueron muchas cosas :D cuando me dediqué a esto, eran "todos los aparatos de iluminación espectacular", es decir, las luces y aparatos que "hacen luces" en las discotecas y programas de televisión del estilo Eurovisión, que se mueven los gobos y esas cosas, los aparatos son los mismos, aunque más limpios... después la fibra óptica, pero con el mismo sistema de control: DMX, esto duró poco, pronto llegaron los leds y se acabó todo eso y pasó a ser, o lo mismo pero en vez de lamparas de 150W, leds de 18W (y menos luz) o directamente los leds a pelo.

Y las empresas cambiando de nombre, dividiéndose... y la última, a tomar viento por falta de pago de los ayuntamientos, sobre todo :( creo que también faltaron vendedores que supieran vender lo que ofertaba y quizá otro carácter del que finalmente vendía, que era muy buena gente, pero de vender no tenía mucha idea. Tuve conocidos que aún dieron más tumbos que yo, en aquel tiempo conseguir trabajo no era como ahora, algo encontrabas siempre.


ah, edito: sí, el cable era manguera para AC, como el de alimentar la caravana, etc. :D y funciona, ¿no ves que es diferencial? si tienes apantallado, mejor, pero si no, solucionas los problemas de rebotes y "arreglado", compensa por que puedes contratar mano de obra que no sepa manejar cable apantallado, cualquier chispas te sirve.

Edito 2: es que en mi caso hablo de cientos de metros p'arriba y p'abajo, si la instalación la hacíamos nosotros, poníamos apantallado, pero por ejemplo en Marina D'Or, no, por qué lo hicieron ellos. Nosotros fuimos después a arreglar el marrón :D

Josefe17
31/03/2015, 19:34
A ver si una imagen te aclara todo:127433

El esquema de arriba es el through como tú lo presentas: lo mismo que entra sale. Pero lo mismo, los 75176 cuelgan en paralelo y tras el del final el terminador balanceador de línea.

El de la derecha arriba muestra un repetidor: la señal entra a un lector 75176, se convierte a TTL y se reenvía a tantos canales como haga falta o puede ser un aparato con repetidor integrado, tal que a su salida rehace la señal DMX pudiendo tener otra tirada de aparatos. Por cierto, puesto que es el último aparato de la cadena que le llega a la entrada sí o sí tendría que tener un terminador a la entrada, ¿no? Por cierto, para lo que vale un 75176 (28 cts) merece la pena regenerar la señal de salida y que no sea un simple "through".

El tercero muestra un dispositivo optoaislado, que también regenera la señal, y si no me equivoco, la impedancia de cada fotoacoplador debería ser de 60 ohmios entre el y masa para que "haga de terminador".

Espero que mis dudas hayan quedao claras. Quizás esto es en lo que más duda tengo, del protocolo eléctrico, junto con lo de los timings.

Luego lo de que los equipos de Tv sean "más limpios" que los de los bolos, si es de mugre te doy la razón. El cubata es muy peligroso, y sobre todo, los manazas que "hacen" esas instalaciones. Todavía no he ido a ninguna sala de fiestas que no haya visto empalmes de focos o equipos de estos de efectos regularmente encintados, puede que con clemas o el mítico Schuko enchufado a la clema gorda.


Y gracias Óscar por tu tiempo.

Aunolose
31/03/2015, 19:49
A ver si una imagen te aclara todo:127433

El esquema de arriba es el through como tú lo presentas: lo mismo que entra sale. Pero lo mismo, los 75176 cuelgan en paralelo y tras el del final el terminador balanceador de línea.

El de la derecha arriba muestra un repetidor: la señal entra a un lector 75176, se convierte a TTL y se reenvía a tantos canales como haga falta o puede ser un aparato con repetidor integrado, tal que a su salida rehace la señal DMX pudiendo tener otra tirada de aparatos. Por cierto, puesto que es el último aparato de la cadena que le llega a la entrada sí o sí tendría que tener un terminador a la entrada, ¿no? Por cierto, para lo que vale un 75176 (28 cts) merece la pena regenerar la señal de salida y que no sea un simple "through".

El tercero muestra un dispositivo optoaislado, que también regenera la señal, y si no me equivoco, la impedancia de cada fotoacoplador debería ser de 60 ohmios entre el y masa para que "haga de terminador".

Espero que mis dudas hayan quedao claras. Quizás esto es en lo que más duda tengo, del protocolo eléctrico, junto con lo de los timings.

Luego lo de que los equipos de Tv sean "más limpios" que los de los bolos, si es de mugre te doy la razón. El cubata es muy peligroso, y sobre todo, los manazas que "hacen" esas instalaciones. Todavía no he ido a ninguna sala de fiestas que no haya visto empalmes de focos o equipos de estos de efectos regularmente encintados, puede que con clemas o el mítico Schuko enchufado a la clema gorda.


Y gracias Óscar por tu tiempo.

Exacto, a eso me refiero con "más limpios". :D


Bueno a ver. No sé donde has leído que el 485 necesite las resistencias de 60 ohmios, pero así no es, o así no lo hacíamos nosotros, nosotros poníamos una única resistencia (de 120) entre A y B, había veces que las masas no estaban unidas, o era opcional unirlas, al estilo de los micrófonos de audio.

No recuerdo ningún aparato que llevara nada para hacer de trought (bonito palabro ¿es nuevo? :( ), los conectores canon de 3, que son los que usan la mayoría de DMX, por dentro iban empalmados entre sí y de esos cables salían para el resto del circuito, concretamente el 75176. Solo en el caso del repetidor era de otra manera, y el repetidor podía estar en medio de la red, con lo cual, no llevar terminador.
No sé lo que quieres montar, pero para empezar montalo sencillo, para poca distancia no te hace falta ni terminador.

Josefe17
31/03/2015, 20:35
Montar nada. Simplemente tener las ideas claras para cuando tenga medios saber como actuar.

Y respecto a lo de que no tengan terminador los repetidores no me acaba de convencer, al menos la teoría. Lo que yo planteo es: la señal entra por un puerto y no hay throught, va al 75176 y luego como TTL a nuevos 75176. Es como si el repetidor fuese el último elemento de la cadena primaria, y a partir de él lo que cuelgan son nuevas cadenas (es como si fuese la mesa), ya que la informacion en un repetidor se transmite entre la entrada y la salida como TTL. Es como si al último dimmer de la cadena, el que tiene el terminador, le conectamos un cable a la salida de su 75176 de lectura y enganchamos otro 75176 en modo driver. Por eso, como veo que el repetidor de cara a la cadena primaria es el último elemento (si no hay "trou"), tendría que haber un terminador siempre conectado a su entrada.

Por cierto, yo tuve una vez un proyecto de diseñar una máquina de humo desde cero, calentador incluído. El primer diseño fue una resistencia de lavadora con un serpentín de tubo de aire acondicionado y papel de aluminio. Calentó una vez, se derivó la resistencia, pero al menos ahumó una vez. Como bomba una de lavaparabrisas y un 317 para regular la velocidad y caudal. El siguiente intento fue enrollar el tubo de cobre sobre una resistencia de cuarzo metida en un tubo de cobre. Ahumó pero no me convencía. Desterré el proyecto, pero un día desmontando una vaporeta de mano encontré un calentador de aluminio y una bomba de pistón. Brincaba de la alegría. Ahumaba pero escupía líquido sin evaporar. Lo dejé por imposible. Entonces llegó la matrícula de honor en circuitos y para quitarme la espinita me compré una máquina comercial :) Mi madre me echó una bronca... Y ahí está, de postureo en la estantería. Sin DMX, pero eso con un relé externo chupado.

Algunas fotillos:

Versión 1:
127434127436127437127438

Versión 2, mismo dimmer y misma bomba:
127440127441127442127443

Versión 3, con vaporeta (prueba de agua, la de humo no la encuentro):
127444127445127446127447

Aunolose
31/03/2015, 22:28
Uyyy una máquina de humo :D ¿sabes que hay líquido con olores? se consiguen con unas gotas en el líquido a evaporar (que no es agua, por cierto) con un tubo de esos como de ensayo pequeño tienes para la tira de litros, a un bidón de 5 litros se le echan unas gotas. Bueno pues llevándolos de un sitio a otro en el coche de un compañero se tumbó y no debía estar bien cerrado por que se desparramó... el coche estuvo oliendo a fresas varios meses :partiendo:



Bueno, al grano. Creo que no acabamos de entendernos. Se supone que un 75176 colgado del bus es como si no estuviera, lo mismo da que en la parte TTL esté un generador que un repetidor, que un flash, entonces puedes colgarlo en cualquier punto, y es por eso que el repetidor también funcionará si lo pones en medio de la red, como no es de ida y vuelta, no hay problema, eso sí, en la rama nueva necesitas otro terminador.

Ahora no tengo tiempo de hacerte un esquema y subirlo, pero el primero de los que has puesto antes es la idea, solo que la resistencia suele estar dentro del aparato, así si lo colocas el último, la activas y ya está. Y la masa no es crítica, cuando lo pruebes la quitas y verás como funciona.

Josefe17
31/03/2015, 23:06
Claro, esa es la idea. El repetidor empieza otra red con la misma información, por lo que ha de haber terminadores en ambas redes, y si coincide que el repetidor es el ultimo elemento de la red, el repetidor tiene el terminador.

Y me has dado una idea con lo de los perfumes para líquidos de humo, ya que conozco varios sitios donde les vendría bien varias garrafas de solo el perfume (nada de tubos de ensayo), empezando por el coche de mi padre y acabando por el portal de mi casa. Y el compuesto sé que no es agua. De hecho para las pruebas iniciales fue una mezcla de glicerina y agua. Luego ya me agencié líquido del bueno (y acabaron varios de mis pantalones pringados), pero ese día en el pueblo sólo tenía agua del grifo y solo pude probar eso.

Aunolose
01/04/2015, 12:14
Bueno, parece que por fin nos hemos aclarado. A cada salida del repetidor (el nuestro tenía 3 salidas) le corresponde un terminador, y si el repetidor es el último, debe colocar la resistencia, por ser el último, no por ser el repetidor. En teoría si te llevas el cable a "200m" y no pones nada, es ahí donde se coloca el terminador, por eso existen y se venden conectores-terminadores. Son conectores normales con la resistencia soldada en los terminales.

Cuando estés de pruebas quita la masa de un extremo y verás como sigue funcionando, y si eres más aventurero, quita el A o el B, los dos no, claro :D en nuestras pruebas funcionaba, por lo menos cuando estaba cerca, lo que ahora no recuerdo es si solo había un dispositivo :scratch: la prueba fue en el talle, con una manguera de varias decenas de metros enrollada, pero no recuerdo si al final había un solo aparato o varios, lo que sí tengo claro es que si había varios, la distancia de cable entre ellos era de un metro más o menos, pues era la medida que teníamos para los cables de prueba.

Josefe17
01/04/2015, 12:45
El hecho es que un repetidor, por su configuración de repetidor, es absurdo que tenga through, aunque pueda, ya que en las salidas repetidas tienes la misma señal que en through pero más y mejor. Por eso lo habitual debe ser que un repetidor sea el último de la cadena principal, aunque haya más equipos luego, pero no enganchados a un through sino a las salidas repetidas, por lo que de cara a diseño, en ese caso el repetidor sería el último de la cadena primaria, ya que en vez de tener through tiene señales repetidas, aunque puede tener through y señales repetidas y en ese caso el terminador iría tras el último elemento conectado al through (o en el repetidor si es el último).

A la conclusión que quiero llegar es que cuando un bus muere en un aparato debe llevar terminador, ya sea porque es el último de la cadena o porque el through no lo sea como tal sino una salida repetida, incluso optoaislada.

Vaya pelis que me monto...

Aunolose
01/04/2015, 14:30
Vaaale, por fin te entiendo del todo :D

Es que cada sitio es de una manera, en redes de estas he visto funcionar todo bien cables empalmados, es decir, llega un cable, ficha (ni siquiera soldado, y eso que era apantallado...) y salir dos cables, las dos ramas funcionando sin problemas, no recuerdo si alguna de las dos llevaba terminador. :scratch:

Al ser diferencial el 485 es muy fiable, pero además, al ser datos repetidos una y otra vez, si se pierde alguna trama, no pasa nada. La cosa cambiaría si fuera bidireccional o las cosas solo se mandarán una vez.


La peor instalación a nivel de rebotes fue la que cuento de Marina D'Or, hay dos o tres pisos y en cada piso varias ramas, y todas se controlan desde el mismo punto, "el mejor sitio"... para comprobar lo de los rebotes...

Josefe17
01/04/2015, 15:47
¿Y pa que tanto DMX en Marina D'Or? Ni que fuese el Teatro Real de la Ópera.
Bueno, el Arduino aun no ha llegado. Ya hasta el lunes nada y estaré en tu tierra. Y luego a la vuelta toca empollar :{

Aunolose
01/04/2015, 15:53
Vaya, el que no estará en mi tierra seré yo, que nos vamos al pueblo...

Hay/había un montón de fuentes de iluminación para fibra optica que se controlan con DMX, eran unas 80 repartidas por todas partes para hacer colorines y tal. Están/estaban en las piscinas del hotel de 5 estrellas. Mejor dicho, no "están" en la piscina, aunque alguna hay, si no que "se ven" los colores desde la piscina.

Josefe17
01/04/2015, 16:16
Me esperaba algo así. No me imaginaba para qué querrían si no en las piscinas de Marina D'Or 60Kw en focos PAR, 10 cabezas móviles, media docena de Scanneres, un par de máquinas de humo, alguna de pompas y otros tantos metros de tira de LED RGB.

Josefe17
27/05/2015, 16:46
Joder 2 meses ya desde semana santa...

Ahora que ando de exámenes y tengo tiempo para procrastinar te comento los avances que he hecho en la materia. Lo primero fue que me llegó el PWM DMX, el arduino y el FT232RL. Probé el PWM DMX. La frecuencia de PWM es de 200 Hz (por eso de que saca 8 PWM de un microcontrolador via software). Filtrar eso a 100 Hz con una atenuación de 44 dB a 200 Hz es hacer un buen filtro de orden alto. Traz hacer pruebas empíricas tengo diseñado un LPF RC de segundo orden con polos a 1.25 Hz y 25 Hz. No es lo que quería, responde lento a las actuaciones del fader (por eso de los 1.25 Hz), pero me valdría. Aun así cortando a 18Hz me sería incluso suficiente, ya que el ojo no aprecia más. Aun así, quiero mejorarlo más. Tengo 2 opciones: o diseñarme un filtro aceptable que me valga tanto para estudiar mi examen del viernes de diseño de filtros así como de filtro pasobajo para el PWM, o subir la frecuencia de PWM. Esto implica diseñarme un PWM DMX con microcontrolador yo mismo. Tras investigar encontré un programa para el Pic18F2550 que lee el DMX y muestra el valor del canal en un display. Lo bueno que tiene es que se encarga de gestionar la USART para leer el DMX y te almacena los 512 canales con su valor en un array de donde son fácilmente accesibles. Estoy haciendo como proyecto inicial y experimental unos relés DMX, que cuando el valor del DMX supere un determinado umbral se encienda el relé y cuando baje de otro se apague. Ideal para máquinas de humo y chismes así. Luego está que yo nunca había programado en C (Java es lo que damos), y bueno, entre eso, entender los fuses y encontrar el compilador adecuado para el código escrito (CCS) eché un par de tardes de mediados de mayo analizando y modificando el código. Aun no lo he probado, ya que no tengo grabador de microcontroladores. Entonces me he pillado un clon del PicKit2 de Microchip y estoy esperando que me llegue. Además el código y el hardware del PicKit2 está publicado por Microchip y es perfectamente factible fabricarse uno. Lo malo es que hay que traducir los componentes SMD a Through hole y tener un programador para programar el microcontrolador que necesita (también el 2550, por cierto). Es como la gallina y el huevo.

Evidentemente para hacer estas pruebas tuve que generar DMX. Probé el FTDI pero no funcionaba. Debía de estar roto. Reclamé al chino, me dijo que me madaba otro y nada, desde finales de abril esperando. Ya he pillado otro, a ver si este cuando llegue va bien. Entonces recurrí al arduino. Tras probar 4 librerías, con la 5ª funcionó y pude hacer mis pruebas, incluso con AnalogRead de un potenciómetro y todo. Cuando llegue el FTDI probaré el interfaz a ver si pruedo usar el FreeStyler.

Por cierto, los Pics me han salido gratis (esos ya los tengo), cortesía de Microchip (free samples y mi condición de alumno de la UPM).

Ahora volvamos con los filtros.

Aunolose
27/05/2015, 18:57
¿Quieres hacer 8 PWM controlados por DMX? ¡Lo tengo hecho! en serio... en serio y en ensamblador... creo que sacaba más de 200Hz, pero el micro se dedicaba solo a eso.
Hay un problema. Tengo que encontrarlo. :(

El código es para 8051, pero es extrapolable. Recuerdo que "la magia" estaba en la instrucción CJNE esta instrucción compara dos datos, uno de ellos puede ser el acumulador y es "rápida" para ser una comparación.

En el acumulador estaba el contador de PWM, en el otro dato, el dato DMX, en la comparación si es mayor (o menor) se activa el (C)arry este bit lo sacas directamente en la siguiente instrucción a la pata que toque, y ya, al siguiente dato, que también se compara con el acumulador, así hasta 8 (ó 16)

Esto en un bucle, al final del bucle se incrementa el contador. sale una frecuencia bastante alta. Creo que durante ese bucle las interrupciones (del puerto serie, el DMX) están desactivadas, así no cambia demasiado, solo se permiten al final, en el incremento del bucle.

Ten en cuenta que puedes perder "un montón" de datos, por que se repiten por lo menos 44 veces por segundo, y no hay aparato que necesite tanto.



Joe, esto del DMX me trae recuerdos que ni recordaba que tenía :scratch: uno de ellos, la hoja impresa (con impresora de agujas) con este mismo código, que es una miseria, ocupa una ridiculez, en ensamblador, insisto, en C se puede hacer exactamente igual, pero saldrá algo más lento.

Aunolose
27/05/2015, 18:59
Ah, el emisor de DMX, también tengo uno. Bueno, tengo dos, uno sencillísimo, que usábamos para borrar las memorias EEPROM y ponerlas a 00h, en vez de FFh, y otro que es "una mesa", este es complicado, creo que ya hablé de él.


Lo pongo por que el protocolo es muy sencillo de poner en marcha y en un momento dado puedes construir uno para las pruebas.

Josefe17
27/05/2015, 19:08
Ensamblador, estas loco... Desde luego el código se puede extrapolar pero me llevaría trabajo. Aun así es un reto, y entender ASM te ayuda a entender lenguajes mas altos. De todas formas estoy pensando la opcion de usar un módulo PWM externo via serie y subir a los Khz y no volverme loco con el filtro integrador. En cualquier caso pásamelo y lo miro entre convolución y convolución. Si necesitas un mail dimelo.

Gracias Óscar.

Aunolose
27/05/2015, 20:06
Si quieres arañar micro segundos... tienes que acabar en ensamblador... en programas complicados es imposible, incluso leí que un buen compilador genera igual o mejor código que un programador de ensamblador (humano) mediano. además la ganancia sería pequeña en conjunto. Pero en programas sencillo como este, donde "cualquiera" lo entiende, seguro que supone doblar la velocidad.

Hay instrucciones que, si no configuras bien el compilador, usan dos instrucciones de ensamblador por que son a piñón, imagina este caso, el contador es el mismo para los 8 canales, en el bucle comparas todos los datos con ese contador. Bien, pues para hacer eso en C, primero se pasar el dato del contador al acumulador y después se compara el acumulador con el dato, la siguiente vez, como es otra instrucción de comparación en C, se vuelve a llevar otra vez el contador al acumulador, así 8 veces, cuando no es necesario, lo llevas una vez y ahí se queda durante todo el bucle, ya que no cambia. En un bucle de 16 instrucciones te has ahorrado 7... y si fueran 16 canales, 15.

Y no conozco ningún compilador (para mincrocontrolador) que no permita meter bloques en ensamblador, en el diseño de los sistemas operativos (buenos...) se hace, se diseña todo en C (o C++ u otro), pero los cuellos de botella, los bloques de código críticos para la velocidad, se rediseñan en ensamblador, o por lo menos se comprueban a ver si son mejorables.


El problema va a ser encontrarlo :( hace poco que tiré un montón de disquettes de 3 1/2...

¿Te corre mucha prisa?, si no lo encuentro te lo pongo en seudocódigo.


Sobre los filtros, me pillas... eso ya me queda muy lejos y apenas lo he usado recientemente, cuando lo he hecho siempre ha sido para sistemas leeentos, donde daba un poco igual el rizado.

Josefe17
27/05/2015, 20:13
No te preocupes, hasta el 26 de junio estio liado con álgebra...

Aunolose
27/05/2015, 20:17
La rutina de PWM (en C) sería algo así.



byte contador;
byte[8] dato;

while (true)
{
if (contador>dato[0]) then
PortB0=0
else
PortB0=1;

if (contador>dato[1]) then
PortB1=0
else
PortB1=1;

if (contador>dato[2]) then
PortB2=0
else
PortB2=1;
.
.
.


if (contador>dato[7]) then
PortB7=0
else
PortB7=1;

contador++; // como es un byte, el solo desborda y se pone a cero.

} // del while


// el if puede sustituirse por esto
// PortBX= (Contador<=dato[X]); y funciona en la mayoría de compiladores...

Aunolose
27/05/2015, 20:23
Espera... hay que depurarlo, creo que el 1 y el 0 están al revés... :scratch: creo que tenía una pega de que siempre, aunque fuera 0, daba un pequeño pulso... hace tanto tiempo... :(

Josefe17
27/05/2015, 20:32
Otra opción sería subir la frecuencia del PIC a lo maximo que de, con cristal y todo. Eso sí, tocaría tocar todo el codigo de la USART para que leyese el DMX como debe. Pero en ese caso tendría que documentarme.

Aunolose
27/05/2015, 20:36
A ver ahora, Tiene como pega que el último bit de los 256 siempre está a cero, aunque el dato sea FFh (255d) y si en vez de poner < en los if, pones <=, entonces el primer bit de los 256 estará siempre a 1, aunque el dato sea 00h.



// PWM Versión mejorada.

byte contador;
byte[8] dato; //aquí van a parar los datos recibidos en la rutina de DMX

while (true)
{
PortB= 00h;
if (contador<dato[0]) then
PortB0=1;

if (contador<dato[1]) then
PortB1=1;

if (contador<dato[2]) then
PortB2=1;
.
.
.

if (contador<dato[7]) then
PortB7=1;

contador++; // como es un byte, el solo desborda y se pone a cero.

} // del while


// En este caso el if se puede sustituir, pero dependiendo del compilador, podría no ser tan rápido.
// PortB[x]= (Contador<=dato[x]);





Esta versión además tiene como "ventaja" el que, según el compilador, ahorrará un salto por "if" y atención por que en cuanto a la rapidez, a lo mejor es preferible hacer la comparación al revés
if (dato[X]>=contador)
hablamos de acelerarlo "mucho", todo dependerá del como lo interprete el compilador y como sea de bueno...

Aunolose
27/05/2015, 20:37
Otra opción sería subir la frecuencia del PIC a lo maximo que de, con cristal y todo. Eso sí, tocaría tocar todo el codigo de la USART para que leyese el DMX como debe. Pero en ese caso tendría que documentarme.

Eso es lo primero :D según la versión, puedes llegar a 24Mhz, me parece...

Josefe17
27/05/2015, 20:42
Me cuesta entender la idea de que haya diferentes compiladores, sintaxis y demás, ya que viniendo de Java, donde todo es siempre lo mismo, alto nivel y excepciones. Solo es un comentario.

Aunolose
27/05/2015, 20:47
Me cuesta entender la idea de que haya diferentes compiladores, sintaxis y demás, ya que viniendo de Java, donde todo es siempre lo mismo, alto nivel y excepciones. Solo es un comentario.

El Java... ¿no es parecido al C? al menos al C# y este al C... ¿o ya estoy desfasado incluso en eso? :(

Aunolose
27/05/2015, 20:49
Por cierto, ¿en microcontroladores también usáis Java? no me extraña que vaya lento...

Josefe17
27/05/2015, 20:56
Noooooooooooo. Dios vaya desfase. Java corre sobre una máquina virtual y está orientado a objetos. La sintaxis básica y la forma de enfocar los programas es similar pero digamos que la máquina y la memoria son transparentes para el usuario y que tu solo trabajas con encapsulamiento en clases y objetos, todo de alto nivel. No hay, por ejemplo, punteros, sino referencias a objetos. Los objetos son dinámicos y se muren si se quedan sin referencias. Y si por ejemplo intentas acceder a la posición -1 de un array, el programa lanza una excepción (error) y se para, no lee la posicion relativa de memoria -1.

Más en http://es.wikipedia.org/wiki/Java_%28lenguaje_de_programaci%C3%B3n%29

Y micros en Java como que no.

Aunolose
27/05/2015, 21:36
Oye, pues no estaba tan mal encaminado, lo que es lo de la programación a objetos de toda la vida...

Sospecho que si te metes en la programación de micros te tocará aprender C...

Josefe17
27/05/2015, 21:58
Si en el fondo me apetecería. Tengo intenciones de en su día coger un programador de lavadora de carraca y levantarle todos los cronogramas de todos los pines con ayuda de Matlab y Arduino (activa un pin, comprueba con cuales de los otros tiene continuidad, lo almacena y pasa al siguiente, y luego con Matlab hacer los plots) y luego pasarlos a un micro. Es solo experiental, por hacerlo y aprender. Lo jodido sería luego digitalizar la temperatura de la lavadora. Requeriría cambiar termostato por NTC (uno cualquiera de lavadora, teniendo su curva sería suficiente, y si no se levanta) o dejar el mando termostático antiguo, y también cambiar la electoválvula de un cuerpo por otra de 4 cuerpos (o 4 simples empalmadas) para las 4 jaboneras, porque las de carraca distribuyen el agua con una varilla desde el programador.
Ya te digo, no creo que lo haga por necesidad, pero sí para aprender a usar C en serio.

Aunolose
28/05/2015, 00:50
Si en el fondo me apetecería. Tengo intenciones de en su día coger un programador de lavadora de carraca y levantarle todos los cronogramas de todos los pines con ayuda de Matlab y Arduino (activa un pin, comprueba con cuales de los otros tiene continuidad, lo almacena y pasa al siguiente, y luego con Matlab hacer los plots) y luego pasarlos a un micro. Es solo experiental, por hacerlo y aprender. Lo jodido sería luego digitalizar la temperatura de la lavadora. Requeriría cambiar termostato por NTC (uno cualquiera de lavadora, teniendo su curva sería suficiente, y si no se levanta) o dejar el mando termostático antiguo, y también cambiar la electoválvula de un cuerpo por otra de 4 cuerpos (o 4 simples empalmadas) para las 4 jaboneras, porque las de carraca distribuyen el agua con una varilla desde el programador.
Ya te digo, no creo que lo haga por necesidad, pero sí para aprender a usar C en serio.

Tú ríete, pero en el pueblo tengo una lavadora de los 70 que funciona de cine... salvo el programador, que de un tiempo a esta parte se para en un punto y no pasa.... Compré una placa de relés en ebay y en algún movil tengo apuntados las entradas, las salidas, algunos tiempos... :D no sé como acabará la cosa por que la tengo lejos y no somos los que más la usamos (hay más presión por acabarla pronto una vez empiece) pero... está to' preparado para cuando llegue el momento :D

Josefe17
28/05/2015, 01:17
¿La del R6? Algo habia oido tuyo de una lavadora y relés pero pensaba que era la del boquete. En cualquier caso si se te para el programador es que no le llega corriente al motor de arrastre o que hay un engranaje tocado. ¿Cómo saberlo? Neon soldado en paralelo con el motor de arrastre del programador. Cuando se pare el programador, si el neón está encendido es fallo mecánico =>Planteate levantar el programa y hacer el código en ese momento. Si no le llega corriente al motor es que algo que no hace contacto. Normalmente llevan un contacto para el motor de arrastre, y dependiendo del diseño, el motor de arrastre se parará cuando acabe el ciclo o también en las fases de carga y calentamiento, pasando a depender del presostato y del termostato, aunque normalmente no dependen de ello por seguridad con el agua. Eso sí, seguro que es bitemperatura: o frio o caliente con termostato por botón, y presostato de un nivel . No creo que lleve muchos contactos el programador, y por no tener no tendrá ni micro de puerta (blocapuertas ni lo pienso). En cualquier caso si te aburres, levanta el cronograma y haz la placa, y ya lo tienes.

Por cierto, vi por ahí un esquema super interesante para manejar un motor asíncrono de lavadora sacando los 3 modos de funcionamiento con un condensador. A ver si lo encuentro. Hubo suerte: http://cdn3.grupos.emagister.com/imagen/circuito_para_probar_motor_lavarropas_538723_t0.jpg Eso sí, yo en vez de poner una conmutador doble con parada para el lavado ponía uno doble sin parada y los comunes en vez de ir directos a fase y condensador los ponia en los otros bornes libres del de centrifugado. Así con 2 conmutadores dobles o relés gestionaba el sentido de giro y velocidad, e interrumpiendo la fase el encendido.

Aunolose
28/05/2015, 09:03
¿La del R6? Algo habia oido tuyo de una lavadora y relés pero pensaba que era la del boquete. En cualquier caso si se te para el programador es que no le llega corriente al motor de arrastre o que hay un engranaje tocado. ¿Cómo saberlo? Neon soldado en paralelo con el motor de arrastre del programador. Cuando se pare el programador, si el neón está encendido es fallo mecánico =>Planteate levantar el programa y hacer el código en ese momento. Si no le llega corriente al motor es que algo que no hace contacto. Normalmente llevan un contacto para el motor de arrastre, y dependiendo del diseño, el motor de arrastre se parará cuando acabe el ciclo o también en las fases de carga y calentamiento, pasando a depender del presostato y del termostato, aunque normalmente no dependen de ello por seguridad con el agua. Eso sí, seguro que es bitemperatura: o frio o caliente con termostato por botón, y presostato de un nivel . No creo que lleve muchos contactos el programador, y por no tener no tendrá ni micro de puerta (blocapuertas ni lo pienso). En cualquier caso si te aburres, levanta el cronograma y haz la placa, y ya lo tienes.

Por cierto, vi por ahí un esquema super interesante para manejar un motor asíncrono de lavadora sacando los 3 modos de funcionamiento con un condensador. A ver si lo encuentro. Hubo suerte: http://cdn3.grupos.emagister.com/imagen/circuito_para_probar_motor_lavarropas_538723_t0.jpg Eso sí, yo en vez de poner una conmutador doble con parada para el lavado ponía uno doble sin parada y los comunes en vez de ir directos a fase y condensador los ponia en los otros bornes libres del de centrifugado. Así con 2 conmutadores dobles o relés gestionaba el sentido de giro y velocidad, e interrumpiendo la fase el encendido.


Sí, es la del R6, pero no la del boquete :D jo, después dicen de dar información por la red...

Un respeto para la lavadora ¿eh? que es de las primeras automáticas :D la temperatura se controla linealmente, todo/nada pero con su mando de ajuste, entre "0" y 90º sí, es el motor de arrastre, le das un toquecito y vuelve a funcionar, de los esquemas he mirado un montón, y tengo ya pensado como poner los relés para el tema del motor :D

Incluso recuerdo haber visto que lo controla con un PLC.

Vamos que tengo ideas a mogollón, lo malo será que el día que se estropee definitivamente no estaré para hacer el cambio (ni tendré el programa hecho :( ) y mi hermana, que es la que la usa pues va más veces, irá a la tienda y comprará una... :(

Aunolose
28/05/2015, 12:09
¡Lo encontré!

Lo pongo tal cual, está. Tiene control de paso por cero, por que es la última versión en la que tenía que controlar 3 leds solo (por eso están comentados los otros) y como la tensión de red no estaba filtrada, solo rectificada, pues había que sincronizar para evitar parpadeos. También está la rutina para recibir DMX y el código relativo a un controlador DA de dos canales por SPI, que luego no se usó, pero la idea era que la misma programación sirviera para dos cosas, configurable mediante un jumper-soldadura.


asm:
;; De bit
DMXok EQU 00H ; PARA LA RUTINA SERIE
Input EQU 02H ; para serie
Conf EQU 03h ; para serie
bloquenuevo EQU 05h
HADR EQU 06h ; para llegar a los 512
Pata256 EQU 07h ; Esta es para llegar a los 256, lo dejaremos a cero de momento
ms20 EQU 08h ; Si han pasado 20 ms
SalvaRB8 EQU 0d5h ; es F0, de proposito general, para recibir DMX si esta a uno

; De Byte
DecDirDMX EQU 08H ; Para no cambiar la dirección, la ponemos aqui y contamos
Direccion EQU 09h ; para guardar la dirección de los interruptores
GuardaASerie EQU 0Ah ; para guardar A en la interrupción serie
GuardaPSWSerie EQU 0Bh ; para guardar la palabra de estado en IRQ serie
DAtoDACA EQU 0Ch ; Dato que coge la rutina para el canal A
DAtoDACB EQU 0Dh ; Dato que coge la rutina para el canal B
DatoAnterior01 EQU 0Eh ; Para saber si hay que mandar o no
DatoAnterior02 EQU 0Eh ; Para saber si hay que mandar o no
DatoAnterior03 EQU 0Eh ; Para saber si hay que mandar o no

; Puertos
DOUT EQU P3.7
CLKDAC EQU P3.4
CSDAC EQU P3.5


PWM01 EQU 50h ; // Primer byte para PWM
PWM02 EQU 51h ; // Primer byte para PWM
PWM03 EQU 52h ; // Primer byte para PWM
PWM04 EQU 33h ; // Primer byte para PWM
PWM05 EQU 34h ; // Primer byte para PWM
PWM06 EQU 35h ; // Primer byte para PWM
PWM07 EQU 36h ; // Primer byte para PWM
PWM08 EQU 37h ; // Primer byte para PWM
PWM09 EQU 38h ; // Primer byte para PWM
PWM10 EQU 39h ; // Primer byte para PWM
PWM11 EQU 3Ah ; // Primer byte para PWM
PWM12 EQU 3Bh ; // Primer byte para PWM
PWM13 EQU 3Ch ; // Primer byte para PWM
PWM14 EQU 3Dh ; // Primer byte para PWM
PWM15 EQU 3Eh ; // Primer byte para PWM
PWM16 EQU 3Fh ; // Ultimo byte para PWM

DMX01 EQU 40h ; // Primer byte que recibe DMX
DMX02 EQU 41h ; //
DMX03 EQU 42h ; //
DMX04 EQU 43h ; //
DMX05 EQU 44h ; //
DMX06 EQU 45h ; //
DMX07 EQU 46h ; //
DMX08 EQU 47h ; //
DMX09 EQU 48h ; //
DMX10 EQU 49h ; //
DMX11 EQU 4Ah ; //
DMX12 EQU 4Bh ; //
DMX13 EQU 4Ch ; //
DMX14 EQU 4Dh ; //
DMX15 EQU 4Eh ; //
DMX16 EQU 4Fh ; // Ultimo byte que recibe DMX

;DatoRecibido EQU 50H ; aqui esta el dato real, lo siguiente es "un puntero"
PrimeroDMX EQU 50H ; es para poner un inmediato, asi siempre apunta bien
UltimoDMX EQU 50H+3 ; es para poner un inmediato, asi siempre apunta bien

ContadorPWM EQU 60h ; Es el que lleva la cuenta de hasta donde debe llegar

Pila EQU 68h ; Es para dejar sitio

DatoA EQU 00100001b
DAtoB EQU 00100010b
RecargaTH0 EQU 256-55


ORG 0000h
LJMP INICIO


ORG 00BH ; timer 0, se encargara de contar los 255 hasta llegar a 20 ms
LJMP BuclePWM ; Mide el minimo pulso 20 / 256

ORG 0013H ; Externa 0, pata 12
RETI
; CLR IE1
LJMP Externa1_PasoPorCero ; Paso Por 0 de la tensión

ORG 0023h
Serie:
MOV GuardaAserie, A
MOV GuardaPSWSerie, PSW
; SETB RecibiDMX
; LJMP LRecepDMX

; *************************************************** RUTINA SERIE

LRecepDMX:
MOV A, SBUF ;RECEPCION : 1EAD
MOV C, RB8
MOV SalvaRB8, C
CLR RI
JB Bloquenuevo, LDMXOFF ; Si aun no se ha hecho caso del otro, no recibas nada
JB DMXok, rec1old
CJNE A, #00H, LDMXOFF
JB SalvaRB8, LDMXOFF
SETB DMXok
SJMP LRETORNO

rec1old: JB Conf, Rec2old
CJNE A, #00H, LDMXOFF
JNB RB8, LDMXOFF
SETB Conf
MOV DecDirDMX, Direccion
MOV C, Pata256 ; Para que el DMX sea a partir de 256
CPL C
MOV HADR, C
SJMP LRETORNO

rec2old: JB Input, L1EF2
JNB SalvaRB8, LDMXOFF
DJNZ DecDirDMX, LRETORNO
JBC HADR, LRETORNO
SETB Input

L1EF2: JNB SalvaRB8, LDMXOFF
MOV @R0, A
Lnadas: INC R0
Lnadar: CLR C
CJNE R0, #UltimoDMX, L1F05 ;; Antes #6bH
SETB Bloquenuevo
CPL P3.5
SJMP LDMXOFF

L1F05: JC LRETORNO

LDMXOFF:
MOV R0, #PrimeroDMX
CLR DMXok
CLR Conf
CLR Input

LRETORNO: ; 1F17
MOV A, GuardaAserie
MOV PSW, GuardaPSWSerie
RETI


; ***************************************************************************************
INICIO:
ANL P3, #E9h ;; Solo P3.4, P3.2 y P3.1 a cero
MOV R0, #00H
Lacero: INC R0 ; Este bucle es para poner TODA la memoria
MOV @R0, #00H ; interna a 00H
CJNE R0, #7FH, Lacero
yaacero:
MOV P1, #0FFH ;; Aqui P1 sirvira para la salida de datos por display
MOV R0, #PrimeroDMX ;; para la recepcion serie
; MOV R1, #PrimeroDMX
MOV SP, #Pila ;; La pila solo va a tener 16 posiciones


MOV SCON, #090H ;; SCON Modo 2 ( 9 bits ); REN =1, Preparado
MOV PCON, #00H ;; SMOD = 0
MOV TMOD, #00100010B ;; TMOD Timers 0 y 1 en modo 2 ( 8 bits CON )
MOV TCON, #04H ;; Externa 1 por flanco
MOV TH0, #RecargaTH0
MOV TL0, TH0
; SETB TR0

MOV IP, #10H ;; IP, Prioridad serie
SETB ES
SETB EA
SETB ET0 ; tIMER 0
; SETB EX1 ; eXTERNA 1
SETB PS ; Prioridad serie, de momento
; SETB PX1 ; Y Tambien Externa 1
; MOV Direccion, #1 ;; Aunque sea el canal 0, es el 1
SETB Pata256 ; Simula la pata del puerto a 1





;TARDAMASPWM:
; SETB BloqueNuevo
;BUCLEDAC:
; NOP
; NOP
; NOP
; NOP
; NOP
SIMISMO:
JB P3.6, SiMismo ; P1.0 es la + y P1.1 - del operacional, P3.6 es la salida
ANL P3, #E9h ;; Solo P3.4, P3.2 y P3.1 a cero
CLR TR0
Esperaeluno: ;
JNB P3.6, Esperaeluno ; Asi esperamos que se ponga a uno, y ahora si que entramos
SETB P3.3
CLR Bloquenuevo ; Para Poder recibir más datos
MOV COntadorPWM, #0 ;; No tenemos externa 1
MOV TL0, TH0
SETB TR0
MOV A, P1 ; Esperamos que se ponga abajo
RRC A ; Pasamos de lo que diga P1.0 en la direccion
RRC A
ORL A, #C0H ;; Pasamos de P1.0 y P1.1
CPL A
JNZ YaEsta
INC A ; Para que el cero sea 1
YaEsta:
MOV Direccion, A
CLR P3.3
ANL P3, #E9h ;; Solo P3.4, P3.2 y P3.1 a cero
SJMP SiMismo
; JNB BloqueNuevo, BUCLEPWM ;BUCLEDAC
; MOV A, DatoDACA
; CJNE A, PWM01, MandaDato
; MOV A, DatoDACB
; CJNE A, PWM02, MandaDato
; SJMP BuclePWM ;BucleDAC
;MandaDato:
; MOV DatoDACA, PWM01
; MOV DatoDACB, PWM02
; LCALL LMandar
;; CLR BloqueNuevo
;; SJMP BUCLEDAC

; ************************************** Cada Cierto Tiempo
BUCLEPWM:

MOV A, ContadorPWM
CJNE A, PWM01, P01
P01:
MOV P3.1, C
CJNE A, PWM02, P02
P02:
MOV P3.2, C
CJNE A, PWM03, P03
P03:
MOV P3.4, C
; CJNE A, PWM04, P04
;P04:
; MOV P1.3, C
; CJNE A, PWM05, P05
;P05:
; MOV P1.4, C
; CJNE A, PWM06, P06
;P06:
; MOV P1.5, C
; CJNE A, PWM07, P07
;P07:
; MOV P1.6, C
; CJNE A, PWM08, P08
;P08:
; MOV P1.7, C
; CJNE A, PWM09, P09
;P09:
; MOV P2.0, C
; CJNE A, PWM10, P10
;P10:
; MOV P2.1, C
; CJNE A, PWM11, P11
;P11:
; MOV P2.2, C
; CJNE A, PWM12, P12
;P12:
; MOV P2.3, C
; CJNE A, PWM13, P13
;P13:
; MOV P2.4, C
; CJNE A, PWM14, P14
;P14:
; MOV P2.5, C
; CJNE A, PWM15, P15
;P15:
; MOV P2.6, C
; CJNE A, PWM16, P16
;P16:
; MOV P2.7, C
FindelBucle:
; ADD A, #4 ;; Voy de 4 en 4 para no tener que dividir por 4 todos los demas
; MOV ContadorPWM, A
SETb P3.7
INC ContadorPWM
MOV A, ContadorPWM
JNZ FinBuclePWM
ANL P3, #E9h ;; Solo P3.4, P3.2 y P3.1 a cero
CLR TR0
; CLR ms20
; MOV P1, #0
; MOV P2, #0
; MOV PWM01, DatoRecibido
; CLR Bloquenuevo ; Para Poder recibir más datos sino lo resetea el paso por cero
FinBuclePWM:
CLR P3.7
RETI

; *********************************************** Se produce una interrupción en el paso por cero
Externa1_PasoPorcero:
ANL P3, #E9h ;; Solo P3.4, P3.2 y P3.1 a cero
MOV ContadorPWM, #0
CLR Bloquenuevo ; Para Poder recibir más datos
CPL P3.5
RETI


; **************************************** RUTINA DAC *************

LMandar:
MOV A, #DatoA ;; Primero le decimos el canal, Ahora El A
CLR CSDAC
RLC A
MOV Dout, C
1bit: SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
2Bit SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
3Bit SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
4Bit SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
5Bit SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
6Bit SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
7Bit SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
8Bit SETB CLKDAC

MOV A, DatoDACA ; Ahora el DATO De A
CLR C ; Para meter un cero
; RLC A ; Para poner ACC.7 en C
; MOV FaseA, C ; y mandarlo a la fase
CLR CLKDAC
RLC A
MOV Dout, C
1bit2: SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
2Bit2 SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
3Bit2 SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
4Bit2 SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
5Bit2 SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
6Bit2 SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
7Bit2 SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
8Bit2 SETB CLKDAC
NOP
CLR CLKDAC
NOP
SETB CSDAC
NOP
CLR CSDAC
MOV A, #DatoB ;; Ahora le decimos el canal B
RLC A
MOV Dout, C
1bitB: SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
2BitB SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
3BitB SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
4BitB SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
5BitB SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
6BitB SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
7BitB SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
8BitB SETB CLKDAC

MOV A, DatoDACB
CLR CLKDAC
CLR C ; Para meter un cero
; RLC A ; Para poner ACC.7 en C
; MOV FaseB, C ; y mandarlo a la fase
RLC A
MOV Dout, C
1bitB2: SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
2Bit2B SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
3Bit2B SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
4Bit2B SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
5Bit2B SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
6Bit2B SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
7Bit2B SETB CLKDAC
RLC A
CLR CLKDAC
MOV Dout, C
8Bit2B SETB CLKDAC
NOP
CLR CLKDAC
NOP
SETB CSDAC
FinMandar:
RET

Aunolose
28/05/2015, 13:22
Que recuerdos...

Prototipo de la controladora DMX de 8 canales cara soldadura
131195

Cara componentes
131201


Prototipo tapa

131198


Final

131199


Prototipos de dos versiones del receptor de DMX que controlaba un motor paso paso y este a su vez un circulo de colores.

131200

Aunolose
28/05/2015, 13:44
En la cara de componentes salió una que no era...

131202

Aunolose
28/05/2015, 17:57
Final

131207

Josefe17
28/05/2015, 19:28
Me sorprende la facilidad que manejas ASM, eso es que le has echado muchas horas. Me hablas de la CJNE como si fuese en vez de una instrucción de ensamblador un sindicato, algo corriente. Entenderlo me llevaría su tiempo, y solo la parte que me interesa, pero no dudes que lo probaré. Digamos que tu pwm se basa en un bucle con un contador de 256 pasos autoreiniciable (overflown), que compara el contador con el valor DMX, poniendo la salida en alto si el contador supera el DMX, esto para los 8 canales, y luego se reinicia. Desde luego lo probaré a ver como resulta y qué frecuencia me da. Ten en cuenta que la frecuencia de reloj mia son 4 Mhz y creo que era 4 ciclos x instrucción, a ver si con suerte llego al Khz (considerando interrupciones y demás no creo que se ejecuten 1000 instrucciones entre paso y paso del PWM, a lo mejor me equivoco) y el filtro mejora.

Por cierto, lo del cruce por cero como lo haces. Es porque eso es lo que necesitaría ya para hacer un dimmer n-fásico microcontrolado analógico-digital, y lo del cruce por cero es algo imprescindible. Eso sí, hardware optoaislado.

Aunolose
28/05/2015, 20:50
Me sorprende la facilidad que manejas ASM, eso es que le has echado muchas horas. Me hablas de la CJNE como si fuese en vez de una instrucción de ensamblador un sindicato, algo corriente. Entenderlo me llevaría su tiempo, y solo la parte que me interesa, pero no dudes que lo probaré. Digamos que tu pwm se basa en un bucle con un contador de 256 pasos autoreiniciable (overflown), que compara el contador con el valor DMX, poniendo la salida en alto si el contador supera el DMX, esto para los 8 canales, y luego se reinicia. Desde luego lo probaré a ver como resulta y qué frecuencia me da. Ten en cuenta que la frecuencia de reloj mia son 4 Mhz y creo que era 4 ciclos x instrucción, a ver si con suerte llego al Khz (considerando interrupciones y demás no creo que se ejecuten 1000 instrucciones entre paso y paso del PWM, a lo mejor me equivoco) y el filtro mejora.

Por cierto, lo del cruce por cero como lo haces. Es porque eso es lo que necesitaría ya para hacer un dimmer n-fásico microcontrolado analógico-digital, y lo del cruce por cero es algo imprescindible. Eso sí, hardware optoaislado.


Uf, a 4Mhz sí que lo tienes chungo...

El paso por cero, sencillo: aparte del puente rectificador, pones un par de diodos que lleven los semiciclos positivos del secundario del transformador a una resistencia a la base de un transistor NPN, el emisor a masa (negativo del puente) en colector con una resistencia de pull up ya lo tienes.

Hablamos de un transformador normal, no de una fuente conmutada, ahí está más chungo y habría que sacarlo de la parte de 220V...




Con el ensamblador todo es ponerse :D

Algunas pistas.


CJNE Compara y Jump si No es Equal.
CJNZ Compara y Jump si No es 0

Estás dos instrucciones lo que hacen en realidad es una resta pero sin guardar el resultado, solo cambian el carry, lo que da como resultado que sabes si es mayor o menor e igual

JC/JNC Jump if Carry / if Not Carry
JB/JNB Jump if Bit / if Not Bit
JZ/JNZ Jump if Zero / if Not Zero (siempre referido al acumulador)

EQU Equal, igual, asignación.

CLR Clear (bit o byte)
SETB Set bit

RETI Retorno Interrupción

MOV Mueve del segundo al primero

INC Incrementa
DEC Decrementa

ADD Suma (al acumulador) X (o dato)

RL Rota el acumulador hacia la Left (izquierda)
RR Rota el acumulador hacia la Rigth (derecha)
RLC Lo mismo que RLC, pero pasando por el Carry
RRC Lo mismo que RRC, pero pasando por el Carry.

ANL And Lógico del dato con lo que sea
ORL Or Lógico ...
CPL Complementa, los ceros los vuelve unos y al revés.

NOP Not Operation.


A Acumulador.

C Carry (Acarreo)

B Un registro que tiene el 8051 por ahí... :dontknow: diferente del resto de la memoria.

RX Registros del 0 al 8 que tiene el 8051
SP Stack Pointer, Puntero de pila, importante para los saltos, se guarda la dirección de vuelta cuando se salta a una interrupción, en los lenguajes de alto nivel también se pasan los parámetros por ahí. Cuando algún programa da un "Desbordamiento de pila/Stack Overflow" es que este puntero se ha salido de la memoria que tenías reservada, y, lo más seguro es que te la va a liar... por que ha machacado una dirección que no tocaba, si es circular (como en los primeros PIC), acabas de machacar la dirección de vuelta a algún sitio, cuando toque volver... lo más probable es que caigas en un bucle infinito... en el caso del 8051, no es circular, pero si te pasas vuelve a cero, y empiezas a machacar lo que haya por allí...


PX Puertos, del 0 al 3
PX.Y Bit de un puerto.

PSW Program Status Word, Palabra de estado, en ella están el Carry, el carry "del medio", el Zero, un bit de propósito general, dos bits de selección de Banco de Registros y el de paridad, básicamente, hay que salvarlo casi siempre que tratas una interrupción.

IE Interrupt Enable, se permiten las interrupciones activas o no se permite ninguna.
EX1 Enable (Interrupt) External 1 Enable (a 1 permite, a 0 no)
ES Enable Serie


RI Receive Interrupt, Flag de interrupción de recepción serie
IP Prioridad Interrupción.

SCON, PCON, TCON, registros de configuración Serie

TMX TimerX
THX, TLX TimerX byte alto y byte bajo (son configurables, pero pueden ser de 16 bits)


ORG Dirección donde poner el código. En el 8051 los vectores de interrupción son fijos.


Puf, seguro que me olvido alguno

Ah, todo pin puesto a 1 es entrada, puesto a 0 es salida, concretamente a 0.

Aunolose
28/05/2015, 20:55
Ya no edito más...

Menos eficiente, entre el puente y el condensador de filtro, un diodo bien polarizado, la señal de antes del diodo, a la base del transistor.

Aunolose
28/05/2015, 21:07
Ahora veo uno importante

RB8, es el noveno bit que se recibe/manda por el puerto serie. Creo que aquí se usa para hacer los dos bits de parada a 1.

Josefe17
28/05/2015, 21:12
Con lo del cruce por cero me refería al software, el hardware +- lo controlo.

Aunolose
28/05/2015, 21:25
Con lo del cruce por cero me refería al software, el hardware +- lo controlo.

:oops: Ah, vale...

Bueno, yo lo metí a una pata que genera interrupción, en este caso la que llama Externa1, por un tema de prioridades, aunque al final creo no fue determinante. Bueno, decía, que a una pata que genera la interrupción, a partir de ahí, hago lo tengo que hacer, que es poner el contador PWM a cero, así como los pines que toquen

Está aquí:



; *********************************************** Se produce una interrupción en el paso por cero
Externa1_PasoPorcero:
ANL P3, #E9h ;; Solo P3.4, P3.2 y P3.1 a cero
MOV ContadorPWM, #0 ;; Pongo a cero el contador
CLR Bloquenuevo ; Para Poder recibir más datos, Así evito que el dato cambie cuando estoy formando el PWM
CPL P3.5 ; En el código es la pata CS del controlador DA, pero no estoy seguro de lo que hace ahora, *
RETI ; retorno de interrupción, es decir, vuelve a lo que estuvieras haciendo.


* puede que lo usará como chivato, para saber cuando empiezan y acaban las cosas, sospecho que este es un código de transición a la última versión

Por si no se ha deducido, # implica "dato inmediato", es decir, una constante, frente a cuando no lleva, que sería un dato de memoria.

Josefe17
28/05/2015, 21:54
No lo he deducido. Vaya triples que te tiras, como dice un amigo mio.
En mi caso no me valdría mucho porque lo que he de hacer es hacer que cuando la fracción del timer supere la fracción del DMX (o su equivalente modificando la respuesta con una curva de dimerizado) dispare. Es evidente que antes de dimerizar he de medir la frecuencia de la red (o hardcodearla, pero prefiero no hacerlo) y luego actualizarla en cada ciclo. La idea sería: arranca el sistema, espera a que haya un cruce por cero, se reinicia el timer y empieza a contar hasta el siguiente cruce por cero, siendo ese valor la duración del ciclo de red (1/(2*Freq-AC)), llamemoslo timer_total. Luego entraría en el main, de tal modo cada vez que suba el timer se compara la ratio timer_actual/timer_total con el parámetro dmx_canal/256 (o incluso analog_read/analog_max) y en ese momento se pone ese pin a alto hasta que el cruce por cero cae de nuevo (ojo con que tarde más en apagar la salida que en que se cambie de semiciclo porque el triac se reactivaría). Además en ese instante volvería a recalcularse el timer total, actualizandose en cada ciclo (o sea se lee una vez antes de empezar a funcionar y se actualiza en cada ciclo). En este caso la frecuencia no sería tan problemática (100Hz de nada...)

Esta es mi idea pero necesito tiempo para ponerme en serio.

Gracias por todo.

Aunolose
28/05/2015, 22:02
:scratch: El ciclo de red ya lo sabes... creo que no lo he entendido, a ver cuando vea el código, pero si esto no es importante, dedícate a estudiar, que sin darte cuenta, se te pasa el tiempo, como me ha pasado a mi "recopilando" instrucciones... :(


Creo que no piensas usar instrucciones ¿puede ser? este es un caso típico para usarlas, por que además son cada mucho, bueno, ahora que lo pienso, si vas a recibir DMX las necesitas ¿no?

Josefe17
28/05/2015, 22:26
De esto que te levantas de siesta y te duele toda la cabeza que eres incapaz de tocar apuntes. Pues eso. No me ha rendido nada la tarde. Ya contaba con ello. Probaré lo de ASM, pero no se hasta que nivel llegaré, pero me ayuda mucho a entender como funcionan todos estos chismes.

Aunolose
29/05/2015, 00:29
:scratch: El ciclo de red ya lo sabes... creo que no lo he entendido, a ver cuando vea el código, pero si esto no es importante, dedícate a estudiar, que sin darte cuenta, se te pasa el tiempo, como me ha pasado a mi "recopilando" instrucciones... :(


Creo que no piensas usar instrucciones ¿puede ser? este es un caso típico para usarlas, por que además son cada mucho, bueno, ahora que lo pienso, si vas a recibir DMX las necesitas ¿no?

¡oye! He puesto instrucciones y quería decir interrupciones. Es un caso en el que las interrupciones vendrían bien.


Mucha suerte con los exámenes

Josefe17
29/05/2015, 00:36
Ya dije yo que no era muy coherente :scratch:

Ya, lo mas seguro es que se haga así.

Josefe17
29/05/2015, 00:53
Esto es lo que tengo de momento y que estoy a la espera de probar, partiendo del código que encontré en Micropic.

Es el del relé DMX. Lo de la USART es del autor del código y el main modificado por mi. Tenía que haberlo pasado antes.




/************************************************************************
* Receptor DMX con PIC 18F2550 *
* El emisor debe tener unos parámetros mínimos de: *
* - DMX Sending Rate 20ms *
* - Data Present 210 *
* - Start/clock 210 *
* *
* Mis agradecimientos a Mark por su código libre para recepción DMX *
* en el que se ha inspirado el núcleo de este programa. *
* *
* www.micropic.es Nocturno - 2007 *
************************************************************************/

/************************************************************************
* Configuración micro *
************************************************************************/
#include <18F2550.h>
#device adc=8

#FUSES NOWDT //No Watch Dog Timer
// #FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT //Code not protected from reading
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV43 //Brownout reset at 4.3V
#FUSES PUT //Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES NOPBADEN //PORTB pins are configured as digital I/O input channels on RESET
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES NOMCLR //Master Clear pin disabled
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PLL1 //No PLL PreScaler

#use delay(clock=8000000, RESTART_WDT)

#byte PORTA= 0xF80
#byte PORTB= 0xF81
#byte PORTC= 0xF82
#byte PORTE= 0xF84


/************************************************************************
* Registros USART *
************************************************************************/

#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

/************************************************************************
* Pinout *
************************************************************************/

#bit Relay0= PORTB.0 // Salida a relés
#bit Relay1= PORTB.1
#bit Relay2= PORTB.2
#bit Relay3= PORTB.3
#bit Relay4= PORTB.4
#bit Relay5= PORTB.5
#bit Relay6= PORTB.6
#bit Relay7= PORTB.7

#byte Relays= PORTB

#bit Dip1= PORTA.6 //Entrada DIP
#bit Dip2= PORTA.5
#bit Dip4= PORTA.4
#bit Dip8= PORTA.3
#bit Dip16= PORTA.2
#bit Dip32= PORTA.1
#bit Dip64= PORTA.0
#bit Dip128= PORTC.1
#bit Dip256= PORTC.0


#bit DMXRX= PORTC.7 // Entrada RX desde el 75176


/************************************************************************
* 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 *
************************************************************************/

char CONST SEGM[36]= { // Esta variable tiene la representación gráfica de cada dígito en 7-seg
// 0 1 2 3 4 5 6 7 8 9
/* Números */ 63,6,91,79,102,109,125,7,127,111,
// A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
/* LETRAS */ 119,124,57,94,121,113,125,118,6,30,118,56,84,84,63,115,103,80,109,120,62,28,28,119,110,91};



int16 direccion0;


int8 DMX_Estado = DMX_ESPERA_BREAK; // Estado de la máquina de estados
int8 DatoRX; // Dato genérico recibido en USART
int16 DMX_Indice = 0; // Apuntador a una posición de la trama DMX


#define TotalCanales 512 // Total canales a almacenar
#define NumeroCanales 8 // Canales a usar
int8 TramaDMX[TotalCanales]; // Trama completa de valores DMX



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;




int LeeInt(){
int16 number;

number=0;
if(Dip1) number+=1;
if(Dip2) number+=2;
if(Dip4) number+=4;
if(Dip8) number+=8;
if(Dip16) number+=16;
if(Dip32) number+=32;
if(Dip64) number+=64;
if(Dip128) number+=128;
if(Dip256) number+=256;

return (number);
}


/************************************************************************
* 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. *
************************************************************************/

#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;
}

//No se usa

int16 pow(int16 base, int16 exp){
if(exp==0) return 1;
int16 index;

for(index=0; index<exp; index++){
base*=base;
}
return base;
}



void main()
{

int8 DMX_Subindice;
int8 RelesDMX[NumeroCanales]; // Canales a usar

// Configuración de Entradas / Salidas

// Puerto A: del 0 al 6 entradas de los DIP
set_tris_a(0b01111111);

// Puerto B: Todo salidas a los relés.
set_tris_b(0x0);

// Puerto C: Entradas 0 y 1 del DIP. Resto salida. El pin RX de la usart se pone
// como entrada al configurar la USART.
set_tris_c(3);

// Puerto E: solo tiene un pin (E3) y se usa como entrada de los DIP
set_tris_e(0x08);

// Configuración del micro:
// - oscilador interno a 8 MHz
// - entradas analógicas desactivadas y Vref desactivada
// - CCP1 activo para PWM
// - comparador desactivado
// - Timer0: interno, con prescaler 64 y a 8 bits
// - Timer1, 2 y 3: desactivados
// - Watchdog activado
// - Sin detección de bajo voltaje

setup_oscillator(OSC_8MHZ|OSC_INTRC|OSC_31250|OSC_PLL_OFF);
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);
//setup_ccp1(CCP_PWM);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64|RTCC_8_bit);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,1,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
// setup_wdt(WDT_ON);
setup_low_volt_detect(FALSE);

// Configuración de la USART
BRGH=1; // Alta velocidad seleccionada.
BRG16=1; // Baudrate de 16 bits
SYNC=0; // Seleccionamos transmisión asíncrona
SPBRG=7; // A 8MHz representa Baudios = 250KHz
SPBRGH=0;
RX9=1; // Activada la recepción a 9 bits
SREN=0; // Desactivada la recepción de un sólo byte
ADDEN=0; // Desactivada la autodetección de dirección
FERR=0; // No hay error de frame
OERR=0; // No hay error de overrun
SPEN=1; // USART activada
CREN=1; // Recepción activada

// Activamos las interrupciones de recepción de la USART y del Timer0 (displays)
enable_interrupts(INT_RDA);
//enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);


Relays=0x0;


while(1) {
direccion0=leeInt();

for(DMX_Subindice=0; DMX_Subindice<NumeroCanales; DMX_Subindice++){
if((direccion0+DMX_Subindice)<TotalCanales){
RelesDMX[DMX_Subindice]=TramaDMX[DMX_Subindice+direccion0];
}
else RelesDMX[DMX_Subindice]=0;
}


//////////////////////////////////////////////////////////
if(Dip16)
RelesDMX[3]=140;
else RelesDMX[3]=120;
////////////////////////////////////////////////////////////

/*
//0
if(RelesDMX[0]>=140){
Relay0=1;
}

if( RelesDMX[0]<=120){
Relay0=0;
}

//1

if(RelesDMX[1]>=140){
Relay1=1;
}

if( RelesDMX[1]<=120){
Relay1=0;
}

//2
if(RelesDMX[2]>=140){
Relay2=1;
}

if( RelesDMX[2]<=120){
Relay2=0;
}
//3
if(RelesDMX[3]>=140){
Relay3=1;
}

if( RelesDMX[3]<=120){
Relay3=0;
}

//4
if(RelesDMX[4]>=140){
Relay4=1;
}
if( RelesDMX[4]<=120){
Relay4=0;
}

//5
if( RelesDMX[5]>=140){
Relay5=1;
}

if( RelesDMX[5]<=120){
Relay5=0;
}
//6

if( RelesDMX[6]>=140){
Relay6=1;
}

if( RelesDMX[6]<=120){
Relay6=0;
}
//7
if( RelesDMX[7]>=140){
Relay7=1;
}

if( RelesDMX[7]<=120){
Relay7=0;
}*/


//También quiero desactivar un pin de pwm en todos los lados que haya que desactivarlo, de momento no quiero pwm...


for(DMX_Subindice=0; DMX_Subindice<NumeroCanales; DMX_Subindice++){
if(RelesDMX[DMX_Subindice]>=140){
bit_set(Relays, DMX_Subindice);
}
else if(RelesDMX[DMX_Subindice]<=120){
bit_clear(Relays, DMX_Subindice);
}


}



};
}


Desde luego he de limpiarlo si funciona.

Aunolose
29/05/2015, 12:47
Sin mirarlo a fondo, parece que puede funcionar. Y no lo parece, pero la interrupción serie hace lo mismo que la otra de ensamblador, aunque muchísimo más claro, eso sí, pues "llama a las cosas por su nombre", me refiero a los estados. Observa que en cuanto algo va mal, desecha la trama entera, lo que hablábamos de que la velocidad de refresco del DMX no es crítica, ya vendrá otra trama.

¿Está hecho con CCS C? me suena lo de poner #int_rda al principio de la rutina.

Josefe17
29/05/2015, 16:36
Sí, CCS C, que me costó lo suyo encontrar el compilador.

Aunolose
29/05/2015, 17:00
En el tema de los relés tienes código ineficiente.

Por ejemplo


if( RelesDMX[7]>=140){
Relay7=1;
}

if( RelesDMX[7]<=120){
Relay7=0;
}


Eso se puede mejorar así.


if( RelesDMX[7]>=140){
Relay7=1;
}

else

if( RelesDMX[7]<=120) {
Relay7=0;
}



de esta manera, si RelesDMX[7] es >= de 140, ya no hace ninguna comparación más. En estos casos estaría bien saber cual de las dos se da con más frecuencia, si es que se puede saber y si es que hay una que predomine más que la otra, en ese caso, es mejor ponerla primero, así solo se ejecuta una comparación la mayoría de las veces y el código resultante es más rápido en general.

Josefe17
29/05/2015, 17:23
Me gusta esa. Lo hice así por mi odio a los else if, que no me aclaro con ellos (o al menos no me compilaba en navidades una cosa de VHDL y lo dejé por eso). Desde luego no está limpiado a expensas de que funcione (y el programador no llega, putos chinos. Ebay está tardando ahora 4 semanas en que las cosas lleguen :triste:).

Aunque esa parte está comentada y la que uso es un bucle for, ya que no sabia como hacer referencia con el indice del for al puerto en cuestion a encender apagar. Sí, es menos eficiente (o no, no lo sé realmente), pero como aqui no me es clave lo quise hacer con un for por gusto:


for(DMX_Subindice=0; DMX_Subindice<NumeroCanales; DMX_Subindice++){
if(RelesDMX[DMX_Subindice]>=140){
bit_set(Relays, DMX_Subindice);
}
else if(RelesDMX[DMX_Subindice]<=120){
bit_clear(Relays, DMX_Subindice);
}


}

Ahora que lo veo, aquí si que tengo puesto el else if. Y ahora que lo pienso, como on y off son equiprobables, si tuviese que poner una delante pondría el apagado, por eso de la seguridad del sistema (si estoy manejando un telon, ante un error a mitad del if prefiero que se pare a que se siga moviendo). Es un poco chorra el criterio, pero alguno ha de haber.
Una pregunta, este código actualiza el estado del canal en cada pasada, ¿esto ocasionaría un parpadeo en cada iteracion (microencendido o microapagado por la actualizacion)?

Aunolose
29/05/2015, 17:42
Me gusta esa. Lo hice así por mi odio a los else if, que no me aclaro con ellos (o al menos no me compilaba en navidades una cosa de VHDL y lo dejé por eso). Desde luego no está limpiado a expensas de que funcione (y el programador no llega, putos chinos. Ebay está tardando ahora 4 semanas en que las cosas lleguen :triste:).

Aunque esa parte está comentada y la que uso es un bucle for, ya que no sabia como hacer referencia con el indice del for al puerto en cuestion a encender apagar. Sí, es menos eficiente (o no, no lo sé realmente), pero como aqui no me es clave lo quise hacer con un for por gusto:


for(DMX_Subindice=0; DMX_Subindice<NumeroCanales; DMX_Subindice++){
if(RelesDMX[DMX_Subindice]>=140){
bit_set(Relays, DMX_Subindice);
}
else if(RelesDMX[DMX_Subindice]<=120){
bit_clear(Relays, DMX_Subindice);
}


}

Ahora que lo veo, aquí si que tengo puesto el else if. Y ahora que lo pienso, como on y off son equiprobables, si tuviese que poner una delante pondría el apagado, por eso de la seguridad del sistema (si estoy manejando un telon, ante un error a mitad del if prefiero que se pare a que se siga moviendo). Es un poco chorra el criterio, pero alguno ha de haber.
Una pregunta, este código actualiza el estado del canal en cada pasada, ¿esto ocasionaría un parpadeo en cada iteracion (microencendido o microapagado por la actualizacion)?

No creo que genere parpadeo, si el dato no cambia.

Lo de los else if, depende del compilador, cuando tengas problemas: pon llaves, el MCC18 de Microchip tiene ese problema. Además, ten en cuenta que en todos los compiladores, si pones else if, ese else solo tiene una instrucción: el if, y ninguna más, esto puede hacer que pongas alguna instrucción detrás pensando que está dentro, y no está dentro.



if (loquesea) then
{
tarari;
}
else { // Atención a este corchete
if (otra cosa) then
{
niananiana;
}

else { // y este otro.
if (la tercera) then
{
la ultima;
} // acaba este if
} // acaba el segundo else
} // acaba el tercer else



// Atención a este caso,

if (condicion) then
haz algo // una sola instrucción, no hace falta corchetes y NO se pone punto y coma
else if (otra condicion) then
haz otra cosa // una instrucción, no hace falta corchetes y NO se pone punto y coma
else if (la ultima) then
ultima instruccion; // está SÍ que lleva punto y coma, aunque no pongas corchetes

// la última instrucción cierra todo el if,


// Otro caso
if (condicion) then
haz algo // una sola instrucción, no hace falta corchetes y NO se pone punto y coma
else { // pongo corchete
if (otra condicion) then
haz otra cosa // una instrucción, no hace falta corchetes y NO se pone punto y coma
else if (la ultima) then
ultima instruccion; // está SÍ que lleva punto y coma aunque no pongas corchetes
} //este corchete cierra el anterior, pero no lo parece,

Josefe17
07/06/2015, 01:20
Traigo buenas noticias de la mano de la electrónica analógica. He conseguido diseñar e implementar un filtro pasobajo con frecuencia de corte a 3 dB de 25 Hz y de 51 dB a 200 Hz, cumpliendo mis espectativas del PWM para obtener mi señal analógica. El filtro es un filtro de Butterworth de orden 3 implementado con un pasobajo RC en cascada con una celda activa de Sallen-Key. Con esto cumplo mis especificaciones y la respuesta del dimmer es buena.
Me he tirado toda la tarde montandolo en un PCB universal y este es el resultado. Queda probarlo.
131646

Aunolose
07/06/2015, 10:58
No has escrito para que te lo digamos pero... ¿has estudiado para los exámenes?... :rolleyes: :D que uno se pone con esto y se olvida del mundo...

Josefe17
07/06/2015, 11:10
Tenia unas horitas ayer (y la muela del juicio dando por saco).

Josefe17
23/06/2015, 01:23
¿Dos semanas ya de la última respuesta? Madre mía... Pues eso, que examenes--, aprobados+=2 y DMX++.
En primer lugar me he hecho una interfaz DMX casera para el FreeStyler, con un FTDI, un 75176 y una caja de aluminio. Queda DPM. Luego he montado el PWM en otra caja y también DPM, con conectores DIN y XLR. Finalmente estuvo mi amigo por los madriles, se trajo el pickit y hemos grabado en un 2550 el código este del relé DMX. Tenía un bug gordo, y es que no leía las direcciones 256-512. Era porque la funcion de leer Dip tenía el retorno forzado a int[8] y claro, el 9º bit nada de nada. Ahora va dpm. Y cuando examenes=0 lo montaré en una caja y lo acabaré. También me dejó grabado el sw de un Pickit2, porque el que compré no llega y acabaré haciéndome uno.

Aunolose
23/06/2015, 15:57
Venga, ánimo que ya queda poco.

Josefe17
26/06/2015, 18:52
https://youtu.be/7812dngARbk

Pues eso, que álgebra done. Puedo aprobar o suspender, ahí está. Y hasta septiembre nada.

Tema DMX. Nos hemos metido en el fregado de hacer un dimmer DMX. La idea de código: basicamente una interrupción debido al cruce por cero tal que pone los triacs a cero y reinicia el temporizador. Luego está la USART que lee el DMX y finalmente el main que coge los canales DMX asignados por los DIP y para esos canales lee en una tabla (array) si el tiempo calculado para el valor DMX presente en el canal es mayor que el temporizador. Si lo es activa la salida hasta el siguiente cruce por cero.

No se si así valdría, teniendo en cuenta todo lo que hay que tener.

Aunolose
27/06/2015, 10:00
He tardado en responder por que quería enterarme con calma. Ahora el wifi hace cosas raras y me toca hacerlo desde el movil...

¿El dimmer es de un canal o de tres?
A priori la idea es buena, si la he entendido bien. Vas a hacer que el temporizador interrumpa 256 veces entre dos pasos por cero, y cada vez compararás los valores y actuarás en consecuencia ¿es eso? Si tienes tiempo de computación para hacerlo, perfecto. Para evitar parpadeos tendrás que dar a ese temporizador más prioridad que a la interrupción serie. Si la interrupción serie interrumpe justo cuando estás poniendo a uno o cero la salida, ese uno o cero durará más de lo que tenía que durar.
Además no puedes cambiar el valor del dato hasta el siguiente paso por cero, aunque lo recibas, si lo haces, puede pasar que el valor anterior sea 100, al llegar a 101 apagas, pero antes de llegar al 0 de nuevo recibes el 200, y lo vuelves a encender, generando parpadeos. Esto me hace pensar que necesitas o bien dos arrays uno para recibir y el otro para procesar o no hacer caso a lo que recibas hasta el siguiente paso por cero. En las rutinas que puse antes se utiliza el último modo, así no hay tanto que tratar. Es el bit "Entratamiento, "tratando" o algo así, si estuviera en el PC lo buscaba :(

Si no te aclarad con lo que digo, dímelo y lo intento explicar de otro modo.

Aunolose
27/06/2015, 10:02
Por cierto, pon optoacopladores que incluyan lo del paso por cero, cuestan lo mismo y te ahorra muchos problemas, incluso disimula algunos fallos de programación.

Josefe17
27/06/2015, 10:32
El problema es que tiramos a lo grande: 12 Canales (yo no pago) y una fase. Sé las limitaciones de potencia pero ese no es el propósito.
Respecto al código no es exactamente así como lo has dicho. Tu planteas 3 tipos de interrupciones: USART, cruce por cero y temporizador, y que el temporizador interrumpa un número determinado de veces (256, que no han de ser por los 256 niveles, o incluso más) y que en cada instante compruebe para cada canal DMX el valor DMX presente y si es mayor o menor que el seteado para cada instante de tiempo en la tabla encienda o apague el opto, aparte de la subrutina de copiado del array. Yo lo planteaba de otra forma: en vez de ser el temporizador el que interrumpa, que sea el main quien vaya pooleando todos los canales DMX ya copiados y filtrados según la dirección (la USART recibe todo, pero sólo se copian los 12 canales posteriores a la dirección fijada por el DIPSW) y para cada uno de ellos que consulte el temporizador global (acceda a su cuenta), y según el valor dmx del canal acceda a una tabla de tiempos y active o no la salida if(cuenta>=tabla_mapping[canales_DMX[1]]) triac1=1; Luego sería la interrupción de cruce por cero la que apagaría todas las salidas y reiniciaría el temporizador, así como veo conveniente que también se encarge de la subrutina de copiar del array de la USART los canales a usar según la dirección. No se si esto sería factible o no como lo planteo (he investigado y acceder a la cuenta del contador requiere de structs y cosas así, sobre todo porque necesitaría 16 bits), si no siempre quedará la opción inversa, que sea el temporizador quien compruebe los valores. En cualquier caso me has dejado claras 2 cosas que me eran importantes y dudaba: la prioridad de la interrupción de cruce por cero debe ser mayor que la de la USART y que han de copiarse los valores de los canales del array de la USART para evitar parpadeos.

Y una cosa, si pongo optos de cruce por cero me quedo sin dimmer (solo encienden en los pasos por cero y lo que quiero es controlar ese punto de disparo).

Aunolose
27/06/2015, 11:16
Eso es lo que yo dudaba, que a 4Mhz tuvieras tiempo de hacerlo todo.
Pero algunos detalles. No me extiendo que me están esperando.
Para un foco 256 niveles son hasta demasiados, pero es que, suponiendo que necesites más niveles, necesitas otro byte DMX, eso convierte los 12 canales en 24, salvo apaños raros de compartir un byte para dos de 12 bits.

La interrupción menos importante es la de recepción DMX, por que no importa que te saltes datos, llegarán nuevos. Es más importante que el valor "108" tenga siempre la misma distancia para evitar parpadeos, además de empezar y acabar en el mismo momento del ciclo para que la tensión eficaz sea la misma, por eso temporizador (o bucle) y paso por cero deben ir sincronizados y a eso ayudan los optos, pero eso lo puedes comprobar fácilmente cambiando uno por otro. Para evitar ruidos en la red, incluso hacer que la lámpara dure más, la conmutación debería hacerse cuando la tensión sea cero, eso solo lo asegura el opto que lo tenga, pero ya digo que es fácil de comprobar.

Que haya tres interrupciones no es tan complicado, lo importante es decidir la prioridad, y cuando acabe una se tratará la otra o la prioritaria interrumpirá a la que no lo es. Hacer estas cosas con bucles en main es delicado precisamente por que cualquier interrupción puede hacer que un bit dure más de lo que tocaba, o eso, o inhibes todas las interrupciones dentro del bucle, que se puede hacer. Creo que es lo que hago en el anterior.

Josefe17
27/06/2015, 11:44
¿Exactamente que hace un opto con cruce por cero? Yo entiendo que si la tensión de la red pasa por cero en pi y 2*pi y vas y tu atacas el optotriac en pi/2, por ejemplo, de tal modo que el optotriac y el triac se enciendan desde pi/2 hasta que el triac corte en pi. Si usas un optotriac con cruce por cero te retrasa el disparo hasta que la tensión llegue a 0, o sea te lo retrasa el encendido desde pi/2 a pi. De este modo activas la carga siempre en multiplos de k*pi, encenderías siempre en k*pi hasta (k+1)*pi. Sin embargo con esto te cargas la regulación, ya que al encender siempre en k*pi hasta (k+1)*pi no eres capaz de controlar la fase, y por ende el valor rms, que es en lo que se basa el control del dimmer. Por eso yo tenía entendido que opto de cruce por cero sólo para conmutación on-off (luego pudes hacer dimmerización controlando el número de semiciclos ENTEROS que enciendes, pero ya no es tan habitual). A lo mejor me equivoco pero es lo que creo.

Aunolose
28/06/2015, 11:40
Piénsalo de esta manera. Tu quieres activar el triac durante 3ms, si lo activas justo en el paso por cero, la lámpara (si eso lo que estás controlando) se encenderá muy poco, pero si los activas justo en medio, cuando la tensión está más alta, se encenderá mucho más, aunque sigan siendo 3ms. Es importante que la activación sean siempre en el mismo momento. Por eso se sincroniza con lo más fácil, el paso por cero.
También es por el ruido eléctrico generado, si activas el foco justo en cero, no metes tanto ruido, el de desactivación lo vas a tener siempre, hagas como lo hagas. Solo el triac de paso por cero te lo asegura, por que si lo haces a través de la interrupción, cuando quieras activarlo la tensión ya no está en cero, será poco, pero no cero.

Lo mejor es que lo compruebes tú mismo, cuestan lo mismo y si la programación está bien hecha, desde fuera, no se va a notar la diferencia.




Esto ya son recuerdos y puedo estar equivocado, pero me suena algún control "analógico", un "seguidor de ritmo" las luces que se encienden al ritmo de la música, sin sincronización ni leches, que funcionaba bien, gracias a esos optos.

Josefe17
28/06/2015, 12:03
El problema es que el triac es un tiristor y solo se apaga cuando la corriente a través de el es cero, tension cero para cargas resistivas, de tal modo que solo puedes controlar el instante de encendido, el de apagado te lo marca el triac, por eso no te vale el de cruce por cero, porque tu aunque quites la tension de puerta no se apaga el triac hasta que la tension llegue a cero, por eso si disparas en cero, hasta que la tension no vuelva a cero el triac no se apaga.

Aunolose
28/06/2015, 12:06
Tirando otra vez de recuerdos. Ya sé por qué funcionaba sin sincronización. El circuito funciona rectificando y filtrando la señal de audio, esto nos da una tensión continua que depende del nivel de esa señal. Y ya está. Si aplicas esta señal continua directamente al led del optoacoplador (adaptando niveles máximos, claro) ya tienes una lámpara que se enciende al ritmo de la música, los pasajes más altos, con más luz, música bajita, menos luz. Pero solo funciona bien si es con un opto de paso por cero, por que por muy grande que sea la señal, empieza a conducir en 0, y se corta cuando la señal (la continua sacada del filtro) no es suficiente para activar el led.

Seguro que hay algún esquema por la red.

Aunolose
28/06/2015, 12:13
Te colaste mientras escribía y buscaba el esquema, que no he encontrado.

Si no ten convenzo, no pasa nada deja eso para el final, a lo mejor no es tan crítico.

Josefe17
06/07/2015, 10:38
Ya tenemos el codigo funcionando para 12 ch. El sistema va a 48 Mhz y regula de maravilla. Al final hemos hecho la idea que planteas de dividir los 10 ms en 256 ranuras y con un temporizador contar 39 uS (10 ms/256) y al interrumpirse comprobar que canales hay que disparar porque ya toque y ranuras++. Por otro lado está el cruce por cero, que reinicia el contador de ranuras y apaga los triacs, así como copia la trama de la usart y la pasa por el mapping lineal (hemos conseguido que la potencia media sea lineal al DMX gracias a Matlab®). Además creo que le pondremos analógico con el ADC (6 entradas sólo con mapping doble) Cuando esté debuggeado te lo paso. Además convertirlo en un pwm para DAC sería fácil (apagar salidas en ranura 255 quitando el cruce por cero y subir la frecuencia de pwm todo lo que se pueda)

Aunolose
06/07/2015, 18:36
A 48Mhz se pueden hacer 12 veces más cosas que a 4Mhz :D

¿al final en C?

Josefe17
06/07/2015, 22:23
Si, en C. ASM es mucho lio para un par de novatos.

Aunolose
07/07/2015, 11:28
¿Para que el ADC? ¿para hacer un fadder? (¿se decía así? :scratch: )

Josefe17
07/07/2015, 11:36
Mas menos. Para meter señal analógica 0-10V. Y creo que es fader ("feider"), sin doblar la d (deriva de fade).

Aunolose
07/07/2015, 19:34
¿Y por qué solo 6 si son 12? ¿habrá un interruptor para seleccionar que 6 se mueven?

Josefe17
07/07/2015, 19:46
Por falta de pines. No, el adc1 maneja canales 1 y 6, adc2 2 y 7 y así.

Aunolose
07/07/2015, 20:15
Si os faltan pines para hacer 12 y solo podéis hacer 6, hacedlo pofesional y con interruptor seleccionáis "los 6 primeros" o "los 6 siguientes", y así controláis los 12 canales, de 6 en 6, pero bueno, menos es na'.

Josefe17
07/07/2015, 20:21
Otra opción sería multiplexar con los pines del selector de direcciones, ya que no se usa en modo analógico, pero eso nos implicaría rehacer pinout, y para lo que queremos nos sobra así. Todo sería pensarlo.

Aunolose
08/07/2015, 12:23
Cuando tienes sitio, poner 12 potenciómetros lineales no son problema, pero si te falta, pues solo 6. El micro podría tener un único convertidor AD y un multiplexor, de hecho, eso es lo que tienen internamente la mayoría, a lo mejor tienes 12 entradas analógicas, pero dentro tienes un solo convertidor y tienes que ir seleccionando que pata quieres convertir. Decía, da igual los DA que tengas, si tienes 6 patas "analógicas", puedes poner ahí los 6 potenciómetros, y en una 7ª pata digital, si lo pones a "cero", los potenciómetros cambian los primeros 6 canales, si lo pones a "uno", los potenciómetros cambian los 6 últimos. Sin necesidad de multiplexores externos ni de poner 12 potenciómetros, que está bien, pero que rara vez vas a controlar simultaneamente.

Para los casos de controlarlos simultaneamente, puedes dedicar uno de ellos para hacerlo, con otro pin (digital) seleccionas esa función y entonces todos los canales obedecen a ese, o poner 7 potenciómetros para tenerlo claro, y multiplexar solo dos de ellos, en combinación con ese pin digital. Hay un montón de opciones. Las mesas profesionales suelen tener ese control de "ahora todos a la vez" o también para limitar el máximo, lo que marque ese, es la máxima salida de todos, da igual donde estén. Lo dicho, un montón de opciones.

Josefe17
09/07/2015, 17:12
Es que más que potes es una entrada 0-10V externa, por lo que eso es lo que tengo. Por eso había pensado lo de los 6 canales, pero dejando el ICSP el firmware se puede actualizar. Y si no 4066 y multiplexado externo.

Aunolose
10/07/2015, 00:48
¿Conoces el 4051? en un solo chip tienes un selector analógico de 8 canales en un solo chip, y al hacer la búsqueda para confirmarlo he visto que hay código para Arduino.

Josefe17
10/07/2015, 01:39
Yo creo que te mereces una foto de mi cacharrada:133202

En primer término una mesa dimmer de 4ch a la que le he acoplado un módulo de entrada-salida analógico a 0-10V (permite excitar la etapa de dimmer externamente y sacar la señal de la mesa en formato 0-10V). Tras ella mi dimmer 0-10V y encima un switch-pack analógico de 3 canales. Luego está ese trasto blanco tan inseparable estos dias. Al fondo la caja gris es el relé dmx (8 ch dmx que adaptan protocolos analógicos varios a dmx, entre ellos el switch pack y la máquina de humo), y la negra de encima es un convertidor PWM de dmx a analógico 0-10V (para excitar los dimmers). No se ve pero falta el interfaz dmx-usb. Y por fin acabé (por ahora).

Respecto al conmutador, preferiria usar el 4066, porque el 4051 es un multiplexor (selector de 8 a 1) y el 4066 interruptor (4 interruptores o 2 selectores de 2 a 1, conmutadores vamos), ya que he de multiplexar 12 canales a 6 pines (2 a 1), aunque creo que al final se hará modular de 6 ch/MCU y problema fuera.

Josefe17
10/07/2015, 01:55
Acabo de ver que el 4053 es triple multiplexor de 2 entradas. Pues me quedo con ese.

Aunolose
10/07/2015, 09:07
Joer. de verdad que va a ser el calor, en algún momento he vuelto a entender que solo tenías un canal AD en el micro, y que por eso ponías los multiplexores...

Además no me acabo de aclarar :( ¿vas a poner 6 potenciómetros o 12? con los últimos mensajes entiendo que 12...

Edito: el trasto blanco inseparable estos días ¿es para la etapa de potencia o para el que no soporta el calor? :lol:

Josefe17
10/07/2015, 09:13
Potes como tal ninguno. Quiero un canal analógico 0-10V por canal. Si son 12 ch, pues necesito leer 12 entradas analógicas. La idea inicial es usar un solo micro y solo dispongo de 6 entradas de ADC, por lo que seria multiplexar 2 a 1 (4553). Finalmente a lo mejor se usa un micro por 6 ch y el problema desapareceria (ADC por canal).

Aunolose
10/07/2015, 10:25
Vaaale, creo que lo voy pillando. En alguna parte tienes una mesa 0-10V de 12 canales y quieres pasarlo a DMX ¿es eso?

En el otro extremo del DMX tendrás el dimmer que ya has construido y que es lo que quieres controlar ¿voy bien?

Es que yo estaba todo el rato con que seguías con el dimmer y no le veía ni pies ni cabeza...

Josefe17
10/07/2015, 10:40
Si pero sin pasar por DMX. O sea el dimmer que pueda ser operado por DMX (el valor del canal sea el que reciba de la USART) o por analógico (el valor del canal sea el que lea el ADC de la entrada 0-10V integrada en el propio dimmer y que viene de la mesa). Con este valor actuará sobre el tiempo de disparo. Y ahí es donde entraba el problema de multiplexar las entradas del ADC.

Vaya películas me monto...

Aunolose
10/07/2015, 15:56
Bueno, ya me voy enterando, estaba equivocado a medias :D

Josefe17
16/10/2015, 20:18
Acabo de entender lo de los rebotes del dmx y el por qué del terminador. Mejor que rebotes llamémoslo onda reflejada en una línea de transmisión metálica cuya respuesta es un sistema diferencial de segundo orden en t y x que no he tenido el placer de despejar (menos mal), que produce una tensión incidente y otra reflejada, que si no es cero malo. Este cero se consigue haciendo que Zo=ZL, vamos, la impedancia característica de la línea igual a la de carga.

¡Como mola aplicar lo que aprendes en la uni a tus inventos! Aunque si el año pasado hubiese dado Campos lo sabría.
Ahora estoy con ASM también.

Aunolose
17/10/2015, 12:27
Ahora explícale eso de los polos y los ceros a tu abuela, a ver que dice... :partiendo: se entiende mejor con el símil de la ola...

Josefe17
17/10/2015, 12:29
Pues los polos los mete al congelador y por los ceros me echa la bronca.