INSTITUTO TECNOLÓGICO Y DE ESTUDIOS SUPERIORES DE MONTERREY
CAMPUS MONTERREY
Diseño de sistemas en chip - TE2003
Grupo: 603
Actividad
Entrega Final
David Gilberto Lomeli Leal | A01571193
Alfonso Solis Diaz | A00838034
Jorge Luis Nájera Espinosa | A01424106
Docentes:
Enrique González Guerrero
Raúl Peña Ortega
Monterrey, Nuevo León, México
31/05/2024
Índice
Índice......................................................................................................................................... 2
Introducción..............................................................................................................................3
Marco Teórico........................................................................................................................... 3
Sistemas embebidos............................................................................................................. 3
RTOS.................................................................................................................................... 3
Linux Embebido................................................................................................................... 4
Justificación...............................................................................................................................4
Metodología...............................................................................................................................5
Descripción...........................................................................................................................5
Hardware, Software y Periféricos.........................................................................................5
Diagrama Esquemático.........................................................................................................6
Figura #. Diagrama esquemático....................................................................................................... 6
Diagrama de Interacción de Tareas (FReeRTOS)................................................................ 7
Diagrama de Flujo por Tarea................................................................................................8
Scheduling de Tareas (RTOS).............................................................................................. 9
Acciones de Mejora en Rasp................................................................................................ 9
Interfaz Final en Python..................................................................................................... 10
Implementación final....................................................................................................................... 11
Datos tractor CSV............................................................................................................................12
Figura #. CSV recolección de datos Final.......................................................................................... 13
Conclusiones y Reflexiones.................................................................................................... 18
Trabajo a Futuro.................................................................................................................... 18
Referencias bibliográficas......................................................................................................18
Introducción
Los sistemas inteligentes de conducción son aquellos que permiten al usuario y vehículo tener
un feedback en tiempo real de sus acciones y los recursos que están usando así como los
elementos exteriores que puedan afectar directamente. ADAS, por sus siglas en inglés, son
los sistemas más actuales de seguridad y cuidado del usuario; llegando a informar e incluso
reaccionar a un siniestro antes que el usuario con tal de protegerlo. Ejemplos de sistemas
embebidos como conductores inteligentes serían el Audi Pre Sense y Conductor inteligente
de Chevrolet; los cuales no solo prevén baches en el camino antes que tu y ajusta los
amortiguadores acordemente; sino de que cuando usas los frenos se aseguran de que el ABS
funcione para evitar desgaste y las bolsas de aire siempre están activas; entre otras cosas. La
importancia de que estos sistemas sean en tiempo real, y de los sistemas en sí, recae en el
hecho de que un humano jamás reaccionara al mismo tiempo que una máquina y una
máquina jamás se distrae. Así que como forma de evitar que cualquier pieza del coche falle y
que el usuario sufra algún daño, el sistema embebido tiene que saber qué está pasando en
cada microsegundo del coche.
Marco Teórico
Sistemas embebidos
Un SoC o System on Chip es un sistema que contiene todo lo necesario para simular
un sistema electos por sí solo. Son una pieza clave de los sistemas embebidos debido a su
capacidad de implementar las funciones de varios chips en uno al coste de su capacidad en
estas funciones sea reducido. Ejemplos buenos son los chips de administración de energía de
Qualcomm usados en varios de tus dispositivos electrónicos, chips de NVIDIA Tegra como
motor gráfico de la Switch o chips de Apple (A1-A17) que funcionan como hub central de
operaciones del teléfono o laptop. En cambio, un microcontrolador es una versión más
completa de un SoC. Mientras que un SoC se ve limitado por su capacidad de energía y
alcance; un microcontrolador funciona como un sistema computacional entero en el tamaño
de un solo componente. Ejemplos prominentes influyen en Arduino, RaspBErry Pi y STM32.
Los microcontroladores funcionan como un sistema computacional completo por si solos y es
por ello que casi siempre son lo que conforma un sistema embebido en casos que interactúen
con puertos GPIO.
RTOS
Un sistema operativo en tiempo real (RTOS) es un sistema que trabaja con cierta
cantidad de tareas y recursos bajo un marco de respuesta en tiempo real. En el mismo existen
deadlines y posibilidades como deadlock o interrupciones exteriores al sistema en cualquier
momento que lleven a fallas del sistema. Es por ello que un sistema en tiempo real es difícil
de implementar como lo son sus algoritmos, sin embargo la ventaja de los mismos es que
usan al máximo la capacidad de la CPU y de implementarse bien logran cumplir las tareas
asignadas de manera completamente eficiente y con un uso asignado de recursos. Siendo
estos capaces de mantener fábricas automatizadas completas por sí solos, o sistemas en línea
completamente ordenados y comunicados así como actualizados en tiempo real.
Linux Embebido
El “Linux Embebido” es como se le llama al sistema operativo Linux al momento de
ser usado dentro de un sistema embebido. Linux en sí es un sistema operativo bajo la licencia
GNU GPL, el cual similar a otros sistemas cuenta con una interfaz gráfica; sin embargo en lo
que difiere es que el mismo cuenta con un sistema de accesos de root o núcleo llamado
Kernel el cual le permite ser óptimo para el uso en sistemas embebidos debido a su rápida
accesibilidad a recursos del sistema para tareas simples. La forma de acceder dichos recursos
es normalmente a través de lo que se le conoce como programación Bash que es la versión
del editor de archivos NANO en lenguaje Python. Bash es una forma de programación muy
fácil de usar pero difícil de dominar; ya que depende mucho de comandos y sus variaciones
internas (flags) para acceder a recursos del sistema. Otra ventaja es que una vez dominado es
muy fácil automatizar cualquier tarea, lo malo es que es sensible a hackeos del sistema
embebido debido a su simplicidad como programa.
Justificación
La problemática presentada por John Deere nos muestra la importancia de desarrollar
un sistema inteligente de conducción para tractores, reflejando una constante en la
automatización y mejora de eficacia en el sector tanto agrícola como automotriz. Se nos
comenta que actualmente los sistemas electrónicos constituyen aproximadamente el 40% del
valor de producción de un vehículo, en este integrando microcontroladores y
microprocesadores los cuales son los que gestionan funciones críticas como la aceleración,
velocidad, marcha, velocidad del motor, freno, etc.
En un futuro se espera que la mayoría de los vehículos en estos incluidos los tractores de John
Deere operen de manera autónoma, esto no solo mejoraría la calidad de vida al reducir
accidentes sino que también optimizar la precisión y eficacia en el campo agrícola.
En este reto buscamos diseñar un sistema inteligente de conducción para tractores haciendo
uso de la tarjeta STM32F103RB y Raspberry Pi 3B.
Metodología
Descripción
El proyecto como sistema embebido fue implementado con la ideología de un sistema
embebido en un tractor que funcionara como parte de un sistema de conducción inteligente.
Específicamente la telemetría del mismo, es decir la recolección y procesado de datos; así
como la representación básica de los mismos. Esto del lado de la STM32; del lado de la
Raspberry Pi se ve como el backend del sistema en el cual se están guardando los datos para
uso futuro así como generando gráficas para análisis posteriores. Es por ello que la STM es la
que tiene todos los inputs y outputs directos y la comunicación a la Rasp es por medio del
puerto Serial. Finalmente, en la última versión, se vió a la Rasp como un componente más
complejo que solo un recibidor de datos y mantenimiento del backend. Gracias a que ocupaba
mandar datos seriales de vuelta se le concibió como un tipo de señal de corrección de un
control virtual en caso de que el sistema del tractor fallará en algo al momento de girar, claro
para que esté completo le faltaría otro tipo de señal o bandera de activación.
Hardware, Software y Periféricos
Hardware:
● Raspberry Pi 3B
● STM32 Nucleo F10
Software Respectivo:
● Thonny en ambiente Raspberry Pi
● STM32 Cube IDE
Periféricos Entrada y Salida (respectivo):
● Teclado Matricial
● Potenciómetro
● UART FTDI
● Modulo RGB
● Pantalla LCD
Diagrama Esquemático
Figura 1. Diagrama esquemático
En este diagrama esquemático podemos observar las conexiones que se utilizaron en el
prototipo final y la interacción de la STM32 con todos los periféricos, entre estos, el teclado
matricial, el LCD, el LED RGB, los potenciómetros y el FTDI.
Diagrama de Interacción de Tareas (FReeRTOS)
Figura 2. Diagrama de Interacción de Tareas
En el diagrama de FreeRTOS podemos observar como tenemos dos entradas, tanto del
teclado matricial como del potenciómetro analogico.
El teclado matricial, controla la dirección ya sea derecha o izquierda y el freno o ”Break”. A
su vez el potenciómetro es el encargado de simular la potencia del acelerador para
posteriormente calcular la velocidad del tractor.
Ambas entradas tanto del teclado como del potenciómetro son recibidas por el task 1 en
donde posteriormente en el task 3 iniciará el modelo y cálculo de las variables usadas en el
código. Por una parte tenemos un código “switch case” en el que detecta si algún dato fue
enviado desde el teclado matrícula, donde según la tecla que se presione en estel es la
dirección que será desplegada en el LCD o por otro lado en caso que la rasp envíe un dato
entraría de igual forma a el “switch case” para pasar por el mismo proceso según el bit que
este envíe.
Por otro lado, con la información que tenemos y con la misma prioridad podemos continuar
ya sea con la task 4 o la task 5.
En la task 4 desplegamos la información en la pantalla LCD como también la dirección
haciendo uso de un LED RGB.
En la task 5 iniciamos un proceso de flujo de información para enviarlo a la Raspberry Pi en
donde guardaremos los datos y a su vez imprimimos los datos en una gráfica siendo
actualizada a tiempo real. A su vez en la misma Raspberry Pi podemos enviar un dato de
información de dirección o freno el cual regresará a la STM32 y reiniciará con el proceso de
la task 3.
Diagrama de Flujo por Tarea
Figura 3. Diagrama de flujo
En el diagrama de STMCubeIDE podemos observar cómo las entradas del teclado matricial y
del potenciómetro analógico se integran para controlar y visualizar las acciones del sistema.
El teclado matricial se utiliza para controlar la dirección y el freno, mientras que el
potenciómetro analógico simula la potencia del acelerador. En Task 1 se leen las entradas del
teclado, y en Task 2 se leen las entradas del potenciómetro mediante un ADC y se responde
en consecuencia. Posteriormente, en Task 3, se actualiza el modelo del sistema con los datos
recibidos, y se decide si modificar el modelo basándose en la información procesada. Si se
ocupa modificar, el proceso regresa a el Task 3 para hacer el cambio, en caso contrario se
inicia el Task 4 en donde se envía la información al LCD y a el LED RGB como también
imprime la información de forma serial a través del UART, estos datos siendo capturados por
la Raspberry Pi y siendo graficados en tiempo real como también almacenados en un archivo
csv.
Scheduling de Tareas (RTOS)
Figura 4. Tareas en la Stm
Acciones de Mejora en Rasp
Se realizaron mejoras significativas en la implementación del proyecto para optimizar tanto la
recolección de datos como la visualización en tiempo real y la interacción con el sistema
embebido. En la versión mejorada, se integró una interfaz gráfica (GUI) utilizando Tkinter
para permitir el envío de comandos de dirección y frenado al microcontrolador desde la
Raspberry Pi. Esto se logró mediante las funciones send_right, send_left y send_stop, que
envían bytes específicos a través de una conexión serial configurada con la librería serial.
Además, se mejoró la visualización de los datos en tiempo real utilizando Matplotlib y su
funcionalidad de animación para actualizar gráficas de velocidad del vehículo, velocidad del
motor y marcha en intervalos regulares. La biblioteca threading se utilizó para manejar la
lectura de datos y la interacción con la GUI de manera concurrente, asegurando una respuesta
fluida y eficiente.
Los datos recolectados se almacenan en un archivo CSV para su análisis posterior, utilizando
la librería csv. Estas mejoras no solo incrementaron la funcionalidad y la usabilidad del
sistema, sino que también proporcionaron una herramienta robusta y detallada para la
monitorización y el control del tractor simulado en tiempo real.
Figura 5. Librerías antes y después (mejora ) python
● [Link].backend_tkagg.FigureCanvasTkAgg: Es una clase que permite
integrar gráficos de Matplotlib en aplicaciones Tkinter.
● tkinter: Es la biblioteca estándar de Python para la creación de interfaces gráficas de
usuario (GUI). Proporciona clases para crear ventanas, botones, campos de entrada de
texto, y otros elementos de la interfaz de usuario.
Figura 6. Integración de GUI
Antes: No había GUI, el control del tractor era limitado.
Después: Se integró una GUI utilizando Tkinter que permite enviar comandos para mover el
tractor a la derecha, izquierda y detenerlo.
Figura 7. Multithreading
Antes: El código no manejaba bien la concurrencia, lo que podía llevar a bloqueos o retrasos.
Después: Se implementó el manejo de hilos (threading) para la lectura de datos y
actualización de la GUI, mejorando la respuesta del sistema.
Figura 8. Mejor Visualización de Gráficas
Antes: Las gráficas eran simples y menos dinámicas, utilizando funciones básicas de
Matplotlib.
Después: Las gráficas se actualizan en tiempo real utilizando [Link] para una
visualización más dinámica y detallada.
Interfaz Final en Python
Justificación de la mejora:
Anteriormente ya se había puesto a prueba nuestro modelo de simulación prototipo con
algunos errores. Específicamente en la entrega anterior notamos no sólo que el documento
.csv no se actualizaba en “tiempo real” sino que había que acceder al mismo y refrescar el
editor nano cada vez que queríamos ver reflejados los valores nuevos. Entonces, el archivo
como tal si contenía los valores pues estos estaban siendo graficados de igual manera. Otro
problema que nos encontramos a la hora de graficar los datos de ingreso era que las gráficas
en si tardaban mucho en reflejar en tiempo real los datos que se reflejaban en la LCD (y de
por si la LCD tarda bastante en reflejar dichos datos), es decir, al momento de llenar los datos
en el archivo .csv todavía había un delay considerable (gracias a delays de programa y falta
de optimización en sí) el cual causaba que las gráficas tardarán aproximadamente un minuto
o minuto y medio en reflejar lo que se movía en el modelo de manera notable: cambio de
marcha, cambio de velocidad del motor, cambio de velocidad del vehículo etc.
Figura 9. Gráficas antes de la interfaz final STM
Implementación final
La implementación final de la interfaz del proyecto permitió la obtención y visualización de
datos en tiempo real del tractor simulado. Utilizando Python, se desarrolló una GUI que
integra controles para dirigir el tractor (derecha, izquierda y freno) y gráficos en tiempo real
para monitorizar la velocidad del vehículo, la velocidad del motor y la marcha.
La interfaz se conecta a un microcontrolador a través de una comunicación UART
configurada en el puerto serial. Los comandos de dirección y frenado se envían mediante
funciones específicas que transmiten bytes específicos al microcontrolador. Paralelamente, se
ejecuta un hilo dedicado a la lectura de datos desde el microcontrolador, los cuales se
decodifican y se almacenan en listas para su posterior graficación.
Para la visualización de los datos en tiempo real, se utilizaron las bibliotecas Matplotlib y
Tkinter. Se creó una figura con tres gráficos que representan las variables monitorizadas. La
función update_plot se encarga de actualizar estos gráficos en intervalos regulares,
permitiendo una visualización dinámica de la información recolectada
Figura 10. Interfaz final en la Raspberry Pi
Datos tractor CSV
Adicionalmente, todos los datos recopilados se guardan en un archivo CSV. Este archivo
contiene las columnas "Engine Speed", "Vehicle Speed" y "Gear", facilitando el análisis
posterior de la información y la identificación de patrones o posibles problemas en el
funcionamiento del tractor simulado. El proceso de almacenamiento se realiza en tiempo real,
asegurando que cada nuevo dato leído del microcontrolador sea registrado inmediatamente en
el archivo.
Este sistema embebido simulado, junto con la interfaz gráfica y la recolección de datos en
tiempo real, proporciona una herramienta robusta para el análisis y mejora del rendimiento
del tractor, permitiendo a nuestro socio formador identificar y resolver problemas de manera
más eficiente.
Figura 11. CSV recolección de datos Final
Código final para la interfaz FINAL
import serial
import time
import threading
import csv
import [Link] as plt
import [Link] as animation
from [Link].backend_tkagg import FigureCanvasTkAgg
import tkinter as tk
# Variable global para detener los hilos
stop_thread = False
# Configura el puerto serial
ser = [Link](
port="/dev/ttyUSB0",
baudrate=115200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=[Link],
timeout=1 # Ajusta el puerto y baudrate
)
def send_right():
[Link](0.5) # Ajustar el delay según sea necesario
[Link](b'\x01') # Envía el byte 0x01 para indicar dirección
derecha
def send_left():
[Link](0.5) # Ajustar el delay según sea necesario
[Link](b'\x03') # Envía el byte 0x03 para indicar dirección
izquierda
def send_stop():
[Link](0.5) # Ajustar el delay según sea necesario
[Link](b'\x02') # Envía el byte 0x02 para indicar freno
# Crear la ventana de la GUI
window = [Link]()
[Link]("Datos del Tractor en Tiempo Real")
# Crear el frame para los botones
button_frame = [Link](window)
button_frame.pack()
# Crear los botones para las direcciones
right_button = [Link](button_frame, text="Right",
command=send_right, width=10, height=2)
left_button = [Link](button_frame, text="Left", command=send_left,
width=10, height=2)
stop_button = [Link](button_frame, text="Brake", command=send_stop,
width=10, height=2)
# Añadir los botones al frame
right_button.grid(row=0, column=0, padx=5, pady=5)
left_button.grid(row=0, column=1, padx=5, pady=5)
stop_button.grid(row=0, column=2, padx=5, pady=5)
# Definir las listas
velocidad_motor = []
velocidad_vehiculo = []
marcha = []
tiempos = []
# Crear un archivo CSV y escribir los encabezados
with open('datos_tractorFINAL2.csv', 'w', newline='') as archivo_csv:
writer = [Link](archivo_csv)
[Link](['Engine Speed', 'Vehicle Speed', 'Gear'])
# Función para leer datos desde el STM32 a través de UART
def read_data():
global stop_thread
while not stop_thread:
# Leer datos desde STM32 a través de UART
data = [Link]().decode().strip()
if data:
data_list = [Link](',')
if len(data_list) == 3:
try:
motor = float(data_list[0])
vehicle = float(data_list[1])
gear = int(float(data_list[2])) # Convertir a
float y luego a int
# Imprimir los datos en la consola
print(f"Velocidad del motor: {motor}, Velocidad del
vehículo: {vehicle}, Marcha: {gear}")
# Añadir datos a las listas
velocidad_motor.append(motor)
velocidad_vehiculo.append(vehicle)
[Link](gear)
[Link](len(tiempos) + 1)
# Escribir datos en el archivo CSV
with open('datos_tractorFINAL2.csv', 'a',
newline='') as archivo_csv:
writer = [Link](archivo_csv)
[Link]([motor, vehicle, gear])
[Link](0.1)
except (IndexError, ValueError) as e:
pass # Ignorar los errores de conversión y formato
# else:
# print(f"Error: datos recibidos no tienen el formato
esperado: {data_list}")
# Función para actualizar las gráficas en tiempo real
def update_plot(i):
[Link]()
[Link]()
[Link]()
[Link](tiempos, velocidad_vehiculo, label="Vehicle Speed",
color='blue')
[Link](tiempos, velocidad_motor, label="Engine Speed",
color='red')
[Link](tiempos, marcha, label="Gear", color='green')
ax1.set_title("Velocidad del vehículo")
ax2.set_title("Velocidad del motor")
ax3.set_title("Marcha")
[Link]()
[Link]()
[Link]()
# Crear la figura y los ejes para matplotlib
fig, (ax1, ax2, ax3) = [Link](3, 1, figsize=(10, 8))
# Ajustar el espacio entre las gráficas
plt.subplots_adjust(hspace=0.5)
# Integrar la figura de matplotlib en tkinter
canvas = FigureCanvasTkAgg(fig, master=window)
canvas.get_tk_widget().pack()
# Iniciar los hilos
[Link](target=read_data).start()
# Iniciar la animación de matplotlib
ani = [Link](fig, update_plot, interval=1000)
# Iniciar el bucle principal de la GUI en el hilo principal
[Link]()
# Detener los hilos al cerrar la ventana
stop_thread = True
[Link]()
Conclusiones y Reflexiones
Gracias al desarrollo realizado hemos aprendido a profundidad como construir e implementar
sistemas embebidos en general. Pero específicamente que involucren periféricos
implementados en el sistema STM32, con análisis en la Rasp. Además de comunicación
bidireccional de dos sistemas embebidos.
Jorge Luis: Gracias a este proyecto aprendí mucho sobre cómo los sistemas embebidos
reciben información del exterior, se comunican entre ellos y expresan esa información en un
frontend y un backend. Además de ello comprendí el uso realista de la calendarización en
tiempo real así como el uso de recursos compartidos en la misma.
Alfonso Solis: Este proyecto me ayudó enormemente a entender cómo se envía información
de la Raspberry Pi al STM32 y viceversa. Aprendí a utilizar las funciones de Python para
manejar la comunicación y el procesamiento de datos en la Raspberry Pi, lo que fue crucial
para el éxito del proyecto. La integración de estos sistemas y la programación en tiempo real
mejoraron mi comprensión de los sistemas embebidos y su aplicación en el mundo real,
especialmente en cuanto a la comunicación bidireccional entre dispositivos.
David Lomeli: Este proyecto me ayudó para profundizar en mi conocimiento de, mutex,
queues y conexiones en STM32. A pesar que fue complicado el lograr completamente la
conexión en FreeRTOS, la práctica en STMCubeIDE fue invaluable. Aprendí a coordinar
tareas, gestionar recursos y asegurar comunicaciones efectivas entre componentes del
sistema. Esta experiencia mejoró mi capacidad para optimizar rendimiento y sincronización
en sistemas embebidos, ayudándome a facilitar mi dinamismo en posibles proyectos a futuro.
Trabajo a Futuro
Planeamos llevar este modelo a un formato físico con motores DC los cuales podamos
manipular el PWM de los motores según la velocidad del modelo
Figura 12. Tractor aplicado a un prototipo movible
Y finalmente mejorar también nuestro sistema de nuestra rasp, para que así mismo pueda ser
más rápido y mejor todo el procesamiento de datos y así de la misma manera el despliegue de
datos.
Figura 13. Imagen de la raspberry pi 5
Referencias bibliográficas
● ▷ Qué es un SOC y cuáles son sus características principales 🥇. (2024, 15 febrero).
Profesional Review.
[Link]
● Audi pre sense. (s. f.). [Link].
[Link]
● Greyrat, R. (2022, 5 julio). Sistema operativo en tiempo real (RTOS) – Barcelona
Geeks. [Link]
● La transformación digital como motor de la seguridad vial. (s. f.). [Link].
[Link]
ws/co/es/2024/apr/[Link]#:~:text=A%20trav%C3%A9s%20de%2
0%27Conductor%20Inteligente,mejorar%20la%20conducci%C3%B3n%20del%20us
uario.
● ¿Qué es un microcontrolador? (s. f.). Electronica Estudio.
[Link]
● ¿Qué es un sistema operativo en tiempo real? (s. f.). Aptiv.
[Link]
n-tiempo-real
● Redacción. (2024, 31 mayo). Audi Drive Select, así funciona. Arrojo.
[Link]
● Sitrack. (s. f.). Todo sobre los sistemas avanzados de asistencia al conductor.
[Link]
ctor#:~:text=Los%20sistemas%20de%20ayuda%20a,al%20conductor%20en%20todo
%20momento.