Controlar un potenciometro con Arduino Iot Cloud


En este post vamos avanzar en las posibilidades de la placa MKR1000 (o MKR 1010) a la nube de Arduino IoT  de modo que podremos hacer cosas mas complejas mas allá de encender o apagar un led  a distancia ( como vimos en este post ). En esta ocasión como ejemplo de la gran potencia de de esta solución  vamos a   leer en remoto las posición de un potenciometro  a través de Internet utilizando el sitio web de Arduino IoT Cloud.

Si le  interesa  como hacerlo, vera que es muy sencillo,  pues como vamos a ver  casi todo esta hecho, pero antes, volvamos a  ver  las semejanzas   y diferencias de ambas placas,  y después veremos paso a paso como lograrlo.

Arduino MKR1000

Arduino MKR1000 es una placa diseñada para ofrecer una solución práctica y rentable para cualquiera que busque agregar conectividad WiFi a sus proyectos con una experiencia mínima en redes.  Su precio no es excesivo  teniendo en cuenta que integra la conectividad  wifi (unos 38€ en Amazon).

El diseño incluye un circuito de carga Li-Po que permite que el Arduino MKR1000 funcione con una  batería o 5V externos, cargando la batería Li-Po mientras funciona con energía externa: el cambio de una fuente a otra se realizara automáticamente  y por tanto no tendremos que preocuparnos de nada más.

El MKR1000 tiene un procesador Arm Cortex-M0 + de 32 bits  corriendo a 2.4ghz ,  y cuenta con  el rico conjunto habitual de interfaces de E / S . Sin duda uno de su punto fuertes  es que integra  WiFi de baja potencia con un chip criptográfico para una comunicación segura.

Una de las grandes ventajas  es que puede programarlo utilizando el software Arduino (IDE) al que estamos  todos familiarizados  siendo muy  fácil de usar.

Todas estas características hacen de esta placa la opción preferida para los proyectos emergentes que funcionan con baterías de IoT en un factor de forma compacto.

 

 Como   se puede  ver en la imagen de  mas abajo , los pines disponibles son casi los mismos que los que solemos tener en un Arduino convencional  : los pines A0  a A6   para entradas  y salidas analógicas , los pines 0 al 14  para entradas salidas binarias y los típicos de alimentación externa(VIN,VCC 5v y GND)   , la referencia (AREF )  y  RESET.

 

Si le interesa esta placa la puede comprar en Amazon por unos 38€

Arduino MKR1010

Hablamos ahora de una placa muy similar a la anterior   algo mas barata que la la Mkr1000 ( unos  33€  en Amazon , es decir unos 5€ mas barato que la MKR1000)

Esta placa  está compuesta por tres bloques principales:

  • Microchip ATSAMD21 MCU basado en un procesador Arm Cortex-M0 
  • Serie u-blox NINA-W10 de baja potencia 2.4GHz IEEE 802.11 b / g / n Wi-Fi ECC508 CryptoAuthentication
  • El diseño incluye un Li-Po Circuito de carga que permite que Arduino MKR WiFi 1010 funcione con batería o 5V externos, cargando la batería Li-Po mientras funciona con energía externa. El cambio de una fuente a otra se realiza automáticamente.

Como  vemos , la gran diferencia  es  el Microcontrolador que es menos potente  pues  cuenta con el  Microchip ATSAMD21 (procesador Arm Cortex-M0 +)  en contraste  con el Arm Cortex-M0 + de 32 bits  corriendo a 2.4ghz del MKR100.

Respecto a la conectividad,  es similar al  MKR1000  contando con WiFi u-blox NINA-W102 (ESP32)

La alimentación se puede hacer con una fuente de alimentación externa de 5v DC  bien por  USB  o bien por el pin VIN , pero  cuenta   además  con conexión para Batería compatible (*) Li-Po de celda única, 3,7 V, 700 mAh  siendo el voltaje mínimo de funcionamiento del circuito 3,3 V .

 

