Autor Tema: Proyecto: Traductor RS232 a Morse (Sonoro y visual)  (Leído 9781 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Proyecto: Traductor RS232 a Morse (Sonoro y visual)
« en: 29 de Junio de 2006, 02:07:16 »
Si decís que tengo la cabeza definitivamente perdída no os faltará razón.  :D  :D  :D

Quería empezar algun proyecto que involucrase transmision / recepción via infrarrojos ... así que lo primero que me planteé fue definir un protocolo que encapsulase mis transmisiones ... y de momento me llegó un flash: decidí darle a esto una vuelta de tuerca y transmitir y recibir ¡¡¡ EN MORSE !!!  :mrgreen:

Así que antes de ponerme a infrarrojear el entorno voy a empezar con atronarlo con bip's y biiiiip's de puntos, rayas, rayas y puntos ....

El concepto, imagino que ya lo sabéis, consiste en traducir cada letra, o número, o símbolo, en una secuencia de pulsos sonoros, o luminosos, o taquimecalavanderos, de longitud variable según una tabla adjunta, separados una distancia en tiempo predeterminada, tanto entre pulsos que definen un carácter, como entre caracteres, como entre palabras. Es un problema de tiempos y de tablas por lo demás muy simple.

Una mínima tabla de transformación entre caracteres y pulsos podría ser:


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

0   - - - - -
1   . - - - -
2   . . - - -
3   . . . - -
4   . . . . -
5   . . . . .
6   - . . . .
7   - - . . .
8   - - - . .
9   - - - - .

,   . - . - . -     Coma
?   - - . . - -     Interrogación
=   - . . . -       Igual
-   - . . . . -     Guión
/   - . . - .       Barra
"   . - . . - .     Dobles Comillas
@   . - - . - .     Arroba

WAT . - . . .       Espera
EOL . - . - .       Fin de Mensaje
RDY - . -           Invitación a Transmitir
EOF . . . - . -     Fin de Transmisión
PNT . - . - . -     Punto (Break)
OKY . . . - .       Enterado
ERR . . . . . . . . Error


La idea es recibir desde el PC por el puerto serie del PIC una secuencia de letras, encontrar cada una de ellas en la tabla precedente y procesarla, estableciendo un tiempo para los puntos, otro mayor para las rayas, uno intermedio para las separaciones entre los anteriores y por fin uno muho mayor para separar entre si los distintos caracteres.

Con estos tiempos definidos podemos encender o apagar leds, o un buzzer o un IR .... y estaremos traduciendo de ASCII a MORSE. El receptor debe hacer exactamente lo contrario, recuperar los tiempos recibidos y consultar la tabla para extraer el caracter transmitido.

Yo, como primera aproximación, voy a utiliar los tres leds que incluí en la RRBOARD2 de forma que el Led verde haga la transmisión (tradución) completa, el amarillo solo transmita los puntos y el rojo sólo las rayas.



Sin embargo aún no he llegado tan lejos. Lo primero era recibir, carácter a carácter, por la RS232 y ser capaz de encontrar la secuencia de puntos y rayas, y devolverlos por el mismo medio para verlos en el monitor serie del PC. El resto ya es cuestión de transformar esos datos en la secuencia temporal de encendido o apagado para realizar la transmision.

Esta primera fase exclusivamente vía RS232 es la que aquí os presento.

Código: C
  1. // Morse plus RS232 v.1.0
  2.  
  3. #include <18f4550.h>
  4. #fuses HS,MCLR,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOPBADEN,NOLVP,NOCPD,NODEBUG,NOWRT,NOVREGEN
  5. #use delay(clock=20000000)
  6. #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
  7.  
  8. const long lapsus=1000;
  9. const long periodo=125;
  10.  
  11. char Version[]="1.0.8\0";
  12. char CharRcv=0;
  13. char Command=0;
  14.  
  15. char Numeros[10][15]={
  16.  
  17.                     "\x010\x02-----\x03 ",
  18.                     "\x011\x02.----\x03 ",
  19.                     "\x012\x02..---\x03 ",
  20.                     "\x013\x02...--\x03 ",
  21.                     "\x014\x02....-\x03 ",
  22.                     "\x015\x02.....\x03 ",
  23.                     "\x016\x02-....\x03 ",
  24.                     "\x017\x02--...\x03 ",
  25.                     "\x018\x02---..\x03 ",
  26.                     "\x019\x02----.\x03 "};
  27.  
  28.  
  29. char Letras[27][11]={
  30.  
  31.                     "\x01A\x02.-\x03    ",
  32.                     "\x01B\x02-...\x03  ",
  33.                     "\x01C\x02-.-.\x03  ",
  34.                     "\x01D\x02-..\x03   ",
  35.                     "\x01E\x02.\x03     ",
  36.                     "\x01F\x02..-.\x03  ",
  37.                     "\x01G\x02--.\x03   ",
  38.                     "\x01H\x02....\x03  ",
  39.                     "\x01I\x02..\x03    ",
  40.                     "\x01J\x02.---\x03  ",
  41.                     "\x01K\x02-.-\x03   ",
  42.                     "\x01L\x02.-..\x03  ",
  43.                     "\x01M\x02--\x03    ",
  44.                     "\x01N\x02-.\x03    ",
  45.                     "\x01O\x02---\x03   ",
  46.                     "\x01P\x02-..-\x03  ",
  47.                     "\x01Q\x02--.-\x03  ",
  48.                     "\x01R\x02-.-\x03   ",
  49.                     "\x01S\x02...\x03   ",
  50.                     "\x01T\x02-\x03     ",
  51.                     "\x01U\x02..-\x03   ",
  52.                     "\x01V\x02...-\x03  ",
  53.                     "\x01W\x02.--\x03   ",
  54.                     "\x01X\x02-..-\x03  ",
  55.                     "\x01Y\x02-.--\x03  ",
  56.                     "\x01Z\x02--..\x03  ",
  57.                     "\x01Ñ\x02--.--\x03 "};  
  58.  
  59.  
  60.  
  61. #int_rda
  62. void rda_handler() {
  63.  
  64.    CharRcv=0;
  65.    if(kbhit()){
  66.       CharRcv=getc();
  67.       if(CharRcv!=0){
  68.          Command=CharRcv;
  69.       }
  70.    }
  71. }
  72.  
  73. void wait_nperiodos(int n){
  74.  
  75.    int x;
  76.  
  77.    for(x=0;x<n;++x){
  78.       delay_ms(periodo);
  79.    }
  80. }
  81.  
  82. void main(){
  83.  
  84.    int x,y;
  85.  
  86.    disable_interrupts(global);
  87.    disable_interrupts(int_timer1);
  88.    disable_interrupts(int_rda);
  89.    disable_interrupts(int_ext);
  90.    disable_interrupts(int_ext1);
  91.    disable_interrupts(int_ext2);
  92.  
  93.    setup_adc_ports(NO_ANALOGS);
  94.    setup_adc(ADC_OFF);
  95.    setup_spi(FALSE);
  96.    setup_psp(PSP_DISABLED);
  97.    setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
  98.    setup_timer_0(RTCC_OFF);
  99.    setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
  100.    setup_timer_2(T2_DISABLED,0,1);
  101.    setup_timer_3(T3_DISABLED);
  102.    setup_comparator(NC_NC_NC_NC);
  103.    setup_vref(FALSE);
  104.    port_b_pullups(FALSE);
  105.    set_tris_e(0b00010000);
  106.    set_tris_c(0b10000000);
  107.    enable_interrupts(global);
  108.    enable_interrupts(int_rda);
  109.  
  110.    delay_ms(333);
  111.  
  112.    printf("\r\n Morse with 18F4550 in RRBOARAD2\r\n");
  113.    printf("    v.%s by Redpic\r\n\n",Version);
  114.  
  115.    output_High(PIN_E0);
  116.    output_High(PIN_E1);
  117.    output_High(PIN_E2);
  118.    wait_nperiodos(lapsus/periodo);
  119.    output_Low(PIN_E0);
  120.    output_Low(PIN_E1);
  121.    output_Low(PIN_E2);
  122.    wait_nperiodos(lapsus/periodo);
  123.  
  124.  
  125.  
  126.    do{
  127.  
  128.       if(Command!=0){
  129.          // Inicializo índices
  130.          x=255;
  131.          y=255;
  132.          // Letras Minúsculas
  133.          if( (Command>'a'- 1) && (Command<'z'+ 1)){
  134.             Command = Command - 'a' + 'A';  
  135.          }
  136.          // Letras Mayúsculas
  137.          if( (Command>'A'- 1) && (Command<'Z'+ 1)){
  138.             x = Command-'A';  
  139.          }
  140.          // Letras Especiales
  141.          if( (Command=='Ñ') || (Command=='ñ')){ // Ñ
  142.             x =26;  
  143.          }
  144.          // Números
  145.          if( (Command>'0'- 1) && (Command<'9'+ 1)){
  146.             y = Command-'0';  
  147.          }
  148.          // Presenta y/o suena
  149.          if(x < 255){
  150.             printf(" %s\r\n",Letras[x]);
  151.          }
  152.          if(y < 255){
  153.             printf(" %s\r\n",Numeros[y]);
  154.          }
  155.          // Recomienza
  156.          Command=0;
  157.       }
  158.  
  159.    }while(TRUE);
  160. }


Y como siempre, al final, el eterno monitor serie que es la mejor muestra de cómo funciona esto, al ir tecleando letras o números uno a uno en el PC, el PIC me responde con la misma letra y su codificación Morse correspondiente:



Voy ahora a darle forma a la emisión por otras vías ...

Os mantendré informados.  :P

Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Proyecto: Traductor RS232 a Morse (Sonoro y visual)
« Respuesta #1 en: 29 de Junio de 2006, 03:26:22 »
Eres un romántico, querido Quijote, ¡¡¡ pero mira que ponerte con el Morse !!!

No me cabe duda que lo dejarás precioso, ánimo.

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: Proyecto: Traductor RS232 a Morse (Sonoro y visual)
« Respuesta #2 en: 30 de Junio de 2006, 18:27:47 »
Menos romanticismos ... y mas traballar ....  :D  :D  :D

Aunque no os interese un pimiento todos esto del Morse, aunque os suene a chino y me tengáis por loco ... o por algo peor ...  :D  :D  :D

Si estáis interesados en manejar strings mediante punteros aquí tenéis un bonito ejemplo. Aunque solo sea por eso os recomiendo que estudieis el código que os acompaño.  :mrgreen:  :mrgreen:  :mrgreen:

Ahora mismo recibo un caracter vía RS232.

Como los códigos ASCII estan ordenados y mi tabla de definiciones Caracter-Codigo Morse tambíen, y ademas coinciden, hago un doble salto mortal carpado hacia delante y extraigo el orden en mi tabla con el mismo codigo ASCII simplemente restándole el ASCII de la letra "A" al que he recibido, así si recibo "A"-"A"=0 o sea el primero de mi tabla de letras, pero si es "B"-"A" = 1 entonces es el segundo ...  :mrgreen:

Me copio la definicion a un string temporal. Esta definicion se compone del caracter 0x01 seguido del caracter a definir, tras él el 0x02 y a continuación los puntos y/o rayas de su codigo Morse, y por fin el caracter 0x00 terminador de todos los strings C. Esta copia me la hago con una de mis Mis Funciones favoritas en CCS C sprintf.

Y ahora llamo a la primera rutina de presentación, que es la de enviar el resultado de vuelta por la RS232, separando el caracter recibido de su código Morse correspondiente. Para ello le envio a morse_rs232 un puntero con lo recién extraido, y desde allí llamo a dos funciones parser, una para el caracter, morse_parse_char , y que es muy sencilla ya que solo ha de tomar el segundo caracter del string que le envio, y otra que extrae los puntos y rayas que le corresponden.

Esta segunda funcion, morse_parse_code, es más simpatica. Le paso como argumento un puntero a la definicion y comenzando en el cuarto caracter realizo un bucle de esos que atacan los nervios a los novatos en C, inicializando en la misma definicion del mismo bucla un par de variables indice, controlando para la salida del bucle un par de condiciones distintas, longitud maxima o caracter \0, e incrementando las dos variables indice.

En este bucle me copio solo los puntos y rayas correspondientes a lo que busco sobre una variable string temporal y devuelvo como resultado un puntero a ese string temporal.  :mrgreen:

Con lo que tengo como resultado final, traca y explosion de ingeniosidad y gracil donosura los dos trozos por separado de lo que quería: El caracter pulsado y su representacion Morse, y ambas las envio, por separado al RS232 dentro de un printf.

El resultado visual es el que sigue, que solo aparentemente es similar al que dió inicio a este hilo:



Y el programa que hace todo esto, exahustivamente comentado para los amables amigos Picmaníacos es

Código: C
  1. // Morse plus RS232 v.1.1.4
  2.  
  3. #include <18f4550.h>
  4. #fuses HS,MCLR,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOPBADEN,NOLVP,NOCPD,NODEBUG,NOWRT,NOVREGEN // Fuses
  5. #use delay(clock=20000000)                       // Clock a 20 Mhz
  6. #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)   // Canal serie con el PC
  7.  
  8. const int  maxlendefinition=12;                  // Maxima longitud de la definicion Morse en las tablas
  9. const long lapsus=1000;                          // Tiempo en milisegundos para Leds al reset
  10. const long periodo=125;                          // Tiempo en milisegundos para unidad Morse = . (un punto)
  11.  
  12. char Version[]="1.1.4\0";                        // Version del programa
  13. char CharRcv=0;                                  // Caracter recibido por la USART
  14. char Command=0;                                  // Caractar a enviar al main para su procesado
  15.  
  16. char Numeros[10][maxlendefinition]={             // Tabla de definicion de los Numeros
  17.  
  18.                     "\x010\x02-----\0  ",
  19.                     "\x011\x02.----\0  ",
  20.                     "\x012\x02..---\0  ",
  21.                     "\x013\x02...--\0  ",
  22.                     "\x014\x02....-\0  ",
  23.                     "\x015\x02.....\0  ",
  24.                     "\x016\x02-....\0  ",
  25.                     "\x017\x02--...\0  ",
  26.                     "\x018\x02---..\0  ",
  27.                     "\x019\x02----.\0  "};
  28.  
  29.  
  30. char Letras[27][maxlendefinition]={              // Tabla de definicion de las Letras
  31.  
  32.                     "\x01A\x02.-\0     ",
  33.                     "\x01B\x02-...\0   ",
  34.                     "\x01C\x02-.-.\0   ",
  35.                     "\x01D\x02-..\0    ",
  36.                     "\x01E\x02.\0      ",
  37.                     "\x01F\x02..-.\0   ",
  38.                     "\x01G\x02--.\0    ",
  39.                     "\x01H\x02....\0   ",
  40.                     "\x01I\x02..\0     ",
  41.                     "\x01J\x02.---\0   ",
  42.                     "\x01K\x02-.-\0    ",
  43.                     "\x01L\x02.-..\0   ",
  44.                     "\x01M\x02--\0     ",
  45.                     "\x01N\x02-.\0     ",
  46.                     "\x01O\x02---\0    ",
  47.                     "\x01P\x02-..-\0   ",
  48.                     "\x01Q\x02--.-\0   ",
  49.                     "\x01R\x02-.-\0    ",
  50.                     "\x01S\x02...\0    ",
  51.                     "\x01T\x02-\0      ",
  52.                     "\x01U\x02..-\0    ",
  53.                     "\x01V\x02...-\0   ",
  54.                     "\x01W\x02.--\0    ",
  55.                     "\x01X\x02-..-\0   ",
  56.                     "\x01Y\x02-.--\0   ",
  57.                     "\x01Z\x02--..\0   ",
  58.                     "\x01Ñ\x02--.--\0  "};
  59.  
  60.  
  61.  
  62. #int_rda                                         // Declaración de Interrupción ...
  63. void rda_handler() {                             // Manejador de la interrupción recepcion USART
  64.  
  65.    CharRcv=0;                                    // Inicializo caracter a recibir
  66.    if(kbhit()){                                  // Si hay algo pendiente de recibir ...
  67.       CharRcv=getc();                            // lo recibo.
  68.       if(CharRcv!=0){                            // Si no es un \0 ...
  69.          Command=CharRcv;                        // lo copio para usarlo en el main
  70.       }
  71.    }
  72. }
  73.  
  74. void wait_nperiodos(int n){                      // Rutina que espera n peridos
  75.  
  76.    int x;                                        // Declaro variable de índice
  77.  
  78.    for(x=0;x<n;++x){                             // Bucle de n periodos
  79.       delay_ms(periodo);                         // Espero un periodo en milisegundos
  80.    }
  81. }
  82.  
  83. char morse_parse_char(char* mistring){           // Rutina que extrae el Caracter de la tabla de definiciones
  84.                                                  // Entrada : Puntero a la definicion Devuelve: Caracter pulsado
  85.    return mistring[1];                           // Devuelvo el segundo caracter de la tabla
  86.  
  87. }
  88.  
  89. char* morse_parse_code(char* mistring){          // Rutina que extrae el código Morse de la tabla
  90.                                                  // Entrada: Puntero a la definicion, Devuelte: Puntero al codigo
  91.    int i,j=0;                                    // Declaro variables de indices para copiar ...
  92.    char c=' ';                                   // Caracter a procesar uno a uno
  93.    char result[maxlendefinition];                // Buffer para el resultado
  94.    
  95.    for(i=3,j=0;i<maxlendefinition,c!='\0';i++,j++){// Bucle que comienza en el caracter 3º y termina al \0 ó en Mñáxima longitud
  96.       c=mistring[i];                             // Tomo los caracteres uno a uno ...
  97.       result[j]=c;                               // y lo copio en el resultado
  98.    }
  99.    result[j]='\0';                               // Finalizo el string del resultado con el estandar \0
  100.    return result;                                // Devuelvo el resultado
  101.  
  102. }
  103.  
  104. void morse_rs232(char* mistring){                // Rutina que monitoriza el código Morse extraído
  105.                                                  // Entrada : Puntero a la definicion
  106.    char  crtr;                                   // Variable para el Carácter pulsado
  107.    char* code;                                   // Puntero a la Variable con el Código correspondiente
  108.  
  109.    crtr = morse_parse_char(mistring);            // Extraigo el caracter pulsado de la definicion
  110.    code = morse_parse_code(mistring);            // Extraigo el codigo morse correspondiente a ese caracter
  111.  
  112.    printf("%c -> %s\r\n",crtr,code);             // Lo envio a la RS232
  113. }
  114.  
  115. void morse_lights(&morsecode){                   // Rutina que enciende los Leds de la RRBOARD2
  116.  
  117. }
  118.  
  119. void main(){
  120.  
  121.    int x,y;                                      // Variables índice relativas a las tablas y al caracter recibido
  122.    char xdefinition[maxlendefinition];           // Buffer para seleccionar la definicion correspondiente
  123.  
  124.    disable_interrupts(global);                   // Deshabilito todas las interrupciones
  125.    disable_interrupts(int_timer1);               // Deshabilito ...
  126.    disable_interrupts(int_rda);
  127.    disable_interrupts(int_ext);
  128.    disable_interrupts(int_ext1);
  129.    disable_interrupts(int_ext2);
  130.  
  131.    setup_adc_ports(NO_ANALOGS);
  132.    setup_adc(ADC_OFF);
  133.    setup_spi(FALSE);
  134.    setup_psp(PSP_DISABLED);
  135.    setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
  136.    setup_timer_0(RTCC_OFF);
  137.    setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
  138.    setup_timer_2(T2_DISABLED,0,1);
  139.    setup_timer_3(T3_DISABLED);
  140.    setup_comparator(NC_NC_NC_NC);
  141.    setup_vref(FALSE);
  142.    port_b_pullups(FALSE);
  143.    set_tris_e(0b00010000);
  144.    set_tris_c(0b10000000);
  145.    enable_interrupts(global);                    // Habilito todas las interrupciones (que esten habilitadas)
  146.    enable_interrupts(int_rda);                   // Habilito la interrupcion por recepcion USART
  147.  
  148.    delay_ms(333);                                // Espero 333 milisegundos a que todo se estabilice
  149.  
  150.    printf("\r\n");                               // Me presento como deben hacer todos los PIC's de
  151.    printf("Morse with 18F4550 in RRBOARAD2");    // buena familia
  152.    printf("\r\n");
  153.    printf("    v.%s by Redpic\r\n\n",Version);
  154.  
  155.    output_High(PIN_E0);                          // Enciendo los tres Led's de la RRBOARD2
  156.    output_High(PIN_E1);
  157.    output_High(PIN_E2);
  158.    wait_nperiodos(lapsus/periodo);               // Espero lo que indica "lapsus" expresado en unidades de "periodo"
  159.    output_Low(PIN_E0);
  160.    output_Low(PIN_E1);
  161.    output_Low(PIN_E2);                           // Apago los tres Led's de la RRBOARD2
  162.    wait_nperiodos(lapsus/periodo);
  163.  
  164.    do{                                           // Bucle Infinito
  165.  
  166.       if(Command!=0){
  167.          // Inicializo índices a un valor imposible
  168.          x=255;
  169.          y=255;
  170.          // Letras Minúsculas, las convierto a mayúsculas
  171.          if( (Command>'a'- 1) && (Command<'z'+ 1)){
  172.             Command = Command - 'a' + 'A';
  173.          }
  174.          // Letras Mayúsculas, calculo el índice en la tabla según su código ASCII
  175.          if( (Command>'A'- 1) && (Command<'Z'+ 1)){
  176.             x = Command-'A';
  177.          }
  178.          // Letras Especiales, puestas a güebo
  179.          if( (Command=='Ñ') || (Command=='ñ')){ // Ñ
  180.             x =26;
  181.          }
  182.          // Números, calculo el índice en la tabla según su código ASCII
  183.          if( (Command>'0'- 1) && (Command<'9'+ 1)){
  184.             y = Command-'0';
  185.          }
  186.          // Guardo en el buffer de main la definicion correspondiente a lo pulsado
  187.          if(x < 255){sprintf(xdefinition,"%s",Letras[x]);}
  188.          if(y < 255){sprintf(xdefinition,"%s",Numeros[y]);}
  189.          // Presenta y/o suena (Ahora solo presenta)
  190.          morse_rs232(xdefinition);
  191.          // Recomienza borrando el comando (letra ó numero) procesado
  192.          Command=0;
  193.       }
  194.  
  195.    }while(TRUE);
  196. }


Y todavía no he empezado a encender y apagar Led's, ni a emitir pitidos ....

Continuamos. Os mantendre informados.  :P


 
« Última modificación: 30 de Junio de 2006, 18:31:29 por RedPic »
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado RaDoN

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1498
Re: Proyecto: Traductor RS232 a Morse (Sonoro y visual)
« Respuesta #3 en: 30 de Junio de 2006, 18:50:27 »
 :D :D :D :D :D :D :D

¡¡Que tio!! Bonita epoca aquella de radioaficionado ... yo con mi super star y mi pedazo de amplificador para joder la tele a todos los vecinos  :mrgreen:

Redpic eres mi idolo!! que tio, las ideas que tiene  :-)
Si juegas contra el mejor, pierdes como los demás.

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: Proyecto: Traductor RS232 a Morse (Sonoro y visual)
« Respuesta #4 en: 01 de Julio de 2006, 07:36:02 »
Ja, ja, ja  :D  :D :D

