Está en la página 1de 11

INFORME

NRC: 5037

FECHA DE ENTREGA: 21-06-2019

TEMA: COMUNICACIÓN PUERTO SERIAL Y RESOLUCION DE MATRICES


PYTHON

RESUMEN:

Para quienes estudiamos el mundo de la electrónica y comunicaciones hemos visto la


necesidad de interactuar y compartir nuestros conocimientos o proyectos de un dispositivo
digital a otro, para esto el puerto Serial es un tipo de comunicación simple, un módulo de
comunicación para un sistema embebido que permite la conexión entre dos dispositivos
digitales. Es el proceso de envío de datos de un bit a la vez, de forma secuencial, sobre un
canal como el cable de conversión USB puerto serie RS232. Para poner en práctica el uso
de puertos seriales hemos escogido el lenguaje de programación Python para la resolución
de matrices, ya que el lenguaje matricial es el punto de partida para una enorme variedad de
desarrollos físicos y matemáticos.

Palabras claves:

Puerto serial: Interfaz de comunicaciones de datos digitales, frecuentemente utilizado por


computadoras y periféricos, donde la información es transmitida bit a bit, enviando un solo
bit a la vez; en contraste con el puerto paralelo que envía varios bits simultáneamente.
Python: Es un lenguaje de scripting independiente de plataforma y orientado a objetos,
preparado para realizar cualquier tipo de programa, desde aplicaciones Windows a
servidores de red o incluso, páginas web.

Resolución de matrices: Resolución de la solución de un conjunto de ecuaciones lineales.

OBJETIVOS:

1) Conocer el funcionamiento del puerto serial desde el punto de vista del programador
Python.

2) Desarrollar una operación de matrices capaz de ser usado en dos dispositivos


diferentes mediante el uso del puerto serial

3) Dominar la comunicación bidireccional usando el cable de conversión USB puerto


serie RS232.

Diseño de Software

Programa emisor: Emisor.py

El programa Emisor.py se encarga de solicitar al usuario que ingrese las dimensiones y


elementos de una matriz, todo esto por teclado, para que posteriormente sean enviados
mediante una conexión serial a otro computador que recibirá estos datos.

import numpy
import serial

Importamos las librerías que vamos a utilizar a lo largo del programa, serial para realizar la
comunicación con el puerto, y numpy, una librería especializada en el álgebra lineal en
Python.

filE = eval (input("Ingrese el numero de filas de la matriz A: "))


colE = eval (input ("Ingrese el numero de columnas de la matriz A: "))
filF = eval (input ("Ingrese el numero de filas de la matriz B: "))
colF = eval (input ("Ingrese el numero de columnas de la matriz B: "))
Se solicita el ingreso por teclado de las dimensiones de la matriz A y B, los cuales se
almacenarán en las variables indicadas.

E=numpy.zeros((filE, colE))
F=numpy.zeros((filF, colF))

Creamos dos matrices de ceros, las cuales tendrán las dimensiones ingresadas por teclado,
estas matrices serán llenadas posteriormente con datos ingresados por teclado.