Como   se puede  ver en la imagen de  mas abajo , los pines disponibles son casi los mismos que los que solemos tener en un Arduino convencional  ( y los mismo que el  MKR100)   : los pines A0  a A6   para entradas  y salidas analógicas , los pines 0 al 14  para entradas salidas binarias y los típicos de alimentación externa(VIN,VCC 5v y GND)   , la referencia (AREF )  y  RESET.

Si le interesa esta placa la puede comprar en Amazon por unos 33€

Agregar un potenciómetro 

Ahora que tenemos confirmación de todo lo que funciona ( como vimos en este post ), podemos agregar nuevas propiedades a nuestra Cosa. Vincularemos la nueva propiedad a un potenciómetro que necesita ser añadido al circuito. El potenciómetro está conectado a la alimentación y a tierra a través de sus respectivos pines y el pin de señal está conectado al Pin analógico A1 de la placa Arduino.

Adding an analog sensor to our breadboard

Para agregar una nueva propiedad vamos a proceder como lo hicimos anteriormente: mientras que en nuestra vista de propiedades de Thing, hagamos clic en el botón + y cree una propiedad denominada .

Establezca el tipo en Int con valor mínimo y valor máximo establecido en 0 y 270 respectivamente.

El permiso debe establecerse en Solo lectura y la propiedad debe actualizarse cuando cambie el valor;

Asimismo podemos establecer un valor Delta mayor que cero si queremos introducir alguna tolerancia para la actualización (por ejemplo: si establecemos Delta en 5, el valor de propiedad se actualizará a través de la nube solo cuando la diferencia entre el nuevo valor y el valor antiguo sea mayor que 5, de lo contrario se omitirá el cambio).

Al hacer clic en CREATE, se agregará la nueva propiedad a nuestra cosa y nos traerá de vuelta a la vista de edición de la propiedad.

Aunque no lo vemos, nuestro boceto se ha actualizado para reflejar los cambios, así que hagamos clic en EDIT CODE para volver al editor.

Mirando thingProperties.h, nos daremos cuenta de que se han añadido dos nuevas líneas:

int angle;

Esta linea declara la variable que representa la propiedad que acabamos de crear

ArduinoCloud.addProperty(angle, READ, ON_CHANGE, NULL, 5.000000);

Este código conecta la variable a su propiedad correspondiente, con permisos READ (es decir: no vamos a poder establecerla desde el panel). Debido al permiso de solo lectura, no se generará ninguna función de devolución de llamada y el penúltimo argumento del método se establece en . El último argumento representa el valor Delta descrito anteriormente.

Para hacer que el potenciómetro interactúe con la nube necesitamos definir el pin al que está conectado:

#define POTENTIOMETER_PIN A1

Luego, en la función, leemos la entrada analógica del potenciómetro y la mapeamos a la variable. De este modo, al girar el potenciómetro se refleja, se cambia el valor de propiedad correspondiente en el panel de la nube.

int angleSensor = analogRead(POTENTIOMETER_PIN);
angle = map(angleSensor, 0, 1023, 0, 270);

Vamos a subir nuestro boceto de nuevo y ver lo que sucede en el tablero de nuestra cosa cuando giramos la perilla del potenciómetro. Deberíamos ver el valor subiendo y bajando de 0 a 270 (esto puede variar con la calidad de construcción del potenciómetro).

Por último, vamos a agregar una última propiedad.  Esta nueva propiedad se asociará a un botón pulsador agregado al circuito anterior como se muestra en los esquemas siguientes: un pin del botón está conectado al riel de alimentación positivo (Vcc), el otro pin está conectado al pin digital 5 (a través del cable blanco) y a tierra a través de una resistencia desplegable de 10k.

Esta configuración fuerza un nivel lógico LOW en nuestro pin cuando el botón está en reposo, mientras que rutea Vcc a través cuando se presiona (nivel lógico HIGH).

Desde el editor, vaya a IOT CLOUD y cree una nueva propiedad denominada , con Tipo ON/OFF (Boolean),Solo lectura de permisos y Actualizar cuando cambie el valor. toggle

Una vez más EDIT CODE y volveremos al editor. Un vistazo rápido a thingProperties.h mostrará que una nueva variable se ha definido y asociado a su propiedad a través de .ToggleArduinoCloud.addProperty(...)

En nuestro archivo .ino definiremos el nuevo pin y dos variables relacionadas con el estado del botón : es decir el estad actual ( btnState) y el estado anterior(btnPrevState) .btnPrevState es necesario porque queremos que la propiedad se actualice solo una vez cuando se presiona el botón y no cuando se libera.

#define BUTTON_PIN 5
int btnState;
int btnPrevState = 0;

Entonces,es importante destacar   la linea que establece como entrada  este pin para

pinMode(BUTTON_PIN, INPUT);

Y finalmente añadimos estas líneas hacia el final de la loop()

btnState = digitalRead(BUTTON_PIN);
if (btnPrevState == 0 && btnState == 1) {
 toggle = !toggle;
}
btnPrevState = btnState;

Con este sencillo código  el botón actúa como un interruptor y al presionarlo debemos ver el interruptor en la nube cambiando en consecuencia alternando  entre ON y OFF.

En este código hay un pequeño problema  pues como puede adivinar no hay gestión de los rebotes (debounce en ingles  )  , es decir la cantidad de ruido ocurrido tras el flanco cuando actuamos sobre el pulsador(en esencia, en el rango de unos microsegundos la señal es puro ruido) . Todos esos picos pueden provocar disparos múltiples de una interrupción. Disponemos de dos formas de aplicar el rebote :añadiendo dispositivos electrónicos que filtren la señal o modificando nuestro código para eliminar el rebote 

 Vamos a ir más allá y simplificar nuestro código de administración de botones usando una biblioteca adicional.

 Usar una biblioteca de anti-rebotes

El código que hemos visto se basa en variables temporales porque necesitábamos almacenar el estado anterior del botón, lo que no hace que el boceto sea sencillo de implementar  , pero  la cosa se complica con los efectos de los rebotes  o la necesidad  de utilizar varios botones ( que añadiría muchas variables).

Una solución fácil es utilizar una biblioteca de rebote,y vamos a confiar en FTDebouncer que se puede instalar a través del Administrador de bibliotecas.

Simplemente vamos a Bibliotecas desde el menú de la barra lateral, ingresamos «FTDebouncer» en el campo de búsqueda en la parte superior y presionamos Intro: aparecerá la biblioteca y podemos añadirla a nuestro boceto pulsando el botón INCLUIR.

Esto agregará la siguiente línea a la pestaña seleccionada actualmente

#include <FTDebouncer.h>

Antes de esto podemos  reemplazar la definición de variables relacionadas con el estado del botónsetup()

int btnState;
int btnPrevState = 0;

con la declaración de una variableFTDebouncer

FTDebouncer buttons;

a continuación, reemplazar la línea donde inicializamos el pin del botón

pinMode(BUTTON_PIN, INPUT);

con las siguientes dos líneas

buttons.addPin(BUTTON_PIN, LOW);
buttons.init();

Al principio le podemos a añadimos este comando antes de loop()

buttons.update();

y eliminar todo el código escrito previamente relacionado con el botón

btnState = digitalRead(BUTTON_PIN);
if (btnPrevState == 0 && btnState == 1) {
    toggle = !toggle;
}
btnPrevState = btnState;

Finalmente, al final del boceto vamos a añadir una función

void onPinActivated(uint8_t pinNr){
	Serial.println(pinNr);
	toggle = !toggle;
}
void onPinDeactivated(uint8_t pinNr){
	Serial.println(pinNr);
}

Gracias a la biblioteca, se llamará a la función (sólo una vez) cuando se pulse el botón. Cuando esto suceda, le diremos a nuestra propiedad que cambie a su valor opuesto. Si es cierto, se volverá falso y viceversa. Esta acción la realiza el operador «!»,también conocido como LogicalNOToperator.FTDebounceronPinActivated()toggle

Si queremos que se ejecute algún código cuando se suelte el botón, la biblioteca llamará a la siguiente función cuando eso suceda. 

 

Deja un comentario

Este sitio utiliza Akismet para reducir el spam. Conoce cómo se procesan los datos de tus comentarios.