- Sigue la línea lo más rápido posible sin salirse.
- Comunicación IoT a través de MQTT
- Comunicación serie entre ESP32 y Arduino UNO
- Si el robot pierde la línea se permite realizar una búsqueda de la línea de nuevo.
## 3. Montaje
- Detección de obstáculos
Consulta el manual que viene con el kit y el siguiente [vídeo](https://www.youtube.com/watch?v=GQi99xmohdw&ab_channel=ElegooOfficial) para realizar el montaje correctamente. Es el primer paso de la práctica.
El robot incorpora un Ardunio UNO que actúa de cerebro del sistema controlando todos los sensores y actuadores.
## 3. Montaje
### 4.1 Ultrasonido
Consulta el manual que viene con el kit y el siguiente [vídeo](https://www.youtube.com/watch?v=GQi99xmohdw&ab_channel=ElegooOfficial) para realizar el montaje correctamente. Es el primer paso de la práctica.
```c
#define TRIG_PIN 13
#define ECHO_PIN 12
## 4. Arduino
```
El robot incorpora un Ardunio UNO que actúa de cerebro del sistema controlando todos los sensores y actuadores.
### 4.2 Sensor Infra-rojo
### 4.1 Ultrasonido
Los sensores infra-rojos, son sensores analógicos. Usa toda su potencia y rango continuo de valores. **¡No los utilices como sensores digitales! **
```
```c
#define PIN_ITR20001-LEFT A2
#define TRIG_PIN 13
#define PIN_ITR20001-MIDDLE A1
#define ECHO_PIN 12
#define PIN_ITR20001-RIGHT A0
```
```
### 4.2 Sensor Infra-rojo
### 4.3 Motores
Los sensores infra-rojos, son sensores analógicos. Usa toda su potencia y rango continuo de valores. **¡No los utilices como sensores digitales! **
El Smart Robot Car incorpora 4 motores DC que se controlan a través de una pequeña placa controladora incorporada en la placa de extensión. Las velocidades las comandaremos por grupos de motores (los del lado derecho, y los del lado izquierdo). A continuación se muestran los pines de control, velocidad y dirección.
```
#define PIN_ITR20001-LEFT A2
```c
#define PIN_ITR20001-MIDDLE A1
// Enable/Disable motor control.
#define PIN_ITR20001-RIGHT A0
// HIGH: motor control enabled
```
// LOW: motor control disabled
#define PIN_Motor_STBY 3
### 4.3 Motores
// Group A Motors (Right Side)
El Smart Robot Car incorpora 4 motores DC que se controlan a través de una pequeña placa controladora incorporada en la placa de extensión. Las velocidades las comandaremos por grupos de motores (los del lado derecho, y los del lado izquierdo). A continuación se muestran los pines de control, velocidad y dirección.
// PIN_Motor_AIN_1: Digital output. HIGH: Forward, LOW: Backward
#define PIN_Motor_AIN_1 7
```c
// PIN_Motor_PWMA: Analog output [0-255]. It provides speed.
// Enable/Disable motor control.
#define PIN_Motor_PWMA 5
// HIGH: motor control enabled
// LOW: motor control disabled
// Group B Motors (Left Side)
#define PIN_Motor_STBY 3
// PIN_Motor_BIN_1: Digital output. HIGH: Forward, LOW: Backward
#define PIN_Motor_BIN_1 8
// Group A Motors (Right Side)
// PIN_Motor_PWMB: Analog output [0-255]. It provides speed.
// PIN_Motor_AIN_1: Digital output. HIGH: Forward, LOW: Backward
#define PIN_Motor_PWMB 6
#define PIN_Motor_AIN_1 7
```
// PIN_Motor_PWMA: Analog output [0-255]. It provides speed.
#define PIN_Motor_PWMA 5
### 4.4 LED
// Group B Motors (Left Side)
La placa de expansión contiene un LED RGB que podemos utilizar para plasmar colores según los estados de tu comportamiento (muy útil para depuración en el circuito).
// PIN_Motor_BIN_1: Digital output. HIGH: Forward, LOW: Backward
#define PIN_Motor_BIN_1 8
IMPORTANTE: Es obligatorio que siempre que tu robot detecte la línea (con cualquiera de los 3 sensores), debe mostrar el color verde en el LED. Si no detecta la línea, debe mostrar el LED en rojo.
// PIN_Motor_PWMB: Analog output [0-255]. It provides speed.
#define PIN_Motor_PWMB 6
Es necesario instalar la siguiente librería (FastLED):
Puedes consultar el siguiente código de ejemplo para entender el funcionamiento [DemoLed](https://gitlab.etsit.urjc.es/roberto.calvo/setr/-/tree/main/practicas/P4-FollowLineIoT/DemoLED)
La placa de expansión contiene un LED RGB que podemos utilizar para plasmar colores según los estados de tu comportamiento (muy útil para depuración en el circuito).
## 5. ESP32
IMPORTANTE: Es obligatorio que siempre que tu robot detecte la línea (con cualquiera de los 3 sensores), debe mostrar el color verde en el LED. Si no detecta la línea, debe mostrar el LED en rojo.
### 5.1 Arduino-IDE y librerías
Es necesario instalar la siguiente librería (FastLED):
El robot incluye un modelo ESP32 CAM, que nos permite comunicarnos a través de cualquier red WiFi. Utilizaremos Arduino-IDE para programarlo, pero es necesario realizar las siguientes acciones:
- Primero, añade el repositorio para ESP32 dentro de tu Arduino IDE
Puedes consultar el siguiente código de ejemplo para entender el funcionamiento [DemoLed](https://gitlab.etsit.urjc.es/roberto.calvo/setr/-/tree/main/practicas/P4-FollowLineIoT/DemoLED)
- Introduce la siguiente URL en "Additional Board Manager URLs"
### 5.1 Arduino-IDE y librerías
```
El robot incluye un modelo ESP32 CAM, que nos permite comunicarnos a través de cualquier red WiFi. Utilizaremos Arduino-IDE para programarlo, pero es necesario realizar las siguientes acciones:
- Primero, añade el repositorio para ESP32 dentro de tu Arduino IDE
- Asegurate que tienes instalado el paquete ESP32 dentro de "Boards Manager" en tu arduino IDE 
- Asegurate de configurar correctamente el modelo de placa "AI Thinker ESP32-CAM" 
- Introduce la siguiente URL en "Additional Board Manager URLs"
Por último asegurate que en los laboratorios, te aparecen 2 puertos detectados (ttyS4 y ttyUSB0). Utiliza éste último para realizar la programación del ESP32.
- Puedes comprobar la conexión WiFi (ESP) y la IP asignada. Para ello utilizaremos la red wifi eduroam. Puedes utilizar de base el código de ejemplo de **[eduroam](https://gitlab.etsit.urjc.es/roberto.calvo/setr/-/tree/main/practicas/P4-FollowLineIoT/ESP32/eduroam)** del repositorio.
- Asegurate que tienes instalado el paquete ESP32 dentro de "Boards Manager" en tu arduino IDE 
Si ves que la wifi no te da IP, puedes realizar pruebas con la wifi que levantes en tu smartphone (Hotspot) o con cualquier otra wifi (incluso la de tu casa, si haces pruebas allí).
- Asegurate de configurar correctamente el modelo de placa "AI Thinker ESP32-CAM" 
Por último asegurate que en los laboratorios, te aparecen 2 puertos detectados (ttyS4 y ttyUSB0). Utiliza éste último para realizar la programación del ESP32.
## 6. Comunicación Serie
### 5.2 Comprobar la conexión WiFi
Revisa el código de ejemplo que encontrarás en [SerialCommunication](https://gitlab.etsit.urjc.es/roberto.calvo/setr/-/tree/main/practicas/P4-FollowLineIoT/SerialComArduinoESP32) para entender como es posible comunicar los puertos serie del ESP y de Arduino. Este ejemplo muestra comunicación en ambos sentidos y hace uso de LedFast.
- Puedes comprobar la conexión WiFi (ESP) y la IP asignada. Para ello utilizaremos la red wifi eduroam. Puedes utilizar de base el código de ejemplo de **[eduroam](https://gitlab.etsit.urjc.es/roberto.calvo/setr/-/tree/main/practicas/P4-FollowLineIoT/ESP32/eduroam)** del repositorio.
La comunicación serie puede ser bidireccional, es decir, podemos mandar mensajes del ESP al arduino y viceversa. El comportamiento sigue línea NUNCA puede comenzar hasta que el ESP confirme que tiene WiFi y está conectado el servidor MQTT.
Si ves que la wifi no te da IP, puedes realizar pruebas con la wifi que levantes en tu smartphone (Hotspot) o con cualquier otra wifi (incluso la de tu casa, si haces pruebas allí).
**IMPORTANTE:** Para que la comunicación serie entre el ESP y Arduino funcione correctamente, el switch S1 de la placa de expansión debe estar en la posición "CAM". Recuerda que ese switch debe estar en la posición "UPLOAD" para cargar el programa en la placa Arduino.
Revisa el código de ejemplo que encontrarás en [SerialCommunication](https://gitlab.etsit.urjc.es/roberto.calvo/setr/-/tree/main/practicas/P4-FollowLineIoT/SerialComArduinoESP32) para entender como es posible comunicar los puertos serie del ESP y de Arduino. Este ejemplo muestra comunicación en ambos sentidos y hace uso de LedFast.
### 7.1 MQTT
La comunicación serie puede ser bidireccional, es decir, podemos mandar mensajes del ESP al arduino y viceversa. El comportamiento sigue línea NUNCA puede comenzar hasta que el ESP confirme que tiene WiFi y está conectado el servidor MQTT.
Desde el ESP32 tendrás que conectarte y mantener la conexión abierta para mandar mensajes al servidor según vayas completando el circuito. Para ello necesitarás instalar la librería **[Adafruit-MQTT](https://github.com/adafruit/Adafruit_MQTT_Library)**
**IMPORTANTE:** Para que la comunicación serie entre el ESP y Arduino funcione correctamente, el switch S1 de la placa de expansión debe estar en la posición "CAM". Recuerda que ese switch debe estar en la posición "UPLOAD" para cargar el programa en la placa Arduino.
Nota: Este servidor es público, lo que quiere decir que puedes conectarte a él desde casa o desde cualquier conexión a internet.
Desde el ESP32 tendrás que conectarte y mantener la conexión abierta para mandar mensajes al servidor según vayas completando el circuito. Para ello necesitarás instalar la librería **[Adafruit-MQTT](https://github.com/adafruit/Adafruit_MQTT_Library)**
Tu robot debe mandar los siguientes mensajes siempre conectando al servidor MQTT y utilizando obligatoriamente el siguiente TOPIC
```
Server: 193.147.53.2 (garceta.tsc.urjc.es)
```bash
Port: 21883
/SETR/2023/$ID_EQUIPO/
```
```
Nota: Este servidor es público, lo que quiere decir que puedes conectarte a él desde casa o desde cualquier conexión a internet.
Para comprobar los mensajes que envía tu robot a través de MQTT puedes utilizar el siguiente comando que debes ejecutar en los ordenadores del laboratorio. Básicamente es un subscriptor a un topic determinado que mostrará todo lo que llega a ese topic.
### 7.2 Mensajes
```
Tu robot debe mandar los siguientes mensajes siempre conectando al servidor MQTT y utilizando obligatoriamente el siguiente TOPIC
Para comprobar los mensajes que envía tu robot a través de MQTT puedes utilizar el siguiente comando que debes ejecutar en los ordenadores del laboratorio. Básicamente es un subscriptor a un topic determinado que mostrará todo lo que llega a ese topic.
* Descripción: Este mensaje debe enviarse siempre justo antes de empezar la vuelta al circuito. Por tanto debe realizarse sólo 1 vez. **IMPORTANTE: La vuelta nunca podrá comenzar si no hay conexión a la red WiFi ni a MQTT.**
Para realizar pruebas puedes probar a publicar de la siguiente manera:
* Descripción: Este mensaje debe enviarse siempre justo antes de empezar la vuelta al circuito. Por tanto debe realizarse sólo 1 vez. **IMPORTANTE: La vuelta nunca podrá comenzar si no hay conexión a la red WiFi ni a MQTT.**
}
```
* Payload JSON:
#### Mensaje de Fin de vuelta
```json
{
* Descripción: Este mensaje debe enviarse siempre al finalizar una vuelta, que lo sabrás porque tendrás un obstáculo delante. Por tanto debe realizarse sólo 1 vez. Presta atención al campo "time", debe contener el tiempo (en milisegundos) transcurrido desde que enviaste tu START_LAP hasta que envías tu END_LAP. La vuelta ha finalizado justo después de detectar un obstáculo.
"team_name":"$TU_NOMBRE_DE_EQUIPO ",
"id":"$ID_EQUIPO",
* Payload JSON:
"action":"START_LAP"
}
```json
```
{
"team_name":"$TU_NOMBRE_DE_EQUIPO ",
#### Mensaje de Fin de vuelta
"id":"$ID_EQUIPO",
"action":"END_LAP",
* Descripción: Este mensaje debe enviarse siempre al finalizar una vuelta, que lo sabrás porque tendrás un obstáculo delante. Por tanto debe realizarse sólo 1 vez. Presta atención al campo "time", debe contener el tiempo (en milisegundos) transcurrido desde que enviaste tu START_LAP hasta que envías tu END_LAP. La vuelta ha finalizado justo después de detectar un obstáculo.
"time":000000
}
* Payload JSON:
```
```json
#### Mensaje Obstáculo Detectado
{
"team_name":"$TU_NOMBRE_DE_EQUIPO ",
* Descripción: Este mensaje debe enviarse siempre que detectes un obstáculo en el camino de la línea. El coche se debe detener entre 5 y 8 cm antes del obstáculo. En el campo distancia debes enviar la distancia detectada en centímetros.
"id":"$ID_EQUIPO",
"action":"END_LAP",
* Payload JSON:
"time":000000
}
```json
```
{
"team_name":"$TU_NOMBRE_DE_EQUIPO ",
#### Mensaje Obstáculo Detectado
"id":"$ID_EQUIPO",
"action":"OBSTACLE_DETECTED",
* Descripción: Este mensaje debe enviarse siempre que detectes un obstáculo en el camino de la línea. El coche se debe detener entre 5 y 8 cm antes del obstáculo. En el campo distancia debes enviar la distancia detectada en centímetros.
"distance":000
}
* Payload JSON:
```
```json
#### Mensaje Línea Perdida
{
"team_name":"$TU_NOMBRE_DE_EQUIPO ",
* Descripción: Este mensaje debe enviarse siempre que tu robot se haya salido de la línea.
"id":"$ID_EQUIPO",
* Payload JSON:
"action":"OBSTACLE_DETECTED",
"distance":000
```json
}
{
```
"team_name":"$TU_NOMBRE_DE_EQUIPO ",
"id":"$ID_EQUIPO",
#### Mensaje Línea Perdida
"action":"LINE_LOST"
}
* Descripción: Este mensaje debe enviarse siempre que tu robot se haya salido de la línea.
```
* Payload JSON:
```json
{
#### Mensajes PING
"team_name":"$TU_NOMBRE_DE_EQUIPO ",
"id":"$ID_EQUIPO",
* Descripción: Mensaje de estado mandado cada **4 segundos** (empezando en 0). El campo time debe reflejar el tiempo (en milisegundos) desde que comenzó la vuelta (START_LAP). Debe priorizar el comportamiento sigue linea al envío de mensajes PING.
"action":"LINE_LOST"
* Payload JSON:
}
```
```json
{
"team_name":"$TU_NOMBRE_DE_EQUIPO ",
"id":"$ID_EQUIPO",
#### Mensajes PING
"action":"PING",
"time":000000
* Descripción: Mensaje de estado mandado cada **4 segundos** (empezando en 0). El campo time debe reflejar el tiempo (en milisegundos) desde que comenzó la vuelta (START_LAP). Debe priorizar el comportamiento sigue linea al envío de mensajes PING.
}
* Payload JSON:
```
```json
{
"team_name":"$TU_NOMBRE_DE_EQUIPO ",
#### Mensaje Inicio Búsqueda de Linea (OPCIONAL)
"id":"$ID_EQUIPO",
"action":"PING",
* Descripción: Opcionalmente tienes la posibilidad de implementar un comportamiento "encuentra línea" una vez que te hayas salido del camino (esto te permitirá reducir la penalización).
"time":000000
* Payload JSON:
}
```
```json
{
"team_name":"$TU_NOMBRE_DE_EQUIPO ",
"id":"$ID_EQUIPO",
#### Mensaje Inicio Búsqueda de Linea (OPCIONAL)
"action":"INIT_LINE_SEARCH"
}
* Descripción: Opcionalmente tienes la posibilidad de implementar un comportamiento "encuentra línea" una vez que te hayas salido del camino (esto te permitirá reducir la penalización).
```
* Payload JSON:
#### Mensaje Fin Búsqueda de Linea (OPCIONAL)
```json
{
* Descripción: Si has implementado la búsqueda de línea una vez que la has perdido, deberás mandar este mensaje en el momento que la hayas encontrado y por tanto finalizado el comportamiento "encuentra línea"
"team_name":"$TU_NOMBRE_DE_EQUIPO ",
* Payload JSON:
"id":"$ID_EQUIPO",
"action":"INIT_LINE_SEARCH"
```json
}
{
```
"team_name":"$TU_NOMBRE_DE_EQUIPO ",
"id":"$ID_EQUIPO",
#### Mensaje Fin Búsqueda de Linea (OPCIONAL)
"action":"STOP_LINE_SEARCH"
}
* Descripción: Si has implementado la búsqueda de línea una vez que la has perdido, deberás mandar este mensaje en el momento que la hayas encontrado y por tanto finalizado el comportamiento "encuentra línea"
```
* Payload JSON:
```json
#### Mensaje Línea Encontrada (OPCIONAL)
{
"team_name":"$TU_NOMBRE_DE_EQUIPO ",
* Descripción: Este mensaje debe enviarse siempre que tu robot haya encontrado la línea. Además este mensaje sólo se debe enviar si anteriormente se ha enviado el mensaje **LINE_LOST**
"id":"$ID_EQUIPO",
* Payload JSON:
"action":"STOP_LINE_SEARCH"
}
```json
```
{
"team_name":"$TU_NOMBRE_DE_EQUIPO ",
"id":"$ID_EQUIPO",
#### Mensaje Línea Encontrada (OPCIONAL)
"action":"LINE_FOUND"
}
* Descripción: Este mensaje debe enviarse siempre que tu robot haya encontrado la línea. Además este mensaje sólo se debe enviar si anteriormente se ha enviado el mensaje **LINE_LOST**
```
* Payload JSON:
#### Mensaje Estadísticas Línea Visible (OPCIONAL)
```json
{
* Descripción: Este mensaje debe enviarse al finalizar la vuelta, es decir, cuando encuentres el obstáculo. Debes enviar el % de veces que has detectado la línea utilizando los infra-rojos. Es decir, si durante la vuelta has leído 1000 veces el infrarojo, y 900 has detectado la línea con alguno de los sensores, y 100 veces no la has detectado, deberás mandar un 90.0 %
"team_name":"$TU_NOMBRE_DE_EQUIPO ",
"id":"$ID_EQUIPO",
* Payload JSON:
"action":"LINE_FOUND"
}
```json
```
{
"team_name":"$TU_NOMBRE_DE_EQUIPO ",
#### Mensaje Estadísticas Línea Visible (OPCIONAL)
"id":"$ID_EQUIPO",
"action":"VISIBLE_LINE",
* Descripción: Este mensaje debe enviarse al finalizar la vuelta, es decir, cuando encuentres el obstáculo. Debes enviar el % de veces que has detectado la línea utilizando los infra-rojos. Es decir, si durante la vuelta has leído 1000 veces el infrarojo, y 900 has detectado la línea con alguno de los sensores, y 100 veces no la has detectado, deberás mandar un 90.0 %
"value":0.00
}
* Payload JSON:
```
```json
## 8 Evaluación
{
"team_name":"$TU_NOMBRE_DE_EQUIPO ",
### 8.1 Día de Test y Día de Examen
"id":"$ID_EQUIPO",
"action":"VISIBLE_LINE",
El **Martes 19 de Diciembre** en horario de clase cada equipo dispondrá de al menos 5 minutos para probar su solución en el circuito real y con la parte de comunicaciones realizada. Podrá comprobar así que los mensajes MQTT están bien formados y son correctos.
"value":0.00
}
El **Jueves 21 de Diciembre** en horario de clase cada equipo dispondrá de máximo de **2 rondas/tests** para realizar el circuito. Entre ronda y ronda está permitido modificar el código del programa.
```
El circuito será idéntico para ambos días.
## 8 Evaluación
#### 8.1.1 Horarios y Examen
### 8.1 Día de Test y Día de Examen
Consultado el listado de horarios [aquí](SETR-2023-ExamenDic)
El **Martes 19 de Diciembre** en horario de clase cada equipo dispondrá de al menos 5 minutos para probar su solución en el circuito real y con la parte de comunicaciones realizada. Podrá comprobar así que los mensajes MQTT están bien formados y son correctos.
### 8.2 Bonificaciones y Penalizaciones
El **Jueves 21 de Diciembre** en horario de clase cada equipo dispondrá de máximo de **2 rondas/tests** para realizar el circuito. Entre ronda y ronda está permitido modificar el código del programa.
* Cuando el coche se salga del circuito, ese test se dará por finalizado y se declarará nulo.
El circuito será idéntico para ambos días.
* Para aprobar la práctica el coche debe terminar el circuito correctamente y mandar los mensajes de comunicación establecidos mediante MQTT. El no envío de mensajes MQTT supondrá tener la práctica suspensa.
* El coche debe parar en el rango [5-8] cm antes del obstáculo. Por cada cm fuera de rango se aplicará una penalización de un 1% al tiempo final.
#### 8.1.1 Horarios y Examen
* Si el coche pierde la línea tiene un máximo de 5 segundos para encontrarla. Si es capaz de recuperarla correctamente y mandar los mensajes MQTT correspondientes obtendrá una rebaja del tiempo final del 2%.
Consultado el listado de horarios [aquí](SETR-2023-ExamenDic)
### 8.3 Nota Final
### 8.2 Bonificaciones y Penalizaciones
La nota final dependerá de:
* Cuando el coche se salga del circuito, ese test se dará por finalizado y se declarará nulo.
- La posición final en la tabla de tiempos
* Para aprobar la práctica el coche debe terminar el circuito correctamente y mandar los mensajes de comunicación establecidos mediante MQTT. El no envío de mensajes MQTT supondrá tener la práctica suspensa.
- Código arduino y mecanismos utilizados.
* El coche debe parar en el rango [5-8] cm antes del obstáculo. Por cada cm fuera de rango se aplicará una penalización de un 1% al tiempo final.
- Mensajes MQTT enviados y periodicidad (PING)
* Si el coche pierde la línea tiene un máximo de 5 segundos para encontrarla. Si es capaz de recuperarla correctamente y mandar los mensajes MQTT correspondientes obtendrá una rebaja del tiempo final del 2%.
- Post en el blog explicando la solución.
**IMPORTANTE:** La práctica estará suspensa si:
### 8.3 Nota Final
* El coche no es capaz de realizar 1 vuelta completa.
* El coche tarda más de 20 segundos en completar la vuelta.
La nota final dependerá de:
- La posición final en la tabla de tiempos
## 9. Otros recursos
- Código arduino y mecanismos utilizados.
- Mensajes MQTT enviados y periodicidad (PING)
* Si tienes problemas con que tu ordenador reconozca el puerto USB para programar el arduino o el ESP, sigue esta [receta](https://askubuntu.com/questions/1389189/how-to-use-esp32-wrover-b-with-ubuntu) y deshabilita el servicio brltty (kudos para Iván Lopez). Una explicación más detallada tienes abajo (por Diego Garcia)
- Post en el blog explicando la solución.
>>>
**IMPORTANTE:** La práctica estará suspensa si:
He tenido problemas para conectar la placa del coche con el PC, y como la solución no parece trivial he querido compartirla por si acaso alguien se encuentra en una situación similar.
* El coche no es capaz de realizar 1 vuelta completa.
* El coche tarda más de 20 segundos en completar la vuelta.
Las placas de la P3 son distintas a las de la P4, diría que usan adaptadores USB-Serial diferentes (Hay dos modelos bastante comunes) y aunque en la P3 no tuve ningún problema con esto ("ttyACM"), la placa de la P4 se estaba intentando listar con "ttyUSB". El problema con esto es que al parecer en mi PC (Y en la de Liam, seguro, porque le pasaba lo mismo) había un servicio que reclamaba antes esa interfaz, se trata de brltty.
## 9. Otros recursos
Esto lo supe gracias a "lsusb", "ls /dev" y "dmesg". "lsusb" y "ls /dev" simplemente daban la información de que el convertidor serial estaba siendo detectado (Al conectar y desconectar la placa, aparecía y desaparecía en "lsusb"), pero por alguna razón, no se estaba montando correctamente (Dado que no aparecía en /dev). Por otro lado, el output de "dmesg" cuando conectaba la placa era:
* Si tienes problemas con que tu ordenador reconozca el puerto USB para programar el arduino o el ESP, sigue esta [receta](https://askubuntu.com/questions/1389189/how-to-use-esp32-wrover-b-with-ubuntu) y deshabilita el servicio brltty (kudos para Iván Lopez). Una explicación más detallada tienes abajo (por Diego Garcia)
```
[ 2093.972105] usb 3-3.3: new full-speed USB device number 22 using xhci_hcd
>>>
[ 2094.085918] usb 3-3.3: New USB device found, idVendor=1a86, idProduct=7523, bcdDevice= 2.64
He tenido problemas para conectar la placa del coche con el PC, y como la solución no parece trivial he querido compartirla por si acaso alguien se encuentra en una situación similar.
[ 2094.085925] usb 3-3.3: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[ 2094.085928] usb 3-3.3: Product: USB Serial
Las placas de la P3 son distintas a las de la P4, diría que usan adaptadores USB-Serial diferentes (Hay dos modelos bastante comunes) y aunque en la P3 no tuve ningún problema con esto ("ttyACM"), la placa de la P4 se estaba intentando listar con "ttyUSB". El problema con esto es que al parecer en mi PC (Y en la de Liam, seguro, porque le pasaba lo mismo) había un servicio que reclamaba antes esa interfaz, se trata de brltty.
[ 2094.136953] usb 3-3.3: ch341-uart converter now attached to ttyUSB0
Esto lo supe gracias a "lsusb", "ls /dev" y "dmesg". "lsusb" y "ls /dev" simplemente daban la información de que el convertidor serial estaba siendo detectado (Al conectar y desconectar la placa, aparecía y desaparecía en "lsusb"), pero por alguna razón, no se estaba montando correctamente (Dado que no aparecía en /dev). Por otro lado, el output de "dmesg" cuando conectaba la placa era:
[ 2097.650930] usb 3-3.3: usbfs: interface 0 claimed by ch341 while 'brltty' sets config #1
[ 2097.654284] ch341-uart ttyUSB0: ch341-uart converter now disconnected from ttyUSB0
[ 2093.972105] usb 3-3.3: new full-speed USB device number 22 using xhci_hcd
```
[ 2094.085918] usb 3-3.3: New USB device found, idVendor=1a86, idProduct=7523, bcdDevice= 2.64
[ 2094.085925] usb 3-3.3: New USB device strings: Mfr=0, Product=2, SerialNumber=0
Resulta que brltty es un daemon que da acceso a la consola para pantallas en braile. Al margen de parecerme interesante, afortunadamente no lo necesito usar, así que tirando por la vía rápida he decidido deshabilitarlo:
Resulta que brltty es un daemon que da acceso a la consola para pantallas en braile. Al margen de parecerme interesante, afortunadamente no lo necesito usar, así que tirando por la vía rápida he decidido deshabilitarlo:
Después de esto, reiniciar el PC, y problema solucionado. Decir que el cambio es persistente. Si algún día, por desgracia, lo necesitáis, bastaría con revertir estos cambios.
```
systemctl stop brltty-udev.service
sudo systemctl mask brltty-udev.service
systemctl stop brltty.service
systemctl disable brltty.service
```
Después de esto, reiniciar el PC, y problema solucionado. Decir que el cambio es persistente. Si algún día, por desgracia, lo necesitáis, bastaría con revertir estos cambios.