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

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

Desconectado RedPic

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


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: 17466
    • 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.
Un saludo desde Sevilla, España.
Visita MicroPIC                                                                                        ɔ!doɹɔ!ɯ ɐʇ!s!ʌ

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5377
    • 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. }
  197.  


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: 5377
    • 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: 5377
    • 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. }
  40.  
  41.  


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: 3585
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: 5377
    • 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. }
  306.  

« Ú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: 17466
    • 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/
Un saludo desde Sevilla, España.
Visita MicroPIC                                                                                        ɔ!doɹɔ!ɯ ɐʇ!s!ʌ

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5377
    • 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: 2459
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: 17466
    • 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
Un saludo desde Sevilla, España.
Visita MicroPIC                                                                                        ɔ!doɹɔ!ɯ ɐʇ!s!ʌ

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


 

anything