Morse Deco – RX mensaje/Python

Se añade la traducción a texto, letra a letra del alfabeto.

Como referencia se usa la función morsedeco(codigo) descrita en Morse Decodificador, desarrollada en otro curso.

Se añade al ejercicio realizado en Morse Deco – RX mensaje morse/Python

0 31
 --- ...  ... --- .
SOS SO
1015 15
 --- ...  ... --- ..
SOS SO
1 31
 --- ...  ... --- ..
SOS SO
1017 15
 --- ...  ... --- ...
SOS SO
0 128
 --- ...  ... --- ...  
SOS SOS 

Tarea: usar en el transmisor un mensaje diferente, escrito por teclado, revisar para arduino el uso del puerto Serial - Envia y Recibe texto.

Con el uso del teclado para el mensaje, observar cuando se inicia la tx y recepción para codificar en Tx y decodificar en Rx.

# Deco señal a morse, luego a texto
# generados desde arduino
# Continuación de: TxRx Inalambrico 433Mhz ASK/OOK
# http://blog.espol.edu.ec/edelros/2018/04/11/txrx-inalambrico-433mhz-askook/

import numpy as np
import matplotlib.pyplot as plt
import serial, time
def morsedeco(codigo): 
    equivale={ 
        '.-':'A', '-...':'B', '-.-.':'C', 
        '----':'CH', '-..':'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', 
        '.-.-.-':'.', '-.-.--':',', '..--..':'?', 
        '.-..-.':'"', '--..--':'!', '   ':' ', 
        ' ':' '}
    caracter=equivale[codigo]
    return(caracter)

# INGRESO
puerto = 'com5'
baudios = 9600
tolera = 100    # rango PIN analógico
ancho = 15      # del mensaje

# PROCEDIMIENTO
arduino = serial.Serial(puerto, baudios)
arduino.setDTR(False)
time.sleep(0.3)

# limpia buffer de datos anteriores
arduino.flushInput()  
arduino.setDTR()  
time.sleep(0.3)
print('\nEstado del puerto: ',arduino.isOpen())
print('Nombre del dispositivo conectado: ', arduino.name)
print('Dump de la configuración:\n ',arduino)
print('\n###############################################\n')


# Lectura de datos
antes = 0
cuenta = 0
simbolo = ''
morse_msg = ''
morse_letra = ''
mensaje = ''