Yo tenía la President Grant para CB y una decamétrica Yaesu FT-500 ... EA7ADR (siete aparato de radio)







« Última modificación: 01 de Julio de 2006, 07:38:03 por RedPic »
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado J1M

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1960
Re: Proyecto: Traductor RS232 a Morse (Sonoro y visual)
« Respuesta #5 en: 01 de Julio de 2006, 07:44:59 »
toma ahí ese peazo proyecto retro con pics!! jajajajaja muy bueno ^^ q disfrutes d las vacaciones kemando muxos pics! :D

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: Proyecto: Traductor RS232 a Morse (Sonoro y visual)
« Respuesta #6 en: 01 de Julio de 2006, 07:51:02 »
Buenooooo .... esto no podeís verlo ya que ahora ya enciendo los Leds de la RRBOARD2

pero ahi vá lo que le he añadido:

Código: C
  1. void morse_light_punto(void){
  2.  
  3.    output_High(PIN_E1);                          // Enciendo Led1 -> Puntos y Led0 -> Completo
  4.    output_High(PIN_E0);
  5.    wait_nperiodos(1);                            // Espero 1 x "periodo" de puntos
  6.    output_Low(PIN_E1);
  7.    output_Low(PIN_E0);                           // Apago  Led1 -> Puntos y Led0 -> Completo
  8.    wait_nperiodos(1);                            // Espero 1 "periodo" de separacion entre puntos y rayas
  9.  
  10. }
  11.  
  12. void morse_light_raya(void){
  13.  
  14.    output_High(PIN_E2);                          // Enciendo Led2 -> Rayas y Led0 -> Completo
  15.    output_High(PIN_E0);
  16.    wait_nperiodos(3);                            // Espero 3 x "periodo" de rayas
  17.    output_Low(PIN_E2);
  18.    output_Low(PIN_E0);                           // Apago  Led2 -> Rayas y Led0 -> Completo
  19.    wait_nperiodos(1);                            // Espero 1 "periodo" de separacion entre puntos y rayas
  20. }
  21.  
  22. void morse_lights(char* mistring){               // Rutina que enciende los Led's de la RRBOARD2
  23.  
  24.    char* code;                                   // Puntero a la Variable con el Código correspondiente
  25.    int   i;                                      // Declaro variable de indice para procesar ...
  26.    char  c=' ';                                  // Caracter a procesar uno a uno e inicializo en blanco
  27.  
  28.    code = morse_parse_code(mistring);            // Extraigo el codigo morse correspondiente a ese caracter
  29.  
  30.    for(i=0;i<maxlendefinition-3,c!='\0';i++){    // Bucle que recorre el contenido de code hasta \0
  31.       c=code[i];                                 // Tomo los caracteres a representar uno a uno ...
  32.       switch(c){
  33.          case '.': morse_light_punto();
  34.                    break;
  35.          case '-': morse_light_raya();
  36.                    break;
  37.       }
  38.    }
  39. }


