PLC USB






Este es un circuito que se desarrolla en función a varios proyectos del site, primero el PLC - uPLCCS - PIC el cual detalla un PLC de programación ICSP (donde uno debe contar con su programador propio), pero este proyecto muestra que se puede programar tanto en ASM, como C, como LADDER, gracias a un IDE para LADDER llamado LDmicro que se encuentra disponible de forma gratuita en la Web de su autor (http://cq.cx/ladder.pl) también van a encontrar los tutoriales, también es posible programar en C con el compilador que deseen (para Microchip), o bien el viejo conocido ASM.
Otro proyecto que se amalgama con este nuevo PLC USB es el transceptor USB/UART, el cual podemos encontrar en el blog como Conversor USB UART TTL, este en base al transceptor MCP2200 cumple la función de crear un puerto serial virtual vía la conexión USB, el cual con sus drivers (proporcionados gratuitamente por Microchip), encontraremos en nuestro administrador de dispositivos del OS, un nuevo puerto Serial. 
Como la mayoría de los microcontroladores que utilizan programación en circuito requieren una señal serial de dos hilos por ejemplo el Clock y el Data, para la programación del mismo, también requieren de una tensión elevada para acceder al modo programación (actualmente existen microcontroladores que utilizan bajo voltaje para esta programación LVP), La mayoría de los microcontroladores utilizan de 10 a 13V para entrar en modo programación lo cual como sabrán excede nuestros 5V del USB, la solución de los programadores en circuito del tipo serial, es aprovechar la norma RS232 que establece unos +/-10V en su norma lo cual aprovechado y canalizado de forma tal provee de esa tensión de programación a los microcontroladores.
Hasta aquí seguimos igual, ya que no usaremos puerto Serial sino USB, aquí el problema de los transceptores comerciales, la mayoría (el 99%) poseen una salida serial a nivel TTL, es decir en 0 y 5V lo que no nos permite programar el microcontrolador ya que requerimos mas de 10V para ello, Claramente es posible realizar una pequeña fuente del tipo SMPS Step-Up para elevar esa tensión en el pin de grabación pero aquí tenemos otra solución tan antigua como la anterior.
Los llamados Bootloader, estos son Cargadores de Arranque cumplen la función de canalizar el programa que programamos en un sector preestablecido de la memoria interna sin necesidad de programar a nivel hardware (con el acceso a programación que mencionaba anteriormente con los 10 a 13V) sino que el programa se aloja mediante otros pines que no son los de programación Data y Clock, es decir.
El microcontrolador debe programarse a nivel hardware una sola vez, donde se grabara el Bootloader, una vez grabado este ya no se requiere grabar nuevamente el microcontrolador.
Esto posee pros y contras: 
Pros, es que es mas sencilla la programación, no se requiere de placas especiales de programación y facilita la transferencia del archivo. 
Contras, se requiere el microcontrolador con el Bootloader grabado previamente y este mismo consume una pequeña parte de la memoria del micro la cual se restara al programa que realicemos. 
En el caso del Bootloader también se puede descargar gratuitamente desde la Web de Microchip (debe ser el que soporta el microcontrolador que vamos a utilizar y también debe detallar el clock que utilizamos).
En el caso de este PLC se utiliza un PIC16F876A el cual cumple su función correctamente pero siempre se pueden utilizar otros diferentes, por razones de costos este viene bien, pero claramente hay otros con puerto USB embebido mediante HID lo cual nos ahorra el MCP2200.
El software debe ser cualquiera que envíe el archivo vía serie que el puerto serial será el virtual creado por el driver del MCP2200 mencionado anteriormente. 
En mi caso he desarrollado un programa cargador para este fin en lenguaje Delphi, pero pueden realizarlo ustedes en el lenguaje que quieran solamente tienen que tener en cuenta que la velocidad de transferencia serial es 9600bps, pero en realidad pueden usar cualquier cargador de Internet.
En la nota de aplicación 851 pueden encontrar una versión del Bootloader de Micrcochip. http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en012031

Especificaciones:

8 Entradas Digitales de 12/24V asiladas con opto-acoplador.

5 Entradas analógicas hasta 5V auto-reguladas.

4 Salidas a contacto de 12V a 250Vac 5A.

Puerto de alimentación de 12V con protección de cambio de polaridad.

Puerto USB, para la carga del programa y para comunicaciones seriales.

Botón de Reset, para reiniciar el sistema y para cargar el programa.

Microcontrolador a utilizar PIC16F876A

            Tipo de memoria de programa: Flash
            Memoria de programa: 14KB
            Velocidad del CPU: 5 MIPS
            Memoria RAM: 368 bytes
            Memoria EEPROM: 256 bytes
            ADC: 5 canales de 10bit de resolución
            Temperatura de trabajo: -40 a 125°C

A continuación se detalla el hardware como también su PCB.

 

 




Ventilador USB

Observando que cada vez mas gente compra ventiladores para la PC, se me ocurrió hacer uno casero de bajo costo.
El circuito que utilice para alimentar este ventilador es una fuente elevadora de tensión en modo switch "SMPS", del tipo StepUp, esto quiere decir que la fuente eleva tensión. En nuestro caso la tensión a elevar sera la que proviene del puerto USB de la PC, que como sabrán es de 5V, la corriente máxima de salida del puerto es de 500mA lo que nos dará unos 2,5W de potencia. Que al pasar por nuestra fuente que posee un rendimiento del 80%, la potencia de salida sera de 2W, pero con una tensión elevada a 12V lo que nos dará una corriente de salida de 170mA máximo.
Lo que nos dice esta corriente máxima en 12V es que tenemos que usar un FAN de máximo 170mA, en mi caso utilice uno de 100mA el cual mantiene por debajo el consumo y el circuito no calienta.

De todas formas el resultado obtenido (el viento) es muy superior al que entregan los ventiladores para PC comprados que he probado. Lo cual me deja mas que satisfecho con este desarrollo.
La próxima mejora de este sera incorporarle una fuente ininterrumpida "UPS" para que el ventilador funcione tras un corte de luz y sea una pequeña solución en el verano.

Review y Modificación de AndroidTV MK808B



Review:

En la caja encontramos el AndroidTV, un cable miniHDMI a HDMI de 20cm, un cable USB OTG de 10cm, una fuente de 5V 2A con su cable.

Con estos accesorios es posible conectar el AndroidTV si necesidad de ninguna otra cosa.
Para controlarlo en mi caso utilice un Mouse Inalámbrico pero podría se cualquier otro dispositivo de entrada.

A primera vista el OS dice que es versión 4.2.2, pero habrá que instalarle alguna aplicación como para saber si es real o es una máscara de marketing…

Claramente como todo lo que no es oficial de Google, el OS tiene un Theme propietario que intenta tener ser similar a un escritorio multimedia de un SmartTV, cosa que le cambie rápidamente por el SmartLauncher que es mucho más sencillo y consume menos recursos.

Las conexiones físicas: USB, USB HOTS, HDMI, USB SUPPLY, miniSD.

Las conexiones Inalámbricas: WiFi, Bluetooth.


Si vemos en la foto tenemos un detalle de las características del dispositivo.

Déjenme hacer una mención de esto, como pueden ver dice que la temperatura en el entorno no debe ser mayor a 35°C, este dato es clave ya que el dispositivo calienta muchísimo, lo cual reduce el rendimiento del mismo y la vida útil. (Medición de temperatura antes de la modificación 55°C, Después de la modificación 25°C)

Otro tema es la conexión WiFi, con la antena microstrip que trae de fabrica obtuve un 15% de la señal lo cual me permite algunas cosas pero el streaming de video se ve comprometido (que es para lo que más me interesa este dispositivo). (Nivel de señal después de la modificación 80%)

Analizando estos dos puntos a mejorar, les mostrare mi modificación.

Modificación:

1) Desarmamos el dispositivo que se encuentra cerrado a presión:


