You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

928 lines
52 KiB
TeX

% !TeX spellcheck = es_MX
%!TeX root=../thesisStructure.tex
\chapter{Desarrollo del sistema} % Chapter title
\label{ch:desarrollo}
\begin{figure}[!h]
\centering
\includegraphics[width=12cm]{figures/system.png}
\caption{Diagrama del sistema desarrollado.}
\label{fig:diagramadelsistema}
\end{figure}
%resumen del capítulo
%sistema de adquisición de datos
%elementos
%beaglebone
%sensores
%atmósfera
%circuito de protección
%programa de adquisición
%funciones
%librerias
%funciones
%conexiones
%archivo de datos
En este capítulo se presenta una descripción detallada del sistema de adquisición de datos desarrollado en este trabajo y sus elementos, tanto de \textit{hardware} como de \textit{software}, así como su funcionamiento, y su utilización.
Dentro de los temas que se abordan están:
descripción de la \textit{single-board computer} utilizada y sus configuraciones,
sensores utilizados y su configuración,
la atmósfera aislada implementada,
el circuito de protección utilizado,
descripción del programa para la adquisición de datos y sus funciones utilizadas,
librerías desarrolladas,
ejemplo del archivo de datos generado,
con los cuales se podrá tener un buen entendimiento profundo de este sistema y utilizarlo o replicarlo.
%desarrollo de un sistema que pueda ser adaptable, configurable...
%Overview del sistema
El sistema implementado en este trabajo, mostrado en la \autoref{fig:diagramadelsistema}, es capaz de recabar información de una atmósfera o un ambiente, obteniendo las mediciones
de las concentraciones de $CO$, $CO_2$ y $O_2$, % monóxido y bióxido de carbono, oxígeno,
además de la temperatura, presión y humedad relativa,
por medio de sensores controlados por una \textit{single-board computer} \textit{Beaglebone}.
%elementos
Este sistema consta de
%beaglebone
una \textit{single-board computer} (computadora de una sola placa) \textit{Beaglebone Black},
%remote device
que es accedida por otro dispositivo de forma remota a través del protocolo Secure Shell (SSH).
%sensores
También integra
los sensores \textit{CO-AF} ($CO$), \textit{SprintIR} ($CO_2$) y \textit{LuminOx} ($O_2$),
%circuito de protección
y un circuito de aislamiento para conectar los sensores a la \textit{Beaglebone} de forma segura.
Dentro de la \textit{Beaglebone} se encuentran los archivos del código fuente del programa para la adquisición de datos, así como el archivo de datos del registro, donde quedan guardadas las mediciones una vez que éstas ha sido realizadas.
El funcionamiento de este sistema puede ser adaptable, pudiendo establecer los parámetros de la duración de la adquisición y su periodo de muestreo al iniciarla desde la terminal de la \textit{Beaglebone}.
%También existe la posibilidad de modificar el código fuente del programa si se requiere una mayor personalización.
%conexiones
Para alimentar al sistema se utiliza una fuente de CD de 5 volts con 2 amperios
y se conecta a una red por medio de un cable \textit{Ethernet} (pudiendo conectarse con \textit{Wi-Fi}, en el caso de disponer de una tarjeta \textit{WLAN})
para poder hacer uso del protocolo \textit{SSH}.
%atmosfera/pruebas
Para realizar mediciones de prueba,
los sensores fueron montados dentro de una atmósfera aislada (parcialmente).
Este sistema se prueba con dos métodos, donde se introducen a la atmósfera aislada los gases de exhalación de una persona en (1), y en (2) se introduce una vela encendida (combustión).
Estas pruebas se describen en el capítulo 4, donde también se muestran los resultados de las mismas.
\section{Beaglebone Black}
Como ya se mencionó anteriormente, este sistema utiliza la \textit{single-board computer} \textit{\textbf{Beaglebone Black}}, mostrada en la \autoref{fig:BBB}, con la cuál
%Funciones que realiza
se controlan los sensores y
se registran las mediciones obtenidas de éstos.
Esta tarjeta cuenta con una generosa variedad de periféricos y un sistema operativo basado en \textit{Linux},
lo que le da gran versatilidad al sistema,
pudiendo adaptarlo a las necesidades de la adquisición de datos
y siendo posible además agregar más funciones para diferentes adquisiciones de datos.
\begin{figure}[!h]
\centering
\includegraphics[width=12cm]{figures/beaglebone-black.jpg}
\caption{Beaglebone Black Rev. C.}
\label{fig:BBB}
\end{figure}
%BBB > control sensores > comandos > conf/mediciones > comm UART > programa > código fuente
La \textit{Beaglebone} controla a los sensores de gas a través de comandos, con los cuales los configura y les solicita mediciones;
también se puede obtener información de los sensores. % con estos comandos).
Dichos comandos son enviados a través de los puertos \textit{UART}, con los cuales la \textit{Beaglebone} se comunica con los sensores.
La gestión de esta comunicación, así como control de los sensores y el registro de las mediciones, se realiza con un programa desarrollado para este sistema, el cuál se ejecuta en la \textit{Beaglebone}.
%El código fuente de este programa y el archivo de datos generado por el mismo se encuentran también dentro de la \textit{Beaglebone}.
El programa y la librería utilizada para la comunicación a través de UART, así como sus funciones, se explican a detalle en la \autoref{sec:program}.
%acceso remoto
En este sistema implementado, la \textit{Beaglebone Black} puede utilizarse con cualquier dispositivo que pueda hacer uso del protocolo SSH.
Por medio de éste, se accede a la terminal para ejecutar comandos \texttt{bash}.
De esta forma es posible correr el programa de adquisición de datos, obtener el archivo de datos con los resultados de la adquisición, o modificar el código fuente del programa (en caso de ser necesario).
%Software de la tarjeta
En esta aplicación, la \textit{Beaglebone Black} utiliza el sistema operativo \textit{Debian},
específicamente la versión \textit{Debian 9.9 Stretch LXQT} (con interfaz gráfica).
Este sistema operativo está instalado
en una memoria de 16 GB insertada en la ranura para tarjetas micro SD de la \textit{Beaglebone}.
De esta forma el sistema no está tan limitado con el espacio de almacenamiento y se pueden instalar actualizaciones y software adicional en caso de ser necesario.
La imagen del sistema operativo puede ser descargada desde la página oficial de \textit{BeagleBoard} (beagleboard.org).
\subsection{Configuraciones realizadas en la \textit{Beaglebone}}
Antes de utilizar la \textit{Beaglebone Black} en esta aplicación, se realizaron algunas configuraciones y actualizaciones para facilitar su utilización, estos cambios se enlistan a continuación:
\begin{itemize}
\item Se cambio el \textit{hostname} a beagleboard, con el comando \texttt{sudo} \texttt{hostnamectl} \texttt{--static} \texttt{set-hostname beagleboard} para poder diferenciarla en caso de haber otras Beaglebone en la misma red.
\item Se configuró la hora local ejecutando el comando \texttt{sudo dpkg-reconfigure tzdata} y eligiendo la zona horaria de México para un manejo correcto de la hora y fecha.
\item Se expandió la partición del sistema de archivos para poder utilizar todo el espacio disponible de la tarjeta micro SD, actualizando el \textit{script} \texttt{grow\_partition} y después ejecutándolo como se muestra en el Listado \ref{lst:grow_partition}.
\item Se ejecutó el comando \texttt{sudo tools/update\_kernel.sh} para
actualizar los \textit{scripts} de \textit{booteo} y \textit{kernel} de \textit{Linux} y así funcionaran de manera óptima.
\item Se actualizaron componentes de la distribución con el comando \texttt{sudo apt update} y \texttt{sudo apt upgrade} y también \texttt{sudo apt install -y ti-tidl mjpg-streamer-opencv-python} para el correcto funcionamiento de estos.
\item Se automatizó la configuración de los pines de los puertos UART durante el arranque del sistema.
Para esto se tuvo que crear el \textit{script} de \texttt{bash} \texttt{config-uart-pins.sh}, mostrado en \autoref{lst:config-uart-pins.sh}, en la ruta: \texttt{/usr/bin};
y un ``servicio del sistema'' (\texttt{ebb-set-uart-pins.service}), mostrado en el \autoref{lst:uart-pins-service}, en la ruta: \texttt{/lib/systemd/system}.
Este servicio del sistema se probó y se instaló utilizando los comandos del \autoref{lst:uart-pins-comandos}.
De esta forma, éste se ejecuta durante el arranque y llama al \textit{script} (\texttt{config-uart-pins.sh}).
Los archivos mencioandos en el último punto se encuentran alojados en \textbf{TBD}, al que se puede acceder desde el enlace: \url{TBC:https://gitlab.com/sayeth.rd/daq-serial-bbb/resources}.
\end{itemize}
\begin{lstlisting}[language=bash, basicstyle=\mlttfamily\fontsize{6}{8}\selectfont, label=lst:grow_partition, frame= lines, caption= {Comandos para expandir la partición del sistema de archivos.}]
cd /opt/scripts
git pull
sudo /opt/scripts/tools/grow_partition.sh
\end{lstlisting}
\begin{lstlisting}[language=bash, basicstyle=\mlttfamily\fontsize{6}{8}\selectfont, label=lst:config-uart-pins.sh, frame= lines, caption= {Archivo \texttt{config-uart-pins.sh}.}]
#!/bin/bash
#uart1
config-pin P9_24 uart
config-pin -q P9_24
config-pin P9_26 uart
config-pin -q P9_26
#uart2
config-pin P9_21 uart
config-pin -q P9_21
config-pin P9_22 uart
config-pin -q P9_22
#uart4
config-pin P9_13 uart
config-pin -q P9_13
config-pin P9_11 uart
config-pin -q P9_11
\end{lstlisting}
\begin{lstlisting}[language=bash, basicstyle=\mlttfamily\fontsize{6}{8}\selectfont, label=lst:uart-pins-service, frame= lines, caption= {Archivo \texttt{ebb-set-uart-pins.service} de servicio del sistema.}]
[Unit]
Description=Enable the UART pins on boot
After=generic-board-startup.service
[Service]
Type=simple
User=root
WorkingDirectory=/usr/bin
ExecStart=/usr/bin/config-uart-pins.sh
[Install]
WantedBy=multi-user.target
\end{lstlisting}
\begin{lstlisting}[language=bash, basicstyle=\mlttfamily\fontsize{6}{8}\selectfont, label=lst:uart-pins-comandos, frame= lines, caption= {Comandos para probar e instalar el servicio \texttt{ebb-set-uart-pins.service} en la \textit{Beaglebone}.}]
cd /lib/systemd/system
sudo su
systemd-analyze verify ebb-set-uart-pins.service
systemctl daemon-reload
systemctl enable ebb-set-uarts-pins.service
\end{lstlisting}
\section{Sensores de concentración de gases}
%intro
En este sistema desarrollado se utilizan tres sensores de concentración de gases diferentes,
cada uno con su respectivo circuito de control.
%sensores
Los sensores utilizados en este sistema son:
el sensor de monóxido de carbono
\textbf{CO-AF} de la compañía \textit{Alphasense}, mostrado en la \autoref{subfig:CO-AFsensor},
el sensor de bióxido de carbono
\textbf{SprintIR} de la compañía \textit{Gas Sensing Solutions}, mostrado en la \autoref{subfig:sprintIR}
y el sensor de oxígeno
\textbf{LuminOx Optical Oxygen LOX-02} del fabricante \textit{SST}, mostrado en la \autoref{subfig:LuminOX}.
%capacidades de los sensores
Con estos sensores, el sistema es capaz de medir concentraciones de hasta
250,000 partes por millón (25\%) de $O_2$,
5,000 partes por millón (0.5\%) de $CO$,
y 200,000 partes por millón (20\%) de $CO_2$.
Algunos de estos sensores también pueden medir la temperatura, humedad y presión del ambiente.
\begin{figure}[!h]
\centering
\subfigure[CO-AF]{
\label{subfig:CO-AFsensor}
\includegraphics[height=3cm]{figures/CO-AFsensor}
}
\subfigure[SprintIR]{
\label{subfig:sprintIR}
\includegraphics[height=3cm]{figures/sprintIRsensor}
}~~~
\subfigure[LuminOX]{
\label{subfig:LuminOX}
\includegraphics[height=3cm]{figures/LuminOXsensor}
}
\caption{Sensores de concentración de gases}
\end{figure}
%montaje
Los sensores utilizados fueron montados dentro de una atmósfera parcialmente aislada para poder realizar mediciones de prueba de las concentraciones de gases y las condiciones ambientales que se encuentran dentro de dicha atmósfera.
\subsection{Circuitos controladores}
Los sensores utilizados en este sistema cuentan con un circuito de control integrado o en placa, a excepción del sensor de monóxido de carbono CO-AF, el cuál se utiliza con el controlador EC200, mostrado en la \autoref{fig:EC200}.
\begin{figure}[!h]
\centering
%\includegraphics[width=12cm]{figures/ec200}
\includegraphics[height=3cm]{figures/ec200}
\caption[Controlador de sensor electroquímico EC200]{Controlador de sensor electroquímico EC200 \cite{ec200man}.}
\label{fig:EC200}
\end{figure}
Los circuitos controladores, además se ser la interfaz de comunicación de los sensores, sirven para acondicionar la señal análoga producida por la exposición de los sensores al gas seleccionado,
convirtiendola en una señal digital, compensandola con los sensores de temperatura y presión y filtrandole el ruido existente.
De este modo, los controladores ayudan a reducir el error y mejorar la precisión de las mediciones, además de que
al transmitirse de forma digital, las señales transmitidas presentan una mayor inmunidad al ruido, lo que mejora la fiabilidad de la transmisión.
\subsection{Configuración de los sensores}
Para utilizar los sensores en la adquisición de datos es necesario realizar ciertas configuraciones.
Éstas se realizan en el programa de adquisición, antes de capturar las mediciones, enviando comandos correspondientes para cada opción configurada en los sensores.
%modo de operación
Para evitar la transmisión innecesaria de mediciones por los sensores y tener un mejor control del tiempo en el que se realiza el muestreo de las variables medidas,
los sensores se configuran de forma que sólo transmitan las mediciones al ser solicitadas,
de esta forma, la \textit{Beaglebone} puede enviar un comando para solicitar las mediciones a los sensores en el momento en el que estas sean requeridas.
Esta configuración se hace enviando los comandos \textbf{``\texttt{K 2}''} a los sensores \textbf{\textit{SprintIR}} y \textbf{\textit{CO-AF}},
y \textbf{``\texttt{M 1}''} al sensor \textbf{\textit{LuminOX}}, con los cuales,
los sensores entran en un modo llamado \textbf{\textit{Polling Mode}}.
%mediciones
Con la finalidad de reducir la cantidad solicitudes de mediciones a los sensores y disminuir el tiempo de comunicación durante el muestreo de las variables,
los sensores también se configuran de forma que transmitan todas las mediciones que serán requeridas para la adquisición a la vez, y así no tener que enviar un comando para obtener cada medición.
Para realizar esta configuración se envía un comando específico a los sensores \textbf{\textit{CO-AF}} y \textbf{\textit{SprintIR}} dependiendo de las mediciones necesarias.
El sensor \textbf{\textit{CO-AF}} %#define M_zZTHB "M 12358\r\n"
se configura con el comando \textbf{``\texttt{M 12358}''} para transmitir mediciones de
concentración de monóxido de carbono, con y sin filtrado, temperatura, presión y humedad relativa,
mientras que el sensor \textbf{\textit{SprintIR}} %#define FILnUNFIL "M 6\r\n"
se configura con el comando \textbf{``\texttt{M 6}''} para transmitir mediciones de
concentración de bióxido de carbono con y sin filtrado.
Por otra parte, el sensor \textbf{\textit{LuminOX}},
al contar ya con un comando para transmitir todas las mediciones necesarias en la adquisición (porcentaje y concentración de oxígeno, temperatura y presión),
no requiere de alguna configuración adicional.
%usage
Para solicitar las mediciones que son configuradas en los sensores \textbf{\textit{CO-AF}} y \textbf{\textit{SprintIR}}
se utiliza el comando \textbf{``\texttt{Q}''},
y para solicitar todas las mediciones del sensor \textit{LuminOX}, el comando \textbf{``\texttt{A}''}.
Los sensores responderán con una cadena donde se encuentran las mediciones solicitadas, identificando cada variable con un caracter clave.
\section{Atmósfera parcialmente aislada}
\label{sec:atm}
Para realizar las mediciones de prueba, y poder realizar algunas otras mediciones, se implementó una atmósfera con una caja de acrílico cerrada, como puede observarse en la \autoref{fig:atm}.
En esta atmósfera pueden introducirse gases u objetos que produzcan alguna reacción química y así realizar mediciones de las concentraciones de monóxido y bióxido de carbono, oxígeno, temperatura, humedad y presión dentro de ella.
\begin{figure}[!h]
\centering
\subfigure[Caja de acrílico]{
\label{subfig:acrylicBox}
\includegraphics[height=5cm]{figures/acrylicBox}
}
\subfigure[Montaje de los sensores]{
\label{subfig:mountedSensors}
\includegraphics[height=5cm]{figures/mountedSensors}
}
\subfigure[Atmósfera abierta]{
\label{subfig:openATM}
\includegraphics[height=5cm]{figures/openATM}
}
\caption{Atmósfera aislada utilizada para las mediciones de prueba.}
\label{fig:atm}
\end{figure}
Esta atmósfera aislada cuenta con una válvula de control, con la cuál puede controlar el flujo de los gases que se van a medir.
Cuenta con una tapa en la parte superior que puede ser retirada con facilidad para introducir o retirar objetos, o ventilar el interior de la atmósfera.
También utiliza un ventilador como mezclador de gases, el cuál ayuda a mover los gases en el interior haciendo una mezcla más homogénea.
Esta caja de acrílico también cuenta con varios orificios, por lo que es posible agregar más válvulas u otras conexiones para realizar pruebas o experimentos diferentes.
\section{Circuito de aislamiento}
Ya que los sensores utilizados en este sistema pueden estar expuestos a distintas condiciones poco favorables dentro de la atmósfera, como humedad condensada, éstos son propensos a algún fallo que podría provocar un corto circuito o un sobrevoltaje en los sensores.
Por esa razón se considera necesario proteger a la tarjeta la tarjeta \textit{Beaglebone} y así evitar que en alguna situación extrema ésta se dañe y así correr también el riesgo de perder la información que se encuentra en la memoria de ésta.
Para hacer la conexión entre los puertos UART de la tarjeta \textit{Beaglebone} y los sensores de forma segura se hace uso de aisladores digitales, los cuales son capaces de transmitir las señales de comunicación utilizando capacitores de aislamiento.
%descripción
Los aisladores digitales utilizados en este sistema son los circuitos integrados ISOW7842 del fabricante \textit{Texas Instruments}, que cuenta con cuatro canales, un par para enviar señales y otro para recibir, como se muestra en \autoref{fig:isow}; con los cuales se pueden aislar hasta dos puertos UART.
Ya que este sistema utiliza un puerto UART para cada sensor, es necesario de dos circuitos integrados como este para aislar tres puertos UART.
\begin{figure}[!h]
\centering
\includegraphics[height=2in]{figures/ISOW7842.png}
\caption[Diagrama de configuración de canales del ISOW7842]{Diagrama de configuración de canales del ISOW7842\cite{isow784xDS}.}
\label{fig:isow}
\end{figure}
El ISOW7842, cuenta con alimentación aislada que permite suministrar hasta 650 mW de potencia, por lo que no es necesario aumentar la cantidad de fuentes de CD para proveer de corriente a los sensores, o algún otro circuito en caso de ser necesario.
A su vez, este circuito se alimenta con la misma fuente de DC que provee energía a la \textit{Beaglebone}.
Para utilizar el ISOW7842 se elaboró una tarjeta basada en el diseño de referencia de \textit{Texas Instruments}\cite{isow784xAR}, colocando el aislador digital ISOW7842, capacitores de desacople, pines para conexiones y puntos de prueba, como se muestra en la \autoref{fig:DI-pcb}.
El esquemático del circuito implementado también se puede observar en la \autoref{fig:DI-sch}, pudiéndose visualizar las conexiones de este circuito.
\begin{figure}[!h]%
\centering
%\subfigure[Esquemático]{
% \label{fig:fig-a}
% \includegraphics[width=5in]{figures/isowsch}}
%\\%New line for figure
\subfigure[Esquemático]{
\label{fig:DI-sch}
\includegraphics[height=3.5cm]{figures/isowsch}
}
~ %Space between figure
\subfigure[Circuito impreso]{
\label{fig:DI-pcb}
\includegraphics[height=3.5cm]{figures/isowbrd}
}
\caption{Tarjeta de aislamiento de señales digitales.}
\label{fig:isowdesing}
\end{figure}
El proyecto del diseño del PCB para el aislador digital se realizó en el \textit{software} \textit{Eagle} de \textit{Autodesk}.
Este proyecto está alojado en un repositorio público, el cuál puede ser accedido a través del enlace \url{https://gitlab.com/sayeth.rd/isow7842_testing_board}.
El repositorio también puede ser clonado (descargado con todo su historial) libremente en un ordenador propio utilizando el comando \texttt{git clone} y la dirección web del repositorio desde la terminal.
En la \autoref{tab:pines} se muestran los pines de conexión de la tarjeta de aislamiento.
\begin{table}[htbp]
\centering
\caption{Descripción de los pines de los conectores}
\label{tab:pines}
\begin{tabular}{l c p{7cm}} % Usamos P para la descripción
\toprule
Pin & Nombre & Descripción \\
\midrule
JP1-1, JP4-1 & V\textsubscript{CC} & Voltaje de alimentación (entrada) \\
JP2-2, JP4-3 & GND1 & Tierra del voltaje de alimentación \\
JP1-3 & INA & Entrada del canal A \\
JP1-4 & OUTC & Salida del canal C \\
JP1-5 & INB & Entrada del canal B \\
JP1-6 & OUTD & Salida del canal D \\
JP1-7, JP4-2 & NC & Sin conectar \\
\midrule % Separador entre grupos de pines
JP2-1, JP3-1 & V\textsubscript{ISO} & Voltaje de alimentación aislado (salida) determinado por SEL \\
JP2-2, JP3-3 & GND2 & Tierra del voltaje de alimentación aislado \\
JP2-3 & OUTA & Salida del canal A \\
JP2-4 & INC & Entrada del canal C \\
JP2-5 & OUTB & Salida del canal B \\
JP2-6 & IND & Entrada del canal D \\
JP2-7, JP3-2 & SEL & Selección de V\textsubscript{ISO}. Si se conecta a GND2, entonces V\textsubscript{ISO} = \SI{3.3}{\volt}. Si se conecta a V\textsubscript{ISO}, entonces V\textsubscript{ISO} = \SI{5}{\volt}. \\
\bottomrule
\end{tabular}
\end{table}
\subsection{Conexiones}
\begin{figure}[h]
\centering
\includegraphics[width=12cm]{figures/connections}
\caption{Diagrama de conexiones del sistema desarrollado.}
\label{fig:connections}
\end{figure}
%Canales de UART y puertos pines de conexión
La \autoref{fig:connections} muestra la conexión de los sensores de concentración de gases a través de las tarjetas de aislamiento.
El sensor \textit{CO-AF} se conecta al \textit{UART1}, el \textit{LuminOx} al \textit{UART2} y el \textit{SprintIR} al \textit{UART4}.
Respetar este orden es crucial para el correcto funcionamiento del sistema debido a la diferencia en comandos y respuestas de cada sensor.
Dado que cada tarjeta de aislamiento puede aislar sólo dos sensores, se requieren dos tarjetas para los tres.
%Voltaje aislado
La \autoref{fig:connections} también ilustra la forma de alimentar cada etapa del sistema.
La tarjeta \textit{BeagleBone} se alimenta de la fuente de \textit{5V},
las tarjetas de aislamiento se alimentan de la salida \textit{5V\_VDD} de la \textit{BeagleBone}
y los sensores se alimentan de la salida \textit{V\textsubscript{ISO}} de los circuitos de aislamiento;
de esta forma, tanto las señales como la alimentación entre la \textit{Beaglebone} y los sensores logra aislarse.
En la \autoref{tab:conexiones_bbb} se muestran los pines de la \textit{Beaglebone} utilizados para conectar los puertos UART y la alimentación.
\begin{table}[htbp]
\centering
\caption{Conexiones de la BeagleBone Black}
\label{tab:conexiones_bbb}
\begin{tabular}{l c l} % O {l P{6cm} c}, si quieres centrar la tercera columna
\toprule
Nombre & Pin & Descripción \\ % O Descripción en lugar de función
\midrule
5V\_VDD & P9-5 ó P9-6 & Alimentación (5V) \\
GND & P9-1 ó P9-2 & Tierra (GND) \\
UART1\_TXD & P9-24 & Transmisión UART1 (TXD) \\
UART1\_RXD & P9-26 & Recepción UART1 (RXD) \\
UART2\_TXD & P9-21 & Transmisión UART2 (TXD) \\
UART2\_RXD & P9-22 & Recepción UART2 (RXD) \\
UART4\_TXD & P9-13 & Transmisión UART4 (TXD) \\
UART4\_RXD & P9-11 & Recepción UART4 (RXD) \\
\bottomrule
\end{tabular}
\end{table}
\section{Programa de adquisición de datos}
%intro
%programa
Para la realizar la adquisición de datos con la \textit{Beaglebone},
se desarrolló un programa escrito en lenguaje \textbf{C}.
En este programa se realizan las tareas necesarias para la adquisición, tales como el manejo de los sensores a través de los puertos UART, y el registro de las mediciones.
%uso del programa\subsection{Uso del programa}
Este programa debe ejecutarse desde una terminal de \textit{Linux} en la \textit{Beaglebone},
pudiendo acceder a ella a través del protocolo SSH.
Para hacerlo
es necesario ubicarse en el directorio donde está alojado el programa
y ejecutar el comando
\texttt{./daq <duración de la adquisición>} \texttt{<periodo de muestreo>},
sustituyendo los valores
\texttt{<duración de la adquisición>} por el tiempo (en horas) durante el cuál se quiere realizar la adquisición, y
\texttt{<periodo de muestreo>} por el tiempo deseado entre cada medición (en segundos).
Si es necesario detener la adquisición antes de la finalización de su período establecido, se puede utilizar la combinación de teclas \texttt{Ctrl + c} en la terminal.
%development/cloud9
El programa desarrollado y su depuración se realizó con la ayuda del IDE en linea \textit{Cloud9}.
Este es posible utilizar desde un navegador web, accediendo al servidor de la misma \textit{Beaglebone}, para esto es necesario conocer la dirección IP de la \textit{Beaglebone} (lo cuál se puede saber con el comando \texttt{ip addr}).
En este entorno fue posible visualizar los archivos del proyecto, depurar el código linea por linea, probar distintas funciones y observar las variables del código y de la estructura \texttt{termios}, entre otras cosas.
El programa realiza varias tareas para la adquisición de datos, específicamente
estas tareas son:
configurar los sensores, y a su vez los puertos UART para su utilización con éstos,
crear el archivo de datos, registrando la fecha de inicio de la adquisición,
solicitar mediciones a los sensores,
recibir las mediciones e interpretarlas, para después registrarlas en el archivo de datos,
y para finalizar, cerrar los archivos de los puertos UART, dejándolos así disponibles para cualquier otro uso.
El código y sus funciones se explican a continuación.
\subsection{Función principal} \label{sec:program}
En la función \texttt{main()} del programa se realizan las tareas principales para la adquisición de datos de forma secuencial, como se muestra en el diagrama de la \autoref{fig:flowchart-Main}.
Esta función se encuentra en el archivo \textit{main.c} de este proyecto, del cuál se muestra su código completo en \autoref{lst:main.c}.
\begin{figure}[!h]
\centering
\includegraphics[width=12cm]{figures/flowchart-Main}
\caption{Diagrama de flujo general de la función \texttt{main} del programa de adquisición de datos.}
\label{fig:flowchart-Main}
\end{figure}
En esta secuencia de tareas,
%configurar sensores
primero se configuran los sensores y los puertos UART haciendo uso de la función \texttt{sensConf()}, la cuál se describe más adelante en la \autoref{sec:sensConf}. Con la ayuda de esta función se establecen configuraciones como: el número del puerto que se va a utilizar, los baudios de la comunicación, su modo de operación y las mediciones que tomarán los sensores.
%aquisición de datos
Siguiendo el diagrama de flujo de la \autoref{fig:flowchart-Main}, después de configurar los sensores se inicia la adquisición de datos, solicitando las mediciones a los sensores y registrandolas en un archivo de datos creado por el programa.
Esta acción es representada por el bloque amarillo nombrado "Adquisición de datos" y se realiza con la función \texttt{DAQ()}, la cuál se describe a detalle en la \autoref{sec:DAQ}.
El muestreo de mediciones se realiza dentro de un bucle durante el tiempo establecido como "Duración de la adquisición" y se realiza cada cierto tiempo, nombrado como "Periodo del muestreo".
%cerrar puertos UART
Una vez que la adquisición de datos finaliza, los archivos utilizados para acceder a los puertos UART se cierran para dejar éstos disponibles para otros programas.
Para realizar esta acción se utiliza la función \texttt{uartClose()} explicada más adelante en la \autoref{sub:uartClose}.
Finalmente la función \texttt{main()} termina, retornando un valor de cero.
Durante su ejecución, \texttt{main()} muestra en la terminal mensajes informativos sobre el progreso de la adquisición, incluyendo las últimas mediciones obtenidas.
\subsection{Función \texttt{sensConf()}} \label{sec:sensConf}
%intro
Los procesos donde se realizan configuraciones en los sensores, mostrados en la \autoref{fig:flowchart-Main}, para cambiar su modo de operación, y las mediciones que van a transmitir, son realizados con la función \texttt{sensConf}.
Con esta función
se pueden configurar algunas opciones permitidas por los sensores
a través de comandos
que se envían por un puerto UART.
Su diagrama de flujo se muestra en la \autoref{fig:flowchart-sensConf}.
%inputs explicación
Esta función tiene varios argumentos de entrada,
los cuales pueden modificarse para ajustarlos a la configuración de cada sensor.
Estos se explican a continuación:
\begin{itemize}
\item \texttt{uint8\_t uartNumber}: Número de puerto UART que se utilizará para el sensor.
\item \texttt{int baudRate}: Velocidad que se va a utilizar en la transmisión.
\item \texttt{char mode[]}: Comando de configuración enviado al sensor.
\item \texttt{char response[]}: Respuesta de confirmación esperada del sensor.
\item \texttt{int tries}: Número de intentos para configurar el sensor en caso de alguna falla.
\end{itemize}
\begin{figure}[!h]
\centering
\includegraphics[width=12cm]{figures/flowchart-sensConf}
\caption{Diagrama de flujo la función \texttt{sensConf} del programa de adquisición de datos.}
\label{fig:flowchart-sensConf}
\end{figure}
%flowchart explicación
En esta función (véase \autoref{fig:flowchart-sensConf}, para configurar el sensor, primero se configura el puerto UART a utilizar.
Después, verifica si aún hay intentos restantes para intentar configurar el sensor.
En caso de haberlos, se envía el comando de configuración y se espera la respuesta del sensor.
Si se recibe la respuesta esperada, la función termina retornando el valor de \texttt{0}.
De lo contrario se reducirá la cantidad de intentos y se volverá a intentar configurar el sensor.
En caso de no haber intentos restantes, la función terminará enviando el valor de (\texttt{-1}), indicando que el sensor no pudo configurarse.
%uso de uart.h y termios.h
En esta función
para configurar el puerto UART, transmitir y recibir datos,
se hace uso de las funciones \texttt{uartConf}, \texttt{uartTransmit} y \texttt{uartReceive} de la librería \texttt{uart.h}.
Para esperar a que los datos sean transmitidos, se hace uso de la función \texttt{tcdrain}, de la librería \texttt{termios.h}, y para mostrar los mensajes en la terminal se utiliza \texttt{printf}.
%Para realizar varios intentos de configuración se uso un \texttt{while} mientras que para las otras condiciones se utilizo un \texttt{if} con un \texttt{else if} y un \texttt{else} como se muestra en el Sección de Código \ref{lst:sensConf}.
En \autoref{lst:sensConf} se muestra la función \texttt{sensConf} completa.
\lstinputlisting[
language=C,
firstline=7,
lastline=28,
basicstyle=\mlttfamily\fontsize{6}{8}\selectfont,
label=lst:sensConf,
frame= lines,
caption= {Función \texttt{int sensConf(uint8\_t uartNumber, int baudRate, char mode[], char response[], int tries)}.}]
{codes/daq.c}
\subsection{Función de adquisición de datos \texttt{DAQ()}} \label{sec:DAQ}
En la función \texttt{DAQ}, mostrada en la \autoref{fig:flowchart-DAQ}, se realizan las tareas para tomar las muestras de las mediciones.
En esta función se crea el archivo de datos, se solicitan las mediciones a los sensores, se reciben y se almacenar en el archivo de datos.
La función utiliza los siguientes parámetros de entrada:
\begin{itemize}
\item \texttt{int t\_hrs}: Establece la cantidad de horas durará la adquisición de datos.
\item \texttt{int sp\_s}: Establece la cantidad de segundos entre cada muestra.
\end{itemize}
\begin{figure}[!h]
\centering
\includegraphics[width=12cm]{figures/flowchart-DAQ}
\caption{Diagrama de flujo la función \texttt{DAQ} del programa de adquisición de datos.}
\label{fig:flowchart-DAQ}
\end{figure}
Esta función comienza creando el archivo ``\texttt{data.dat}'', donde se guardaran los datos, en el mismo directorio donde está alojado el proyecto. %(``\texttt{/var/lib/cloud9/c9projets/DAQ}'').
Posteriormente, registra la hora y fecha en la que se comenzó la adquisición en la primera linea del archivo, y debajo escribe
el encabezado de las variables medidas en la adquisición con los nombres de cada una (tiempo, concentraciones de gases, temperatura, etc.)
separados por una tabulación horizontal (TVS) para crear las columnas.
%la primera fila de las columnas del nombre de cada variable y el tiempo en el que se realizaron.
%Las columnas se separan unas con otras con una tabulación horizontal (TVS).
Este encabezado también se muestran en la terminal para tener más claridad al ser monitoreadas. Estas acciones mencionadas se realiza con las lineas mostradas en la Sección de Código \ref{lst:DAQa}.
\lstinputlisting[
language=C,
firstline=30,
lastline=56,
basicstyle=\mlttfamily\fontsize{6}{8}\selectfont,
label=lst:DAQa,
frame= lines,
caption= {Comienzo de la funcinón \texttt{int DAQ(int t\_hrs, int sp\_s)}.}
]{codes/daq.c}
%ciclo
Después de haber creado el archivo, con la fecha y las columnas de cada medición, y habiendo establecido el tiempo del próximo muestreo, como se muestra en la Sección de Código \ref{lst:DAQb},
%en el cuál será el próximo muestreo de las variables
la función entra en un ciclo, que se repetirá para realizar cada muestreo hasta que termine el tiempo de adquisición.
%durante el transcurso de la adquisición.
Este ciclo se controla con la variable ``\texttt{t}'', que comienza en cero y va aumentando el periodo de muestreo en cada iteración hasta que sobrepasa la duración de la adquisición, terminando con el ciclo.
\lstinputlisting[
language=C,
firstline=58,
lastline=61,
basicstyle=\mlttfamily\fontsize{6}{8}\selectfont,
label=lst:DAQb,
frame= lines,
caption= {Parámetros del ciclo de la función DAQ y los tiempos de adquisición.}
]{codes/daq.c}
%código de adquisición
Dentro de este ciclo
%solicitar mediciones
se envían los comandos de solicitud de mediciones a los sensores y
%recibir respuestas de los sensores
se reciben las respuestas de estos mismos, las cuales
%interpretar respuestas
se interpretan y, posteriormente,
%separadas / extraer
se extraen de estas las mediciones de cada variable y se almacenan en cadenas (de caractéres) individuales.
%cadena de datos
Con estas cadenas se construye una cadena, con el tiempo y todas las mediciones realizadas, separados por una tabulación horizontal, que
%mostrar en terminal
se muestra en la terminal, para que las mediciones puedan ser monitoreadas, y
%agregar al
se agrega al final del archivo de datos ``\texttt{data.dat}''.
%establecer el tiempo del próximo muestreo
Finalmente, se establece el tiempo del próximo muestreo para la siguiente iteración del ciclo.
Todas estas tareas son realizadas con la sección de código mostrada en \autoref{lst:DAQc}.
\lstinputlisting[
language=C,
firstline=74,
lastline=108,
basicstyle=\mlttfamily\fontsize{6}{8}\selectfont,
label=lst:DAQc,
frame= lines,
caption= {Tareas realizadas en el ciclo de la función DAQ para solicitar, obtener, mostrar y almacenar las mediciones.}
]{codes/daq.c}
%tiempo de procesamiento
El tiempo de ejecución que le lleva al procesador hacer estas tareas, es medido en cada iteración, con el fin de saber el tiempo restante para siguiente muestreo y poner el programa inactivo durante este tiempo.
%medición del tiempo de procesamiento
La medición del tiempo de procesamiento se
hace utilizando la función \texttt{clock()}, de la librería \texttt{time.h},
obteniendo la diferencia entre los ciclos de reloj antes y después de realizar las tareas, y convirtiéndola a microsegundos.
%calculo del tiempo de inactivdad
El tiempo de inactividad es calculado
con el tiempo de procesamiento medido y el periodo de muestreo,
%margen de tiempo
considerando un margen a favor
para que el administrador de tareas del sistema operativo regrese al programa y se realicen otras operaciones que no son consideradas en la medición del tiempo de procesamiento.
%verificación tiempo de inactividad
Este tiempo de inactividad obtenido es verificado,
por si la duración del muestreo anterior es excesiva
y el tiempo de inactividad calculado resultó menor a 1 microsegundo (sin tiempo de inactividad).
En este caso,
se muestra un aviso en la terminal (indicando que el tiempo en la adquisición anterior ha sido excedido),
se establece el siguiente muestreo en el próximo segundo y
se actualiza el valor de tiempo de la adquisición,
de lo contrario, si hay tiempo de inactividad,
entonces se pone el programa en reposo.
Después de manejar los dos casos, en los que hay o no tiempo de inactividad,
se espera a que llegue el tiempo de muestreo
como se muestra en la Sección de Código \ref{lst:timepoInactividad}.
\lstinputlisting[
language=C,
firstline=63,
lastline=72,
basicstyle=\mlttfamily\fontsize{6}{8}\selectfont,
label=lst:timepoInactividad,
frame= lines,
caption= {Código para verificar el tiempo de inactividad y esperar el próximo muestreo.}]
{codes/daq.c}
%tiempo de muestreo
El tiempo de cada muestreo se maneja con la función \texttt{time()}, de la librería \texttt{time.h}, con la cuál se obtiene la hora actual del calendario del sistema.
De esta forma se puede establecer un tiempo de referencia (en el cuál inicia la adquisición) y saber cual es la hora actual para realizar los muestreos con una resolución de segundos.
%solicitud/recepción de mediciones
En los muestreos,
la solicitud y recepción de mediciones se hacen con las funciones \texttt{uartTransmit} y \texttt{uartReceive}, de la librería \texttt{uart.h},
enviando el comando de solicitud de mediciones correspondiente a cada sensor y
recibiendo las mediciones en el \textit{buffer} de recepción de cada puerto UART.
%separación de mediciones
Las mediciones se obtienen individualmente utilizando la función \texttt{getMeasures}, mostrada en la Sección de Código \ref{lst:getMeasures}.
\lstinputlisting[
caption= Función char *getMeasures(char src[{],} char fval{,} int nchar).,
language=C,
firstline=114,
lastline=123,
basicstyle=\mlttfamily\fontsize{6}{8}\selectfont,
label=lst:getMeasures,
frame= lines]
{codes/daq.c}
La función\textbf{ \texttt{getMeasures}} recibe como argumentos los siguientes parámetros:
\begin{itemize}
\item \texttt{char scr[]}: Cadena de caractéres enviada por sensores, contiene las mediciones.
\item \texttt{char fval}: Carácter que identifica cada tipo de medición.
\item \texttt{int nchar}: Número de caractéres que tiene el valor de la medición.
\end{itemize}
Así mismo, la función regresa lo siguiente:
\begin{itemize}
\item \texttt{static char s}: Cadena de caractéres de la medición solicitada.
\end{itemize}
Esta función hace un escaneo en la cadena, desde el primer caracter,
buscando el caracter de la medición que se quiere obtener (\texttt{fval)}.
Cuando lo encuentra,
avanza hasta el valor de la medición (saltandose el espacio) y
copia el valor de la medición en una cadena (\texttt{s}),
la cuál retorna.
%La cadena con todas las mediciones se crea con la función \texttt{sprintf}.
\section{Libreria \texttt{uart.h v1.0} }
Para realizar la comunicación, a través de los puertos UART de la \textit{Beaglebone}, en el programa de adquisición de datos escrito en lenguaje \textbf{C},
es necesario crear una librería con las funciones para la comunicación a través de los puertos UART,
la cuál es utilizada en el programa
para tener interacción con los puertos y a su vez con los sensores.
Esta librería se encuentra alojada en el repositorio del proyecto, el cuál puede ser accesado desde el enlace: \url{https://gitlab.com/sayeth.rd/daq-serial-bbb}.
La librería \texttt{uart.h} contiene las funciones:
\begin{itemize}
\item \texttt{uartConf}, configura el puerto UART para su utilización, %para establecer los parámetros de comunicación de los puertos UART,
\item \texttt{uartClose}, cierra el puerto una vez haya sido desocupado,
\item \texttt{uartTransmit}, transmite datos a través de los puertos UART y
\item \texttt{uartReceive}, recibe datos de los puertos UART.
\end{itemize}
Cada función es descrita a continuación.
\subsection{Función \texttt{uartConf()}}
La función \texttt{uartConf}, mostrada en la Sección de Código \ref{lst:uartConf}, es utilizada para configura los puertos UART,
estableciendo los parámetros de entrada, control y salida de la comunicación.
Esta función permite elegir el puerto UART que se va a configurar y los baudios a los que operará,
recibiendo estos parámetros como valores de entrada.
Para configurar el puerto, en la función,
se abre el archivo del puerto, en el sistema de archivos del SO, %con las opciones O-RDWR, O-NOCTTY, O-NDELAY, O-NONBLOCK
y se asignan los atributos de comunicación del puerto
a una estructura \texttt{termios}
para poder manipularlos.
Estos atributos de la comunicación de entrada, control y salida
son limpiados
para después asignar los deseados.
De esta forma, se asignan los parámetros de control:
%control
\begin{itemize}
\item la tasa de baudios recibida por la función
\item mascara de los caractéres de ocho bits de tamaño
\item receptor habilitado
\item ignorar lineas de control del módem.
\end{itemize}
%input
En los parámetros de entrada solamente
se inhabilita la detección de errores de paridad.
Posteriormente
se limpia el \textit{buffer} de transmisión, para descartar información no transmitida,
y se aplican los cambios de las opciones del puerto UART.
\lstinputlisting[
language=C,
firstline=10,
lastline=44,
basicstyle=\mlttfamily\fontsize{6}{8}\selectfont,
label=lst:uartConf,
frame= lines,
caption= {Función \texttt{int uartConf(uint8\_t uartNumber, int baudRate}).}
]{codes/uart.c}
\subsection{Función \texttt{uartClose()}} \label{sub:uartClose}
La función \texttt{uartClose}, mostrada en la Sección de Código \ref{lst:uartClose}, se utiliza para cerrar el puerto UART,
una vez que haya sido desocupado por el programa,
para que éste quede disponible para su utilización por otro programa.
Esta función recibe como parámetro de entrada el número del puerto UART que se desea cerrar.
Para cerrar el puerto UART, la función accede al archivo del puerto UART
en el sistema de archivos del SO
para cerrarlo con la función \texttt{close},
introduciendo la ruta del archivo UART que se quiere cerrar.
\lstinputlisting[
language=C,
firstline=46,
lastline=51,
basicstyle=\mlttfamily\fontsize{6}{8}\selectfont,
label=lst:uartClose,
frame= lines,
caption= {Función \texttt{int uartClose(uint8\_t uartNumber)}.}]
{codes/uart.c}
\subsection{Función \texttt{uartTransmit()}}
La función \texttt{uartTransmit}, mostrada en la Sección de Código \ref{lst:uartTransmit}, se utiliza para transmitir datos a través del puerto UART.
Esta función recibe como parámetros de entrada: el número del
puerto UART que se va a utilizar para transmitir los datos
y el mensaje que va a ser enviado.
Para transmitir los datos, la función, una vez configurado el puerto,
accede al archivo del puerto UART mediante el sistema de archivos del SO
para escribir el mensaje en éste
con la función \texttt{write},
introduciendo la dirección del archivo, el mensaje, y su longitud.
Posteriormente, se descarta la información no transmitida
para asegurar que el \textit{buffer} de salida quede limpio.
\lstinputlisting[
caption= Función \texttt{int uartTransmit(uint8\_t uartNumber{,} char message[{]})}.,
language=C,
firstline=53,
lastline=65,
basicstyle=\mlttfamily\fontsize{6}{8}\selectfont,
label=lst:uartTransmit,
frame= lines]
{codes/uart.c}
\subsection{Función \texttt{uartReceive()}}
La función \texttt{uartReceive}, mostrada en la Sección de Código \ref{lst:uartReceive}, se utiliza para obtener los datos recibidos a través del puerto UART.
Esta función recibe como parámetros de entrada el número del
puerto UART donde se reciben los datos.
Para obtener los datos recibidos, una vez ajustados los parámetros de comunicación,
la función accede al archivo del puerto UART, mediante el sistema de archivos del SO,
usando la función \texttt{read} para leerlo.
Para usar esta función, se deben de introducir:
la dirección del archivo,
el puntero de la variable donde se guardarán los datos leídos y
el número de bits que se van a leer.
Los \textit{buffers} de recepción de datos de los puertos UART son declarados de forma global en la librería \texttt{uart.h} de la siguiente forma: \texttt{char receive[6][100]}.
\lstinputlisting[
language=C,
firstline=67,
lastline=75,
basicstyle=\mlttfamily\fontsize{6}{8}\selectfont,
label=lst:uartReceive,
frame= lines,
caption= {Función \texttt{int uartReceive(uint8\_t uartNumber)}.}]
{codes/uart.c}
\section{Archivo de datos}
El programa desarrollado para este sistema crea un archivo de datos, en el cuál se almacenan las mediciones obtenidas por los sensores.
%ubicación del archivo
Este archivo de datos (\texttt{data.dat}) es creado en la carpeta ``DATA'', en el mismo directorio donde se encuentra el programa.
%sobreescritura
En caso de existir un archivo con el mismo nombre en la carpeta, el programa lo sobre-escribirá con un archivo de datos nuevo.
%registro hora y fecha
En este archivo se registra además la hora y fecha en la cuál se inicia la adquisición.
En el archivo se crean columnas para cada medición, separándolas con una tabulación horizontal, iniciando con la columna del tiempo de las mediciones y siguiendo con las mediciones de concentración
de bióxido de carbono, %co2_uf, co2_f,
monóxido de carbono, %co_uf, co_f,
oxígeno, %o2_ppm, o2_xcent,
y en seguida las mediciones de las condiciones de la atmósfera
temperatura, %co2_temp, o2_temp,
presión y %co2_press, o2_press,
humedad relativa;%co2_relH
como se muestra en el Listado \ref{lst:data}.
\begin{lstlisting}[
language=bash,
basicstyle=\mlttfamily\fontsize{6}{8}\selectfont,
label=lst:data,
frame= lines,
caption= {Ejemplo del archivo \texttt{data.dat} con las mediciones obtenidas}]
Starting DAQ at Fri Feb 28 17:05:16 2020
t CO2 CO2 f CO CO f O2 O2 T CO T O2 P CO P O2 RH
s ppm ppm ppm ppm ppO2 % C*10 C mBar mBar .%
0 00243 00236 00000 00000 0165.1 020.36 01254 +24.8 00811 0811 00382
1 00226 00238 00226 00000 0165.1 020.36 01254 +25.1 00811 0811 00382
2 00240 00238 00001 00000 0165.2 020.36 01254 +25.0 00813 0811 00382
3 00243 00236 00000 00000 0165.2 020.36 01254 +25.0 00814 0811 00382
4 00227 00240 00002 00000 0165.1 020.37 01254 +25.2 00814 0811 00382
5 00241 00242 00000 00000 0165.1 020.36 01254 +24.8 00814 0811 00382
6 00235 00243 00000 00000 0165.1 020.36 01254 +25.2 00814 0811 00382
\end{lstlisting}
En este archivo se almacenan las mediciones como son obtenidas de los sensores, por lo que conservan su formato original.
Las mediciones de temperatura tomadas por la tarjeta controladora \textit{EC200} (columna ``T CO'')
tienen un desplazamiento de $ +1,000 $ y un factor de $10$, por lo que para obtener las mediciones en grados Celsius hay que
restar -1000 y después dividir el número entre 10 (\eg $(01254 - 1000)/10 = 25.4$).
Las mediciones de humedad relativa (columna ``R H'') también tienen un factor de $ 10 $, por lo tanto éstas se necesitan dividir entre 10 para poder ser interpretadas en porcentaje.
Por otra parte, las mediciones de CO$_2$ (columnas ``CO2'' y ``CO2 f'') tienen un factor de $0.1$, por lo que deben multiplicarse por 10 para obtener las mediciones en ppm.
El archivo de datos puede ser leído con el comando \texttt{cat} para visualizarlo completamente, o el comando \texttt{more} si se quiere leerlo progresivamente. También puede ser copiado a un dispositivo local con el comando \texttt{scp}.
\section{Conclusiones}
En este capítulo se detalló el desarrollo de un sistema embebido basado en BeagleBone Black para la adquisición de mediciones de gases y variables ambientales. El sistema, que incluye la BeagleBone, sensores, un circuito de aislamiento y software de control en C, fue construido y probado preliminarmente. Se cumplió el objetivo de describir el desarrollo, incluyendo una librería UART reutilizable. Aunque funcional para pruebas de concepto, el sistema presenta limitaciones para entornos complejos. El siguiente capítulo evaluará el rendimiento a partir de los resultados de las pruebas.
WORK IN PROGRESS...
%Para hacer estas funciones hace uso de las librerías \texttt{unistd.h}, \texttt{string.h}, \texttt{time.h} y una librería propia para la comunicación UART (\texttt{uart.h}), que a su vez usa las librería \texttt{stddef.h}, \texttt{time.h}, \texttt{termios.h}, \texttt{fcntl.h}, \texttt{unistd.h}, \texttt{sys/types.h}, \texttt{string.h}.
%En el Sección de Código \ref{lst:test}...
%
%\begin{lstlisting}[
% language=C,
% label=lst:test,
% frame= lines,
% caption= {Implementation of the Normality-tests in C.}]
%
% #include <stdlib.h>
% #include <stdio.h>
% #include <string.h>
%
% int
% max(int a, int b)
% {
% if(a>b) return a;
% else return b;
% }
%
% void
%\end{lstlisting}
%
%
%Otro ejemplo para pseudo código
%\begin{algorithm}[!h] %or another one check
% \caption{How to write algorithms}
% \SetAlgoLined
%
% \While{not at end of this document}{
% read current\;
% \eIf{understand}{
% go to next section\;
% current section becomes this one\;
% }{
% go back to the beginning of current section\;
% }
% }
%
%\end{algorithm}
%La función usa un ciclo \texttt{while} para tratar de configurar el sensor varias veces en caso de que no pueda ser configurado exitosamente la primera vez por cuestiones de posibles fallas en la conexión al inicio.
%Dentro del ciclo \texttt{while}, al comienzo se envía el comando de configuración del sensor usando una función para transmisión UART, se espera a que termine la transmisión y después se recibe la respuesta con una función para recepción UART.
%Una vez recibida la respuesta del sensor, se comprueba si es la respuesta esperada haciendo una comparación de cadenas con la función \texttt{strcmp}, si no hay diferencias entre las cadenas si considera que el sensor ha sido configurado y se termina la función retornando un \texttt{0}, pero si hay alguna diferencia entre las dos cadenas se repite este proceso hasta un número máximo de 10 veces antes de terminar la función enviando un mensaje de error y retornando \texttt{-1} como resultado de la función.
%Los sensores son configurados de forma que sólo envíen mediciones en el momento en el que son solicitadas.
%En este sistema la \textit{Beaglebone Black} se encarga de configurar los sensores y de pedirles y almacenar las mediciones que estos van realizando.
%Esto se hace por medio de un programa realizado en lenguaje \textbf{C} que puede ejecutarse desde la terminal de la \textit{Beaglebone}.