Y ahora corro a modificar todo esto para recibir sobre un Buffer y transmitir letras, palabras y frases completas cuando envíe el [Intro] correspondiente (0x0D) ... haciendo uso de mi propio Ejemplito 16F876A: Recibiendo del RS232 sobre un Buffer y procesandolo posteriormente.

 :P  8)  :lol:  :)  :D  :-)


 
« Última modificación: 01 de Julio de 2006, 08:22:36 por RedPic »
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado jfh900

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3595
Re: Proyecto: Traductor RS232 a Morse (Sonoro y visual)
« Respuesta #7 en: 01 de Julio de 2006, 09:15:16 »
Bueno Diego pronto veremos el primer chat en Morse  :D

Un saludo.
* Cuando hables, procura que tus palabras sean mejores que el silencio.
* 'Todos somos ignorantes, lo que ocurre es que no todos ignoramos las mismas cosas.' Albert Einstein.
* No hay nada peor que un experto para evitar el progreso en un campo
* "La vida es como una novela. No importa que sea larga, sino que esté bien narrada" Seneca
* La vida no se vive por las veces que respiras, sino por los momentos que dejan sin aliento.
* Dios dijo: ∇·E=ρ/ε0 ; ∇·B=0 ; ∇xE=-dB/dt ; ∇xB= μ0ε0dE/dt..y la luz se hizo..!!..

