|
cursada_mc2
Base de control de temperatura para EDU-CIAA-NXP
|
Entorno reproducible para la EDU-CIAA-NXP (LPC4337, core M4) en Windows usando VS Code, CMake, OpenOCD y GDB, sin PlatformIO ni Eclipse.
La documentacion de la API generada con Doxygen esta publicada en GitHub Pages: agustinavila.github.io/cursada_mc2.
La aplicacion actual implementa una base para control de temperatura sobre la EDU-CIAA-NXP.
Un caso de uso concreto para esta base es el control de temperatura durante la fermentacion de cerveza. En ese proceso, mantener la temperatura dentro de un rango estable es importante porque afecta directamente la actividad de la levadura, la velocidad de fermentacion y el perfil final de aromas y sabores. Una temperatura demasiado alta puede generar subproductos no deseados y una temperatura demasiado baja puede frenar o volver ineficiente la fermentacion.
La base soporta ambos modos de trabajo, calentar y enfriar, pero en este caso el uso mas comun suele ser enfriar, porque la fermentacion es un proceso exotermico. Eso permite, por ejemplo, habilitar la circulacion de un chiller a traves de una serpentina cuando la temperatura supera el valor objetivo. En una implementacion concreta, la accion de control podria activar una bomba para forzar esa circulacion o una electroválvula que habilite el paso del fluido de enfriamiento.
Tambien hay un caso complementario en temporadas de invierno o en ambientes muy frios, donde la temperatura exterior puede hacer caer demasiado la temperatura del fermentador. En esa situacion, el mismo esquema de control permite trabajar en modo calentar para sostener la temperatura de fermentacion dentro del rango deseado.
A grandes rasgos, el flujo es este:
DS18B20 mide la temperatura del proceso sobre un bus 1-Wireon/off con histeresis y tiempos minimos de encendido/apagadoLED1 como actuador de pruebaEl lazo implementado hoy es un control on/off. Eso significa que la salida no trabaja de manera proporcional, sino que solo tiene dos estados posibles: encendida o apagada. El controlador compara la temperatura medida contra el setpoint y decide si debe activar o desactivar la salida segun el modo de trabajo:
calentar, la salida se activa cuando la temperatura cae por debajo del rango permitido y se desactiva al recuperar la temperatura objetivoenfriar, la salida se activa cuando la temperatura supera el rango permitido y se desactiva al volver al objetivoPara evitar que la salida conmute continuamente alrededor del setpoint, el control usa histeresis. La histeresis define una banda de tolerancia alrededor del valor objetivo y evita que pequeñas variaciones o ruido en la medicion produzcan encendidos y apagados repetidos. Sin histeresis, si la temperatura se mantuviera oscilando muy cerca del setpoint, la salida podria cambiar de estado demasiado seguido.
Ademas, el control incorpora tiempos minimos de encendido y apagado. Estos delays no bloquean el lazo principal, sino que obligan a que la salida permanezca un tiempo minimo en cada estado antes de permitir una nueva conmutacion. Esto ayuda a filtrar cambios rapidos debidos a ruido, mediciones inestables o fluctuaciones transitorias del proceso. En una aplicacion real tambien sirve para proteger actuadores que no conviene conmutar demasiado seguido, como un compresor, una electroválvula o un relé.
En el estado actual:
DS18B20app, no en la HMIon/offEsta base hoy esta enfocada en un solo lazo de control simple, pero hay varias extensiones razonables para etapas futuras del proyecto:
HI)LO)on/off, se podria agregar un control proporcional o PIPWMPWM puede ser util cuando el actuador admite modulacion en vez de simple conmutacionLa interfaz de usuario usa el LCD de 16x2 y los cuatro pulsadores del poncho.
La pantalla principal muestra el estado general del sistema:
SP e H--.-CLa navegacion actual se hace asi:
Tecla 1: entra o sale del menuTecla 2: sube o incrementaTecla 3: baja o decrementaTecla 4: entra en una opcion o confirma edicionCada tecla se captura por PIN_INT0..3, se valida con debounce por software y la HMI consume un evento discreto cuando la pulsacion queda confirmada. Como feedback de interfaz, cada pulsacion valida tambien activa un beep corto en el buzzer del poncho.
La HMI implementa una FSM simple con tres pantallas fijas: pantalla principal, menu y edicion. En el LCD:
MENU, en un submenu o en modo EDITARMenu actual:
Param controlSetpointHisteresisTmin ONTmin OFFModoLos cambios de parametros se aplican solo al confirmar con Enter. Si se sale de la edicion con Menu, el valor temporal se descarta.
Esta base se fue armando con la idea de tener un proyecto embebido que pudiera entenderse, compilarse y depurarse sin depender del IDE original. En otras palabras, la meta fue dejar un entorno de desarrollo claro y reproducible para la EDU-CIAA-NXP, usando herramientas abiertas y configuraciones visibles en el repo.
Hoy el trabajo se apoya en:
VS Code como editor e integracion de tareasCMake como generador de buildarm-none-eabi-gcc como toolchainOpenOCD para programacion y servidor GDBarm-none-eabi-gdb para debug del core M4La idea general es que el build, el arranque del micro, el linker, los drivers y la aplicacion queden visibles y trazables, sin pasos ocultos del IDE.
El objetivo principal fue independizar el desarrollo del firmware respecto de Eclipse o MCUXpresso. Para eso hubo que resolver de forma explicita:
SystemInitELF, BIN y HEXOpenOCDGDB desde VS CodeLa idea es mejorar la reproducibilidad y control del entorno de desarrollo (en MCUExpresso es mas dificil). El flujo oficial del repo no depende de archivos generados por un IDE ni de configuraciones ocultas: lo que define el build esta en CMake, lo que define el debug esta en .vscode/ y lo que define la plataforma esta en platform/.
El desarrollo del proyecto fue avanzando por etapas relativamente claras:
Entorno moderno sin EclipseCMake, VS Code, arm-none-eabi-gcc, OpenOCD y GDBStartup basico del microResetISR, SystemInit y linker script integrados al buildDesarrollo y prueba de driversDesarrollo de app separada de mainmain se dejo deliberadamente chico y la orquestacion real se movio a appDesarrollo de la HMImain ni app con detalles de presentacionLa arquitectura actual del firmware se reparte asi:
mainappcontrolon/offhmidriversstartupSystemInit y los simbolos necesarios para boot y enlazado del firmwareEn la practica, main queda minimo y app pasa a ser el coordinador central del firmware.
Los drivers propios viven en src/drivers/. No todos tienen el mismo nivel de uso en el firmware actual: algunos participan directamente del lazo principal, otros estan inicializados pero hoy no afectan el control, y otros quedaron como desarrollo previo o soporte potencial para futuras etapas.
buttons_driverPIN_INT0..3, aplica un debounce simple por software y deja un evento pendiente para que la interfaz lo consumadelay_driverStopWatch de LPCOpen y se inicializa una sola vez1-Wiretimer_driverRIT1 ms y permite ejecutar el lazo principal cada 20 ms sin usar un delay bloqueanteonewire_driverapp; entra como base del ds18b20_driverds18b20_driverds18b20_driver_t, dispara conversiones no bloqueantes y toma la ultima medicion disponibleds18b20_init(), ds18b20_start_conversion(), ds18b20_process() y ds18b20_get_latest_raw()eeprom_driverparametros para guardar y restaurar la configuracion del controllcd_driverled_driverLED1 como actuador de prueba para reflejar el estado de la salida del controlled_init(), led_turn_on() y led_turn_off()buzzer_driverapp y se apaga explicitamente al arranqueadc_driverkeyboard_driveruart_driveruart_driver_irqUSART0, USART2 y USART3El startup define una vector table completa con handlers por defecto, pero eso no significa que todo ese conjunto de interrupciones este realmente en uso. En el codigo propio solo aparecen algunas ISR especificas y, aun asi, no todas forman parte activa del comportamiento actual del producto.
RIT_Handlertimer_driverPIN_INT0..3main existen handlers chicos para las cuatro teclasbuttons_driver y limpiar el flag de hardwarePIN_INT4..7 del keyboard_driverADC0_IRQn del adc_driverUSART0/2/3_IRQn del uart_driver_irqsrc/: codigo propio del firmware, incluyendo aplicacion, HMI, control, drivers y startup.third_party/: codigo vendor reutilizado sin modificar internamente, como LPCOpen.platform/: archivos de soporte especificos de la placa y del entorno de desarrollo, como linker scripts, OpenOCD y SVD.cmake/: toolchain y helpers de CMake para bare-metal..vscode/: tasks, launch y settings para VS Code.Si en el futuro aparece otro archivo necesario para linker, flashing o debug de la placa, deberia agregarse en platform/ antes que en src/.
Algunas carpetas todavia incluyen notas cortas para orientar el recorrido del repo, por ejemplo src/, src/drivers/, src/hmi/, src/startup/ y third_party/lpcopen/.
Estas herramientas tienen que estar accesibles desde PATH:
cmakeninjaarm-none-eabi-gccarm-none-eabi-gdbarm-none-eabi-objdumpopenocdEnlaces oficiales, alineados con las versiones validadas en este repo cuando fue posible:
VS CodeCMakeNinjaArm GNU ToolchainOpenOCDC:\OpenOCD\ y agregar C:\OpenOCD\bin al PATHHerramienta opcional:
cppcheck2.20.0Versiones validadas en esta maquina para el flujo actual:
cmake: 3.27.6ninja: 1.11.1arm-none-eabi-gcc: Arm GNU Toolchain 14.2.Rel1, gcc 14.2.1 20241119arm-none-eabi-gdb: Arm GNU Toolchain 14.2.Rel1, gdb 15.2.90.20241130-gitarm-none-eabi-objdump: Arm GNU Toolchain 14.2.Rel1, objdump 2.43.1.20241119openocd: 0.12.0 (2023-01-14-23:37)Para que CMake, VS Code, OpenOCD y las tasks del proyecto funcionen sin rutas absolutas, estas herramientas deben poder ejecutarse directamente desde una terminal:
cmakeninjaarm-none-eabi-gccarm-none-eabi-gdbarm-none-eabi-objdumpopenocdOpcional:
cppcheckEn la practica, lo que suele agregarse al PATH no es el ejecutable individual sino la carpeta bin de cada herramienta.
Ejemplos tipicos:
C:\Program Files\CMake\binC:\Program Files\NinjaC:\Program Files (x86)\Arm GNU Toolchain arm-none-eabi\14.2 rel1\binC:\OpenOCD\binC:\Program Files\CppcheckInicio.Editar las variables de entorno del sistema.Variables de entorno.Variables de usuario o Variables del sistema, elegir Path.Editar.bin o carpeta de ejecutables.Despues de eso, conviene verificar:
Y si tambien queres usar analisis estatico local:
Con estas versiones se validaron:
debug y releasecursada_mc2_appmainSi el toolchain no esta en PATH, podes configurar una ruta explicita al momento de configurar. Usa la carpeta raiz del toolchain o su subcarpeta bin, segun tu instalacion:
cursada_mc2_app: aplicacion actual con los drivers existentes.Cada target genera:
*.elf*.bin*.hexLos artefactos quedan en build/debug/ o build/release/.
Uso previsto de cada formato:
*.elf: debug con simbolos, GDB y VS Code*.bin: programacion de flash con OpenOCD*.hex: artefacto alternativo para programacion o distribucionEl repo incluye un Doxyfile en la raiz para generar documentacion HTML a partir de README.md, src/ y los comentarios Doxygen del codigo.
Uso local:
La salida queda en:
build/docs/doxygen/htmlVersion publicada:
GitHub Actions:
Doxygen Docs genera la documentacion en cada PR contra mainpush a main, publica automaticamente la documentacion en GitHub PagesPaso manual necesario en GitHub:
Settings -> PagesBuild and deployment, elegir Source: GitHub ActionsUna vez habilitado, la documentacion quedara publicada desde el sitio de Pages del repo.
La idea de esta base es que los archivos de CMake se puedan seguir sin conocer demasiado la herramienta. Cada archivo tiene un rol concreto:
CMakeLists.txtlpc43xx_commonsrc/src/CMakeLists.txtcursada_mc2_appsrc/drivers/CMakeLists.txtcursada_mc2_driverscmake/lpc4337.cmake.elf, .bin, .hex y el target de flash con OpenOCDcmake/toolchain-arm-none-eabi.cmakearm-none-eabi-*arm-none-eabi-gcc.cmakecmake/toolchain-arm-none-eabi.cmakeCMakePresets.jsondebug y releaseSi agregas o eliminas codigo propio, normalmente alcanza con editar uno de estos dos archivos:
.c en src/CMakeLists.txt.c en src/drivers/CMakeLists.txtEjemplo: si agregas src/control/control_pi.c, tenes que sumarlo a la lista CURSADA_MC2_APP_SOURCES en src/CMakeLists.txt.
Ejemplo: si agregas src/drivers/eeprom_driver.c, tenes que sumarlo a la lista CURSADA_MC2_DRIVER_SOURCES en src/drivers/CMakeLists.txt.
CMakeLists.txtthird_party/lpcopen/chip_43xx/CMakeLists.txtcmake/lpc4337.cmakecmake/toolchain-arm-none-eabi.cmakeCMakePresets.jsonCada vez que agregues, quites o muevas fuentes en CMake, conviene repetir:
Si tambien cambiaste el entorno de desarrollo o la integracion local, conviene correr ademas:
Como alternativa, el proyecto expone un target opcional de CMake:
Si cppcheck no esta instalado en la maquina, ese target no falla: solo informa que el analisis se omite.
Configurar y compilar en debug:
Release:
Aplicacion actual:
Ese target:
*.bin desde el *.elf0x1A000000*.binSe usa *.bin en vez de programar el *.elf directamente porque el flujo es mas robusto con OpenOCD en LPC43xx, especialmente cuando el ELF tiene secciones con direccion de ejecucion en RAM.
OpenOCD usa siempre:
Extensiones recomendadas:
ms-vscode.cmake-toolsmarus25.cortex-debugms-vscode.cpptoolsFlujo:
Configure [debug] o usar el preset debug de CMake Tools.Build App [debug] o Build + Flash App [debug].Flash App [debug].Debug App (OpenOCD) en la pestana Run and Debug.runToEntryPoint: main, asi que debe detenerse en main.La configuracion de debug sigue usando el *.elf, mientras que el target de flash de CMake usa el *.bin.
Tambien hay un perfil complementario:
Attach App (OpenOCD)Ese perfil sirve para adjuntarse a una placa ya programada sin relanzar la carga desde VS Code. Es util cuando primero queres flashear desde terminal o task de CMake y despues abrir una sesion GDB sobre ese firmware.
La configuracion de VS Code referencia:
platform/svd/LPC43xx_43Sxx.svdEse archivo habilita la vista de perifericos y registros en cortex-debug.
Estado actual:
launch.jsonLPC4337 concretoSi mas adelante se consigue un SVD mas preciso para el LPC4337/M4F, conviene reemplazarlo sin cambiar el flujo de debug.
Validacion minima de conectividad:
Ese comando deberia detectar al menos el TAP lpc4337.m4.
Para inspeccionar dispositivos USB/driver en Windows:
Si necesitas ver mas detalle del FTDI:
Buscar la interfaz FTDI con VID 0403 y PID 6010.
LPCOpen queda reducido a vendor code de soporte:
No se usa board library. El codigo propio vive en src/ y se apoya en lpc_chip_43xx como capa de bajo nivel.
En esta etapa:
third_party/lpcopen/chip_43xx/ para dejar mas claro su rol de vendorLa base actual conserva estos archivos como parte del arranque bare-metal del M4:
src/startup/cr_startup_lpc43xx.csrc/startup/sysinit.csrc/startup/crp.cplatform/ldscripts/default/mem/mem.ldplatform/ldscripts/default/sections/sections.ldOrigen y criterio:
No se reemplazaron en esta etapa porque hoy no son el problema principal del repo y ya resuelven correctamente:
SystemInitLa base actual incluye soporte para sensores DS18B20 conectados sobre un bus 1-Wire implementado por bit-banging sobre GPIO.
Conexionado probado sobre el Poncho Educativo UNSJ:
1-Wire en P8.GPIO0P6_1 / GPIO3[0]DQ del sensor -> P8.GPIO0VDD del sensor -> 3.3VGND del sensor -> GND4.7 kOhm entre DQ y 3.3VAlimentacion soportada y documentada:
3.3Vparasite powerLa aplicacion usa un unico sensor DS18B20 al iniciar:
LED1onewire_driver: implementa el bus 1-Wire por bit-banging sobre GPIOds18b20_driver: soporta lectura de un sensor, seleccion por ROM y gestion de multiples sensores sobre un mismo busDS18B20_MAX_DEVICES0x28DS18B20 al bus P8.GPIO0.4.7 kOhm.No detectado: revisar cableado, 3.3V, GND, DQ y la resistencia pull-upopenocd previo reteniendo la interfaz FTDIopenocd -f platform/openocd/ciaa-nxp.cfg -c "init; targets; shutdown".WinUSB solo si OpenOCD deja de abrir la interfaz FTDI o no aparece el dispositivo correcto.arm-none-eabi-gdb este en PATH.openocd arranca sin errores con el mismo cfg.launch.json apunte al .elf del preset debug y que arm-none-eabi-gdb, arm-none-eabi-objdump y openocd esten en PATH.Attach App (OpenOCD) en vez de Debug App (OpenOCD).openocd abierto, cerrar la sesion de debug o terminar el proceso antes de reintentar.arm-none-eabi-gcc --version.PATH, configurar ARM_NONE_EABI_TOOLCHAIN_PATH al correr cmake --preset debug.cmake --preset debug.CMakeCache.txt viejos de otra ruta.platform/ldscripts/default/.src/startup/cr_startup_lpc43xx.c y src/startup/sysinit.c esten siendo compilados.chip.h.cursada_mc2_app.cursada_mc2_app.elf, .bin y .hex.cursada_mc2_app.Debug App (OpenOCD) en VS Code.main.