print ("\n--------------------------INGRESE LOS ELEMENTOS DE LAS MATRICES--------


---------------")
print ("MATRIZ A: ")
for i in range (0,filE):
for j in range (0, colE):
E [(i, j)] =input ("ELEMENTO A["+str(i+1) +","+str(j+1) +"]: ")

print ("\nMATRIZ B:")


for i in range (0, filF):
for j in range (0, colF):
F [(i, j)] =input ("ELEMENTO B["+str(i+1) +","+str(j+1) +"]: ")

print ("\nMATRIZ A")


print (E)
print ("\nMATRIZ B")
print (F)

Se imprime un mensaje informando que se ingresarán los elementos de las matrices,


iterando un for dentro de otro, ingresamos los valores dentro de E, esto es posible gracias a
que en una variable de tipo numpy.nparray requiere de dos datos para especificar la
posición de las variables ingresadas en ella, de esta manera, cuando j llegue a su valor
máximo, se reiniciará e i aumentará su valor por uno cada vez que esto ocurra, de esta
forma, se itera cada uno de los valores dentro del array, debido a que el primer valor que
requiere E es el que corresponde a la fila en la que se trabaja, la cual es una lista en sí, que
contiene valores como cualquier otra. E contendrá los valores que corresponden a la matriz
A, este valor pese a ser ingresado originalmente como tipo str (carácter), se adjuntará a la
matriz como variable de tipo numpy.float64, que es una variante de float (enteros y
decimales).

Para la matriz F, que corresponde a la matriz B, se realiza la misma operación, se iterará un


for dentro de otro para especificar las posiciones de los elementos y el mensaje explicará el
orden en el que se están ingresando los datos.

Al finalizar el ingreso de los datos, se imprimirán las matrices con sus nuevos valores
explicando cual es cual, una después de la otra.

s = serial. Serial("COM3",9600)

Establece el nombre del objeto que servirá de conexión con el puente creado entre el
COM3 Y el COM3 de otro computador. En este caso, al tratarse del emisor, conecta al
COM3, y se coloca una velocidad de transmisión en 9600 (baudios), además, como no se
define un tiempo de espera de error, el programa proseguirá intentando realizar las acciones
descritas que tengan algo que ver con el objeto s.

s.write(str(filE).encode())
s.write(str(colE).encode())
s.write(str(filF).encode())
s.write(str(colF).encode())

En vista de que se necesita enviar datos por medio de un puerto serial, usamos las funciones
definidas dentro de la librería serial para objetos ligados a puertos seriales, en este caso
usaremos write(), el cual envía datos de tipo byte o cadena de bytes por medio del puerto
serial, debido a que este el único dato que se soporta al enviar. Como se requiere enviar los
datos que corresponden a las dimensiones de E y F, los cuales son de tipo int (entero), se
requiere transformarlos a byte, esto es posible mediante la función encode(), el cual
codifica como cadena de bytes cualquier dato ingresado, el problema es que solo
transforma cadenas de caracteres, por lo tanto se tiene que transformar primero a str
(cadena de caracteres) antes de utilizar encode() para que sean enviados. Por este motivo es
que la sintaxis del dato enviado es de la forma “str(dato).encode()”.
El orden en el que se envían los datos es:
Filas de E
Columnas de E
Filas de F
Columnas de F

for fil in range (0,filE):


for col in range(0, colE):
try:
i=str(E[fil,col])
s.write(str(len(i)).encode())
s.write(i.encode())
except: pass

for fil in range (0,filF):


for col in range(0,colF):
try:
i=str(F[fil,col])
s.write(str(len(i)).encode())
s.write(i.encode())
except: pass

De sintaxis para ingresar los datos dentro de la matriz se deriva este proceso, el cual itera
valor a valor los datos dentro de la matriz, sean estos del número de cifras que sean, y los
procede a enviar, primero almacena en i el valor en str (cadena de caracteres) del dato
iterado, se envía su longitud, en otras palabras, el número de datos que contiene, con la
función len(i), como esto nos devuelve un valor entero, debe ser transformado a cadena de
caracteres para ser enviado, por último se envía el dato iterado, como i ya almaceno su
valor como cadena de caracteres, solo se utiliza encode() para enviarlo.

Este proceso se repite para los valores de ambas matrices, pero como es de esperarse los
datos que se envían primero son los de E, correspondiente a la matriz A, y posteriormente
F, correspondiente a la matriz B.
s. close()

Para evitar problemas en los que el puerto se mantiene abierto aun después de terminar la
ejecución, lo cual causa que este puerto ya no pueda ser utilizado posteriormente, pérdida al
momento de enviar datos, etc.; se utiliza la función close (), la cual cierra el objeto s y po
ende la conexión con el puerto en el que se trabaja.

Programa emisor: Receptor.py

import numpy
import serial
s = serial.Serial("COM3",9600)

Este programa toma todos los datos enviados por el primero, los almacena en variables y
transforma su tipo original (byte) en uno más conveniente para trabajar dentro de un
programa de matrices. Además, pregunta al usuario que operaciones quiere realizar con los
datos que le ha sido enviados e imprime el resultado.

Importamos a las dos librerías con las que trabajó el programa emisor y creamos un objeto
para conectar con el puerto serial ‘COM3’, y sólo definimos la velocidad de conexión en
baudios, no colocamos un timeout, debido a que esto haría que read() deje de esperar los
datos a leer después de un determinado tiempo, la idea es que el programa espere
indefinidamente hasta que los datos sean enviados completos.

filE=s.read().decode()
colE=s.read().decode()
filF=s.read().decode()
colF=s.read().decode()

filE=int(filE)
colE=int(colE)
filF=int(filF)
colF=int(colF)

Almacenamos los valores de filas y columnas de las matrices que se desean leer en este
programa, para ello, usamos la función read(), la cual está ligada a objetos de tipo serial,
esto me devuelve una cantidad determinada de datos de los cuales fueron ingresados en el
anterior programa. La sintaxis de la función read es: “.read(size)” donde size representa a la
cantidad de datos que se desea leer, el cual debe estar en valores de tipo entero, si no se
especifica un dato dentro de los paréntesis se toma 1 como valor por defecto. Como los
datos enviados son de tipo cadena de bytes, el tipo de dato a leer será del mismo tipo, razón
por la cual usamos la función decode(), la cual realiza la acción inversa a encode(), es decir,
esta función me transforma una cadena de bytes en cadena de caracteres.

Una vez leídos y almacenados los valores que se requieren, es necesario transformarlos a
enteros debido a que realizaremos operaciones en las cuales se necesita que estos valores
sean numéricos.

La sintaxis para esto es: “x= int(x)”, la cual permite que el valor ingresado dentro de una
variable sea almacenado en ella misma, pero ahora de un tipo diferente, en este caso,
entero.

A=numpy.zeros((int(filE),int(colE)))
B=numpy.zeros((int(filF),int(colF)))
C=numpy.zeros((int(filE),int(colF)))
D=numpy.zeros((int(filE),int(colE)))

Creamos 4 matrices nulas de la dimensión enviada por el programa emisor, estas matrices
me servirán para almacenar e imprimir las respuestas en esta parte del programa. Las
matrices nulas se crean gracias a la función zeros(()) que pertenece a la librería de numpy,
la cual permite crear una matriz nula del orden indicado dentro de los paréntesis.

for i in range(0,int(filE)) :
for j in range(0,int(colE)):
l=int(s.read())
A[i,j]=float(s.read(l))
print("")
print("Matriz A \n")
print(A)
Al igual que antes, iteramos un for dentro de otro para especificar las posiciones de los
elementos dentro de la matriz. En este caso, primero almacenamos en l el valor entero del
dato que se está leyendo, este dato me sirve de referencia para saber cuántos caracteres
debe leer la siguiente línea de código, después, ingresamos el valor tipo float (decimal y
entero) leído, para saber la cantidad de datos que se requiere leer se utiliza len.

Una vez ingresados todos los datos se imprime la matriz para mostrar lo que se ha leído
hasta ahora.

Este proceso se repite para ingresar los datos dentro de B, que tomará los valores de la
matriz F definida dentro del programa emisor.

def menu():
print ("\n")
print ("\t1 - Suma")
print ("\t2 - Producto")
print ("\t3 - Transpuesta")
print ("\t4 - Determinante")
print ("\t5 - Salir")

Definimos una función interna que imprime un menú de opciones de las operaciones que se
pueden hacer en este programa.

Esta función específica el número que se debe ingresar para realizar una operación.

while True:
menu()
op=input("Seleccione una opción:")
if op=="1":
if filE==filF and colE==colF:
print ("\n---------------------------RESULTADO-----------------------")
print("\nSuma de matrices")
for i in range(filE):
for j in range(colF):
D[i][j]=A[i][j]+B[i][j]
print (D)
else:
print ("\n---------------------------RESULTADO-----------------------")
print("\nNo se pueden sumar las matrices")
print("\n")

elif op=="2":
if colE!= filF:
print ("\nNO SE PUEDE MULTIPLICAR LAS MATRICES")
print ("REVISAR LAS DIMENSIONES")
else:
print ("\n---------------------------RESULTADO-----------------------")
print("\multiplicación de matrices")
for i in range (0,filE):
for j in range (0,colF):
for r in range (0,colE):
C[i, j]+=A[i,r]*B[r,j]
print ("\nLa matriz resultante es una de:")
print (filE,"x",colF)
print ("\nMultiplicacion C =")
print (C)

elif op=="3":
print ("\n---------------------------RESULTADO-----------------------")
print("\nMatriz transpuesta de A")
print(numpy.transpose(A))
print("\nMatriz transpuesta de B")
print(numpy.transpose(B))

elif op=="4":
print ("\n-----------------------RESULTADO--------------------")
if filE==colE and filF==colF:
print("\nDeterminante de A:")
print("{0:.1f}".format(numpy.linalg.det(A)))
print("\nDeterminante de B:")
print("{0:.1f}".format(numpy.linalg.det(B)))
else:
if filE==colE:
print("\nDeterminante de A:")
print("{0:.1f}".format(numpy.linalg.det(A)))
else:
print("\nLa matriz A no es cuadrada")
if filF==colF:
print("\nDeterminante de B:")
print("{0:.1f}".format(numpy.linalg.det(B)))
else:
print("\nLa matriz B no es cuadrada")

elif op=="5":
break

Se crea un bucle que se repetirá infinitamente a menos que se ingrese 5, ya que si se ingresa
esto se llama al evento break, el cual termina con las repeticiones del bucle.

Dependiendo del número ingresado se imprimirá el resultado deseado y se realizará las


operaciones pertinentes para hallarlo.

Conclusiones

El programa fue llevado a en su totalidad con éxito, esto se puede afirmar debido a que no
sólo me permite el ingreso de valores enteros, sino que también me permite el ingreso de
valores negativos y de tipo float (decimal y entero).
El uso de librerías, como lo son numpy, puede agilitar y compactar el proceso de
programación de manera que es más fácil para el programador cumplir los requisitos que se
deseaban para el sistema.

Recomendaciones

Utilizar librerías para ahorrar programación y optimizar espacio dentro del módulo.

Revisar adecuadamente la sintaxis de las funciones que se desea usar, esto ayudaría a
usarlas mejor y a aumentar su eficiencia dentro del programa. Me refiero a funciones como
print, read, write, etc.

Identificar correctamente el puerto serial que vamos a utilizar para la conexión, tanto para
emisión como para recepción.

También podría gustarte