Desde España Jesús

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: Proyecto: Traductor RS232 a Morse (Sonoro y visual)
« Respuesta #8 en: 01 de Julio de 2006, 16:13:55 »
Ea. Punto (y raya) final a este curioso proyecto.

Traductor RS232 a Morse terminado instalado y funcionando.  :mrgreen:

Le he integrado el Recibiendo del RS232 sobre un Buffer y procesandolo posteriormente. de mis Ejemplitos 16F876A y ya mi Traductor Morse funciona recibiendo todo un texto y enviandolo en Morse al recibir el [Intro] de finalización.

Ha quedado monísimo ...  :-/  :-/  :-/ (Lástima que no podais ver los Leds bailando al son del Morse)




Y el código completo y definitivo (por ahora  :D ):

Código: C
  1. // Traductor Morse RS232 -> Lights & Sound
  2.  
  3. #include <18f4550.h>
  4. #fuses HS,MCLR,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOPBADEN,NOLVP,NOCPD,NODEBUG,NOWRT,NOVREGEN // Fuses
  5. #use delay(clock=20000000)                       // Clock a 20 Mhz
  6. #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)   // Canal serie con el PC
  7.  
  8. const int  maxlendefinition=12;                  // Maxima longitud de la definicion Morse en las tablas
  9. const long lapsus=1000;                          // Tiempo en milisegundos para Leds al reset
  10. const long periodo=75;                           // Tiempo en milisegundos para unidad Morse = . (un punto)
  11. const int  lenrecbuffer=64;                      // Tamaño en bytes del buffer de recepcion
  12. const int  COMMAND_NULL=0;                       // COMANDO NULO -> No hay comando
  13. const int  COMMAND_PROCESS=1;                    // COMANDO PROCESA TEXTO -> Convertir buffer a Morse
  14.  
  15. char Version[]="1.5.0\0";                        // Version del programa
  16. char CharRcv=0;                                  // Caracter recibido por la USART
  17. char Command=0;                                  // Caractar a enviar al main para su procesado
  18. char recbuffer[lenrecbuffer];                    // Buffer de recepción
  19. int  nextc=0;                                    // Indice de siguiente caracter en recbuffer
  20.  
  21. char Numeros[10][maxlendefinition]={             // Tabla de definicion de los Numeros
  22.  
  23.                     "\x010\x02-----\0  ",
  24.                     "\x011\x02.----\0  ",
  25.                     "\x012\x02..---\0  ",
  26.                     "\x013\x02...--\0  ",
  27.                     "\x014\x02....-\0  ",
  28.                     "\x015\x02.....\0  ",
  29.                     "\x016\x02-....\0  ",
  30.                     "\x017\x02--...\0  ",
  31.                     "\x018\x02---..\0  ",
  32.                     "\x019\x02----.\0  "};
  33.  
  34.  
  35. char Letras[27][maxlendefinition]={              // Tabla de definicion de las Letras
  36.  
  37.                     "\x01A\x02.-\0     ",
  38.                     "\x01B\x02-...\0   ",
  39.                     "\x01C\x02-.-.\0   ",
  40.                     "\x01D\x02-..\0    ",
  41.                     "\x01E\x02.\0      ",
  42.                     "\x01F\x02..-.\0   ",
  43.                     "\x01G\x02--.\0    ",
  44.                     "\x01H\x02....\0   ",
  45.                     "\x01I\x02..\0     ",
  46.                     "\x01J\x02.---\0   ",
  47.                     "\x01K\x02-.-\0    ",
  48.                     "\x01L\x02.-..\0   ",
  49.                     "\x01M\x02--\0     ",
  50.                     "\x01N\x02-.\0     ",
  51.                     "\x01O\x02---\0    ",
  52.                     "\x01P\x02-..-\0   ",
  53.                     "\x01Q\x02--.-\0   ",
  54.                     "\x01R\x02-.-\0    ",
  55.                     "\x01S\x02...\0    ",
  56.                     "\x01T\x02-\0      ",
  57.                     "\x01U\x02..-\0    ",
  58.                     "\x01V\x02...-\0   ",
  59.                     "\x01W\x02.--\0    ",
  60.                     "\x01X\x02-..-\0   ",
  61.                     "\x01Y\x02-.--\0   ",
  62.                     "\x01Z\x02--..\0   ",
  63.                     "\x01Ñ\x02--.--\0  "};
  64.  
  65. char Signos[7][maxlendefinition]={               // Tabla de definicion de las Letras
  66.  
  67.                     "\x01 \x02 \0      ",        // Espacio
  68.                     "\x01,\x02.-.-.-\0 ",        // Coma
  69.                     "\x01?\x02--..--\0 ",        // Interrogación
  70.                     "\x01=\x02-...-\0  ",        // Igual
  71.                     "\x01-\x02-....-\0 ",        // Guión
  72.                     "\x01/\x02-..-.\0  ",        // Barra
  73.                     "\x01@\x02.--.-.\0 "};       // Arroba
  74.  
  75.  
  76. #int_rda                                         // Declaración de Interrupción ...
  77. void rda_handler() {                             // Manejador de la interrupción recepcion USART
  78.  
  79.    CharRcv=0;                                    // Inicializo caracter a recibir
  80.    Command=COMMAND_NULL;                         // Inicializo comando para main
  81.    if(kbhit()){                                  // Si hay algo pendiente de recibir ...
  82.       CharRcv=getc();                            // lo recibo sobre RecRcv.
  83.       if(CharRcv!=0){                            // Si no es un \0 ...
  84.          recbuffer[nextc]=CharRcv;               // lo copio en el buffer, ...
  85.          if(CharRcv==0x0D){                      // Si he recibido un [Intro] 0x0D 13 ...
  86.             recbuffer[nextc]='\0';               // Sustituyo el 0x0D en recbuffer por el terminador \0            
  87.             Command=COMMAND_PROCESS;             // lo copio sobre command para procesarlo en main
  88.          } else
  89.          {
  90.             putc(CharRcv);                       // lo envío de vuelta como eco y continuo ...
  91.          }
  92.          if(++nextc==lenrecbuffer){              // Y si despues de incrementar nextc es igual a lenrecbuffer ...
  93.            nextc=0;                              // lo vuelvo a poner a cero
  94.          }
  95.       }
  96.    }
  97. }
  98.  
  99. void limpia_recbuffer(void){
  100.  
  101.    int i;                                        // Declaro variable de índice
  102.  
  103.    for(i=0;i!=lenrecbuffer;i++){                 // Bucle de 0 a lenrecbuffer
  104.       recbuffer[i]='\0';                         // Pongo a \0
  105.    }
  106.    nextc=0;
  107. }
  108.  
  109. void wait_nperiodos(int n){                      // Rutina que espera n peridos
  110.  
  111.    int x;                                        // Declaro variable de índice
  112.  
  113.    for(x=0;x<n;++x){                             // Bucle de n periodos
  114.       delay_ms(periodo);                         // Espero un periodo en milisegundos
  115.    }
  116. }
  117.  
  118. char morse_parse_char(char* mistring){           // Rutina que extrae el Caracter de la tabla de definiciones
  119.                                                  // Entrada : Puntero a la definicion Devuelve: Caracter pulsado
  120.    return mistring[1];                           // Devuelvo el segundo caracter de la tabla
  121.  
  122. }
  123.  
  124. char* morse_parse_code(char* mistring){          // Rutina que extrae el código Morse de la tabla
  125.                                                  // Entrada: Puntero a la definicion, Devuelte: Puntero al codigo
  126.    int i,j=0;                                    // Declaro variables de indices para copiar ...
  127.    char c=' ';                                   // Caracter a procesar uno a uno
  128.    char result[maxlendefinition];                // Buffer para el resultado
  129.  
  130.    for(i=3;i<maxlendefinition,c!='\0';i++,j++){  // Bucle que comienza en el caracter 3º y termina al \0 ó en Mñáxima longitud
  131.       c=mistring[i];                             // Tomo los caracteres uno a uno ...
  132.       result[j]=c;                               // y lo copio en el resultado
  133.    }
  134.    result[j]='\0';                               // Finalizo el string del resultado con el estandar \0
  135.    return result;                                // Devuelvo el resultado
  136.  
  137. }
  138.  
  139. void morse_rs232(char* mistring){                // Rutina que monitoriza el código Morse extraído
  140.                                                  // Entrada : Puntero a la definicion
  141.    char  crtr;                                   // Variable para el Carácter pulsado
  142.    char* code;                                   // Puntero a la Variable con el Código correspondiente
  143.  
  144.    crtr = morse_parse_char(mistring);            // Extraigo el caracter pulsado de la definicion
  145.    code = morse_parse_code(mistring);            // Extraigo el codigo morse correspondiente a ese caracter
  146.  
  147.    printf("%c -> %s\r\n",crtr,code);             // Lo envio a la RS232
  148. }
  149.  
  150. void morse_light_punto(void){
  151.  
  152.    output_High(PIN_E1);                          // Enciendo Led1 -> Puntos y Led0 -> Completo
  153.    output_High(PIN_E0);
  154.    wait_nperiodos(1);                            // Espero 1 x "periodo" de puntos
  155.    output_Low(PIN_E1);
  156.    output_Low(PIN_E0);                           // Apago  Led1 -> Puntos y Led0 -> Completo
  157.    wait_nperiodos(1);                            // Espero 1 "periodo" de separacion entre puntos y rayas
  158.  
  159. }
  160.  
  161. void morse_light_raya(void){
  162.  
  163.    output_High(PIN_E2);                          // Enciendo Led2 -> Rayas y Led0 -> Completo
  164.    output_High(PIN_E0);
  165.    wait_nperiodos(3);                            // Espero 3 x "periodo" de rayas
  166.    output_Low(PIN_E2);
  167.    output_Low(PIN_E0);                           // Apago  Led2 -> Rayas y Led0 -> Completo
  168.    wait_nperiodos(1);                            // Espero 1 "periodo" de separacion entre puntos y rayas
  169. }
  170.  
  171. void morse_lights(char* mistring){               // Rutina que enciende los Led's de la RRBOARD2
  172.  
  173.    char* code;                                   // Puntero a la Variable con el Código correspondiente
  174.    int   i;                                      // Declaro variable de indice para procesar ...
  175.    char  c=' ';                                  // Caracter a procesar uno a uno e inicializo en blanco
  176.  
  177.    code = morse_parse_code(mistring);            // Extraigo el codigo morse correspondiente a ese caracter
  178.  
  179.    for(i=0;i<maxlendefinition-3,c!='\0';i++){    // Bucle que recorre el contenido de code hasta \0
  180.       c=code[i];                                 // Tomo los caracteres a representar uno a uno ...
  181.       switch(c){
  182.          case ' ': wait_nperiodos(5);            // Espero 5 x "periodo" ( espacio entre palabras)
  183.                    break;
  184.          case '.': morse_light_punto();
  185.                    break;
  186.          case '-': morse_light_raya();
  187.                    break;
  188.       }
  189.    }
  190. }
  191.  
  192. void morse_process(char* mitext){
  193.  
  194.    int  i,x,y,z;                                 // Variables indice de ratreo de mitext, índice relativas
  195.                                                  // a las tablas y al caracter recibido
  196.    char xdefinition[maxlendefinition];           // Buffer para seleccionar la definicion correspondiente
  197.    char  c=' ';                                  // Caracter a procesar uno a uno e inicializo en blanco
  198.    
  199.    for(i=0;i<lenrecbuffer,c!='\0';i++){
  200.       // Cargo siguiente caracter a procesar
  201.       c=mitext[i];
  202.       if(c!='\0'){
  203.          // Inicializo índices de tablas a un valor imposible
  204.          x=0xff;
  205.          y=0xff;
  206.          z=0xff;
  207.          // Letras Minúsculas, las convierto a mayúsculas
  208.          if( (c>'a'- 1) && (c<'z'+ 1)){
  209.             c = c - 'a' + 'A';
  210.          }
  211.          // Letras Mayúsculas, calculo el índice en la tabla según su código ASCII
  212.          if( (c>'A'- 1) && (c<'Z'+ 1)){
  213.             x = c-'A';
  214.          }
  215.          // Letras Especiales, puestas a güebo
  216.          if( (c=='Ñ') || (c=='ñ')){              // Ñ
  217.             x =26;
  218.          }
  219.          // Números, calculo el índice en la tabla según su código ASCII
  220.          if( (c>'0'- 1) && (c<'9'+ 1)){
  221.             y = c-'0';
  222.          }
  223.          //Signos y puntuación, puestos a güebo
  224.          if(c==' ') z = 0;                             // Espacio
  225.          if(c==',') z = 1;                             // Coma
  226.          if(c=='?') z = 2;                             // Interrogación
  227.          if(c=='=') z = 3;                             // Igual
  228.          if(c=='-') z = 4;                             // Guión
  229.          if(c=='/') z = 5;                             // Barra
  230.          if(c=='@') z = 6;                             // Arroba
  231.          // Guardo en el buffer de main la definicion correspondiente a lo pulsado
  232.          if(x < 255){sprintf(xdefinition,"%s",Letras[x]);}
  233.          if(y < 255){sprintf(xdefinition,"%s",Numeros[y]);}
  234.          if(z < 255){sprintf(xdefinition,"%s",Signos[z]);}
  235.          // Presenta y/o suena (Ahora solo presenta)
  236.          morse_rs232(xdefinition);
  237.          morse_lights(xdefinition);
  238.       }
  239.    }
  240.    
  241. }
  242.  
  243. void on_reset(){
  244.  
  245.    disable_interrupts(global);                   // Deshabilito todas las interrupciones
  246.    disable_interrupts(int_timer1);               // Deshabilito ...
  247.    disable_interrupts(int_rda);
  248.    disable_interrupts(int_ext);
  249.    disable_interrupts(int_ext1);
  250.    disable_interrupts(int_ext2);
  251.  
  252.    setup_adc_ports(NO_ANALOGS);                  // Configuro todo lo que voy
  253.    setup_adc(ADC_OFF);                           // a usar y lo que no ...
  254.    setup_spi(FALSE);
  255.    setup_psp(PSP_DISABLED);
  256.    setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
  257.    setup_timer_0(RTCC_OFF);
  258.    setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
  259.    setup_timer_2(T2_DISABLED,0,1);
  260.    setup_timer_3(T3_DISABLED);
  261.    setup_comparator(NC_NC_NC_NC);
  262.    setup_vref(FALSE);
  263.    port_b_pullups(FALSE);
  264.    set_tris_e(0b00010000);
  265.    set_tris_c(0b10000000);
  266.    enable_interrupts(global);                    // Habilito todas las interrupciones (que esten habilitadas)
  267.    enable_interrupts(int_rda);                   // Habilito la interrupcion por recepcion USART
  268.  
  269.    delay_ms(333);                                // Espero 333 milisegundos a que todo se estabilice
  270.  
  271.    printf("\r\n");                               // Me presento como deben hacer todos los PIC's de
  272.    printf("Morse with 18F4550 in RRBOARAD2");    // buena familia
  273.    printf("\r\n");
  274.    printf("    v.%s by Redpic\r\n\n\n",Version);
  275.  
  276.    output_High(PIN_E0);                          // Enciendo los tres Led's de la RRBOARD2
  277.    output_High(PIN_E1);
  278.    output_High(PIN_E2);
  279.    wait_nperiodos(lapsus/periodo);               // Espero lo que indica "lapsus" expresado en unidades de "periodo"
  280.    output_Low(PIN_E0);
  281.    output_Low(PIN_E1);
  282.    output_Low(PIN_E2);                           // Apago los tres Led's de la RRBOARD2
  283.    wait_nperiodos(lapsus/periodo);
  284.    limpia_recbuffer();                           // Limpio el buffer de recepción
  285. }
  286.  
  287. void main(){
  288.  
  289.    On_reset();
  290.  
  291.    do{                                           // Bucle Infinito
  292.  
  293.       if(Command!=COMMAND_NULL){
  294.      
  295.          if(Command==COMMAND_PROCESS){           // COMMAND_PROCESS : Convierte a Morse el contenido de recbuffer
  296.             printf("\r\n\n");                      // Paso una linea en el monitor rs232
  297.             morse_process(recbuffer);            // Mando procesar el contenido de recbuffer
  298.             printf("\r\n");                      // Paso otra linea en el monitor rs232
  299.             limpia_recbuffer();                  // Limpio el buffer de recepción
  300.             Command=COMMAND_NULL;                // Limpio el ultimo comando procesado
  301.          }
  302.       }
  303.  
  304.    }while(TRUE);
  305. }

