Full text
TRABAJO FINAL DE MÁSTER TÍTULO: DESARROLLO DE UNA PASARELA MULTIRED LIN PARA APLICACIONES EN LA INDUSTRIA AUTOMOTRIZ AUTOR: SONG, YOUYI FECHA DE PRESENTACIÓN: 8 DE JULIO DE 2024
APELLIDO: SONG NOMBRE: YOUYI TITULACIÓN: MÁSTER UNIVERSITARIO EN INGENIERÍA DE SISTEMAS AUTOMÁTICOS Y ELECTRÓNICA INDUSTRIAL PLAN: MÁSTER UNIVERSITARIO EN INGENIERÍA DE SISTEMAS AUTOMÁTICOS Y ELECTRÓNICA INDUSTRIAL DIRECTOR: SARRIA GANDUL, DAVID CODIRECTOR: GARCIA BENADI, ALBERT DEPARTAMENTO: EEL - DEPARTAMENTO DE INGENIERÍA ELECTRÓNICA Calificación del TFM TRIBUNAL PRESIDENTE SECRETARIO VOCAL FECHA DE LECTURA: 8 DE JULIO 2024 Este proyecto tiene en cuenta aspectos medioambientales: Sí x No
RESUMEN Este proyecto tiene como objetivo el desarrollo de una plataforma de control capaz de gestionar múltiples redes LIN. El hardware está basado en una Raspberry Pi Pico y el controlador de cuatro puertos LIN SJA1124 que se gestiona vía SPI (Serial Peripheral Interface). El hardware descrito se controla a través de una aplicación para PC, programada en LabVIEW, que se comunica con la Raspberry Pi Pico a través del puerto USB. La comunicación entre ambos se realiza a través de un protocolo basado en comandos que ofrece flexibilidad, permitiendo configurar individualmente el baudrate de cada puerto y enviar o recibir tramas LIN de longitud variable. El código de la Raspberry Pi Pico, programado en MicroPython, se encarga de interpretar los comandos recibidos del PC, controlar el SJA1124 (realizando lecturas o escrituras en los registros correspondientes a través de SPI) y enviar la respuesta de vuelta al PC. Para validar el sistema se han utilizado y programado múltiples placas de evaluación de Microchip, las cuales simulan diferentes centralitas LIN (esclavos). Mediante estas placas se ha podido validar el correcto funcionamiento del sistema en los dos escenarios posibles: esclavos compartiendo el mismo bus y en buses independientes. Palabras Clave LIN, Multiredes, Automoción, SJA1124, LabVIEW, Raspberry Pi Pico, MicroPython
ABSTRACT This project aims to develop a control platform capable of managing multiple LIN networks. The hardware is based on a Raspberry Pi Pico and the four-port LIN controller SJA1124, which is managed via SPI (Serial Peripheral Interface). The described hardware is controlled through a PC application, programmed in LabVIEW, which communicates with the Raspberry Pi Pico via the USB port. Communication between the two is conducted through a command-based protocol that offers flexibility, allowing individual configuration of the baud rate for each port and sending or receiving LIN frames of variable length. The Raspberry Pi Pico code, programmed in MicroPython, is responsible for interpreting the commands received from the PC, controlling the SJA1124 (performing reads or writes on the corresponding registers via SPI), and sending the response back to the PC. Multiple Microchip evaluation boards, simulating different LIN control units (slaves), have been used and programmed to validate the system. These boards have enabled the validation of the system's correct functioning in both possible scenarios: slaves sharing the same bus and on independent buses. Keywords LIN, Multiple networks, Automotive, SJA1124, LabVIEW, Raspberry Pi Pico, MicroPython
ÍNDICE 1 Introducción ................................................................................................................................. 1 1.1 Contexto ............................................................................................................................... 1 1.2 Objetivos .............................................................................................................................. 1 1.3 Medios disponibles .............................................................................................................. 2 2. Documentación ........................................................................................................................... 3 2.1 Fundamentos LIN ................................................................................................................ 3 2.1.1 LIN y sus características ............................................................................................. 3 2.1.2 La capa física de LIN .................................................................................................. 4 2.1.3 La capa de protocolo LIN............................................................................................ 5 2.2 Transceptores LIN .............................................................................................................. 12 2.3 Integrado SJA1124 ............................................................................................................. 13 2.3.1 Características ........................................................................................................... 13 2.3.2 Modo de Trabajo ....................................................................................................... 14 2.3.3 Comunicación SPI ..................................................................................................... 16 3. Herramientas ............................................................................................................................. 18 3.1 Placa de evaluación de microchip ...................................................................................... 18 3.1.1 Descripción ............................................................................................................... 18 3.1.2. Hardware ........................................................................................................................ 18 3.2 Raspberry pico y placa SJA1124 ....................................................................................... 21 3.3 Entornos de programación utilizados ................................................................................. 23 3.3.1 Thonny ...................................................................................................................... 23 3.3.2 LabVIEW .................................................................................................................. 24 4. Desarrollo .................................................................................................................................. 25 4.1 Especificaciones ................................................................................................................. 25 4.2 Esquemas y diagramas de bloques ..................................................................................... 25 4.3 Protocolo de comunicaciones ............................................................................................. 26 4.4 Aplicaciones desarrolladas ................................................................................................. 26 4.4.1 Aplicación para PC .................................................................................................... 27 4.4.2 Firmware para Raspberry Pi Pico .............................................................................. 29 4.4.3 Firmware para la placa de evaluación de Microchip ................................................. 33 5 Pruebas y resultados ................................................................................................................... 38 5.1 Esquema del montaje ......................................................................................................... 38 5.2 Pruebas y validación .......................................................................................................... 40 6. Conclusiones ............................................................................................................................. 42 6.1 Logros del proyecto ........................................................................................................... 42 6.2 Limitaciones y desafíos ...................................................................................................... 42 6.3 Trabajo futuro ..................................................................................................................... 43
Referencias bibliográficas ............................................................................................................. 44 Anexos........................................................................................................................................... 45 Anexo A – Código fuente Raspberry Pi Pico ........................................................................... 45 Anexo B – Códigos fuente aplicación para PC ........................................................................ 49 Anexo C - Mapa de memoria del controlador LIN SJA1124 ................................................... 54 Anexo D - Firmware para placa Microchip CAN-LIN ............................................................ 56
ÍNDICE DE FIGURAS Figura 1. Esquema de componentes del proyecto ................................................................................... 3 Figura 2. Esquema de componentes del driver. [fuente: Controlador] ................................................... 4 Figura 3. Especificación en tensión para los receptores [fuente: Especificación de Señal para Receptores] .......................................................................................................................................... 4 Figura 4. Especificación en tensión para los emisores [fuente: Especificación de Señal para Emisores] ............................................................................................................................................. 5 Figura 5. Diagrama de comunicación del master [Fuente: Encabezado y respuesta] ........................... 5 Figura 6. Esquema de estructura del Encabezado de la trama ............................................................... 6 Figura 7. Estructura del campo PID ....................................................................................................... 6 Figura 8. Diagrama de la Trama incondicional ..................................................................................... 8 Figura 9. Diagrama de la Trama de diagnóstico .................................................................................... 9 Figura 10. Diagrama de la tabla de programación [ Fuente:https://blog.csdn.net/] ........................... 10 Figura 11. Esquema de estructura de los slots de trama [ fuente:https://blog.csdn.net/] ...................... 10 Figura 12. Una señal de despertar[fuente:https://blog.csdn.net/] ........................................................ 11 Figura 13. La estructura de la trama de dormir[fuente:https://blog.csdn.net/] ................................... 12 Figura 14. Esquema de conexión de los dispositivos [Fuente: Diagrama SJA1124] ........................... 13 Figura 15. Estructura de los componentes internos de la placa SJA1124 [Fuente:Diagrama de Estructura] ........................................................................................................................................ 14 Figura 16. Descripción de los pines de la placa SJA1124 [Fuente: Los pines de SJA1124 ] ............... 14 Figura 17. Diagrama de los cuatro modos de trabajo. [Fuente: Modos de trabajo] ........................... 15 Figura 18. SPI timing protocol .............................................................................................................. 17 Figura 19. Estructura de Datos SPI ...................................................................................................... 17 Figura 20. Placa de evaluación DSPIC33EV 5V CAN-LIN Starter Kit ................................................ 18 Figura 21. Esquema de Raspberry Pi Pico Pinout para presentar las funciones de cada pin ............. 22 Figura 22. Diagrama de la conexión entre Pico y SJA1124 (SPI, Los puertos de LIN, BAT y GND de sja1124) ........................................................................................................................................ 22 Figura 23. Diagrama de una placa para conectar a Raspberry Pi Pico .............................................. 22 Figura 24. Raspberry Pi Pico y placa evaluación SJA1124 .................................................................. 23 Figura 25. La interfaz de Thonny .......................................................................................................... 23 Figura 26. La interfaz de LABVIEW ..................................................................................................... 24 Figura 27. Esquema del proyecto .......................................................................................................... 25 Figura 28. Cuatro modelos de VISA ...................................................................................................... 27 Figura 29. Los eventos de enviar y salir ............................................................................................... 27 Figura 30. Esquema de la estructura de RX en LabVIEW .................................................................... 28 Figura 31. Esquema de la estructura de cuatros casos (OPEN/CLOSE/TX/RX) en LabVIEW ............ 28 Figura 32. Esquema de estructura RX recibido para separar los datos en LabVIEW .......................... 29 Figura 33. El Código de configuración global antes de enviar la trama.............................................. 29 Figura 34. Código Open - Baudrate...................................................................................................... 30 Figura 35. Código Open – inicializción ................................................................................................ 30 Figura 36. El Código de write para calcular la longitud de los datos recibido ................................... 30 Figura 37. El Código en Thonny para confirma estado de recepción del SJA1124 y el modo usado ........................................................................................................................................................... 31
Figura 38. El Código en Thonny con configuración LIN y write los datos a los registros ................... 31 Figura 39. El Código de read para confirma estado de recepción del SJA1124 y el modo de transmitir ........................................................................................................................................... 32 Figura 40. El Código de read para confirma la longitud del dato ........................................................ 32 Figura 41. El Código de read para escribir unos datos básico a sus registros .................................... 32 Figura 42. El Código de read para leer los datos de los registros ........................................................ 33 Figura 43. La interfaz de MPLAB para eliminar CAN ......................................................................... 34 Figura 44. El código de Text_Mode cambiado ...................................................................................... 34 Figura 45. EL código cambiado parar encender los leds en función de la trama LIN recibido ........... 35 Figura 46. El codigo sobre como eliminar la una funcion de LED2..................................................... 36 Figura 47. Añadir unos códigos para verificar el ID ............................................................................ 37 Figura 48. Diagrama de conexión......................................................................................................... 38 Figura 49. Diagrama de conexión detallado ........................................................................................ 38 Figura 50. Esquema del montaje final .................................................................................................. 39 Figura 51. la interfaz de usuario en LabVIEW y una aplicación del puerto serie virtual .................... 40 Figura 52. La interfaz final de LabVIEW .............................................................................................. 41 Figura 53. Montaje final y estados de los LEDs tras la prueba ........................................................... 41 Figura 54. Esquema del evento ENVIAR en LabVIEW ......................................................................... 49 Figura 55. Esquema de open ................................................................................................................. 49 Figura 56. Esquema de close ................................................................................................................ 49 Figura 57. Esquema de RX y el encabezado de la trama es ACK ......................................................... 50 Figura 58. Esquema de TX .................................................................................................................... 50 Figura 59. Esquema de verdad .............................................................................................................. 50 Figura 60. Esquema de falso ................................................................................................................. 50 Figura 61. Esquema del evento SALIR .................................................................................................. 50 Figura 62. La interfaz del proyecto para realizar las funciones de control y respuesta ....................... 51 Figura 63. Diagrama de la estructura del proyecto en LabVIEW ........................................................ 51 Figura 64. Esquema de conexiones del subVI enviar ............................................................................ 51 Figura 65. Esquema de la estructura de RX en subVI........................................................................... 52 Figura 66. Esquema de OPEN en subVI ............................................................................................... 52 Figura 67. Esquema de la close EN subVI ............................................................................................ 52 Figura 68. Esquema de TX en subVI para enviar los datos de switch, temperatura y potenciómetro ........................................................................................................................................................... 52 Figura 69. Esquema de RX para enviar los datos de rx , linx, id y bytes rx ......................................... 53 Figura 70. La interfaz de subVI para leer los datos .............................................................................. 53 Figura 71. Diagrama de subVI .............................................................................................................. 53
ÍNDICE DE TABLAS Tabla 1. Comparativa transceptores LIN multipuerto [fuente: NXP] ................................................... 12 Tabla 2 Conexiones LIN los modos de transmisión y recepción ........................................................... 21 Tabla 3 Estructura de la trama Open (PC a Pico) ................................................................................ 26 Tabla 4 Estructura de la trama Open (Pico a PC) ................................................................................ 26 Tabla 5 Estructura de la trama Close (PC a Pico) ............................................................................... 26 Tabla 6 Estructura de la trama Close (Pico a PC) ............................................................................... 26 Tabla 7 Estructura de la trama Tx (PC a Pico) .................................................................................... 27 Tabla 8 Estructura de la trama Tx (Pico a PC) .................................................................................... 27 Tabla 9 Estructura de la trama Rx (PC a Pico) .................................................................................... 27 Tabla 10 Estructura de la trama Rx (Pico a PC) .................................................................................. 27 Tabla 11. los registros de control del sistema ....................................................................................... 54 Tabla 12. los registros de estado del sistema ........................................................................................ 54 Tabla 13. los registros de inicialización de canal LIN .......................................................................... 54 Tabla 14. los registros de envío de trama de canal LIN ........................................................................ 54 Tabla 15. los registros de obtención de estado del canal LIN ............................................................... 55 Tabla 16. Registro de configuración del PLL (PLLCFG; dirección 01h). ............................................ 55
7 Tal como se muestra en la Figura 7 los primeros seis bits de PID son el ID de la trama, seguidos por bits de paridad. Si hay un error en la transmisión del ID de la trama, ello causará que la señal no llegue correctamente a su destino. Por lo tanto, se introduce la siguiente fórmula: 𝑃0 = 𝐼𝐷0⨁𝐼𝐷2⨁𝐼𝐷4 𝑃1 = ¬(𝐼𝐷1⨁𝐼𝐷3⨁𝐼𝐷4⨁𝐼𝐷5) El PID no presentará la situación de ser 0 o totalmente 1, por lo que, si un nodo recibe 0xFF o 0x00, se puede considerar un error de transmisión. Trama respuesta (Frame response) Se analizan los campos detallados como trama de respuesta, que son Data y la verificación de suma: Data: Los datos enviados por un nodo se encuentran en este segmento, que incluye de uno a ocho bytes. Los bytes se envían en orden ascendente. El segmento de datos contiene dos tipos de datos: señales (signal) y mensajes de diagnóstico (diagnostic messages). Un segmento de datos correspondiente a un ID de trama puede contener una o varias señales. Para garantizar la integridad de una señal, su actualización debe ser completa y no parcial. Normalmente, una señal es emitida por un nodo fijo, denominado el nodo emisor (publisher) de esa señal; otros uno o varios nodos la reciben, y se les llama nodos receptores (subscribers) de la señal. La información de diagnóstico (diagnostic message) se transmite a través de tramas de diagnóstico, y su interpretación depende del estado interno y del estado del nodo. Suma de verificación(checksum): Método de verificación: Para el objeto de verificación, se realiza una suma binaria con acarreo en cada byte (restando 255 cada vez que el resultado es mayor o igual a 256), y luego se realiza la operación de negación bit a bit en el resultado final. Este resultado se utiliza como la verificación a enviar. En el lado receptor, se realiza la misma suma binaria con acarreo en los datos recibidos, según el tipo de verificación. El resultado final no se nega. Luego, se suma este resultado con la verificación recibida. Si el resultado es 0xFF, la verificación es correcta. Realizar la verificación de los contenidos transmitidos en la trama, la verificación se divide en la suma de comprobación clásica (classic checksum) y la suma de comprobación mejorada (enhanced checksum). Suma de comprobación clásica (classic checksum): Verifica principalmente los bytes de la sección de datos y se aplica a las tramas de diagnóstico. Suma de comprobación mejorada (enhanced checksum): Verifica principalmente los bytes de la sección de datos y el PID. 2.1.3.2 Tipos de trama Existen varios tipos de tramas que tienen diferente función y característica. A continuación, se detallan las empleadas. Trama incondicional (Figura 8): Usualmente utilizado para transmitir datos útiles sin necesidad de ninguna otra condición. Está compuesto por un encabezado de trama y una respuesta. El nodo principal envía el encabezado de trama como solicitud, y luego nodos específicos responden en consecuencia. Los nodos secundarios determinan si deben enviar una
8 respuesta basándose en la identificación (ID). Debido a que la trama incondicional está incluida, no hay conflictos durante la operación. Un solo intervalo de tiempo solo puede usarse por un nodo, así que las tramas incondicionales son ideales para la transmisión de datos periódicos. Figura 8. Diagrama de la Trama incondicional Trama desencadenada por evento (event triggered frame): Se utiliza para enviar información impulsada por eventos, solo se envía cuando es necesario por parte del nodo. A diferencia de las tramas incondicionales, varios nodos secundarios pueden enviar respuestas a una trama desde el nodo principal. Cuando el nodo principal envía un encabezado de trama con la ID de trama desencadenada por evento, los nodos secundarios correspondientes pueden agregar sus respuestas específicas después de este encabezado de trama. El primer byte de datos en las respuestas de las tramas desencadenadas por evento suele ser el PID de la trama incondicional correspondiente a esa respuesta, permitiendo identificar qué nodo envió la respuesta. Debido a que varios nodos pueden responder simultáneamente a las tramas desencadenadas por evento, puede ocurrir conflicto. Usualmente, el nodo principal utiliza una tabla de programación de resolución de conflictos (Collision Resolving Schedule) para resolver este problema. Trama ocasional (sporadic frame): El nodo principal utiliza tramas ocasionales para enviar información de uso muy esporádico. Esta trama es equivalente a una trama incondicional, con la diferencia de que varias tramas incondicionales pueden compartir el mismo intervalo de tiempo. El nodo principal envía tramas ocasionales según sea necesario. Si no es necesario enviar, los intervalos correspondientes quedan vacíos. Las tramas ocasionales pueden considerarse como las tramas desencadenadas por eventos del nodo principal. Trama de diagnóstico (Figura 9): Según ISO 15765-2 y ISO 14429UDS, el protocolo define dos tipos de tramas de diagnóstico: la trama de solicitud principal y la trama de respuesta secundaria. La trama de solicitud principal se usa para solicitudes de diagnóstico o para configurar nodos secundarios, y la trama de respuesta secundaria se usa para respuestas de diagnóstico. Al igual que con otras tramas, consta de un encabezado de trama y una respuesta
9 de trama. Para la trama de solicitud principal, el nodo principal transmite el encabezado de la trama y la respuesta de la trama, con un encabezado de ID igual a 0x3C. Para la trama de respuesta secundaria, el nodo principal envía el encabezado de la trama, y el nodo secundario diagnosticado envía la respuesta de la trama, con un encabezado de ID igual a 0x3D. Figura 9. Diagrama de la Trama de diagnóstico 2.1.3.3 Tabla de programación La tabla de programación de tramas (Figura 10) establece el orden y el tiempo de transmisión de los encabezados de trama en el bus. Esta tabla se encuentra en el nodo principal, y las tareas principales del nodo se programan según sea necesario. Puede haber varias tablas de programación y, por lo general, cuando se ejecuta una tabla, se comienza desde la entrada de la tabla y se continúa hasta la última trama en la tabla. Si no se inicia una nueva tabla de programación, se regresa al comienzo de la tabla actual. También es posible que ocurran interrupciones durante la ejecución de una tabla, saltando a otra tabla y luego regresando. Esto se aplica, por ejemplo, a las tramas desencadenadas por eventos.
10 Figura 10. Diagrama de la tabla de programación [ Fuente:https://blog.csdn.net/] Se establece también el tamaño de los slots de trama (frame slot) (Figura 11), que es el tiempo desde el inicio del encabezado de una trama hasta el inicio del encabezado de la siguiente trama. Cada trama puede tener un slot de trama diferente. Jitter es la diferencia de tiempo entre el flanco descendente del segmento de slot de sincronización de una trama y el momento en que comienza el slot de trama. La base de tiempo es la unidad más pequeña de tiempo en la subred LIN, generalmente configurada en 5 ms o 10 ms. El slot de trama debe ser un múltiplo entero de la base de tiempo. Al iniciar desde el momento de la base de tiempo y al cambiar a otra tabla, es necesario esperar al final del slot de trama actual. Figura 11. Esquema de estructura de los slots de trama [ fuente:https://blog.csdn.net/]
11 2.1.3.4 Gestión de red La gestión de red se puede dividir en 2 partes. La primera es para activar o despertar la red, para habilitar la recepción y la segunda parte la de aletargar o dormir la red para no recibir mensajes. Despertar (wakeup): Cuando el bus está en estado de inactividad, tanto los nodos maestros como los nodos esclavos pueden enviar una señal de despertar al bus (Figura 12). La duración de la señal de despertar oscila entre 250 µs y 5 ms. Los demás nodos determinan la señal de despertar con un umbral de detección de más de 150 µs. Cada nodo esclavo debe prepararse para recibir comandos del maestro dentro de los 100 ms posteriores al final del pulso explícito de la señal de despertar. El nodo maestro también debe ser despertado. Dentro de los 100 ms, el nodo maestro inicia la comunicación enviando el encabezado de la trama. El intervalo de sincronización del nodo maestro también puede actuar como una señal de despertar. Dado que los nodos esclavos necesitan tiempo para la inicialización, es posible que la trama enviada por el nodo maestro no sea haya recibido correctamente. Figura 12. Una señal de despertar[fuente:https://blog.csdn.net/] Si un nodo envía una señal de despertar, no recibe comandos en el bus de 150 a 250 ms, puede volver a enviarla. La señal de despertar puede reenviarse hasta tres veces, tras lo cual debe esperar al menos 1,5 segundos antes de poder enviar la señal de despertar nuevamente. Dormir (sleep): Se entra en modo de reposo en dos situaciones: 1. Utilizando la trama de solicitud del nodo maestro 0x3C como comando de reposo en una trama de diagnóstico. Se solicita que el primer byte del segmento de datos sea 0x00 y los bytes restantes sean 0xFF. El comando de reposo es enviado por el nodo maestro, y los nodos esclavos en el bus evalúan el primer byte del segmento de datos, ignorando los demás. Después de recibir el comando de reposo, los nodos esclavos no necesariamente deben entrar en modo de bajo consumo, dependiendo de la configuración de la capa de aplicación. 2. Cuando el bus está en silencio (sin cambios explícitos ni implícitos en el nivel eléctrico) durante 4-10 segundos, los nodos entran automáticamente en modo de reposo.
12 Figura 13. La estructura de la trama de dormir[fuente:https://blog.csdn.net/] 2.1.3.5 Estado de gestión Estado de gestión se implementa para detectar errores en el funcionamiento. Una vez que se detecta un error, se toman medidas diferentes según el diseño. Un método implica la sustitución simple de nodos con errores, mientras que otra opción es poner el nodo con problemas en un modo de autoprotección (Limp Home Mode). 2.2 Transceptores LIN Se hizo una búsqueda de transceptores LIN con múltiples puertos y encontré cuatro modelos diferentes: TJA1022, TJA1024, TJA1124, SJA1124 (NXP Semiconductors), ver Tabla 1. De estos, solo SJA1124 tiene unas características más interesantes que el resto, en primer lugar, se controla por SPI y en segundo lugar implementa la capa de enlace de datos. Así, esta solución no solo reduce la complejidad del diseño hardware, al reducir el número de líneas y requerimientos hardware del microcontrolador, sino que también simplifica el desarrollo del software al implementar la capa de enlace. Es la solución utilizada en este proyecto. . Tabla 1. Comparativa transceptores LIN multipuerto [fuente: NXP]
13 Cuando el SJA1124 se conecta a SPI (SCK, SDI, SDO, SCSN), puede lograr hasta cuatro salidas LIN como máximo. Si es necesario agregar otro sja1124 para gestionar más puertos LIN, simplemente necesitamos añadir un pin adicional para cada chip select. (N. N. Semiconductors, 2022) Figura 14. Esquema de conexión de los dispositivos [Fuente: Diagrama SJA1124] 2.3 Integrado SJA1124 2.3.1 Características Aquí hay algunas de sus características y se muestran dos figuras para comprender: una es el diagrama de la estructura interna del SJA1124 (Figura 15), y la otra es el diagrama de distribución de pines y sus funciones correspondientes (Figura 16). 1) Sja1124 es un chip que hereda la función de controlador y transceptor para LIN, compatible con hasta cuatro puertos de comunicación LIN.
14 2) Admite los estándares internacionales de protocolos LIN2.0, LIN2.1, LIN2.2, LIN2.2A y protocolos relacionados, con una velocidad de transmisión máxima de hasta 20 kbps. 3) Se puede despertar de bajo consumo con SPI o LIN. 4) Requiere una fuente externa para el reloj de comunicación LIN cuando está en modo LIN. 5) La configuración del hardware LIN solo necesita ajustar los registros Figura 15. Estructura de los componentes internos de la placa SJA1124 [Fuente:Diagrama de Estructura] Figura 16. Descripción de los pines de la placa SJA1124 [Fuente: Los pines de SJA1124 ] 2.3.2 Modo de Trabajo El SJA1124 admite dos modos de funcionamiento principales: modo normal y modo de bajo consumo. También se admiten modos adicionales de protección, como undervoltage de suministro de batería (Off), undervoltage de VIO intermedio (VIO UV) y protección contra sobrecalentamiento (Overtemp). El diagrama de estado del SJA1124 se muestra en la Figura 17.
15 Figura 17. Diagrama de los cuatro modos de trabajo. [Fuente: Modos de trabajo] modo de bajo consumo El SJA1124 consume significativamente menos energía en el modo de bajo consumo que en el modo normal. Todos los controladores de comandos LIN y el PLL están desactivados. Aunque el consumo de corriente es muy bajo en el modo de bajo consumo, el SJA1124 aún puede detectar eventos SPI y de activación remota en los pines LINx. Cuando el SJA1124 cambia al modo de bajo consumo, el pin INHN se establece en flotante, el acceso al registro SPI se desactiva y todos los valores del registro se restablecen. El SJA1124 cambia del modo normal al modo de bajo consumo cuando el bit LPMODE en el registro de modo está configurado, siempre que todos los canales LIN estén en modo de suspensión LIN (SLEEP = 1 en el registro LCFG1), no haya transmisión de trama LIN en curso y no haya interrupciones pendientes. modo normal El modo normal es el estado operativo normal del SJA1124. Los registros pueden ser accedidos a través del SPI. El PLL está habilitado y puede ser configurado. Para la transmisión de tramas LIN, un canal LIN debe estar en modo normal LIN y el PLL debe estar bloqueado. El SJA1124 cambia del modo de apagado al modo normal cuando el voltaje en el pin BAT supera el umbral de detección de encendido, V th(det)pon. El SJA1124 cambia del modo de bajo consumo al modo normal cuando se detecta una activación remota en uno de los pines LINx o se desencadena un evento de activación SPI. Los registros contendrán valores predeterminados después de una transición desde los modos de apagado o bajo consumo al modo normal. La interrupción del estado de inicialización se establece y la salida INTN se fuerza a LOW. INITI debe ser despejado antes de que expire el tiempo de espera de inactividad de INITI, t to(idle)INITI. De lo contrario, el SJA1124 cambia al modo de bajo consumo. Las transiciones al modo normal toman tinit(norm).
16 lin sleep mode Un canal LIN puede detectar eventos de activación remota LIN en el pin LIN asociado en el modo de suspensión LIN. Típicamente, un canal LIN se configura en modo de suspensión LIN después de la transmisión de un comando LIN denominado "go-to-sleep", que es una trama de solicitud especial del comandante LIN emitida para forzar a los nodos respondedores LIN al estado de suspensión de la red LIN.Un canal LIN cambia al modo de suspensión LIN cuando el bit SLEEP en el registro de configuración LIN asociado se establece en 1 y la transmisión de tramas LIN se ha completado. lin normal mode En el modo normal LIN, un canal LIN puede utilizarse para la transmisión de tramas LIN.Un canal LIN cambia al modo normal LIN cuando el bit SLEEP en el registro de configuración LIN asociado se establece en 0, siempre que el bit INIT = 0. Después de cambiar al modo normal LIN, el canal LIN estará listo para la transmisión de tramas LIN después de un breve período de inicialización (tinit (LIN)). lin initialization mode Los canales LIN pueden inicializarse en este modo. Todas las transferencias de mensajes hacia y desde el bus LIN se abortan cuando el SJA1124 entra en modo de inicialización LIN. Por lo tanto, el estado del canal LIN debe verificarse (a través del registro de estado LIN) antes de cambiar al modo de inicialización LIN. Las salidas del bus LIN, LINx, están en estado recesivo (ALTO) en este modo. El SJA1124 cambia al modo de inicialización LIN cuando el bit INIT en el registro de configuración LIN 1 se establece en 1 (siempre que el modo de suspensión LIN no esté seleccionado; SLEEP = 0). lin high speed mode En el modo LIN de alta velocidad, el transceptor LIN asociado admite velocidades de baudios superiores a 20 kbaudios. De lo contrario, el comportamiento es idéntico al modo LIN normal. Un canal LIN cambia al modo LIN de alta velocidad cuando se establece el bit LxHC asociado en el registro de comunicación LIN 1. 2.3.3 Comunicación SPI SPI proporciona el enlace de comunicación con el microcontrolador, admitiendo operaciones de múltiples respondedores. El SPI utiliza transferencia de datos dúplex completa. Con la transferencia de datos dúplex completa, se devuelve información de estado cuando se ingresa nuevo dato de control. La interfaz también ofrece una opción de acceso de solo lectura, que permite que los registros sean leídos por la aplicación sin cambiar el contenido del registro. Además, el formato de transferencia de datos SPI proporciona una longitud de datos variable de hasta 16 bytes.
23 Figura 24. Raspberry Pi Pico y placa evaluación SJA1124 3.3 Entornos de programación utilizados 3.3.1 Thonny La Raspberry Pi Pico se puede programar en Micro-Python y C. Por sencillez se optó por programar la placa con MicroPython utilizando el entorno Thonny. En la Figura 25, podemos ver la interfaz de Thonny, y se detallan las partes principales (Micropython.org, 2017). Figura 25. La interfaz de Thonny
24 [1]. La interfaz para escribir programas en MicroPython. [2]. Puede revisar aquí los resultados de la ejecución del programa; si hay errores, se mostrarán los casos detallas (por ejemplo, si la imagen no está conectada correctamente al Raspberry Pi Pico, se indicará que no se ha encontrado la conexión adecuada). [3]. Muestra el estado de conexión del Raspberry Pi Pico. [4]. Las funciones aquí incluyen abrir o guardar archivos, así como los botones de control para ejecutar o detener el programa. También puede encontrar información detallada en la ayuda sobre cómo utilizar el software. Si desea cambiar la vista mostrada, puede ajustar la configuración aquí. [5]. Si la conexión al Raspberry Pi Pico es exitosa, en este lugar se mostrará el contenido almacenado en la placa del Raspberry Pi Pico. Por lo general, después de completar el trabajo en el código, es necesario guardar el código en la placa del Raspberry Pi Pico y nombrarlo como "main.py". [6]. Ayuda en la programación. Thonny no incluye documentación de MicroPython, ésta debe de consultarse en otras fuentes. La principal fuente de recursos para programar con Micro- Python se encuentra en [https://micropython.org/]. 3.3.2 LabVIEW La aplicación de PC se programó con la versión de LabVIEW 2018 SPI. En el entorno de LabVIEW se muestran 2 tableros, uno de programación, panel izquierdo de la Figura 26 denominado como 1 en la figura, y uno de visualización entrada y salida, panel derecho de Figura 26, denominado como 2 en la figura. Figura 26. La interfaz de LABVIEW
25 (1) Panel de programación de LabVIEW En el panel de programación se desarrolla el código de los programas. El código en LabVIEW es a través de bloques en lugar de líneas de código. La interfaz permite simular paso a paso la ejecución del programa, lo que facilita la verificación de la corrección del código. (2) Panel de entrada y salida En esta ventana se diseña el entorno gráfico de la interfaz del programa. En la ventana se ubican los controles e indicadores necesarios para controlar y monitorizar las variables de la aplicación. (3) Panel de herramientas En esta interfaz, podemos seleccionar los módulos o VIs. Dependiendo de las necesidades lógicas específicas, podemos elegir diferentes módulos y colocarlos en la ventana 1 para programar. En este proyecto el principal módulo que se utiliza es VISA, que es el módulo que permite la comunicación por el puerto serie y mediante el cual se realizará la comunicación entre el PC y la Raspberry Pico, como se explicará en el próximo capítulo. 4. Desarrollo 4.1 Especificaciones En este proyecto, esperamos implementar la comunicación LIN para controlar la placa, y usaremos programación en LabVIEW en el ordenador para facilitar el envío de datos experimentales y la recepción de los resultados del experimento. Las placas utilizadas incluyen Raspberry Pi Pico y Microchip dsPIC33EV256GM106. El Raspberry Pi Pico se emplea para establecer la comunicación con el PC, siendo programado en el lenguaje Python para recibir y procesar las instrucciones enviadas desde LabVIEW. Debido a que hemos seleccionado la comunicación LIN, utilizamos una placa SJA11124 para manejar la salida SPI del Raspberry Pi Pico. El objetivo principal es lograr el control sobre tres lámparas indicadoras, un sensor de temperatura y un interruptor giratorio de voltaje en el Microchip. Esta es una descripción general de nuestro proyecto y los materiales que se utilizarán. En la Figura 27, se puede ver el esquema completo del proyecto. 4.2 Esquemas y diagramas de bloques En la Figura 27, se muestra el proceso del proyecto, que incluye el software LabVIEW en pc y tres hardware. Las flechas indican la comunicación entre ellos, y las palabras encima representan los protocolos transmitidos. Figura 27. Esquema del proyecto
26 4.3 Protocolo de comunicaciones El protocolo de comunicaciones entre el PC y la Raspberry Pi Pico está basado en cuatro comandos: “Open”, “Close”, “Tx” y “Rx”. Cada comando contiene diferentes campos, todos ellos representados con caracteres alfanuméricos y cada campo separado del anterior por comas. Las tramas terminan con un retorno de carro y salto de línea (CR+LF). Por otro lado, cada comando enviado tiene una trama de respuesta por parte de la Raspberry Pi Pico. Cada trama de respuesta incluye un campo que indica si el comando ha sido procesado correctamente (ACK) o contiene errores (NACK). Esta última situación puede darse si el comando es incorrecto o uno de sus campos contiene un valor no adecuado o fuera de rango. A continuación, se detalla la estructura de los campos de cada uno de los comandos que conforman el protocolo de comunicaciones entre el PC y la Raspberry Pi Pico. Comando Open El comando Open permite configurar el baudrate de cada puerto LIN de forma independiente. La respuesta es una réplica de la trama recibida junto con el campo de validación de la trama. Tabla 3 Estructura de la trama Open (PC a Pico) OPEN LIN1-4 BAUDRATE Tabla 4 Estructura de la trama Open (Pico a PC) ACK/NACK OPEN LIN1-4 BAUDRATE Comando Close El comando Close cierra la comunicación de uno de los puertos de forma independiente al resto. Tabla 5 Estructura de la trama Close (PC a Pico) CLOSE LIN1-4 Tabla 6 Estructura de la trama Close (Pico a PC) ACK/NACK CLOSE LIN1-4 Comando Tx El comando Tx permite generar una trama LIN de tipo “comando y respuesta” por parte del controlador SJA1124. Enviando dicha trama, la Raspberry Pi Pico actuará sobre los registros adecuados del SJA1124 para generar este tipo de trama. En este tipo de trama se envía el ID (dirección del dispositivo al que se le destinarán los datos) y los datos que se le desean enviar, campo “Datos Tx” (máximo 8 bytes).
27 Tabla 7 Estructura de la trama Tx (PC a Pico) TX LIN1-4 ID DATOS TX Tabla 8 Estructura de la trama Tx (Pico a PC) ACK/NACK TX LIN1-4 ID DATOS TX Comando Rx El comando Rx permite generar una trama LIN de tipo “comando”. En este tipo de trama se envía únicamente el ID (dirección del dispositivo a interrogar), y es el esclavo el que contesta con los datos (hasta un máximo de 8 bytes). Dado que el número de bytes recibidos depende del eslavo, la trama contiene el campo “Nº Bytes Rx” para indicar a priori cuántos datos se esperan recibir y así validar que se han recibido todos ellos. En la respuesta se encuentran los datos que ha enviado el esclavo “Datos Rx”. Tabla 9 Estructura de la trama Rx (PC a Pico) RX LIN1-4 ID Nº BYTES RX Tabla 10 Estructura de la trama Rx (Pico a PC) ACK/NACK RX LIN1-4 ID DATOS RX 4.4 Aplicaciones desarrolladas 4.4.1 Aplicación para PC La comunicación entre el PC y la Raspberry Pi Pico se realiza por USB, por ello hago uso de la librería VISA (ver en la Figura 28) y su utilización en la Figura 54. Figura 28. Cuatro modelos de VISA En LabVIEW hemos utilizado una estructura de eventos y configurado dos eventos (Figura 29): uno para cuando se presiona el botón de enviar y otro para cuando se presiona el botón de detener el programa. Cuando se desencadena cualquiera de estos eventos, la estructura se ejecuta. Esta estructura está contenida dentro de un bucle while. Figura 29. Los eventos de enviar y salir
28 El modelo enviar.vi contiene la estructura concreta de las cuatro funciones que necesitamos implementar. Utilizamos una estructura tipo "case", donde el selector de case está conectado a un enumerador que precede al comando. Este Enum contiene los casos: open, tx, rx y close. En la Figura 31 se puede observar su construcción. El código del caso Tx difiere de los demás porque se debe construir los datos de la trama LIN para compatibilizarlos con los que espera el esclavo. La trama del esclavo espera el estado de los tres interruptores en el primer byte. La temperatura que ocupa 2 bytes, con un rango de 0x200xd0 a 0x030x20. El potenciómetro también ocupa 2 bytes, con un rango de 0x000x00 a 0x0f0xff. En la Figura 30, podemos observar que en el lado izquierdo de la entrada se encuentran Lin y id. Cuando el comando es RX, se concatenan las cadenas RX, Lin, id y bytes rx, luego se separan por comas y se añade un salto de línea al final. Sus construcciones son similares; en cada evento se seleccionan los datos de entrada correspondientes y se concatenan en una cadena separada por comas. En la Figura 31, hay la información de otros casos. Figura 30. Esquema de la estructura de RX en LabVIEW Figura 31. Esquema de la estructura de cuatros casos (OPEN/CLOSE/TX/RX) en LabVIEW
29 Todos los datos recibidos se almacenan en una ventana llamada "historial" para evaluar l los resultados. Solo en el caso de "RX", mostramos los datos recibidos de forma independiente. Cuando recibimos una trama del Raspberry Pi Pico enviada a LabVIEW, eliminamos las comas y la convertimos en un array. Luego, verificamos si el primer elemento del array es ACK o NACK. Si es NACK, se activa la luz; si es ACK, los datos que necesitamos mostrar comienzan desde la cuarta unidad (ver en la Figura 32). Figura 32. Esquema de estructura RX recibido para separar los datos en LabVIEW 4.4.2 Firmware para Raspberry Pi Pico Antes de presentar la funcionalidad, necesitamos realizar una configuración básica para la comunicación SPI. Luego, definimos funciones de lectura y escritura para facilitar usar en el código siguiente. De manera similar, para simplificar el código posterior, usamos un diccionario para almacenar todas las direcciones de registro. Hay dos conjuntos de registros (LBD1-8) con los mismos nombres. Por lo tanto, hay una subdivisión adicional dentro. Al llamar a los registros, es necesario especificar si es para enviar o recibir datos para garantizar la correcta escritura o lectura de datos. Esta parte no se detalla aquí, puede leer el código detallo en anexo A. (ver en Anexo A – Código fuente Raspberry Pi Pico) Para evitar que la placa SJA1124 está en modo de suspensión y falle al trabajar correctamente después de ser abierta, escribimos el siguiente código para mantenerla activa antes de comenzar a enviar los comandos. (ver en la Figura 33). El valor de PLLCFG es 0x07, lo que indica que f(clk(PLL)in) está entre 3.5 MHz y 4.5 MHz, con un factor de multiplicación de M = 8.5. El valor de INT1 es 0x80, lo que significa que el dispositivo ha sido inicializado. Figura 33. El Código de configuración global antes de enviar la trama Open: Recibir el comando de open, y recibir el comando de qué canal LIN se va a utilizar y el valor de baudrate. Seguidamente, según el valor de baudrate, calculamos los valores de IBR y FBR, Mediante la siguiente fórmula, podemos calcular las dos valore de IBR y FBR, dado que conocemos el valor de baudrate y f(clk(PLL)out) . Podemos ver el proceso de calcular en la Figura 34. 𝑏𝑎𝑢𝑑𝑟𝑎𝑡𝑒 = 𝑓𝑐𝑙𝑘(𝑃𝐿𝐿)𝑜𝑢𝑡 16 × 𝐼𝐵𝑅 + 𝐹𝐸𝑅
30 Figura 34. Código Open - Baudrate Escribir los valores en los registros. Se escribirán en cinco registros específicos (ver en la Figura 35), El valor de LCFG1 es 1 porque es una solicitud de inicialización. Cuando el valor es 1, está en modo de inicialización LIN. Cuando es 0, está en modo LIN normal. Luego, se escriben secuencialmente los tres valores calculados anteriormente, y finalmente el valor 0x08 es la longitud del comando de ruptura LIN, que es de 11 bits. Figura 35. Código Open – inicializción Write: según la Figura 36, hemos calculado la longitud de los datos recibidos. La longitud restante después de restar los primeros tres comandos es la longitud de los datos. Figura 36. El Código de write para calcular la longitud de los datos recibido Cuando recibimos el comando de TX, el canal LIN y el ID que se va a escribir, podemos calcular el DFL basado en la longitud de datos previamente calculada. DIR serán 1 (respuesta del
31 comando LIN del emisor al destinatario) y el valor de CCS será 0 (cálculo de suma de verificación mejorado; con identificador protegido). Dado que estos tres valores al final ocuparán cinco bits y se convertirán en hexadecimal para ser transmitidos al mismo registro, hay un proceso de conversión final. (ver en la Figura 35) Figura 37. El Código en Thonny para confirma estado de recepción del SJA1124 y el modo usado Después de completar el proceso anterior, realizamos operaciones de escritura en los registros correspondientes. Al finalizar, realizamos una evaluación booleana para confirmar si la transmisión se ha completado. Con esto, hemos completado la parte de escritura del código (ver en la Figura 38). LES son los registros de estado de error LIN, escribir 0xF1 es para realizar la detección de errores. LS son los registros de estado LIN, que reflejan el estado de la transmisión del marco LIN. Contiene dos fuentes de interrupción de estado de transferencia de marco LIN. Cuando su valor es mayor que 0x42, significa que la transmisión de datos se ha completado y se ha recibido el primer byte de respuesta. LC es un registro control, es valor es 0x01 que significa generar la transmisión de encabezado LIN. Figura 38. El Código en Thonny con configuración LIN y write los datos a los registros
32 Read: esta parte, la estructura será similar a la TX, pero sin datos de entrada. Solo recibiremos el puerto LIN, el ID y la longitud de los datos que se desean leer. Además, la dirección (Respuesta de la trama LIN del respondedor al comandante.) es igual a 0, y el valor de CCS también es 0(ver en la Figura 39). Figura 39. El Código de read para confirma estado de recepción del SJA1124 y el modo de transmitir Aquí es necesario realizar una verificación de la longitud de entrada de datos, ya que el rango de tamaño de datos almacenado en nuestros registros es de 1 a 8. Si está fuera de este rango, podría causar errores durante la ejecución en la Raspberry Pi Pico (ver en la Figura 40) Figura 40. El Código de read para confirma la longitud del dato Las siguientes operaciones son similares a las de TX. Realizamos operaciones de escritura en los registros correspondientes. (ver en la Figura 41) Figura 41. El Código de read para escribir unos datos básico a sus registros Después de completar las operaciones anteriores, realiza una evaluación numérica. Realiza una operación de lectura de verificación del registro LS, determinas si los datos esperados han sido recibidos. El valor de LS es 0x44, lo que significa que la transmisión de datos LIN ya se ha completado y también se ha completado la recepción de datos. Después de confirmar la recepción de los datos, procedemos a la operación de lectura de cada uno de ellos y se envían a través de la trama de comunicación ideada (ver en la Figura 42). Se ha implementado un bucle iterativo de 100 intentos, si se supera el número de intentos y los datos no han llegado, eso podría ser debido a un problema con el dispositivo esclavo, se genera un mensaje de alarma.
39 El conexionado se resumen en las siguientes referencias: Tabla 2 Conexiones LIN los modos de transmisión y recepción Figura 22. Diagrama de la conexión entre Pico y SJA1124 (SPI, Los puertos de LIN, BAT y GND de sja1124) Figura 24. Raspberry Pi Pico y placa evaluación SJA1124 Conexión de la placa de evaluación al PC El código de la placa envía por una de las UART de la placa los datos recibidos por LIN. Para poder validar las comunicaciones LIN se conecta un conversor de puerto serie a la UART de la placa, según los manuales y el código fuente de esta placa, la patita de transmisión de la UART del micro corresponde con el pin RB4. El esquema del montaje final En la Figura 50, se utilizan tres placas para verificar el proyecto. Una placa (ID 0x23) está conectada al puerto LIN1, mientras las otras dos placas están conectadas al puerto LIN2 y tienen IDs diferentes (0x23 y 0x24). El cable rojo se utiliza para alimentar tensión al SJA1124 LIN y a las placas (hay dos tipos: 2V y 5V). El cable negro es el cable de masa y debe conectar al SJA1124 y al LIN. Los cables amarillo y verde están conectados a LIN1 y LIN2. Las dos líneas en la parte inferior de la Figura 50 son para alimentar la tensión de 5V a las placas. Figura 50. Esquema del montaje final Después de haber confirmado que todos los dispositivos están funcionando correctamente tras la conexión, comenzamos a validar el proyecto final.
40 5.2 Pruebas y validación Prueba primera En la Figura 51, mostramos la interfaz de control de LabVIEW. Controlamos las luces, la tensión y la temperatura en la placa enviando comandos. Además, hemos conectado un microchip a un puerto serie virtual. A la izquierda de la Figura 51, podemos ver los datos recibidos por este puerto serie virtual". En este experimento sencillo, abrimos el puerto LIN1 con una velocidad de baudios de 4800 y configuramos el ID de la placa como 35. Luego enviamos señales de encendido y apagado para la luz, así como valores de temperatura y tensión a la placa. Después de varios envíos, podemos observar si la luz funciona correctamente en la placa y si los datos mostrados en la imagen de la izquierda son iguales a los datos que enviamos. Después de haber validado con éxito esta etapa, nuestro código debería ser correcto y capaz de controlar el funcionamiento normal de una placa. Por lo tanto, el siguiente paso es intentar si nuestro código y dispositivos pueden funcionar correctamente en múltiples puertos. Este objetivo del paso es para verificar si podemos completar las funciones básicas para que podamos detectar y resolver problemas de los códigos. Figura 51. la interfaz de usuario en LabVIEW y una aplicación del puerto serie virtual Prueba segunda En la Figura 52, esta es la última versión de la interfaz de control de LabVIEW. Hemos diseñado diferentes funciones en comparación con la versión anterior, lo que la hace más concisa. En el lado izquierdo de la Figura 52 se encuentra la pantalla de control, que incluye el puerto COM y los comandos que queremos enviar. Las figuras debajo representan las luces, la temperatura y la tensión en la placa. En la parte inferior se encuentran los botones de enviar y parar. En el lado derecho de la Figura 52 se muestra la validez de los comandos enviados. Si está en rojo, significa que ha encontrado un problema. La tabla debajo muestra el historial de envío y recepción de datos.
41 Después de confirmar que todos los dispositivos están funcionando correctamente tras la conexión, comenzamos a validar nuestro proyecto completo. Abrimos el puerto LIN1 y enviamos un comando para encender el LED1 a la placa con ID 35. Luego, abrimos el puerto LIN2 y enviamos un comando para encender los LED1 y LED2 a la placa con ID 35, y enviamos un comando para encender los tres LED a la placa con ID 36. En la Figura 53, podemos observar que después estos pasos, todos los LEDs funcionan correctamente según los comandos que enviamos anteriormente. Figura 52. La interfaz final de LabVIEW Figura 53. Montaje final y estados de los LEDs tras la prueba
42 6. Conclusiones 6.1 Logros del proyecto En este proyecto, utilizamos la placa Raspberry Pi Pico junto con el SJA1124 y Microchip para implementar la comunicación LIN, y logramos visualizar el envío y recepción de los resultados experimentales en la interfaz de LabVIEW. Finalmente, desarrollamos con éxito una interfaz de LabVIEW para la visualización de los resultados experimentales. A través de esta interfaz, pudimos observar de manera intuitiva los datos enviados y recibidos durante el experimento, lo que facilitó la evaluación del éxito del experimento. Además, logramos escribir código para la Raspberry Pi Pico que permitió recibir y procesar los datos correctamente, logrando así la comunicación LIN. En la placa SJA1124, de hecho, hay cuatro puertos LIN diferentes. Logro personal: En este proyecto, aproximadamente estudié tres meses para aprender conocimientos relacionados. Dado que mis conocimientos previos sobre Python y LabVIEW eran muy básicos, y la última vez que había estudiado estos temas fue hace un año, tuve que volver a aprender los contenidos relevantes. Mi tutor diseñó algunos ejercicios simples según mi tesis para ayudarme a comprender mejor el funcionamiento de LabVIEW y Raspberry Pi Pico. Durante este proceso, también me enfrenté a algunos problemas de programación de software, pero finalmente los resolví buscando en internet y consultando otros ejemplos. Asimismo, en el proyecto también encontré algunos problemas de hardware, como que la placa no funcionaba correctamente, pero estos problemas se resolvieron con la ayuda de mi tutor. Este proceso fue muy bueno para mí. Quiero expresar mi sincero agradecimiento a mi tutor David Sarriá Gandul, quien diseñó un plan perfecto para que yo pudiera aprender gradualmente los conocimientos relevantes y entender cómo debería avanzar nuestro proyecto. A pesar de mi limitado nivel de idioma, él me presentó el proyecto pacientemente cada semana y siempre respondió a mis preguntas por correo electrónico de manera oportuna. Aquí también quiero agradecer especialmente al codirector: Albert Garcia Benadi. Agradezco sus consejos útiles en la escritura de código y su ayuda con los requisitos específicos de formato y problemas de lenguaje mientras escribía este informe. 6.2 Limitaciones y desafíos Al inicio del proyecto, debido al tiempo y a algunos otros factores, recortamos parte del plan general para poder terminar este proyecto más rápidamente. Inicialmente intentamos implementar dos modos: recepción y respuesta, pero al final, elegimos implementar solo el modo recepción. En la parte de Thonny, debido a mi limitado nivel de codificación, es posible que haya problemas en la escritura del código Python, y todavía puede optimizar el código. El propósito del experimento era simplemente implementar el control de comunicación de microchip, pero creo que podríamos intentar conectar más dispositivos al sistema para probar su funcionamiento.
43 6.3 Trabajo futuro Debido a limitaciones de tiempo y otros factores, se recortó el plan original, y aunque las aplicaciones (LabVIEW y Raspberry Pi Pico) admiten enviar o consultar datos, en los esclavos no se implementado la consulta de datos, por lo que éstos solo atienden a comandos y no devuelven información. En un trabajo futuro podría añadirse esta funcionalidad a los esclavos y disponer de un sistema o modelo completo que pueda servir como referencia para otros trabajos o futuras investigaciones.
44 Referencias bibliográficas [1]. Micropython.org. (2017). MicroPython-Python for microcontrollers. https://micropy thon.org/ [2]. MyMicrochip technology. (2014). dsPIC33EV 5V CAN-LIN Starter Kit User’s Guid e. https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocu ments/UserGuides/50002311A.pdf [3]. Raspberry Pi Ltd (2023). Raspberry Pi Pico Datasheet RP2040-based microcontrolle r board. https://datasheets.raspberrypi.com/pico/pico-datasheet.pdf [4]. Semiconductors, N. (2022). SJA1124 Product Leaflet. www.nxp.com [5]. Semiconductors, N. N. (2022). SJA1124 - Quad LIN commander transceiver with LIN commander controller - data sheet. https://www.nxp.com/docs/en/data-sheet/ SJA1124.pdf
45 Anexos Anexo A – Código fuente Raspberry Pi Pico import machine import utime csn = machine.Pin(5, machine.Pin.OUT, value=1) cle = machine.Pin(9, machine.Pin.OUT, value=1) spi = machine.SPI(0, baudrate=100_000, polarity=0, phase=1, bits=8, firstbit=machine.SPI.MSB, sck=machine.Pin(2), mosi=machine.Pin(3), miso=machine.Pin(4)) #pin para la configuracion spi def read_register(register_address): datos_tx = bytes([register_address, 0x80, 0x00]) #0x80 es el modo de leer datos_rx = bytearray(3) csn.value(0) spi.write_readinto(datos_tx, datos_rx) csn.value(1) return datos_rx[2] # print("Data received open:", datos_rx) def write_register(register_address, data): datos_tx = bytes([register_address, 0x00, data]) #modo de envbir:0x00 datos_rx = bytearray(3) # print("register:",hex(register_address), "Data:", hex(data)) csn.value(0) spi.write_readinto(datos_tx, datos_rx) csn.value(1) # print("Data received write:", datos_rx) # las dos “print”, para aporbar si esta funcionado en thoony lin_config = { "LIN1": {"LCFG1": 0x30, "LCFG2": 0x31, "LITC": 0x32, "LGC": 0x33, "LRTC": 0x34, "LFR": 0x35, "LBRM": 0x36, "LBRL": 0x37, "LIE": 0x38, "LC": 0x39, "LBI": 0x3A, "LBC": 0x3B, "LCF": {"send": 0x3C,"get": 0x52}, "LBD1":{"send": 0x3D,"get": 0x53},"LBD2":{"send": 0x3E,"get": 0x54},"LBD3":{"send": 0x3F,"get": 0x55},"LBD4":{"send": 0x40,"get": 0x56},"LBD5":{"send": 0x41,"get": 0x57},"LBD6":{"send": 0x42,"get": 0x58},"LBD7":{"send": 0x43,"get": 0x59},"LBD8":{"send": 0x44,"get": 0x5a}, "LSTATE": 0x4F, "LES": 0x50, "LS": 0x51},
46 "LIN2": {"LCFG1": 0x60, "LCFG2": 0x61, "LITC": 0x22, "LGC": 0x63, "LRTC": 0x64, "LFR": 0x65, "LBRM": 0x66, "LBRL": 0x67, "LIE": 0x68, "LC": 0x69, "LBI": 0x6A, "LBC": 0x6B, "LCF": {"send": 0x6C,"get": 0x82}, "LBD1":{"send": 0x6D,"get": 0x83},"LBD2":{"send": 0x6E,"get": 0x84},"LBD3":{"send": 0x6F,"get": 0x85},"LBD4":{"send": 0x70,"get": 0x86},"LBD5":{"send": 0x71,"get": 0x87},"LBD6":{"send": 0x72,"get": 0x88},"LBD7":{"send": 0x73,"get": 0x89},"LBD8":{"send": 0x74,"get": 0x5a}, "LSTATE": 0x7F, "LES": 0x80, "LS": 0x81}, "LIN3": {"LCFG1": 0x90, "LCFG2": 0x91, "LITC": 0x92, "LGC": 0x93, "LRTC": 0x94, "LFR": 0x95, "LBRM": 0x96, "LBRL": 0x97, "LIE": 0x98, "LC": 0x99, "LBI": 0x9A, "LBC": 0x9B, "LCF": {"send": 0x9C,"get": 0xB2}, "LBD1":{"send": 0x9D,"get": 0xB3},"LBD2":{"send": 0x9E,"get": 0xB4},"LBD3":{"send": 0x9F,"get": 0xB5},"LBD4":{"send": 0xA0,"get": 0xB6},"LBD5":{"send": 0xA1,"get": 0xB7},"LBD6":{"send": 0xA2,"get": 0xB8},"LBD7":{"send": 0xA3,"get": 0xB9},"LBD8":{"send": 0xA4,"get": 0xBa}, "LSTATE": 0xAF, "LES": 0xB0, "LS": 0xB1}, "LIN4": {"LCFG1": 0xC0, "LCFG2": 0xC1, "LITC": 0xC2, "LGC": 0xC3, "LRTC": 0xC4, "LFR": 0x35, "LBRM": 0xC6, "LBRL": 0xC7, "LIE": 0xC8, "LC": 0xC9, "LBI": 0xCA, "LBC": 0xCB, "LCF": {"send": 0xCC,"get": 0xE2}, "LBD1":{"send": 0xCD,"get": 0xE3},"LBD2":{"send": 0xCE,"get": 0xE4},"LBD3":{"send": 0xCF,"get": 0xE5},"LBD4":{"send": 0xD0,"get": 0xE6},"LBD5":{"send": 0xD1,"get": 0xE7},"LBD6":{"send": 0xD2,"get": 0xE8},"LBD7":{"send": 0xD3,"get": 0xE9},"LBD8":{"send": 0xD4,"get": 0xEa}, "LSTATE": 0xDF, "LES": 0xE0, "LS": 0xE1}, "GLOBAL":{"MODE":0x00, "PLLCFG":0x01, "INTE1EN":0x02, "INTE2EN":0x03, "INTE3EN":0x04, "INT1": 0x10, "INT2": 0x11, "INT3": 0x12, "STATUS": 0x13, "LCOM1": 0x20, "LCOM2": 0x21 , "MCFG": 0xF0, "MMTPS": 0xF1, "MCFGCRC": 0xF2, "MTPCS": 0xFE, "ID": 0xFF} } #es una diccionario que contiene todas las direcciones de registrio (sja1124) csn.value(0) csn.value(1) write_register(lin_config["GLOBAL"]["PLLCFG"], 0x07) #incializar la frecuancia clk(PLL) write_register(lin_config["GLOBAL"]["INT1"], 0x80) #Asi,no se vuelva a dormir despues de haberlo despertado while True: trama_input = input() partes = trama_input.split(',') cantidad = len(partes)-3 estado = partes[0].strip().upper() #cautro casos de estaso: open, tx, rx, close, otro:NACK if estado == "OPEN": try: LIN = partes[1].strip().upper() baud = partes[2].strip().upper() baud_rate = int(baud) IBR = int((34000000) / (16 * baud_rate)) #calcular el valor IBR, Fclk(pll)out=M*Fclk(pll)in. el valor(34000000) se puede calular según datasheet hex_value = hex(IBR)[2:] while len(hex_value) < 4: hex_value = '0' + hex_value IBRLOW=int(hex_value[2:], 16) #convierta el valor de IBR a binario,el último octeto es ibrlow y el valor anterior es ibrhigh IBRHIGH=int(hex_value[:2], 16) FBR= round((34000000 / baud_rate) - 16 * IBR) #el valor calculado puede no ser un numero entero, uso el comando "roundo"
47 if LIN in lin_config: config = lin_config[LIN] #la inicinalización se realiza en función de los datos calculado antes for step in [("LCFG1", 0x01), ("LFR", FBR), ("LBRM", IBRHIGH), ("LBRL", IBRLOW), ("LCFG1", 0x08)]: register_address, data = config[step[0]], step[1] write_register(register_address, data) print("ACK,"+trama_input) else: print("NACK,"+trama_input) except: #despúes de recibir el "string" de baudario. no es un numero y no puede realizar la funcion "int". NACK print("NACK," + trama_input) elif estado == "TX" : try: LIN = partes[1].strip().upper() ID = int(partes[2].strip().upper()) DFLDIR= cantidad - 1 DIRCCS= 2 #dir es 1(master a esclavo), ccs es 0 DFLDIR_DIRCCS = DFLDIR*4+DIRCCS if LIN in lin_config: config = lin_config[LIN] write_register(config["LBI"], ID) write_register(config["LBC"], DFLDIR_DIRCCS) for i in range(cantidad): #determinar que registros utilizar en función de los datos escritos if f"LBD{i+1}" in config: write_register(config[f"LBD{i+1}"]["send"], int(partes[3+i])) #en los dos casos(sent y get) los registros tienen el nombre mismo y la direccion diferente write_register(config["LC"], 0x01) print("ACK,"+trama_input) else: print("NACK,"+trama_input) except: print("NACK," + trama_input) elif estado == "RX" : try: LIN = partes[1].strip().upper() ID = int(partes[2].strip().upper()) DATOSLEER = int(partes[3].strip().upper()) DIRCCS= 0 #dir es 1(esclavo a master), ccs es 0
48 DFLDIR_DIRCCS = (DATOSLEER - 1)*4 + DIRCCS if LIN in lin_config and 1 <= DATOSLEER <= 8: #limitar el númerode de los datos,en el chip solo hay ocho registros para la funcion.si el valor es 0, tampoco no funciona config = lin_config[LIN] write_register(config["LBI"], ID) write_register(config["LBC"], DFLDIR_DIRCCS) write_register(config["LC"], 0x01) datos_leidos="" for i in range(DATOSLEER): dato_leido = read_register(config[f"LBD{i+1}"]["get"]) datos_leidos += str(dato_leido)+"," #connectar los datos y separar por coma trama_output = datos_leidos[0:-1] #eliminar la última coma print("ACK,"+trama_input+","+trama_output) else: print("NACK,"+trama_input) except: print("NACK,"+trama_input) elif estado == "CLOSE" : print("ACK,"+trama_input) else: print("NACK,"+trama_input)
55 42h 72h A2h D2h LBD6 DATA5 43h 73h A3h D3h LBD7 DATA6 44h 74h A4h D4h LBD8 DATA7 Tabla 15. los registros de obtención de estado del canal LIN Address Register Bit LIN 1 LIN 2 LIN 3 LIN 4 7 6 5 4 3 2 1 0 4Fh 7Fh AFh DFh LSTATE RXBSY - LINS 50h 80h B0h E0h LES SZF TOF BEF CEF - FEF 51h 81h B1h E1h LS - DRBNE - DRF DTF - 52h 82h B2h E2h LCF CF 53h 83h B3h E3h LBD1 DATA0 54h 84h B4h E4h LBD2 DATA1 55h 85h B5h E5h LBD3 DATA2 56h 86h B6h E6h LBD4 DATA3 57h 87h B7h E7h LBD5 DATA4 58h 88h B8h E8h LBD6 DATA5 59h 89h B9h E9h LBD7 DATA6 5Ah 8Ah BAh EAh LBD8 DATA7 Tabla 16. Registro de configuración del PLL (PLLCFG; dirección 01h). Bit Symbol Access Value Description 3:0 PLLMULT R/W PLL multiplication of input frequency 0h fclk(PLL)in = 0.4 MHz to 0.5 MHz multiplication factor: M = 78 1h fclk(PLL)in = 0.5 MHz to 0.7 MHz multiplication factor: M = 65 2h fclk(PLL)in = 0.7 MHz to 1.0 MHz multiplication factor: M = 39 3h fclk(PLL)in = 1.0 MHz to 1.4 MHz multiplication factor: M = 28 4h fclk(PLL)in = 1.4 MHz to 1.9 MHz multiplication factor: M = 20 5h fclk(PLL)in = 1.9 MHz to 2.6 MHz multiplication factor: M = 15 6h fclk(PLL)in = 2.6 MHz to 3.5 MHz multiplication factor: M = 11 7h fclk(PLL)in = 3.5 MHz to 4.5 MHz multiplication factor: M = 8.5 8h fclk(PLL)in = 4.5 MHz to 6.0 MHz multiplication factor: M = 6.4 9h fclk(PLL)in = 6.0 MHz to 8.0 MHz multiplication factor: M = 4.8 Ah* fclk(PLL)in = 8.0 MHz to 10.0 MHz multiplication factor: M = 3.9 other not used
56 Anexo D - Firmware para placa Microchip CAN-LIN El código de MPLAB (línea 681-814): void Lin_RX_to_UART(void) { // LIN message out the monitor UART // U2STAbits.UTXEN = 1; putsU2("*** REMOTE LIN MESSAGE ID = "); // // display remote ID byte // hex_dig = (char)(LIN_RXBUF[1] & 0x3f); // strip parity bits if (LIN_ID == hex_dig) { ascii_hi = hex_dig & 0xF0; // Obtain the upper 4 bits (MSBs) of hex number ascii_hi = (ascii_hi >> 4) + 0x30; // ASCII conversion ascii_lo = (hex_dig & 0x0F) + 0x30; // Obtain the lower 4 bits (LSBs) of hex number putU2(ascii_hi); putU2(ascii_lo); // send out the ID byte as ASCII putsU2(" RECEIVED ***"); while (U2STAbits.TRMT == 0); U2TXREG = 0x0a; while (U2STAbits.TRMT == 0); U2TXREG = 0x0d; putsU2("Remote Pot Voltage: "); PotValue = ((LIN_RXBUF[6]) | (LIN_RXBUF[5] << 8)); Pot_Volts = (float)(PotValue * (float)5.0 / (float)4096.0); // // convert to ASCII // pBuf = Buf_result; ftoa(Pot_Volts, pBuf); for (i = 0; i <= (NUM_DIGITS - 1); i++) { while (U2STAbits.TRMT == 0); U2TXREG = Buf_result[i]; } while (U2STAbits.TRMT == 0); U2TXREG = 0x0a; while (U2STAbits.TRMT == 0); U2TXREG = 0x0d;
57 putsU2("Remote Temperature: "); // // print the temperature reading out the UART // datal = ((LIN_RXBUF[4]) | (LIN_RXBUF[3] << 8)); Pot_Volts = (float)((datal - 368) / 15.974); // // convert to ASCII // pBuf = Buf_result; ftoa(Pot_Volts, pBuf); for (i = 0; i <= (NUM_DIGITS - 1); i++) { while (U2STAbits.TRMT == 0); U2TXREG = Buf_result[i]; } while (U2STAbits.TRMT == 0); U2TXREG = 0x0a; while (U2STAbits.TRMT == 0); U2TXREG = 0x0d; putsU2("Remote Switch Status"); while (U2STAbits.TRMT == 0); U2TXREG = 0x0a; while (U2STAbits.TRMT == 0); U2TXREG = 0x0d; // ON = pressed OFF = up if ((LIN_RXBUF[2] & 0x1) == 0) { putsU2("SW3: OFF "); LED3 = 0; } else { putsU2("SW3: ON"); LED3 = 1; } while (U2STAbits.TRMT == 0); U2TXREG = 0x0a; while (U2STAbits.TRMT == 0); U2TXREG = 0x0d;
58 // ON = pressed OFF = up if ((LIN_RXBUF[2] & 0x2) == 0) { putsU2("SW2: OFF "); LED2 = 0; } else { putsU2("SW2: ON"); LED2 = 1; } while (U2STAbits.TRMT == 0); U2TXREG = 0x0a; while (U2STAbits.TRMT == 0); U2TXREG = 0x0d; // ON = pressed OFF = up if ((LIN_RXBUF[2] & 0x4) == 0) { putsU2("SW1: OFF "); LED1 = 0; } else { putsU2("SW1: ON"); LED1 = 1; } while (U2STAbits.TRMT == 0); U2TXREG = 0x0a; while (U2STAbits.TRMT == 0); U2TXREG = 0x0d; // // toggle LED 2 to show LIN message reveived // //LED2 = 1; // // wait 100ms, turn off LED3 // //delay_10ms(10); //LED2 = 0; }
59 else{ //no operation } } El código de MPLAB (línea 975-989): void Test_Mode(void) { if ((SW1 == 0) || (SW2 == 0) || (SW3 == 0)) { delay_10ms(30); // wait 300ms if ((SW1 == 0) || (SW2 == 0) || (SW3 == 0)) { mode = TRANSMIT; return; } } mode = RECEIVE; }