2) Al abrir la carcasa encontramos la siguiente placa:


Aquí vemos el disipador de pequeñas dimensiones que posee, el cual ayuda al incremento de temperatura que les menciono.

3) Modificación del disipador de calor, para esto hay que retirar el mismo el cual debe hacerse con mucho cuidado ya que corremos riesgo de romper el microprocesador, el mismo al no poseer tornillos de sujeción se encuentra pegado, se utiliza un pegamento conductor térmico como en las lámparas leds. Este se debe despegar con un destornillador de pala fino que se introduzca entre el disipador y el microprocesador. (no es tan complicado ya que los chinos ahorraron bastante y solo tenía una gota en el centro pero de todas formas hay que hacerlo con precaución).
Otra forma es llenar de grasa siliconada el disipador que ya trae y montar encima de este el nuevo. En mi caso utilice un disipador ZD5x50mm el cual pegue con pegamento conductor térmico para leds.


4) Ahora la mejora Wifi, para esto en mi caso desoldé la antena microstrip que posee de fábrica y soldé un conector SMA al cual luego conecte una antena TP-Link de 5dBi.


Como se puede ver en la parte inferior derecha se suelda el cable coaxial que conecta la antena con la placa. Son solo dos conexiones las que deberemos desoldar para luego soldar el conector de antena SMA que se ve a la derecha.