« Última modificación: 01 de Julio de 2006, 16:35:02 por RedPic »
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Proyecto: Traductor RS232 a Morse (Sonoro y visual)
« Respuesta #9 en: 27 de Mayo de 2010, 13:10:33 »
Querido Diego, alguien ha sacado una versión USB del invento. Mira:
http://us.cactii.net/~bb/morsekey/

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: Proyecto: Traductor RS232 a Morse (Sonoro y visual)
« Respuesta #10 en: 27 de Mayo de 2010, 17:17:03 »
¡¡¡Bah!!! esta hecho con un Atmel Ja, ja, ja  :D :D :D
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Proyecto: Traductor RS232 a Morse (Sonoro y visual)
« Respuesta #11 en: 28 de Mayo de 2010, 08:41:01 »
Qué lindo el telégrafo y el código Morse!!!!

Fue el primer experimento que hicimos con mi primo. Pero simplemente tiramos un cable bipolar entre nuestras casas (alrededor de 50mts de distancia) y los terminales eran sólamente sonoros.  Claro, estoy hablando de cuando tenía 12 años.
Que recuerdos!!!!!!!!
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Proyecto: Traductor RS232 a Morse (Sonoro y visual)
« Respuesta #12 en: 28 de Mayo de 2010, 08:43:57 »
Jaja, yo hice algo parecido con un amigo de mi calle. Tiramos un cable coaxial de casa a casa y nos pasábamos los juegos del MSX mediante un radiocassete en una casa y el grabador en la otra  :D

Desconectado vicmez12

  • PIC10
  • *
  • Mensajes: 1
Re: Proyecto: Traductor RS232 a Morse (Sonoro y visual)
« Respuesta #13 en: 10 de Julio de 2010, 22:48:49 »
Saldos amigo RedPic me parece super interesante lo que haces con el codigo morse y me gustaria poder montar tu modelo para la presentacion de un proyecto en mi facultad.... soy nuevo en esto de los Pic y estube buscando en tus ejemplos la simulacion en Proteuss pero veo q aun no la publicas Por favor nesecito ayuda para lograr este proyecto..