Skip to content
Snippets Groups Projects
Commit 13565f6a authored by Martina Barreiro Guerra's avatar Martina Barreiro Guerra
Browse files

Arduino

parent cb171877
No related branches found
No related tags found
No related merge requests found
import time
import numpy as np
import serial
import serial.tools.list_ports
import array as arr
from ImpetomCError import ImpetomCError
from Archivos import Archivos
class Arduino:
"""
Esta clase permite la creación y manejo del objeto Arduino.
"""
def __init__(self,baudrate, timeout,vThreshold):
"""
Método constructor para la clase Arduino. Permite la creación del objeto arduino. En caso de existir un Arduino conectado a la PC, lo detecta y guarda en este objeto el puerto COM y abre el canal serial.
:param baudrate: Es la frecuencia del canal serial
:param timeout: Es el valor máximo de tiempo antes de que el canal se cierre sin que se haya recibido ningun dato. Se recomienda no poner timeout menor a 0.1 ya que si no da la conexión da problemas.
:param vThreshold: Es el valor de voltaje a partir del cual se considera que el electrodo esta mal conectado (debe ser un float)
:exception ImpetomCError: Devuelve una excepción indicando que no se detecto ningun arduino conectado a la pc
"""
self.puerto = self.__buscarPuertoCom()
self.baudrate = baudrate
self.modo = 0 # Modo Setup por defecto, modo Reconstrucción = 1
self.timeout = timeout
self.frecuenciaDDS = "30000"
self.ard = serial.Serial(port=self.puerto,baudrate=self.baudrate,timeout=self.timeout)
self.vThreshold = vThreshold
self.__establecerComunicacion()
self.modoColocacionPares = False
self.datos = np.zeros(208)
def __buscarPuertoCom(self):
"""
Esta función permite buscar al arduino dentro de los puertos COM conectados al PC
:exception ImpetomCError: Tira un error en caso de no encontrar ningún arduino conectado al sistema
"""
ports = list(serial.tools.list_ports.comports())
ArduinoPort = ''
for p in ports:
if "CH340" in p.description or "USB" in p.description or "COM3" in p.description:# Windows reconoce así al arduino
ArduinoPort = p.name
if ArduinoPort == '':
raise ImpetomCError ("Error: No se encontró ningún dispositivo Arduino conectado.")
else:
return ArduinoPort
def __establecerComunicacion (self):
"""
Esta función establece la comunicación entre la pc y el arduino de impetomC.
:exception ImpetomCError: Devuelve una excepción indicando que el Arduino conectado no es el arduino de Impetom Clínico.
"""
data = ""
intento = 0
while data == "" and intento < 20:
self.ard.write(bytes("1", 'utf-8'))
time.sleep(0.05)
data = self.ard.readline().decode('utf-8').rstrip()
intento += 1
if intento == 20 or data != "ImpetomC":
raise ImpetomCError("Error: No se encontró el dispositivo de ImpetomC.")
time.sleep(0.05)
def obtenerMedidas(self):
"""
Esta función obtiene las 208 medidas de tensión realizadas por el arduino ImpetomC para la reconstrucción tomográfica.
:returns: **datos** - Devuelve el vector con las 208 medidas realizadas.
**voltajesElevados** - Devuelve la cantidad de voltajes por encima de vThreshold.
**frecuenciaArd** - Retorna el valor de la frecuencia a la que esta operando el dispositivo Impetom.
**voltajesElevadosSeguidos** - Retorna la cantidad de voltajes elevados consecutivos (> vThreshold) que fueron detectados. Este dato se utiliza para verificar si hay electrodos desconectados en el dispositivo físico.
**tiraMedidaElevada** - Retorna el valor del electrodo que se detectó esta desconectado en el dispositivo físico.
:exception ImpetomCError: En caso de que el Arduino ImpetomC se haya desconectado durante la adquisición de datos devuelve una excepción.
"""
modo = str(self.modo)
try:
self.ard.write(bytes(modo, 'utf-8'))# Indico al Arduino ImpetomC en que modo debe operar (0 - Setup ; 1 - Reconstrucción)
self.ard.write(bytes(self.frecuenciaDDS,'utf-8')) # Indico al Arduino ImpetomC a que frecuencia debe operar
i=0
j=0
tiraMedida = 0
tiraMedidaElevada = np.zeros(16)
ele_seguidos=0
voltajesElevadosSeguidos=0
voltajesElevados=0
while i < 208:
data = self.ard.readline().decode('utf-8').rstrip()
if data != "": # Esto es para asegurarme que cada vez que le pido un dato al equipo, lo recibo sin problemas. A veces sucede que no da la velocidad del canal
num = float(int(data) * 5 / 1023)
self.datos[i]= num
i += 1
if i % 13 == 0: # Cada par de electrodos de corriente tiene 13 medidas de tensión asosciadas, con esto identifico los electrodos de corriente
tiraMedida += 1
if num > self.vThreshold :
ele_seguidos +=1
voltajesElevados += 1
voltajesElevadosSeguidos = max(voltajesElevadosSeguidos, ele_seguidos)
if ele_seguidos % 13 == 0: # Registro tira de 13 voltajes elevados
if j<16 and tiraMedidaElevada[j] != tiraMedida:
tiraMedidaElevada[j] = tiraMedida
j += 1
else: ele_seguidos = 0
frecuenciaArd = self.ard.readline().decode('utf-8').rstrip()
except serial.SerialException:#Manejo del error de si el dispositivo se desconecta durante la adquisición de datos
raise ImpetomCError("El Hardware se desconectó durante la adquisición.")
self.datos=np.float32(self.datos)
return [self.datos,voltajesElevados,frecuenciaArd,voltajesElevadosSeguidos,tiraMedidaElevada]
def cambiarModoDeOperacion(self,mode):
"""
Esta función permite realizar el cambio de modo del Arduino ImpetomC.
:param mode: String que debe indicar : "Reconstrucción" o "Setup".
:exception ImpetomCError: Tira una excepción en caso de que mode sea distinto a los valores aceptados.
"""
if (mode == "Reconstruccion"):
self.modo = 1
elif (mode == "Setup"):
self.modo = 0
else:
raise ImpetomCError("Error: Modo de operación incorrecto. Debe ser \"Reconstruccion\" o \"Setup\"")
def cambiarFrecuenciaDDS(self,frecuenciaDDS):
"""
Función que permite cambiar el valor de la frecuencia del DDS del dispositvo ImpetomC.
:param frecuenciaDDS: Valor de la nueva frecuencia del DDS.
"""
if(type(frecuenciaDDS) != str):
raise ImpetomCError("Error: La frecuencia del DDS debe estar en formato String")
self.frecuenciaDDS=str(frecuenciaDDS)
def abrirPuertoSerie(self):
"""
Permite abrir el puerto serie.
Por defecto cuando se crea el objeto el puerto queda abierto, por lo que solo se debe usar si el puerto se
cerró en algun momento.
:except ImpetomCError: En caso de utilizarse con el puerto ya abierto devuelve una excepción.
"""
try:
self.ard.open()
self.__establecerComunicacion()
except serial.SerialException as se: # En caso de que se haya desconectado el dispositivo
if (str(se) == "El puerto ya está siendo utilizado"): # En caso de que el puerto ya esté abierto
raise ImpetomCError(str(se))
else: # En caso de que el error sea por una desconexión
self.puerto=self.__buscarPuertoCom()
self.ard = serial.Serial(port=self.puerto,baudrate=self.baudrate,timeout=self.timeout)
self.__establecerComunicacion()
def cerrarPuertoSerie(self):
"""
Permite cerrar el puerto serie.
"""
self.ard.close()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment