STM32F4: Configuración y uso básico del ADC

Como continuación de los tutoriales relacionados con la placa de desarrollo STM32F411E-Discovery, en este post vamos a explicar las nociones básicas para el uso del ADC.
El ADC (Analog to Digital Converter) es un elemento que se utiliza en electrónica para convertir una señal analógica en una señal digital, es decir, es la comunicación entre Hardware y Software. Al permitir esta comunicación, el ADC se convierte en un elemento fundamental a la hora de poder utilizar las señales digitalmente.

En este tutorial aprenderemos el funcionamiento básico para realizar la lectura de un dato y de una señal, sin utilizar el DMA.

 

CONFIGURACIÓN INICIAL

El primer paso es utilizar CubeMX, al igual que en el resto de tutoriales. Para entender la configuración básica nos basamos primero en lo que nos cuentan los documentos relacionados con nuestra discovery (manual de usuario y manual de referencia) y con el ADC, y segundo en lo que nosotros buscamos obtener. Esto implica conocer los siguientes conceptos sobre la configuración:

  • Clock Prescaler: la frecuencia a la que se capturarán datos del ADC.
  • Scan Conversion Mode: este modo se activa cuando queremos usar varios canales del ADC.
  • Continuous Conversion Mode: al activarlo el ADC se pone a leer muestras de forma continua.
  • Discontinuous Conversion Mode: se utiliza para convertir un grupo cerrado de conversiones.
  • DMA Continuous Requests: se habilita cuando queremos utilizar el DMA.
  • End Of Conversion Selection: este flag se utiliza para determinar cuando se ha realizado una conversión.
  • Number of Conversion: determina el número de canales que van a realizar conversiones.

En este caso, el trigger externo no es necesario, por lo que se deja la opción de configuración mediante el software. Las opciones de Rank se dejan por defecto salvo que en los documentos anteriores nos indique lo contrario.

Por tanto, escogemos el pin PA1 como ADC1_IN1 y seguimos la configuración que puede verse en las imágenes. Tras lo cual, podemos pasar el código a Eclipse (el resto de pines que se ven marcados son los que se marcan al aceptar la configuración por defecto).

Configuración del ADC
Pin del ADC

Es importante tener en cuenta que aunque el modo continuo esté habilitado, si el modo End Of Conversion Selection está habilitado sólo se realizará una lectura.

 

LECTURA DE UN POTENCIÓMETRO

Conectamos un potenciómetro a la discovery, siendo la salida la conexión con el pin PA1 y los otros dos pines se conectan a VDD (alimentación) y GND (masa).

Entonces, dentro del main.c, tenemos que utilizar una función que permita empezar la conversión, otra que compruebe que el ADC está funcionando de forma correcta (utilizando la opción de polling) y otra que permita leer el valor del ADC. Se deja al lector la implementación de estas 3 funciones, las cuales pertenecen a la HAL – Hardware Abstraction Layer (es decir, aquellas funciones que permiten la interación entre Hardware y Software). Por ello, es conveniente revisar estas funciones, explicadas en este link. El valor deberá ser guardado en una variable.

Finalmente, compilamos y lanzamos el debugger. Al darle a empezar lo que tendremos será el valor que el ADC ha leído del potenciómetro una vez, el cual se encuentra entre 0 y 4096 (debido a los 2^12 bits que tiene el ADC). Para tener claro si el valor es leído correctamente, lo mejor es hacer 3 medidas: una con el potencióemtro en el mínimo (la variable tendría un valor cercano a 0), otra con el potenciómetro en el máximo (la variable tendría un valor cercano a 4096) y otra con el potenciómetro en el valor intermedio (la variable tendría un valor cercano a 2048).

Para leer la variable es necesario pausar la reproducción y poner el cursor encima de la variable en cuestión.

 

LECTURA DE UNA SINUSOIDE

El siguiente paso a dar es conseguir leer una sinusoide correctamente, es decir, teniendo en cuenta que la frecuencia de la señal obtenida es la misma que la de la sinusoide de entrada.

Conectamos el generador de funciones al pin PA1 y generamos una sinusoide de 1 KHz. El uso del osciloscopio para comprobaciones de entrada o salida es opcional y su uso se deja a elección del lector.

Las propiedades del ADC que tenemos que cambiar son las siguientes:

  • hadc1.Init.ContinuousConvMode = ENABLE; — Si lo teníamos DISABLE.
  • hadc1.Init.EOCSelection = DISABLE;

Esto se puede hacer directamente en el archivo adc.c, no es necesario ir a cubeMX a cambiar la configuración.

Sería necesario un array en el que guardar las muestras necesarias para la lectura de la sinusoide. Tras recoger las muestras, es necesario comprobar la señal que se está guardando a partir de estas muestras, lo cual se puede hacer utilizando cualquier herramienta que permita la representación de datos. En este caso, hemos utilizado MatLab, y lo que hemos obtenido es lo que se muestra en la imagen siguiente.

Sinusoide obtenida con los datos leídos del ADC

Podríamos pensar que ha funcionado correctamente al ver la imagen, pero si tenemos en cuenta que tenemos un array de 1000 elementos y una señal de entrada de 1 KHz, deberíamos estar haciendo 1 lectura cada milisegundo como máximo, y entonces podríamos ver un período de la señal. Si realizáramos lecturas más rápidas, veríamos menos de un período; y si son más lentas estaríamos perdiendo muestras y la señal no sería la misma. El problema es que no sabemos a qué velocidad se está realizando la captura y lectura de datos del ADC, pero por la imagen podemos deducir que lo que ocurre es el último caso. Las lecturas son más lentas, lo que provoca que estemos perdiendo muestras, y al perder muestras, para rellenar el array, necesitamos muestras de períodos siguientes, lo que hace que en su representación se observen varios períodos.

Una forma de intentar corregir este aspecto es aumentar la frecuencia de muestreo. Si no conseguimos una buena representación ni cuando la aumentamos, esto quiere decir que la limitación se encuentra en el tiempo que tarda el microcontrolador en procesar las instrucciones, y ahí poco podemos mejorar.

 

CONCLUSION

En este tutorial hemos aprendido a configurar un ADC y a realizar lecturas del mismo, tanto individuales como continuas. Pero los resultados muestran que esta forma de obtener datos solo es útil si buscamos obtener datos independientes o de forma continuada pero lenta.

Para mejorar este comportamiento tenemos dos opciones: utilizar interrupciones o utilizar el DMA. Ambas formas son explicadas en los siguientes tutoriales.

 

Nota: La imagen de la portada ha sido obtenida de THine Electronics

How to deploy a Node-Red environment on a GCP instance

Son numerosos los tutoriales en Internet que explican cómo montar un servidor Node-RED sobre GCP haciendo uso de clústers. Sin embargo cuesta encontrar (si es que los hay), tutoriales sobre como desplegar dicho servidor en una instancia, por lo que en este tutorial, nos centraremos en este caso. ¿Te suena a chino todo lo que hemos dicho? ¿Por qué montarlo sobre una instancia y no un clúster? Expliquemos brevemente los conceptos más raros de la frases anteriores para entendernos mejor.

  • Node-RED: es una herramienta de programación, de libre distribución, la cual nos permite de una forma rápida, y sobretodo muy intuitiva, desplegar una web con un estilo moderno y funcional. Node-RED hace uso de la programación “en cajas”, en la cual interconectamos distintos bloques ya pre hechos de las librerías disponibles. Node-RED usa Javascript y permite introducir bloques con nuestro propio código, pero para las tareas más sencillas no será siquiera necesario saber Javascript. Un ejemplo de un desarrollo simple en Node-RED sería el siguiente:

node_red_example

Node-RED permite además añadir librerías creadas por usuarios, siendo la librería “dashboard” una de las más populares, pues incorpora cajas con elementos visuales que permiten la interacción con el usuario así como la visualización de datos. Un ejemplo de ello:

maxresdefault

¿Fácil, verdad? Quien diría viendo esa web que se ha hecho sin necesidad de saber ningún lenguaje, solo juntando las cajas correctas. Existen otras opciones, como thingsboard.io, pero para gustos los colores, además de no ser la mayoría gratuitas (o tener planes gratuitos muy limitados). Nosotros preferimos Node-RED porque integra soporte para comunicaciones por UDP, TCP y el reciente MQTT, lo que permite comunicaciones con cualquier tipo de dispositivo, especialmente con dispositivos IoT. Además, la comunidad de desarrolladores es enorme y podemos encontrar muchos ejemplos ya hechos para su libre distribución, siendo estos ejemplos a veces, justo lo que buscamos.

Tenemos muchas formas de ejecutar Node-RED, en nuestro PC (esto es corriendo en un servidor local), en páginas que ponen a nuestra disposición servidores ya montados y listos para empezar a trabajar (FRED) o en servidores virtuales privados (VPS) de los cuales hay cientos de ofertas en Internet (aunque destacan por su catálogo y precios Microsoft Azure, Amazon Web Services [AWS] y Google Cloud Platform [GCP]). Las ventajas de ejecutar nuestro entorno en un VPS frente a nuestro ordenador o un entorno ya hecho (y cerrado) son inmensas: disponibilidad total, herramientas de protección, escalabilidad, no compromiso de nuestros datos privados, gestión de recursos… y esas son solo alguna de ellas.

  • Google Cloud Platform: es uno de los tantos servicios de gestión de VPS que hay hoy en día. Si bien es cierto que uno de los que más fuerza tiene es AWS, Google ofrece algo que no ofrece el resto: un servidor gratuito al año con 24/7 en ejecución. Vale que es un servidor muy modestito (10 GB de almacenamiento; 0.6 GB de RAM y un único procesador), pero es gratis y para diseños simples puede ser más que suficiente. Es por esto que nos centraremos en este gestor VPS en este tutorial.
  • Instancia vs. cluster: Google denomina a cada uno de los VPS que creamos instancia. Un grupo de instancias trabajando de forma conjunta, compartiendo recursos y distribuyéndose el tráfico de red entre ellas forma un clúster. Claro, a priori parece que el clúster es mejor (y lo es), pero no es gratis. La instancia, sin embargo, sí. Siempre y cuando esa instancia sea de las más simples de Google, como ya hemos comentado antes.

Ahora que ya hemos explicado todo un poco, relee si quieres el primer párrafo del post. Ahora ya parece obvio por qué queremos desplegar Node-RED (y no otro) sobre una instancia (y no un clúster), porque…

free

 

Empecemos…

Lo primero, lógicamente, es tener una cuenta de Google activa. Nos dirigiremos a la consola de Google Cloud y activaremos nuestra cuenta, registrándonos en la versión de prueba gratuita.  Solo por registrarnos Google nos regala 300 $ en servicios GCP. Para nuestros propósitos no nos harán falta, pero nos vendrán genial si queremos cacharrear con todas las opciones que GCP ofrece. Completaremos todos nuestros datos (incluida la tarjeta de crédito, pero no pasa nada: Google nos avisará previamente en caso de que hiciéramos algo que incurriera en un desembolso). Tras registrarnos se nos creará nuestro primer proyecto (que podremos renombrar si queremos pinchando en configuración de proyecto).

En el buscador escribimos Compute Engine y en la nueva ventana, una vez cargue, creamos una nueva instancia, con la configuración que vemos en la siguiente imagen:

g1
La zona da igual siempre que sea en América (salvo Virginia del Norte). América es la única región con VPS gratuitas. El tipo de máquina ha de ser micro y permitir el tráfico HTTP y HTTPS. Nosotros hemos elegido Ubuntu por familiaridad con los comandos, pero cualquier otra distribución de las gratuitas que ofrece Google es válida. Notad que para saber que estáis siguiendo los pasos correctos, debe apareceros el texto de la derecha donde os informa de que la máquina seleccionada es gratuita. Pulsamos en crear y esperamos.

Una vez creada, hay diferentes cosas que sería interesante hacer antes de empezar a cacharrear (asignarnos una IP estática y abrir algunos puertos).

-Asignando IP estática podremos entrar en nuestro servidor sin necesidad de consultar qué IP nos ha concedido Google esta vez: siempre será la misma. Para ello escribimos Red de VPC en el buscador y entraremos en la sección del menú lateral izquierdo “Direcciones IP externas”. Seleccionaremos nuestra instancia y cambiaremos su tipo a estática. Le ponemos un nombre identificativo a esta IP y aceptamos.

-Abriendo puertos (bien sea TCP o UDP) permitiremos un acceso remoto a nuestro servidor. Hay que notar que esto es un arma de doble filo, pues si bien no podemos hacer mucho sin tener acceso a nuestro servidor remoto también es una puerta abierta a hackers, por lo que recomendamos abrir solamente los puertos que vayamos a necesitar. En nuestro caso será obligatorio abrir el puerto TCP 1880, pues será el que usará Node-RED tanto para la interfaz de diseño (donde colocaremos las cajitas) como para la interfaz web (donde nos mostrará el resultado de colocar y conexionar esas cajitas). Para ellos tecleamos en el buscador “Reglas de cortafuegos” y elegimos la opción que lleve también escrito Red de VPC.

Creamos una regla nueva:allowtcp

 

El nombre es opcional, todo lo demás, recomiendo dejarlo a esos valores. Cuando cojáis más soltura con GCP os recomiendo etiquetar vuestras distintas instancias para poder elegir destinos de reglas del cortafuegos y así que cada máquina tenga abiertos los puertos que necesita. Por ahora, y como solo tenemos una máquina creada, no pasa nada por aplicar en el campo destinos “todas las instancias de la red”. Guardamos y ya estaremos listos para empezar la instalación de Node-RED sobre nuestro VPS.

Volvemos a la vista de Compute Engine, donde estará nuestra instancia. En el campo “Conectar” pulsamos sobre SSH. Se nos abrirá una ventana nueva y cuando cargue ya estaremos dentro de nuestro VPS.

Para poder empezar a trabajar, tecleamos los siguientes comandos:

Nótese que entre los comandos, se instalará nodejs. En nuestro caso hemos instalado la versión 8.x por ser la recomendada en el momento de realizar este tutorial, pero se aconseja mirar en la página de nodejs cual es la última versión recomendada. Escribimos ahora el comando que instalará Node-RED en nuestro VPS.

Es también interesante instalar algunas herramientas de node-red que nos harán más fácil la gestión de nuestro servidor, por lo que teclearemos:

Después de esto ya podemos probar que Node-RED está correctamente instalado. Para ellos tecleamos:

Lo que debería arrojar en el terminal una salida que acaba con:

Esto es indicativo de que todo está correcto. ¡Probémoslo! Escribamos en nuestra barra del navegador la IP estática concedida por Google (sin http ni https delante seguida del puerto de acceso a Node-RED, separado por dos puntos “:”), algo así como 123.123.123.123:1880. Deberíamos ver esto:

node-red1

 

¡Todo funciona! Sin embargo esto presenta un enorme, enorme inconveniente: cualquiera que sepa nuestra IP puede acceder a nuestro servidor Node-RED y borrarnos todo el trabajo o inyectar código malicioso. Por ello, el siguiente paso, de vital importancia, es proteger nuestro servidor. Volviendo a la terminal abierta por SSH, pulsamos ctrl+C para parar la ejecución de Node-RED y escribiremos:

Lo que nos preguntará por la contraseña con la que deseamos proteger el servidor. Tras escribirla y pulsar intro, nos devolverá una secuencia hash con nuestra contraseña encriptada, que deberemos copiar, pues usaremos ahora. Escribiremos sobre el archivo de configuración de Node-RED. En el terminal tecleamos:

y dentro de este archivo buscaremos el siguiente texto:

adminAuth: {
type: “credentials”,
users: [{
username: “USUARIO“,
password: “HASH_GENERADO“,
permissions: “*”
}]
},

// To password protect the node-defined HTTP endpoints (httpNodeRoot), or
// the static content (httpStatic), the following properties can be used.
// The pass field is a bcrypt hash of the password.
// See http://nodered.org/docs/security.html#generating-the-password-hash
httpNodeAuth: {user:”USUARIO“,pass:”HASH_GENERADO“},
httpStaticAuth: {user:”USUARIO“,pass:”HASH_GENERADO“},

En usuario escribiremos el usuario que queramos, y en los campos password y pass, el hash generado anteriormente. La primera parte protegerá la parte de gestión (donde colocamos las cajitas), la segunda, la parte de visualización (la web que crean las cajitas). Es importante descomentar las lineas necesarias (esto es, eliminar los caracteres “//” con los que empiezan algunas lineas), para que el resultado quede tal y como hemos puesto arriba. Guardamos con CTRL+O y salimos con CTRL+X.

Por último, será interesante que nuestro servidor cargue automáticamente Node-RED cuando se reinicie, lo que hará más tolerante a fallos nuestra implementación. Para ello, escribimos:

Que nos indicará nuestro nombre de usuario. A continuación:

donde copiaremos el siguiente texto:

[Unit]
Description=Node-RED
After=syslog.target network.target

[Service]
ExecStart=/usr/bin/node-red
Restart=on-failure
KillSignal=SIGINT

# log output to syslog as ‘node-red’
SyslogIdentifier=node-red
StandardOutput=syslog

# non-root user to run as
WorkingDirectory=/home/TUUSUARIO/
User=TUUSUARIO
Group=TUUSUARIO

[Install]
WantedBy=multi-user.target

Hay que modificar solo los campos en rojo. Nuevamente, guardamos con CTRL+O y salimos con CTRL+X. Activamos el servicio creado escribiendo:

Comprobaremos que todo se haya hecho correctamente. Para ello primero es necesario reiniciar, por lo que escribimos:

Y tras esperar unos dos minutos, cargamos de nuevo la página con la IP del servidor en nuestro navegador. Ahora, al cargar node-RED debería pedirnos login, tanto a la parte de gestión como a la de visualización.

¡Eso es todo por nuestra parte! Ahora, a jugar.

STM32F4: Interrupción externa

En el ejemplo de hoy veremos como asociar la generación de una interrupción externa al botón de usuario que hay en la placa de desarrollo 32F411-DISCOVERY. Después vincularemos a la atención de esa interrupción el toggle del led rojo.

Empezaremos configurando CubeMX, donde ya por defecto nos han puesto el GPIO PA0 configurado como GPIO_EXTI0 que indica que ese pin está configurado como interrupción externa. 

Para ello en la pestaña Configuration, dentro de la configuración de GPIO seleccionamos el pin PA0-WKUP y lo configuramos en modo External Interrupt Mode with Rising edge trigger detection, No pull-up and no pull-down.

Ahora debemos activar dicha interrupción bajo la pestaña Configuration, en la configuración de NVIC, debemos activar la línea EXTI line0 interrupt

Activando estas opciones en CubeMX nos generará el código correspondiente a la inicialización del sistema y activará la interrupción asociada a la linea 0, que en nuestra placa está vinculada al botón de usuario.

Si abrimos el fichero main.c y pinchamos sobre la definición de la función MX_GPIO_Init() podemos ver dos líneas al final del método que fijan la prioridad y activan la interrupción.

Si abrimos el fichero stm32f4xx_it.c podemos ver como ha aparecido una función para la gestión de la interrupción EXTI line0. Si pulsamos sobre la definición de HAL_GPIO_EXTI_IRQHandler(), nos lleva a otro método que limpia el flag de interrupción asociado al GPIO que ha generado la interrupción y llama a su callback asociado HAL_GPIO_EXTI_Callback(). Si vamos a la definición de esta última función vemos que está definida como tipo __weak y en un comentario nos dicen que debe ser implementada en espacio de usuario.

Como nosotros somos muy obedientes copiamos la definición de la función y nos lo llevamos al fichero gpio.c donde dentro del USER CODE 2 pegamos:

A este callback acudirá nuestro programa cuando se detecte una pulsación del botón. Ya que es recomendable hacer el mínimo de operaciones dentro del callback de una interrupción, en este callback sólo realizaremos la operación de toggle del led.

Para ello, dentro de este callback haremos la llamada a HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14). De esta forma cada vez que se pulse el botón de usuario el led rojo de la placa debe conmutar.

Se deja al lector la resolución de varios problemas tales como el sistema antirebotes software que habría que poner asociado a las interrupciones que se generan a través del botón, o el problema asociado a que dentro del callback habrá que distinguir entre los diferentes GPIOs que generen interrupción.

Solo nos falta compilar, y debuguear en Ac6 STM32 C/C++ Application. Y con eso podremos ver conmutar el led rojo de la placa cada vez que pulsamos el botón de usuario.

STM32F4: Primeros pasos con el entorno de desarrollo

En el tutorial que vamos a llevar a cabo hoy veremos como instalar todas las herramientas de desarrollo para poner en marcha la placa de desarrollo 32F411-DISCOVERY. Una vez tengamos todas las herramientas instaladas procederemos a compilar y ejecutar un programa que haga parpadear un led.

Unos de los entornos de desarrollo integrado (IDE) que nosotros usamos en el B105 es eclipse. Para trabajar y poder compilar de forma cruzada para los STM32 existe una versión de eclipse que contiene todos los plugins y librerias necesarias para trabajar con dispositivos de STM llamada System Workbench for STM32 (SW4STM32). Es una herramienta gratuita que debéis descargar e instalar en vuestro ordenador. Para poder descargarla tendréis que registraros en la web. Es posible, que si no lo tenéis instalado todavía, tengáis que instalar Java en vuestro ordenador.

eclpse

 

Ahora procedemos a descargar e instalar el software STM32CubeMX que no es más que un generador de código de inicialización para los microcontroladores y plataformas de desarrollo de ST. Con este software podremos crear el código inicial con las capas de abstracción hardware con las que queremos inicializar nuestra plataforma.

cubmxAl instalar SW4STM32 y CubeMX se nos deberían instalar los drivers correspondientes para poder usar el programador integrado en la placa Discovery para el STM-Link v2 o v2.1.

Proyecto Toggle Led

Abrimos CubeMX y creamos un nuevo proyecto. En la pestaña Board Selector elegimos nuestra placa STM32F411E-DISCO.

cubemx1

 

A través de este software se pueden activar y desactivar los periféricos y los middlewares disponibles en el microcontrolador STM32F411. Además se pueden asociar los periféricos y funciones a los pines, o asignar funciones alternativas a un pin tales como: GPIO de salida, entrada, de interrupción, analógico, de PWM, etc.

Antes de configurar nada del microcontrolador vamos a configurar el programa para que nos genere el código con la estructura correcta. Para ellos entraremos en Project Settings, pondremos un nombre a nuestro proyecto en Project Name, por ejemplo Toggle Led. En Toolchain/IDE seleccionaremos SW4STM32 y desactivamos el Generate Under Root.

Bajo la pestaña Code Generator seleccionamos Copy only the necessary library files, Generate peripheral initialization as a pair of ‘.c/.h’, Keep user code when re-generating y Delete previously generated files when not re-generated. Aceptamos la configuración.

Ahora nos fijaremos en el pin PD12, que está asociado al led verde. Comprobamos que está en modo GPIO_Output. Y ahora simplemente confiamos que el resto de configuraciones por defecto son correctas.

Generamos el código pulsando sobre Project -> Generate Code. El programa comenzará a generar todo el código y al finalizar, en el cuadro emergente pulsaremos sobre abrir proyecto. Esto nos debe abrir e incluir el proyecto en SW4STM32 (Eclipse).

Podemos ver como tenemos una estructura de directorios y ficheros que nos ha generado CubeMX con todos los drivers y librerias necesarias para nuestro sencillo proyecto. Si abrimos el main.c podemos ver que hay muchas líneas que dicen USER CODE BEGIN/END.

eclipse2

 

Es muy importante que todo el código que escribamos lo hagamos dentro del bloque BEGIN/END. De lo contrario, cuando volvamos a generar código CubeMX lo sobreescribirá y no lo conservará.

En la inicialización vemos que se hace la llamada a MX_GPIO_Init(), con eclipse si mantenemos pulsado la tecla Ctrl mientras hacemos click sobre las función, nos abrirá su definición. Si la leemos un poco podemos ver una sección donde se define la funcionalidad del LD4_Pin asociado al puerto GPIOD y pin GPIO_PIN_12 que en nuestro caso es el GPIO asociado al Led Verde.

Si ahora accedemos a la definición de HAL_GPIO_Init() nos abrirá el fichero stm32f4xx_hal_gpio.c donde podemos ver todas las funciones de la HAL que nos ha generado CubeMX, entre ellas las de Read, Write y Toggle de un GPIO.

En nuestro caso, dentro del while(1) del main() haremos uso de HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12) para hacer parpadear el led. Para que podamos visualizarlo tendremos que poner un HAL_Delay(500).

Solo nos falta compilar, y debuguear en Ac6 STM32 C/C++ Application. Si dado el caso os preguntan que interfaz deseas utilizar (JTAG o SWD), debéis seleccionar SWD para la correcta comunicación con la placa de desarrollo. Y con eso podremos ver parpadear nuestro led verde cada 0.5 segundos en nuestra plataforma de desarrollo.