5) Una vez realizado el cambio del disipador y la antena, se monta todo el sistema en un gabinete plástico con respiración.


Como podemos ver la única conexión al gabinete es el conector SMA, el resto de las conexiones se realizan con su cableado directo para facilitar el montaje.


Display 7seg - Mensaje con Desplazamiento (Scroll)

Al igual que en la nota anterior http://electgpl.blogspot.com.ar/2013/11/matriz-8x8-mensaje-con-desplazamiento.html En este caso cambie la matriz de 8x8 por 8 displays de Cátodo Común, que en este caso ya se encuentran interconectados de forma matricial, pero se puede realizar con displays comunes interconectándolos.
El circuito es igual de simple que el comentado anteriormente de la matriz (Tener en cuenta el consumo de los leds, y las resistencias limitadoras que deben ir al menos en todo un puerto del microcontrolador).
En la simulación no son necesarias pero en la realidad si.
El programa es el mismo que el anterior pero en lugar de crear cada caracter con los puntos de la matriz, creamos cada caracter (limitado por el display) con un solo byte es posible crear un caracter.
Como podemos ver en el programa no hice todo el abecedario sino que algunas letras fltan y lo dejo a la imaginación de cada uno ya que hay letras que se complican para formar en un display de 7 segmentos.
Luego el otro cambio que podría decirse que es una pequeña mejora, es que le agregue la macro FRAMES que tiene el valor 50, esto lo que hace es poner 50 en todas las partes del programa donde aparezca FRAMES, al igual que la otra macro que se llama LARGO.
Los frames son la cantidad de veces que refresca la pantalla, pero si lo hace muchas veces, el movimiento sera mas lento, y si lo hace menos veces el movimiento sera mas veloz. No es exactamente como debería funcionar un Frame, pero esta ligado a la velocidad de desplazamiento, por ende en estos displays para que se pueda leer se le aumento la cantidad de frames, pero pueden variarla modificando ese numero.
El gif animado se ve relativa mente sincronizado aunque en la vida real se ve mucho mejor.