while True:
    # espera hasta recibir un dato
    while (arduino.inWaiting()==0):
        pass
    
    # lee binario del puerto serial
    lectura = arduino.readline()
    # binario a texto, elimina /r/n
    texto = lectura.decode().strip()
    valor = int(texto)
    
    # Busca duración de símbolo
    # valor repetido
    diferencia = np.abs(valor-antes)
    if (diferencia < tolera):
        cuenta = cuenta + 1
    
    else:
        print(antes,cuenta)
        # Revisa espacios
        if (antes<(0+tolera)):
            # Cambio de simbolo
            if (cuenta<(2*ancho+4)):
                simbolo = ''
            else:
                # letra completa
                letra = morsedeco(morse_letra)
                mensaje = mensaje + letra
                morse_letra = ''
                if (cuenta<(4*ancho+5)):
                    simbolo = ' '
                else:
                    # cambio de palabra
                    simbolo = '  '
                    mensaje = mensaje + ' '
        
        # Revisa punto o raya        
        else:
            if (cuenta40:
            morse_msg = ''
            mensaje = ''
            
    antes = valor
    
# Cerrar el puerto serial.
serial.Serial.close

Morse Deco – RX mensaje morse/Python

Decodifica en python desde el puerto serial los valores del pin del receptor descrito en: Morse Codec - TxRx Inalámbrico 433Mhz ASK/OOK

Se recibe en el puerto serial la señal OOK equivalente al mensaje morse de "SOS".

La lectura del puerto serial continua de lo presentado en Serial - Lectura datos se obtienen los valores entre [0,1023]

El resultado se convierte a símbolos morse ' .-' contando las veces que cada valor se repite "Alto"(1) o "Bajo"(0). Se toma como referencia el ancho de 15 para un simbolo, pues el transmisor usa una DURACION =100. Si se modifican éstos valores, se deben ajustar.

1016 15
 --- ...  ...
0 63
 --- ...  ... 
1016 47
 --- ...  ... -
0 32
 --- ...  ... -
1020 47
 --- ...  ... --
0 31
 --- ...  ... --
1019 47
 --- ...  ... ---
0 63
 --- ...  ... --- 
1018 15
 --- ...  ... --- .
0 31
 --- ...  ... --- .
1016 15
 --- ...  ... --- ..
0 31
 --- ...  ... --- ..
1016 15
 --- ...  ... --- ...

las instrucciones en python

# Deco señal a morseñ
# generados desde arduino
# Continuación de: TxRx Inalambrico 433Mhz ASK/OOK
# http://blog.espol.edu.ec/edelros/2018/04/11/txrx-inalambrico-433mhz-askook/

import numpy as np
import matplotlib.pyplot as plt
import serial, time

# INGRESO
puerto = 'com5'
baudios = 9600
tolera = 100    # rango PIN analógico
ancho = 15      # del mensaje

# PROCEDIMIENTO
arduino = serial.Serial(puerto, baudios)
arduino.setDTR(False)
time.sleep(0.3)

# limpia buffer de datos anteriores
arduino.flushInput()  
arduino.setDTR()  
time.sleep(0.3)
print('\nEstado del puerto: ',arduino.isOpen())
print('Nombre del dispositivo conectado: ', arduino.name)
print('Dump de la configuración:\n ',arduino)
print('\n###############################################\n')


# Lectura de datos
antes = 0
cuenta = 0
simbolo = ''
morse_msg = ''

while True:
    # espera hasta recibir un dato
    while (arduino.inWaiting()==0):
        pass
    
    # lee binario del puerto serial
    lectura = arduino.readline()
    # binario a texto, elimina /r/n
    texto = lectura.decode().strip()
    valor = int(texto)
    
    # Busca duración de símbolo
    # valor repetido
    diferencia = np.abs(valor-antes)
    if (diferencia < tolera):
        cuenta = cuenta + 1
    
    else:
        print(antes,cuenta)
        # Revisa espacios
        if (antes<(0+tolera)):
            if (cuenta<(2*ancho+4)):
                simbolo = ''
            else:
                if (cuenta<(4*ancho+5)):
                    simbolo = ' '
                else:
                    simbolo = '  '
        
        # Revisa punto o raya        
        else:
            if (cuenta<(ancho+3)):
                simbolo = '.'
            else:
                simbolo = '-'
        cuenta = 0
        morse_msg = morse_msg + simbolo
        print(morse_msg)
        
        if len(morse_msg)>40:
            morse_msg = ''
            
    antes = valor
    
# Cerrar el puerto serial.
serial.Serial.close

Morse Codec - TxRx Inalámbrico 433Mhz ASK/OOK

El punto de partida es la combinación de Morse Codec - LEDTxRx Inalambrico 433Mhz ASK/OOK . Al primero se añade el pin 4 con el dato/símbolo bit "Alto"(1) o "Bajo" (0), que al repetirlos genera el espacio o tono morse.

Como receptor se usa la misma configuración de TxRx Inalambrico 433Mhz ASK/OOK , que permite visualizar lo recibido en un segundo arduino.

El mensaje de prueba del transmisor es " SOS   " que permite observar los valores o la gráfica en el monitor o plotter serial del programa de arduino.

Al separar el receptor del transmisor, o bloquear la señal, se obtendrán lecturas diferentes a las ideales, lo que permite disponer de nuevo material de trabajo para decodificar la señal correctamente.

Temas como corrección de errores, distancias de cobertutas, etc aparecen a partir de éste punto.

El siguiente paso consiste en decodificar la secuencia de 0's y 1's como puntos y rayas, previo a convertirlos nuevamente a letras.

Calidad de Señal entre Tx y Rx

El los dispositivos RF433 transmisor y receptor se encuentran muy cercanos, a unos 10 cm, pues aún no se les ha añadido una antena. Al separar un poco los RF433 se visualiza ruido en la señal, que afecta al mensaje enviado.

Si se presentan muchos problemas, simplifique conectando un cable entre el TxRfPin 4 y el RxRfPin A0

/*  CODificador morse
 *   recibe un mensaje y transmite usando RF 433 Mhz
 *   equivale: estructura de datos char y string
 *   funciones: codificar y decodificar
 */

// PIN para el LED, led integrado = 13
#define PIN_LED 13
//Duración de un símbolo en  ms
#define DURACION 100
#define TxRfPin 4 

void setup(){
  pinMode(PIN_LED, OUTPUT );
  digitalWrite( PIN_LED, LOW );
  pinMode(TxRfPin, OUTPUT);
  digitalWrite( TxRfPin, LOW );
  
}

void loop(){
  String mensaje = " SOS  ";
  String mensajemorse;
  char simbolo;
  int n;
  mensajemorse = codifica(mensaje);
  // Transmite el mensaje
  n = mensajemorse.length();
  for(int i=0; i<=n; i++){
    simbolo = mensajemorse[i];
    morseTxRF(simbolo);
  }
}

void morseTxRF(char simbolo){
    if (simbolo == '.'){
        digitalWrite(PIN_LED, HIGH );
        digitalWrite(TxRfPin, HIGH);
        delay( DURACION ); 
        digitalWrite(PIN_LED, LOW );
        digitalWrite(TxRfPin, LOW);
        delay( DURACION );
    }
    if (simbolo == '-'){
        digitalWrite(PIN_LED, HIGH );
        digitalWrite(TxRfPin, HIGH);
        delay( DURACION*3 );
        digitalWrite(PIN_LED, LOW );
        digitalWrite(TxRfPin, LOW);
        delay( DURACION );
    }
    if (simbolo == ' ') {
        digitalWrite(PIN_LED, LOW );
        digitalWrite(TxRfPin, LOW);
        delay( DURACION );
    }
}

// Equivalente letra a código Morse. Estructura de datos
static const struct {const char letra, *codigo;} equivale[] =
{
  { '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', "--.." }, 
  { ' ', " " },   //espacio entre palabras 
  { '1', ".----" }, { '2', "..---" }, { '3', "...--" },
  { '4', "....-" }, { '5', "....." }, { '6', "-...." }, 
  { '7', "--..." }, { '8', "---.." }, { '9', "----." }, 
  { '0', "-----" },
  { '.', ".–.–.–" }, { ',', "--..--" }, { '?', "..--.." },
  { '!', "-.-.--" }, { ':', "---..." }, { ';', "-.-.-." }, 
  { '(', "-.--." }, { ')', "-.--.-" }, { '"', ".-..-." },
  { '@', ".--.-." }, { '&', ".-..." },
};

String codifica(String mensaje){
  String mensajemorse = "";
  int i, j, n, m;
  bool encontre;
  n = mensaje.length();
  m = (sizeof equivale / sizeof *equivale);
  for( i = 0; i<n; i++ ){
    encontre = 0;
    j=0;
    while(j<m and encontre==0){
      if(toupper(mensaje[i]) == equivale[j].letra){
        mensajemorse += equivale[j].codigo;
        encontre=1;
       }
      j++;
    }
    mensajemorse += " "; //separador de caracteres
  }
  return mensajemorse;  
}

Por realizar:

Fácilmente se determina la necesidad de un decodificador que use los datos y convierta a morse, o a texto, en el arduino o en un computador a partir de los datos seriales. Mostrar los datos en pantalla del PC o en una pantalla LCD en el arduino.

Morse Codec - LED y Buzzer

Se puede escuchar el tono del código morse enviado a un Buzzer en el pin 9.

Se añade al ejemplo anterior para un led la instrucción tone(PIN_BUZZER, NOTA, DURACION),

que requiere PIN_BUZZER, la frecuencia de la NOTA para el sonido y la duración.

El pin de señal S del Buzzer se conecta el Pin 9 del arduino, y se alimenta el VCC (+) y GND(-) completando todo lo necesario para que empiece a sonar el mensaje en el buzzer.

/*  CODificador morse
 *   recibe un mensaje y controla un buzzer en pin 9
 *   equivale: estructura de datos char y string
 *   funciones: codificar y decodificar
 */

// PIN para el LED, led integrado = 13
#define PIN_LED 13
#define PIN_BUZZER 9
#define NOTA 440
//Duración de un símbolo en  ms
#define DURACION 100

void setup(){
  pinMode( PIN_LED, OUTPUT );
  pinMode( PIN_BUZZER, OUTPUT );
  digitalWrite( PIN_LED, LOW );
}

void loop(){
  String mensaje = "SOS   ";
  String mensajemorse;
  char simbolo;
  int n;
  mensajemorse = codifica(mensaje);
  // Transmite el mensaje
  n = mensajemorse.length();
  for(int i=0; i<=n; i++){
    simbolo = mensajemorse[i];
    morseLedTx(simbolo);
  }
}

void morseLedTx(char simbolo){
    if (simbolo == '.'){
      digitalWrite( PIN_LED, HIGH );
      tone(PIN_BUZZER, NOTA, DURACION);
      delay( DURACION );
      digitalWrite( PIN_LED, LOW );
      delay( DURACION );
    }
    if (simbolo == '-'){
      digitalWrite( PIN_LED, HIGH );
      tone(PIN_BUZZER, NOTA, DURACION*3);
      delay( DURACION*3 );
      digitalWrite( PIN_LED, LOW );
      delay( DURACION );
    }
    if (simbolo == ' ') {
      delay( DURACION );
    }
}

// Equivalente letra a código Morse. Estructura de datos
static const struct {const char letra, *codigo;} equivale[] =
{
  { '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', "--.." }, 
  { ' ', " " },   //espacio entre palabras 
  { '1', ".----" }, { '2', "..---" }, { '3', "...--" },
  { '4', "....-" }, { '5', "....." }, { '6', "-...." }, 
  { '7', "--..." }, { '8', "---.." }, { '9', "----." }, 
  { '0', "-----" },
  { '.', ".–.–.–" }, { ',', "--..--" }, { '?', "..--.." },
  { '!', "-.-.--" }, { ':', "---..." }, { ';', "-.-.-." }, 
  { '(', "-.--." }, { ')', "-.--.-" }, { '"', ".-..-." },
  { '@', ".--.-." }, { '&', ".-..." },
};

String codifica(String mensaje){
  String mensajemorse = "";
  int i, j, n, m;
  bool encontre;
  n = mensaje.length();
  m = (sizeof equivale / sizeof *equivale);
  for( i = 0; i<n; i++ ){
    encontre = 0;
    j=0;
    while(j<m and encontre==0){
      if(toupper(mensaje[i]) == equivale[j].letra){
        mensajemorse += equivale[j].codigo;
        encontre=1;
       }
      j++;
    }
    mensajemorse += " "; //separador de caracteres
  }
  return mensajemorse;  
}

Referencia: https://www.arduino.cc/reference/en/language/functions/advanced-io/tone/

Serial - Envia y Recibe texto

Recibe mensajes de teclado usando el puerto serial, para prueba se usa "Monitor Serial" del programa de Arduino.

El programa solo hace ECO de lo recibido por el arduino, puede ser usado para enviar mensajes e intrucciones al arduino.

/*
 * Recibe y envia texto por puerto serial
 */
String datoserial = "";
void setup(){
  Serial.begin(9600);
}
void loop(){
    // Revisa datos escritos en monitor serial:
    if (Serial.available() > 0) {
        datoserial = Serial.readStringUntil('\n');
        //presenta en pantalla
        Serial.print("ECO Recibido: "); 
        Serial.println(datoserial);
        }
}

Referencia:

https://playground.arduino.cc/ArduinoNotebookTraduccion/Serial

https://www.arduino.cc/en/Serial/ReadStringUntil

 

TxRx Inalambrico 433Mhz ASK/OOK

Para la transmisión/recepción simplificada usa el módulo RF 433MHz, que dispone de un pin para DATA único necesario para el ejemplo.

No se incluyen librerias para los periféricos de transmisión TX o Receptor RX

Transmisor: un bit alto y un bit bajo.

La señal de prueba se compone de un bit alto (1) por 100ms, y un bit bajo(0) por 100ms, suficiente para exponer el concepto que se quiere dar.

Sin embargo, el ancho de bit puede ser cambiado de forma simétrica, asimétrica, ajustado a las necesidades de uso.

La señal se aplica en dos formas:

  • pin de transmisión, pin 4, aplicado al transmisor RF433 en DATA
  • pin para LED, pint 13, del arduino, como señal visual .

Las instrucciones para el primer arduino que controla la transmisión corresponden a:

/* Prueba de transmisión,
 *  parpadeo de led y transmisión de bit
*/

#define TxRfPin 4 
#define ledPin 13 

void setup(){
    pinMode(TxRfPin, OUTPUT); 
    pinMode(ledPin, OUTPUT); 
    digitalWrite(TxRfPin,LOW); 
    digitalWrite(ledPin, LOW);   
}

void loop(){ 
    digitalWrite(TxRfPin, HIGH); 
    digitalWrite(ledPin, HIGH); 
    delay(100); 
    
    digitalWrite(TxRfPin,LOW); 
    digitalWrite(ledPin, LOW); 
    delay(100); 
 }

Receptor

El receptor se arma con otro arduino y el periférico receptor. El pin DATA del receptor se conecta al arduino usando como entrada el pin analógico A0; se obtienen valores en el rango [0, 1023].

Una muestra de lo recibido en forma gráfica se obtiene de "Serial Plotter" del programa arduino, y los datos del "Serial Monitor"

0
0
0
0
0
0
0
0
0
1023
1022
1023
1023
1023
1023
1023
1023
1022
1023
1023
1023
1023
1023

Dado que los valores obtenidos son lecturas analógicas y pueden variar, se usan umbrales para la detección de un bit 1 y un bit 0 para encender o apagar el led del receptor.

Encender o apagar el led se decide con los valores de umbral.

/* 
*  Receptor RF 433
*  Prueba de recepción data analógico
*/

#define RxRfPin A0 
#define ledPin 13 
unsigned int data = 0;   
const unsigned int umbralAlto = 800; 
const unsigned int umbralBajo = 400;

void setup(){
    pinMode(ledPin, OUTPUT);
    digitalWrite(ledPin, LOW);
    Serial.begin(9600);
 }
 
void loop(){
    data=analogRead(RxRfPin);
    Serial.println(data);
    if(data>umbralAlto){
        digitalWrite(ledPin, HIGH);
    }
    if(data<umbralBajo){
        digitalWrite(ledPin, LOW);
    }
}

Esquematico de conexiones


Información adicional

Especificaciones técnicas del RF433 de geektech:

Transmisor

  • voltaje de funcionamiento: 3V ~ 12V\n\r
  • corriente de trabajo : max 40mA (12V ) , min 9mA ( 3V )
  • Resonance : ondas de sonido ( SAW)
  • modo de modulación: ASK / OOK
  • frecuencia de trabajo: 315MHz-433.92MHz,
  • Transmission potencia : 25 mW ( 315 MHz a 12 V )
  • Frequency : + 150 kHz (max)
  • velocidad: 10Kbps
  • self : negativo
  • Aerial Longitud: 24cm ( 315MHz ) , 18 cm ( 433,92 MHz )

RX especificaciones técnicas:

  • voltaje de funcionamiento: 5.0VDC + 0.5V
  • corriente de trabajo: 2.5mA (5.0VDC)
  • principio de funcionamiento: superheterodyn
  • Método de trabajo : OOK / ASK
  • Operating Frecuencia : 315 MHz , 433,92 MHz,
  • ancho de banda : 2 MHz ( 315 MHz , con el resultado de la prueba en Lowing la sensibilidad 3DBm )
  • sensibilidad: sobresale -105dBm (50)
  • señal de salida: señal de nivel eléctrico TTL total transmitir

Referencia: https://arduinobasics.blogspot.com/2014/06/433-mhz-rf-module-with-arduino-tutorial.html Revisado wl 14/04/2018

Capacitor carga y descarga

El experimento usa como sensor un puerto analógico/digital de un "arduino uno" para medir el voltaje del capacitor y el tiempo transcurrido desde el inicio del proceso de carga o descarga.

El concepto básico se aplica mediante un resistor y capacitor como el mostrado en el diagrama.
El valor de +V es de +5 Voltios, C = 220 μF y R = 1 kΩ.

Mediciones

El sensor entrega las mediciones del voltaje del capacitor como valores discretos en el rango [0, 1024), que son los valores discretos para el rango de voltajes [0, 5] en +V.

El dispositivo de medición entrega el tiempo transcurrido en microsegundos (μs) desde el inicio de evento de carga o descarga.

Los datos del sensor para la ejecución de un experimento se encuentran en el siguiente archivo de texto :
CargaDescargaDatos01.txt , cuyos datos se pueden procesar y graficar en cualquier software. El archivo contiene el número de muestra i, tiempo transcurrido y el valor de la medición, separados por comas (','):

i, tiempo, valor
0,212,5
1,5560,3
2,10948,2
3,16388,4
4,21820,4
....

Preguntas

  1. ¿Cuál es el valor de cada paso dy de en el eje y?,

Circuito de prueba con Arduino

Para las pruebas se usó un arduino uno con los valores de componentes mostrados en el diagrama esquematico.

Las mediciones de los voltajes del capacitor se realizan en el pin A0, que está en el bloque de entradas analógicas. El control de la carga se realiza con el pin 13 que pasa de estado alto +5V a estado bajo 0V, mientras que para la descarga se habilita el pin 11 para descarga más rápida con la resistencia R2. En el estado de carga el pin 11 pasa a un estado de alta impedancia, por lo que no afecta al circuito en general.

Como referencia se muestra el diagrama de conexiones físicas de los dispositivos.

El script de arduino usado en el arduino destaca los procesos de carga y descarga, asi como la escritura de los datos en el puerto serial.

/* carga y descarga de un capacitor, 
 * Para el ejercicio C=220 microf, Rcarga=1 kOhm, Rdescarga=470 Ohm
*/

// Pines usados
#define cargar 13   
#define descargar 11    // descarga auxiliar
#define medir 0 
unsigned long t0;   // tiempo inicio lecturas
unsigned int valorsensor;

void setup () {
  pinMode(cargar, OUTPUT );    // pin de carga  
  pinMode(descargar, OUTPUT ); // pin de descarga auxiliar
  Serial.begin(9600);          // envio dato serial
}

void loop(){
  /* Descarga capacitor */ 
  digitalWrite(cargar, LOW );
  pinMode(descargar, OUTPUT );               
  digitalWrite(descargar, LOW );          

  t0 = micros ();                 // tiempo inicial
  valorsensor = analogRead(medir);
  while (valorsensor> 0) {
    Serial.print ( micros ()-t0); // tiempo transcurrido 
    Serial.print ( "," );
    Serial.println(valorsensor) ;
    valorsensor = analogRead(medir);
  }
  
  /* carga capacitor */ 
  digitalWrite (cargar, HIGH ); 
  pinMode(descargar, INPUT );    // pin auxiliar con alta impedancia
  t0 = micros ();                 // tiempo inicial 
  valorsensor = analogRead (medir); 
  while (valorsensor <1016) {         // valor maximo de carga de 1024 
    Serial.print ( micros ()-t0);
    Serial.print ( "," );
    Serial.println (valorsensor);
    valorsensor = analogRead (medir);
  }
}

Lectura de datos con Python

Los datos de arduino se reciben en el computador por el puerto USB/Serial donde se encuentra conectado el arduino. Para el experimento se han tomado 500 muestras que luego se almacenan en el archivo de texto y se grafican los datos.

Para usar el código, será necesario verificar el puerto "com5" donde se encuentra conectado el arduino y los baudios usados para la transmisión de los datos. El puerto se revisa en el programa de arduino en el menú de herramientas/puerto cuando el arduino está conectado.

# Captura de datos desde puerto serial
# Generados desde arduino uno
import serial, time
import numpy as np
import matplotlib.pyplot as plt

# PROGRAMA
muestras = 500

puerto = 'com5'
baudios = 9600

# Procedimiento

# Inicializa comunicación con arduino
arduino = serial.Serial(puerto, baudios)
arduino.setDTR(False)  
time.sleep(0.3)  
# limpia buffer de datos anteriores
arduino.flushInput()  
arduino.setDTR()  
time.sleep(0.3)
print('\nEstado del puerto: ',arduino.isOpen())
print('Nombre del dispositivo conectado: ', arduino.name)
print('Dump de la configuración:\n ',arduino)
print('\n###############################################\n')

# Captura datos
datos = []
i = 0
while (i<muestras):
    while (arduino.inWaiting()==0):
        pass #esperar hasta recibir un dato
    linea = arduino.readline() # lee puerto serial
    lectura = linea.decode().strip() # elimina /r/n
    lectura=lectura.split(',')
    if (len(lectura)==2):
        tiempo = int(lectura[0])
        valor = int(lectura[1])
        undato= [i, tiempo, valor]
        datos.append(undato)
        print(undato)
        i=i+1
arduino.close()
# convierte lista a arreglo
datos=np.array(datos)

# Salida
np.savetxt('CargaDescargaDatos.txt',datos, fmt='%d', delimiter=',' )
plt.plot(datos[:,0],datos[:,2])
plt.title('Carga y descarga de capacitor')
plt.xlabel('muestra i')
plt.ylabel('valor[i]')
plt.show()

La comunicación se inicializa limpiando el bufer de datos anteriores que pueden distorsionar la toma de los primeros datos. El estado de la comunicación se muestra en el mismo bloque.

La captura de datos convierte la lectura en el puerto serial, a formato numérico para ser anadido a los datos.

Al final se almacenan los datos en un archivo en formato texto y se grafica lo obtenido.

Referencia: https://www.arduino.cc/en/Tutorial/CapacitanceMeter

Morse Deco - mensaje morse

decodificador de un mensaje en morse, al puerto serial

Puede visualizar el mensaje en la ventana del monitor Serial o algun programa que capture los datos.

/*  DECOdificador morse
 *   recibe un mensajemorse
 *   equivale: estructura de datos char y string
 *   funciones: codifica y decodifica
 */

// PIN para el LED, led integrado = 13
#define PIN_LED 13
//Duración de un símbolo en  ms
#define DURACION 250

void setup(){
  pinMode( PIN_LED, OUTPUT );
  digitalWrite( PIN_LED, LOW );
  Serial.begin(9600);
}

void loop(){
  String mensajemorse = ". ... .--. --- .-..   .. -- .--. ..- .-.. ... .- -. -.. ---   .-.. .-   ... --- -.-. .. . -.. .- -..   -.. . .-..   -.-. --- -. --- -.-. .. -- .. . -. - --- ";
  String mensaje;
  mensaje = decodifica(mensajemorse);
  Serial.println(mensaje);
  Serial.println(mensajemorse);
  delay(1500);
}

// Equivalente letra a código Morse. Estructura de datos
static const struct {const char letra, *codigo;} equivale[] =
{
  { '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', "--.." }, 
  { ' ', " " },   //espacio entre palabras 
  { '1', ".----" }, { '2', "..---" }, { '3', "...--" },
  { '4', "....-" }, { '5', "....." }, { '6', "-...." }, 
  { '7', "--..." }, { '8', "---.." }, { '9', "----." }, 
  { '0', "-----" },
  { '.', ".–.–.–" }, { ',', "--..--" }, { '?', "..--.." },
  { '!', "-.-.--" }, { ':', "---..." }, { ';', "-.-.-." }, 
  { '(', "-.--." }, { ')', "-.--.-" }, { '"', ".-..-." },
  { '@', ".--.-." }, { '&', ".-..." },
};

String decodifica(String mensajemorse){
  String simbolo, mensaje = "";
  bool encontre = 0;
  int j ,n, m, desde, proximo,cuenta;
  n = mensajemorse.length();
  m = sizeof equivale / sizeof *equivale;
  desde = 0;
  proximo = mensajemorse.indexOf(' ', desde);
  while(desde<n){
    //Busca equivalente
    encontre = 0;
    simbolo = mensajemorse.substring(desde, proximo);
    j = 0;
    while(j < m && encontre==0){
      if(simbolo == equivale[j].codigo){
        mensaje += equivale[j].letra;
        encontre = 1;
      }
      j++;
    }
    desde = proximo+1;
    // Espacios entre palabras
    proximo = mensajemorse.indexOf(' ', desde);
    while(mensajemorse[desde] == ' ' && mensajemorse[proximo+1]== ' '){
       proximo ++;
    }
  }
  return mensaje;
}

Morse Codec - LED

Codificador texto a morse.
Usando un LED para la señal morse. El led mas sencillo de usar es el incorporado en el Arduino.

Tareas por realizar:

  • usar un tono en un parlante o buzzer/zumbador.
  • usar un laser para transmitir la señal a distancias con linea de vista
  • usar un transmisor inalámbrico para transmitir la señal
  • Probar con un Xbee
  • analizar la secuencia de datos con un modelo de Cadena de Markov
/*  CODificador morse
 *   recibe un mensaje
 *   equivale: estructura de datos char y string
 *   funciones: codificar y decodificar
 */

// PIN para el LED, led integrado = 13
#define PIN_LED 13
//Duración de un símbolo en  ms
#define DURACION 250

void setup(){
  pinMode( PIN_LED, OUTPUT );
  digitalWrite( PIN_LED, LOW );
}

void loop(){
  String mensaje = "SOS ";
  String mensajemorse;
  char simbolo;
  int n;
  mensajemorse = codifica(mensaje);
  // Transmite el mensaje
  n = mensajemorse.length();
  for(int i=0; i<=n; i++){
    simbolo = mensajemorse[i];
    morseLedTx(simbolo);
  }
}

void morseLedTx(char simbolo){
    if (simbolo == '.'){
      digitalWrite( PIN_LED, HIGH );
      delay( DURACION );
      digitalWrite( PIN_LED, LOW );
      delay( DURACION );
    }
    if (simbolo == '-'){
      digitalWrite( PIN_LED, HIGH );
      delay( DURACION*3 );
      digitalWrite( PIN_LED, LOW );
      delay( DURACION );
    }
    if (simbolo == ' ') {
      delay( DURACION );
    }
}

// Equivalente letra a código Morse. Estructura de datos
static const struct {const char letra, *codigo;} equivale[] =
{
  { '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', "--.." }, 
  { ' ', " " },   //espacio entre palabras 
  { '1', ".----" }, { '2', "..---" }, { '3', "...--" },
  { '4', "....-" }, { '5', "....." }, { '6', "-...." }, 
  { '7', "--..." }, { '8', "---.." }, { '9', "----." }, 
  { '0', "-----" },
  { '.', ".–.–.–" }, { ',', "--..--" }, { '?', "..--.." },
  { '!', "-.-.--" }, { ':', "---..." }, { ';', "-.-.-." }, 
  { '(', "-.--." }, { ')', "-.--.-" }, { '"', ".-..-." },
  { '@', ".--.-." }, { '&', ".-..." },
};

String codifica(String mensaje){
  String mensajemorse = "";
  int i, j, n, m;
  bool encontre;
  n = mensaje.length();
  m = (sizeof equivale / sizeof *equivale);
  for( i = 0; i<n; i++ ){
    encontre = 0;
    j=0;
    while(j<m and encontre==0){
      if(toupper(mensaje[i]) == equivale[j].letra){
        mensajemorse += equivale[j].codigo;
        encontre=1;
       }
      j++;
    }
    mensajemorse += " "; //separador de caracteres
  }
  return mensajemorse;  
}