Decidimos usar como controlador central al microcontrolador ESP32, que es potente y versátil; proporciona entradas y salidas suficientes y, gracias a sus múltiples posibilidades de comunicación, permite conectar sensores y actuadores fácilmente. La alimentación del controlador se realiza a través del clásico LM7805 que se alimenta a través de la batería del vehículo y regula su salida a +5V, y de un LM1117, que proporciona +3,3V. Se añaden condensadores de filtro, fusible y diodos de protección.
La altura del vehículo se intentó medir originalmente con sensores de ultrasonidos (sónares), pero no se obtuvieron buenos resultados. Se probaron solamente opciones de bajo coste y no funcionaron cuando los cables se prolongaron y el sensor se colocó en la posición adecuada. Un pequeño chasco.
Actualmente estamos esperando la llegada de módulos láser de medida de distancia por TOF (Time Of Flight), que son más precisos y tienen puntos ciegos más lejanos que los de ultrasonidos. Hay bastantes tutoriales para hacerlos funcionar. Además soportan varios protocolos de comunicación.
Los sensores de presión han sido sencillos de colocar y utilizar. Funcionan como simples divisores de voltaje; es decir que reciben alimentación positiva (3.3V) y tierra por dos cables, y por el tercer cable devuelven un valor de voltaje proporcional a la presión ejercida sobre el sensor. Tienen un rango justo pero suficiente, llegan a medir hasta 1.2 MPa (175 PSI). Después de hacer una calibración rápida utilizando otros sensores digitales observamos una linealidad más que aceptable. Pueden verse los datos en la galería. Sus valores son leídos en el ESP32 como simples entradas analógicas.
Sobre el giróscopo/acelerómetro MCU6050 no hay mucho que contar salvo que funciona bastante bien. Se pueden encontrar tutoriales sencillos (gracias Luis Llamas) y se comunica cómodamente usando protocolo I2C. Requiere una rápida calibración y posteriormente se pueden obtener las coordenadas angulares del dispositivo (roll, pitch y yaw) con poco retardo.
La pantalla LCD Nextion es muy cómoda de programar y ofrece posibilidades muy interesantes. Se comunica con el ESP32 utilizando protocolo serie. La comunicación es bidireccional y la carga de procesamiento de imágen recae sobre la pantalla, no sobre el ESP32. La pantalla se programa utilizando su propio software Nextion Editor. En Randomnerdstutorials puedes ver en esta entrada cómo programarla paso a paso y comunicarte con tu microcontrolador favorito… ¡qué buena es esa web! ¡Gracias Rui y Sara Santos!
Es interesante también controlar la iluminación de la pantalla para que se atenúe cuando no se está actuando sobre ella. Para ello se puede usar la comunicación con el interfaz Nextion para que tras un tiempo de inacción se apague suavemente; volviendo a iluminarse completamente cuando se pulsa cualquier botón. Se puede ver en el código cómo se implementa. El código actual sigue siendo una versión Alpha, es decir, que no está completamente implementado. Aún así, la mayoría de las cosas ya funcionan juntas.
La medida del voltaje de la batería se realiza con un simple divisor de voltaje y una lectura analógica en el ESP32. Para segurar que el voltaje de entrada al microcontrolador no supera nunca los 3,3V colocamos un diodo zener que actuará de limitador de voltaje.
El control analógico SIN la pantalla táctil se realiza a través de los cuatro botones ya disponibles previamente (que sirven para el modo MANUAL) a los que se le añade un conmutador de 4 posiciones (AUTO, TRAIL, ROAD, PARKING) y un botón para su lectura en caso de querer realizar el control automático. El control se realiza de manera que solo actúa cuando el usuario pulsa uno de los botones de modo, momento en el cual se regula la altura o en ángulo de acuerdo al modo seleccionado. Una vez alcanzada la posición deseada, no se vuelve a realizar una acción de control hasta que el usuario vuelve a pulsar un botón.
Es importante recordar que el código de un microcontrolador está básicamente regido por un bucle infiinto, en el que se hacen las mismas cosas una y otra vez. Dentro de ese bucle se pueden utilizar condicionales para que las cosas solo se realicen cuando lo desees. Ese bucle infinito también se encarga de leer las posibles señales procedentes de la pantalla (entradas del usuario), por lo que es importante que responda a las pulsaciones instantáneamente y sin perderse ninguna. Para ello es necesario que en prácticamente ningún momento el código quede “atrapado” haciendo algo, o esperando sin hacer otra cosa. Por ello es necesario el uso de la función millis() continuamente, y evitar todo lo posible el uso de delay() en el código; un fallo de principiantes en el que todos caemos…