#include <16F883.h>
#use delay(int=4000000)
#define LARGO 28                      //Longitud de la tabla
#define FRAMES 50                     //Cant. de muestras (velocidad)
int const tabla[LARGO+16]={
                          0b00000000, //Espacio
                          0b00000000, //Espacio
                          0b00000000, //Espacio
                          0b00000000, //Espacio
                          0b00000000, //Espacio
                          0b00000000, //Espacio
                          0b00000000, //Espacio
                          0b00000000, //Espacio   
                          0b01110111, //Dato de tabla A
                          0b01111100, //Dato de tabla b
                          0b00111001, //Dato de tabla C
                          0b01011110, //Dato de tabla d
                          0b01111001, //Dato de tabla E
                          0b01110001, //Dato de tabla F
                          0b00111101, //Dato de tabla G
                          0b01110110, //Dato de tabla H
                          0b00000110, //Dato de tabla I
                          0b00011110, //Dato de tabla J
                          0b00111000, //Dato de tabla L
                          0b01010100, //Dato de tabla N
                          0b00111111, //Dato de tabla O
                          0b01110011, //Dato de tabla P
                          0b10111111, //Dato de tabla Q
                          0b00110011, //Dato de tabla R
                          0b01101101, //Dato de tabla S
                          0b00110001, //Dato de tabla T
                          0b00111110, //Dato de tabla U
                          0b01101110, //Dato de tabla Y
                          };
void main(){
   byte const bitMask[8]={1,2,4,8,16,32,64,128}; //Mascara
   int i,j,k;                         //Variables contadores
   while(TRUE){                       //Ciclo infinito
      for(i=0;i<LARGO+16;i++){        //Recorrido de tabla
         for(k=0;k<FRAMES;k++){       //Refresco de matriz
            for(j=0;j<8;j++){         //Barrido de columnas
               output_a(~bitMask[j]); //Columnas ponderadas
               output_b(tabla[j+i]);  //Desplazamiento de tabla
               delay_ms(1);           //Demora de multiplexado
            }  
         }
      }
   }  
}   




Amplificador de 3 transistores a 5V

Circuito simple y rápido para amplificar una señal de audio a 1/4W desde una alimentación de 5V.
El circuito es muy simple, se basa en una configuración PushPull clásica con un pre-amplificador de entrada.
Los transistores pueden ser reemplazados por cualquier otro de uso general (ECG123AP).





Matriz 8x8 - Mensaje con Desplazamiento (Scroll)

Una de las aplicaciones mas comunes cuando uno utiliza una matriz de leds, es escribir caracteres o mostrar mensajes desplazándose por ella de forma tal que se pueda leer fácilmente un mensaje.

Como en post anteriores se mostró que la forma de que se pueda presentar una imagen estática en la matriz es mediante la técnica de multiplexado, es decir como en una matriz de 8x8 tenemos 64 puntos los cuales claramente no podemos acceder individualmente porque seria muy poco practico y extremadamente lleno de conexiones, la técnica para este es la de controlarlo de forma matricial con solo 16 pines, es decir 8 para las filas y 8 para las columnas, de esta forma si se activa una fila y una columna se encenderá el punto donde estas hacen intersección.
Ejemplo:
 
Como podemos ver en la imagen de arriba, al activar la columna E y la fila 4, logramos que la intersección entre estos encienda el punto de color azul, esta seria la forma en la que podemos encender un punto en una matriz.
Para que esto sea posible el multiplexado funciona de la siguiente forma:
Se activa la columna A, y se muestra el dato completo de las 8 filas. es decir Columna A, Filas (1,2,3,4,5,6,7,8), luego se repite lo mismo pero con la Columna B, y las 8 Filas nuevamente, y de esta forma hasta llegar ala columna H, entonces de esta forma se hace un recorrido de todas las columnas.
Ahora si el dato es siempre el mismo por ejemplo en el dibujo podemos ver que el único bit en 1 es el 4, y el resto están en cero, Filas(1,2,3,4,5,6,7,8) lo que seria en el dibujo como (000100000), y en este caso si nosotros hacemos el proceso de arriba de ir barriendo las columnas y el dato de las filas es siempre el mismo lo que se vera es una linea en toda la fila
Podemos ver en camara lenta como seria con el mismo dato en las filas.
Ahora en la realidad si nosotros realizamos este desarrollo tendremos que hacer que el barrido entre columnas sea lo suficientemente rápido como para que el ojo humano no perciba el multiplexado, lo cual como vemos en la imagen, el 4017 tendrá que conmutar mas rápido las columnas.
Bueno aquí aumente la frecuencia a 100Hz para que se pueda ver en velocidad, por un tema del gif animado no se puede apreciar el efecto, pero al generar un barrido de columnas de 100Hz la fila 4 queda encendida totalmente. Esto como mencionaba antes se debe a que el dato en las filas es siempre el mismo, como pueden ver en los seteos de estado de arriba de la imagen siempre mantiene el mismo encendido.
Pero en la realidad cuando requiere realizar un dibujo o una letra, tiene que variar estos datos de las filas, (las columnas siempre realizan el mismo trabajo de conmutación) pero en este nuevo concepto las columnas tienen que variar. La forma de esta variación sera en función de lo que se desee mostrar. 
Si uno quiere mostrar un circulo dibujado, tendrá que mostrar en cada columna el dato que corresponda, es decir observen la siguiente tabla de valores binarios:

COLUMNAS  
00011000  
00100100 F
01000010 I
10000001 L
10000001 A
01000010 S
00100100  
00011000  

Bueno analizando esta tabla, lo que tendríamos que haces es que para la columna A, el dato a mostrar en las filas sera 00011000, en la columna B, el dato sera 00100100, en la columna C, sera 01000010, luego seguirá como se muestra en la tabla. 
Nuevamente de forma lenta para comprender como se recorre la tabla:
Ahora al igual que antes vamos a verlo con una frecuencia de 100Hz pero gracias al gif otra vez se va a ver medio cortado. pero imaginen que lo hace rapido como se debe, conformando así el pseudo circulo sin que se pueda percibir por el ojo humano esta conmutación de columnas.
 
Bueno ahora la idea de hacer esto con un microcontrolador que pueden verlo en otro post en este blog [http://electgpl.blogspot.com.ar/2012/05/adaptador-de-matriz-de-5-x-7-puntos.html] aquí se muestra todo lo mencionado hasta ahora. 
En este otro post se puede ver como mediante una secuencia de tablas, es posible ir cambiando cada imagen estática [http://electgpl.blogspot.com.ar/2012/05/control-de-matriz-estatica.html]

Ahora el motivo de este nuevo post es el de crear una matriz dinámica, es decir que el texto que contenga no se muestre letra por letra de forma estática sino de forma dinámica como un desplazamiento o como se le dice en el resto del mundo Scroll.
A pesar de que la forma de generar un muestreo, conmutación o multiplexado de columnas se suele realizar mediante el uso de Timers en el microcontrolador, en este ejemplo lo haré de la forma mas sencilla sin ningún timer, simplemente con lazos for.
El uso de Timers se requiere para que de forma independiente se pueda generar el barrido de las columnas o el muestro (cantidad de frames) de la imagen a mostrar en la matriz, sea de forma independiente al resto del programa, esto es porque el muestreo de columnas suele ser mucho mas rápido que el desplazamiento del texto en la matriz, entonces se soluciona muy sencillo con el uso de los timers, pero en mi caso intento hacer lo mas sencillo posible este post para que sea muy fácil de entender.

Para esto veremos el programa y luego lo explicare.

#include <16F883.h>
#use delay(int=4000000)
#define LARGO 28                      //Longitud de la tabla
int const tabla[LARGO+8]={
                          0b00000000, //Espacio
                          0b00000000, //Espacio
                          0b00000000, //Espacio
                          0b00000000, //Espacio
                          0b00000000, //Espacio
                          0b00000000, //Espacio
                          0b00000000, //Espacio
                          0b00000000, //Espacio 
                          0b11111111, //Dato de tabla H
                          0b00001000,
                          0b00001000,
                          0b11111111,
                          0b00000000, //Espacio
                          0b01111110, //Dato de tabla O
                          0b10000001,
                          0b10000001,
                          0b01111110,
                          0b00000000, //Espacio
                          0b11111111, //Dato de tabla L
                          0b00000001,
                          0b00000001,
                          0b00000000, //Espacio
                          0b01111111, //Dato de tabla A
                          0b10001000,
                          0b10001000,
                          0b01111111,
                          0b00000000, //Espacio
                          0b00000000, //Espacio
                          };
void main(){
   byte const bitMask[8]={1,2,4,8,16,32,64,128}; //Mascara
   int i,j,k;                         //Variables contadores
   while(TRUE){                       //Ciclo infinito
      for(i=0;i<LARGO+8;i++){         //Recorrido de tabla
         for(k=0;k<20;k++){           //Refresco de matriz
            for(j=0;j<8;j++){         //Barrido de columnas
               output_a(~bitMask[j]); //Columnas ponderadas
               output_b(tabla[j+i]);  //Desplazamiento de tabla
               delay_ms(1);           //Demora de multiplexado
            }  
         }
      }
   }  
}   

Bueno aqui podemos ver principalmente la tabla con los caracteres realizados en funcion a las filas que forma la palabra HOLA, ahora lo mas importante que son los for anidados.
Notemos desde el for que se encuentra mas profundo hacia al for que se encuentra en la superficie.
El for(j=0;j<8;j++)cumple la función de recorrer las columnas que se encuentran en el puerto A, por eso encontramos la sentencia output_a(~bitMask[j]), donde bitMask[j] es el vector definido mas arriba que contiene los valores {1,2,4,8,16,32,64,128}, esto hace referencia a 00000001, 00000010, 00000100, 00001000, 00010000, 00100000, 01000000, 10000000. De esta forma activamos cada columna una a una. Luego como podemos ver tenemos la salida del puerto B la cual posee el vector de la tabla donde su indice dice j+i, bueno esto es clave para que la matriz desplace la palabra dentro de ella. 
Ahora el for(i=0;i<LARGO+8;i++)lo que hace es recorrer la tabla, como pueden ver el valor constante LARGO que se carga en la parte de arriba del programa es la longitud de la tabla, es decir el largo del vector, pero se le suma 8, esto es porque la matriz posee 8 columnas las cuales debe mostrar apagadas al finalizar dicho mensaje para que no se solape cuando se repita.
Volviendo a lo mencionado anterior que era clave el j+i lo que hace es que cada vez que se refrescan las columnas, se recorre toda la tabla, pero por cada refresco, la tabla se recorre desde un inicio distinto, es decir, para crear el movimiento de la matriz, lo que se hace es mostrar el contenido de la tabla desde su primer byte hacia el ultimo, pero cada vez que se genera un muestreo en lugar de comenzar del primero se comienza del segundo, luego del tercero, y por eso el j+i, lo que nos genera la ilusion óptica del movimiento. Ahora se mostrara en el siguiente gif animado, a velocidad lenta para la comprensión y a velocidad normal para ver el resultado obtenido.
Por ultimo el for(k=0;k<20;k++) lo que hace es la cantidad de frames, es decir la cantidad de veces que refresca la pantalla por cada barrido de columnas, lo que quiere decir es que realizara 20 barridos de matriz completa por cada movimiento del desplazamiento de la palabra en la matriz.
Tener en cuenta que el gif animado no se muestra en tiempo real, pero servirá para tener en cuenta el funcionamiento.
Esta sera la versión final a velocidad aceptable para leer y sin parpadeos.


 





Transmisor ASK de 80m a 5V

Este es un transmisor de ASK en la banda de 80m alimentado con 5V, de todas formas por la forma en que se encuentra construido la frecuencia de operación puede variar, ya que la base de tiempo del oscilador de portadora se encuentra realizada con cristal de cuarzo.
En este caso el Oscilador local está construido con compuertas Schmitt Trigger (40106), donde simplemente se requieren pocos componentes pasivos para conformar el oscilador.
Se implementa un cristal de 3.58MHz pero es posible utilizar otros valores.
El transistor de abajo cumple la función de amplificar la señal de salida del oscilador a cristal, la alimentación de este amplificador se encuentra acoplada mediante el inductor de 100uHy al transistor de modulación que se encarga de variar la amplitud del amplificador en función del nivel de señal de la entrada de modulación.
De esta se modifica la amplitud de la portadora amplificada, lo cual da como resultado una Amplitud Modulada. Aunque como los datos son digitales y la amplitud se modula por el desplazamiento de dichos pulsos, el transmisor se convierte en ASK, el circuito está calculado para que el transistor modulador funcione en un hibrido entre la clase A y la clase E.
La antena se acopla mediante los condensadores de 10nF y 330pF, debe ser de 50ohms.
Es posible aumentar la tensión de alimentación pero solo lo he probado con 5V, claramente aumentara el alcance de este transmisor al aumentar la alimentación, pero se deben recalcular las resistencias de polarización del punto Q del transistor de arriba.



Generador RTTY Baudot con PIC


Aquí les traigo un sencillo generador de caracteres en código Baudot con modulación en doble tono para conformar el protocolo RTTY, el mismo posee el generador de tonos integrado y la generación de Baudot en el mismo.

El circuito no está en el post porque en si es solo el micro controlador y un pin de salida que en este caso se elige un 16F84A y se usa el pin RA2 como salida. Pero claramente por la sencillez del programa puede usarse cualquier micro controlador.

El programa es muy sencillo de comprender.

Básicamente tenemos dos funciones, freq1 y freq0, esto es para generar dos frecuencias (de ahí viene el doble tono) donde la freq1 "del 1 lógico" la calcule yo a 800Hz y la freq0 "del 0 lógico" a 970Hz, nótese que la distancia es de 170Hz por ende si quieren usar otros valores de frecuencia (que es totalmente valido) deben tener una distancia de 170Hz entre una frecuencia y la otra.

La norma RTTY aparte de exigir estos 170Hz también exige que cada dato se envié a 22ms por ende aquí vienen las cuentas.

tomamos como ejemplo la función freq1, observamos que ponemos el pin de salida a 0 y después a 1, la velocidad que usamos son 625us de Ton y 625us de Toff, quedando así una periodo T de 1250us lo cual si lo pasamos a frecuencia nos da 800Hz, ahora hasta ahí todo bien logramos los 800Hz que queríamos, pero cada dato debe enviarse a 22ms entonces debemos hacer que se demore durante 22ms, para ello usamos un loop del tipo while donde cuenta 17 veces y luego sale del loop, si multiplicamos 17 * 1250us nos dará 21,2ms (es casi el valor de 22ms, gracias a que existe una tolerancia no tendremos problemas). 

La función freq0 es lo mismo que esto pero calculado para 970Hz.

Estas dos funciones forman parte de la generación de doble tono, lo que sería nuestro "modem".

Ahora viene la generación de baudot, para esto se crea un vector de 18 posiciones (lo cual son 18 porque use 18 caracteres para formar "  ELECTGPL  RTTY  ").

El protocolo dice que debe ser 1 bit de start a 0 lógico, seguido de esto 5 bit del dato o el carácter y por ultimo 2 bit de Stop a 1 lógico. Notaran que en el programa está al revés, es decir primero el stop y por último el start, eso es por la forma en la que el micro entrega los bit de forma serie (pero pueden cambiarlo, yo lo he dejado así porque ya lo había codificado así).

Tenemos otro vector que es para la máscara, es decir tiene los valores ponderados de un valor binario de 8 bit, esto es simple, la forma de enviar el dato de forma serial, debe ser bit a bit, entonces esto lo hacemos comparando el dato a enviar con la máscara. Por ejemplo en el loop que tiene un for que itera 8 veces lo que se hace es comprar el byte a enviar (start, dato, stop, stop) con el byte de la máscara. Entonces si aplicamos la operación lógica AND, donde exista un 1 lógico dará verdadero y donde exista un 0 lógico dará falso, entonces si tenemos por ejemplo el primer byte a enviar "11001000" y lo comparamos contra la máscara 8 veces (mediante el incremento del índice del vector) nos dirá como resultado lo siguiente:


11001000 & 00000001 = False

11001000 & 00000010 = False

11001000 & 00000100 = False

11001000 & 00001000 = True

11001000 & 00010000 = False

11001000 & 00100000 = False

11001000 & 01000000 = True

11001000 & 10000000 = True


Esto es lo que hace el for que itera 8 veces, de esta forma recorre bit a bit todo el byte del dato y lo compara contra la máscara. Ahora, seguido de este tenemos la condición, si es verdadero llama a la función freq0 y si es falso a la función freq1, entonces como quedaría esto modulado?, de la siguiente forma.

800Hz 22ms 800Hz 22ms 800Hz 22ms 970Hz 22ms 800Hz 22ms 800Hz 22ms 970Hz 22ms 970Hz 22ms. Esta sería la salida del micro, que luego se repetirá como dice el while unas 18 veces que coincide con los 18 valores vector de datos.

La salida puede ser acoplada como en mi práctica a un transmisor de AM de 80m pero es posible acoplarla a cualquier entrada de AF.

#include <16F84A.h>
#fuses XT
#use delay(clock=4000000)
#define AUDIO PIN_A2
freq1(){        //625us + 625us = 1250us = 800Hz
   int q=0;
   while(q<17){ //22ms / 1250us = 17 veces.
      output_low(AUDIO);
      delay_us(625);
      output_high(AUDIO);
      delay_us(625);
      q++;
   }  
}
freq0(){        //515us + 515us = 1030us = 970Hz
   int p=0;
   while(p<21){ //22ms / 1030us = 21 veces.
      output_low(AUDIO);
      delay_us(515);
      output_high(AUDIO); 
      delay_us(515); 
      p++;
   }  
}
void main(){
   int i,j;     
   byte valor;
   byte const bitMask[8]={1,2,4,8,16,32,64,128};
   byte const ByteDatosSalida[18]={
      0b11001000, //11 00100 0, STOP STOP ESPACIO START
      0b11001000, //11 00100 0, STOP STOP ESPACIO START
      0b11000010, //11 00001 0, STOP STOP "E" START
      0b11100100, //11 10010 0, STOP STOP "L" START
      0b11000010, //11 00001 0, STOP STOP "E" START
      0b11011100, //11 01110 0, STOP STOP "C" START
      0b11100000, //11 10000 0, STOP STOP "T" START
      0b11110100, //11 11010 0, STOP STOP "G" START
      0b11101100, //11 10110 0, STOP STOP "P" START
      0b11100100, //11 10010 0, STOP STOP "L" START
      0b11001000, //11 00100 0, STOP STOP ESPACIO START
      0b11001000, //11 00100 0, STOP STOP ESPACIO START
      0b11010100, //11 01010 0, STOP STOP "R" START
      0b11100000, //11 10000 0, STOP STOP "T" START
      0b11100000, //11 10000 0, STOP STOP "T" START
      0b11101010, //11 10101 0, STOP STOP "Y" START
      0b11001000, //11 00100 0, STOP STOP ESPACIO START
      0b11001000};//11 00100 0, STOP STOP ESPACIO START
   while(true){
      delay_ms(3000);              //delay de repeticion 3s
      i=0;
      while(i<18){                 //cantidad de caracteres 18
         valor=ByteDatosSalida[i]; //carga valor con dato de salida
         for(j=0;j<8;j++){         //recorre los 8 bit del baudot
            if(valor&bitMask[j])   //aplica la mascara
               freq0();            //si es verdadero envia 970Hz
            else
               freq1();            //si es falso envia 800Hz
         }i++; 
      }
   }
}