ThingSpeak™ es un servicio web gratuito muy veterano y del que hemos hablado en este blog en numerosas ocasiones que permite recopilar y almacenar datos de sensores conectados a Rasberry Pi, Arduino ,Netduino entre otros para enviarlos hacia un servicio de datalogger en la nube.
Asimismo también sirve para desarrollar aplicaciones de Internet de las cosas como por ejemplo desencadenar ciertas acciones ante determinados cambios en las medidas , tal y como vamos a ver en este caso desencadenando envíos de tweets con el motivo de la alerta.
Photo by panumas nikhomkhai on Pexels.com
El servicio de web de ThingSpeak es uno de los servicios mas veteranos en la red proporcionando aplicaciones que le permiten analizar y visualizar los datos en MATLAB®y luego actuar sobre los cambios en esos datos desencadenando acciones.
Los datos de los sensores pueden enviarse a ThingSpeak desde un Arduino®, Raspberry Pi™, BeagleBone Black asi como desde Netduino+ entre otras plataformas
En este post vamos a intentar ver cómo se puede enviar un tweet cuando los datos de punto de rocío superan un umbral usando dos aplicaciones como son ThingTweet y React :
ThingTweet sirve para vincular una cuenta Twitter® a su cuenta ThingSpeak. Sus dispositivos pueden enviar alertas a través de Twitter utilizando la API de TweetContol. Por ejemplo, puede hacer que un dispositivo tuitee cuando la temperatura de su invernadero disminuya o cuando las baterías de un dispositivo se estén agotando. Los pasos son sencillos : entraremos c en Link Twitter Account para vincular una cuenta de Twitter a su cuenta ThingSpeak y cuando se le pida que autorice a ThingTweet a usar su cuenta ingresaremos el nombre de usuario y contraseña de Twitter marcando la casilla Recordarme para guardar en caché las credenciales de Twitter en su pc y por supuesto haciendo clic en Autorizar aplicación
React funciona con las aplicaciones ThingHTTP, ThingTweet y MATLAB Analysis para realizar acciones cuando los datos del canal cumplen una determinada condición. Por ejemplo se puede hacer que una aplicación móvil informe su latitud y longitud a un canal ThingSpeak, de modo que cuando su posición esté dentro de una cierta distancia de su casa, ThingHTTP encienda las luces de su sala.
Como pasos previos para poder usar ambos servicios se requiere que ya han realizado estos pasos:
Crear una cuenta de Twitter® .
Iniciar sesión a su cuenta de MathWorks® o la cuenta de ThingSpeak™ , o crear una nueva cuenta de MathWorks .
Crear un canal como el canal calculados del punto de rocío.
Leer los datos de estación meteorológica( por ejemplo desde una placa Netduino) en su canal y calcular el punto de rocío como vimos en el post anterior
Nota : En este ejemplo vamos a utilizar una medida intermedia que es calculada en función de la humedad y temperatura , pero lógicamente los desencadenantes se pueden lanzar desde medidas sencillas que no requieran un calculo intermedio .
Vincular la cuenta de Twitter a ThingSpeak
Para empezar tenemos que vincular una cuenta de twitter a nuestra cuenta de thingspeak . Para ello puede seguir lo siguintes pasos:
Validese en su cuenta de ThinSpeak
Ir a aplicaciones(Apps) > ThingTweet.
En la página ThingTweet, haga clic en (enlace decuenta de Twitter (Link Twitter Account ) para vincular su cuenta de Twitter a tu cuenta de ThingSpeak.
Tiene que autorizar el acceso a su cuenta de twitter desde ThingSpeak
Introduzca su nombre de usuario de Twitter y contraseña y haga clic en Autorizar la aplicación.
En la página de autorización , haga clic en volver a ThingTweet(back to ThingSpeak). Nos avisara de que su cuenta de Twitter está relacionada con ThingSpeak devolviendonos el valor del APIKEY , el cual por cierto podemos fiorzar a cambiar gracis al boton Regenerate API Key.
Si queremos deshacer este cambio simplemente pulsaremos sobre el botón desenlazar cuenta («Unlink Account»)
Reaccionar al cambio en el punto de rocío
Una vez vinculada su cuenta de twitter a thingspeak ya podemos indicar a React que envie un tweet cada vez que el nivel de punto de rocío supere un valor va sobre 15ªC , testeando el canal cada 10 minutos.
Estos son los pasos para hacerlo:
Ir a aplicaciones > react hacera clic en Reaccionar de nuevo.
Nombre este react por ejemplo como «Tweet de punto de rocío.»
Defina el tiponumérico.
Ajuste la Frecuencia de la prueba a cada 10 minutos.
Establecer la condición cuando el valor de la humedad en su canal alcanza o supera los 60:
Si canal: seleccione el canal de medición de punto de rocío.
campo: seleccione 3 (punto de rocío).
Para el tipo de condición, seleccione es mayor o igual a.
El valor de condición, entre 60 (se refiere a grados Fahrenheit)
Ajuste acción en ThingTweet.
Entrar en esta cadena en tweet a continuación:
Turn off that humidifier! It's above 60F
Seleccione su cuenta de Twitter con la cuenta de Twitter.
En Opciones, elija Ejecutar acción cada vez que la condición se cumple.
Click Save React.
El tweet se envíara cada vez que el nivel de humedad supere los 15,5ºC o 60 ° F.
Es evidente que esta facilidad de ThingSpeak ,que sinsisteimo es soportado por un amplio abanico de hardware (como Raspberrry, Arduino o el propio Netduino), tiene una utilidad indudable para infinidad de condiciones que nos pueden facilitar la vida como por ejemplo apertura de puertas o ventanas, temperaturas anómalas , caídas de tensión , y un largo etcétera.
Netduino es una plataforma de desarrollo de código abierto integrado similar a la famosa plataforma Arduino, excepto que utiliza .NET Micro Framework para su programación. La placa de desarrollo Netduino tiene el mismo factor que Arduino Uno, y por lo tanto la mayoría de los escudos de Arduino son también compatibles con Netduino. Las placas de desarrollo Arduino se basan en 8 bits microcontroladores Atmel que corren a una velocidad máxima de reloj de 16 MHz en su versión primera ,pero el hardware Netduino usa potentes procesadores de 32 bits (en el caso de la primera versión un Atmel SAM7x en Netduino, y STMicro STM32F4 en versiones Netduino Plus) y funciona a una velocidad mucho más rápida (48 MHz a 168 MHz).
En el siguiente ejemplo extraido de embedded-lab.com ademas de intenatr dar una introducción a la plataforma Netduino y asegurar que cualquier principiante, estudiante o aficionado, será rápidamente capaz de empezar a usarlo para sus propios proyectos y diseños embebidos vamos a ver la gestiona de un display de 7 segmentos de led con nuestro Netduino Plus .
Una salida visual siempre añade valor a cualquier proyecto .En esta ocasión , vamos a mostrar un poco de información numérica, alfabética, así como dos personajes simbólicos en un módulo LED de siete segmentos de 4 dígitos en función de luminosidad captada por una foto-resistencia,es decir vamos a leer una tensión analógica de un sensor LDR y mostraremos la salida del ADC en cuatro módulos de siete segmentos.
En realidad el control de un display de 7 segmentos ( en realidad 8 si contamos con el punto) , es bastante intuitivo , si se piensa en que cada segmento corresponde a un solo led .Por ejemplo para mostrar dígito «1», tenemos que enviar la señal de alto para el LED «b» y «c» solamente y tierra el cátodo.
Como un display cuenta con siete segmentos LED se hace con siete más un LED, cada LED tiene su propio nombre, por ejemplo ,si tenemos que mostrar «15» la forma en que hacemos es mostrando un «1» ( segmentos B y C) en un bloque LED ,luego apagamos ese primer display ( cátodo a uno lógico) y luego nos vamos a mostrar «5» en el segundo display LED( segmentos A,F,G y D) y luego lo apagamos también (cátodo a uno lógico), y repetimos el bucle indefinidamente :esto es básicamente la multiplexación porque todos lo segmentos los unimos eléctricamente para ahorrar bits de control de modo que solo controlamos el encendido de uno de ellos a una frecuencia tan rápida que sea inapreciable por el ojo humano
.
Configuración de Circuito y Teoría
En la sección analógica, hemos utilizado una LDR como nuestro dispositivo de entrada analógica. Con la iluminación, la resistencia de la LDR cambiará causando el cambio en el voltaje debido al divisor de tensión formado por el LDR y una resistencia de 10k .La caída o subida de tensión entre el punto de unión entre el LDR y la resistencia nos dará una tensión que conectemos a nuestro pin analógico A1 de Netduino
En la sección digital, las conexiones son también muy sencillas. Cada pin (a hasta g) de los siete segmentos LED están conectados a los pines digitales DO a D6 de Netduino+ través de una resistencia de 330 ohmios . Posteriormente cada display de siete segmentos LED al ser estos de cátodo común y haber cuatro unidades , los controlaremos por medio de 4 transistores NPN ( por ejemplo BC547) con sus resistencias de base de 10k que conectaremos a los pines digitales D8,D9;D10 y D11 de nuestro Netduino
Cuando la base del transistor está forzado a un uno lógico, el transistor conduce y entonces el ánodo correspondiente se conecta a tierra, que completaría el circuito justo en los segmentos cuyos pines lógicos estén a uno logico encendiendo así el LED correspondiente a ese led
.
Programa en c#
El código escrito por embedded-lab va usar una pequeña biblioteca (Clase SevenSegments) que soporta un poco más que los dígitos que muestran. Veamos paso a paso. En el código de abajo, primero creamos una instancia de la clase AnalogInput lo que nos permite obtener el valor de nuestro dispositivo analógico que es LDR en este caso. Luego creamos una instancia independiente de la clase SevenSegments. El constructor de esta clase lleva varios pines como argumentos. Una vez que tenemos SevenSetments instancia simplemente llamar al método Show y pasar el valor que se lee desde el dispositivo analógico
public static void Main() {AnalogInput aInPin = new AnalogInput(Pins.GPIO_PIN_A1);
//se puede usar cualquier pin analógico
aInPin.SetRange(0, 1234); //dar un rango. Debug.Print(«Analog value: » + aInPin.Read()); // inicializacion del display de 7 segmentos pasando los pines adecuados SevenSegments sevenSegments = new SevenSegments( Pins.GPIO_PIN_D0, Pins.GPIO_PIN_D1, Pins.GPIO_PIN_D2, Pins.GPIO_PIN_D3, Pins.GPIO_PIN_D4, Pins.GPIO_PIN_D5, Pins.GPIO_PIN_D6, new Cpu.Pin[] { Pins.GPIO_PIN_D8, Pins.GPIO_PIN_D9, Pins.GPIO_PIN_D10, Pins.GPIO_PIN_D11 });
// Valor de pantalla leido por en entrada analogica sevenSegments.FlickerDelay = 5; // Pausa entra cada letra durante la repeticio en una unidd de LED sevenSegments.UnitSevenSegmentLedDelay = 1; //Duracion de una unida led estando a ON sevenSegments.UnitRepetition = 50; /// Repeticion de todo la tira while (true) { sevenSegments.Show(aInPin.Read()); Debug.Print(aInPin.Read().ToString()); } }
El proceso pesados principal se hace en la clase SevenSegment. Por lo tanto, vamos a echar un vistazo rápido a las diferentes secciones de esta clase.
Sección constructor de la clase SevenSegment
Aquí hemos definido algunas E / S digitales para los segmentos de LED a hasta g. Para soportar cualquier número de unidades LED, los pines asociados a ánodos o al cátodo común son recibidos como una matriz. Ahora, para mostrar una carta o un alfabeto, se ha construido una serie de Boole. Todas estas matrices se almacenan en una tabla hash con una clave que corresponde a un dígito o un alfabeto o un símbolo. Finalmente algunas propiedades se inicializan con algunos valores
public SevenSegments(Cpu.Pin a, Cpu.Pin b, Cpu.Pin c, Cpu.Pin d, Cpu.Pin e, Cpu.Pin f, Cpu.Pin g, Cpu.Pin[] commonAnodeCathodePin) { OutputPort PinD0Out_a = new OutputPort(a, false); OutputPort PinD1Out_b = new OutputPort(b, false); OutputPort PinD2Out_c = new OutputPort(c, false); OutputPort PinD3Out_d = new OutputPort(d, false); OutputPort PinD4Out_e = new OutputPort(e, false); OutputPort PinD5Out_f = new OutputPort(f, false); OutputPort PinD6Out_g = new OutputPort(g, false); segmentPins = new OutputPort[] { PinD0Out_a, PinD1Out_b, PinD2Out_c, PinD3Out_d, PinD4Out_e, PinD5Out_f, PinD6Out_g }; // inicializacion de commonAnodeCathodePin ledSegmentUnit = new OutputPort[commonAnodeCathodePin.Length]; for (int i = 0; i < commonAnodeCathodePin.Length; i++) { ledSegmentUnit[i] = new OutputPort(commonAnodeCathodePin[i], false); } // crear una lista de caracteres soportados ledSegmentTable = new Hashtable(); ledSegmentTable.Add(«0», new bool[] { true, true, true, true, true, true, false }); ledSegmentTable.Add(«1», new bool[] { false, true, true, false, false, false, false }); ledSegmentTable.Add(«2», new bool[] { true, true, false, true, true, false, true }); ledSegmentTable.Add(«3», new bool[] { true, true, true, true, false, false, true }); ledSegmentTable.Add(«4», new bool[] { false, true, true, false, false, true, true }); ledSegmentTable.Add(«5», new bool[] { true, false, true, true, false, true, true }); ledSegmentTable.Add(«6», new bool[] { true, false, true, true, true, true, true }); ledSegmentTable.Add(«7», new bool[] { true, true, true, false, false, false, false }); ledSegmentTable.Add(«8», new bool[] { true, true, true, true, true, true, true }); ledSegmentTable.Add(«9», new bool[] { true, true, true, true, false, true, true }); ledSegmentTable.Add(«a», new bool[] { true, true, true, false, true, true, true }); ledSegmentTable.Add(«b», new bool[] { false, false, true, true, true, true, true }); ledSegmentTable.Add(«c», new bool[] { true, false, false, true, true, true, false }); ledSegmentTable.Add(«d», new bool[] { false, true, true, true, true, false, true }); ledSegmentTable.Add(«e», new bool[] { true, false, false, true, true, true, true }); ledSegmentTable.Add(«f», new bool[] { true, false, false, false, true, true, true }); ledSegmentTable.Add(«g», new bool[] { true, true, true, true, false, true, true }); ; ledSegmentTable.Add(«h», new bool[] { false, false, true, false, true, true, true }); ledSegmentTable.Add(«i», new bool[] { false, true, true, false, false, false, false }); ledSegmentTable.Add(«j», new bool[] { false, true, true, true, true, false, false }); ledSegmentTable.Add(«l», new bool[] { false, false, false, true, true, true, false }); ledSegmentTable.Add(«n», new bool[] { false, false, true, false, true, false, true }); ledSegmentTable.Add(«o», new bool[] { false, false, true, true, true, false, true }); ledSegmentTable.Add(«p», new bool[] { true, true, false, false, true, true, true }); ledSegmentTable.Add(«q», new bool[] { true, true, true, false, false, true, true }); ledSegmentTable.Add(«r», new bool[] { false, false, false, false, true, false, true }); ledSegmentTable.Add(«s», new bool[] { true, false, true, true, false, true, true }); ledSegmentTable.Add(«t», new bool[] { false, false, false, true, true, true, true }); ledSegmentTable.Add(«u», new bool[] { false, false, true, true, true, false, false }); ledSegmentTable.Add(«y», new bool[] { false, true, true, false, false, true, true }); ledSegmentTable.Add(«-«, new bool[] { false, false, false, false, false, false, true }); ledSegmentTable.Add(«?», new bool[] { false, true, true, false, true, true, false }); ledSegmentTable.Add(«?», new bool[] { true, false, false, true, false, false, true }); // Inicializar campos por defecto FlickerDelay = 5; SevenSegmentsUnits = commonAnodeCathodePin.Length; UnitSevenSegmentLedDelay = 0; UnitRepetition = 50; RightToLeft = true; }
Para mostrar un dígito o un signo del alfabeto, vemos un método Show de esta clase. Hay tres sobrecargas de este método Show que vamos a ver a continuación.
El primero toma int como argumento y llama directamente segundo método Mostrar que tiene cadena como argumento. En este método, dependiendo de si RightToLeft se establece en verdadero o falso, y el código salta a la sección correspondiente. Esta sección básicamente extrae la letra correcta para mostrar y luego llama el tercer método Mostrar.
public void Show(string stringToShow) {
// este bucle hará que parezca que todos los leds permanezcan encendidos for (int j = 0; j < UnitRepetition; j++) { if (RightToLeft) { int ledUnit = SevenSegmentsUnits – 1; // indice basados en 0 index for (int i = stringToShow.Length; i > 0; i–) { string eachLetter = stringToShow.Substring(i – 1, 1); Show(eachLetter, ledUnit); ledUnit -= 1; // si longitud de stringToShowes mayor que // SevenSegmentsUnits los restamos if (ledUnit < 0) ledUnit = SevenSegmentsUnits – 1; // – 1 es un indice basado en 0x Thread.Sleep(UnitSevenSegmentLedDelay); } } else { int ledUnit = 0; // indice basado en 0 for (int i = 0; i < stringToShow.Length; i++) { string eachLetter = stringToShow.Substring(i, 1); Show(eachLetter, ledUnit); ledUnit += 1; // Si longitud de stringToShow es mayor //que SevenSegmentsUnits restalo ledUnit = ledUnit % SevenSegmentsUnits; Thread.Sleep(UnitSevenSegmentLedDelay); } } Thread.Sleep(FlickerDelay); } }
El tercer método Mostrar toma dos argumentos, primero es la cadena que se mostrará y segundo es dónde mostrara es decir, en que bumero de display LED. En la HashTable definida durante la construcción, se rellena la matriz correcta de Boole y entonces el pin correspondiente se establece a nivel alta o baja en base a esta matriz booleana. En el paso final, todos los pines asociados al ánodo o al cátodo común se establecen a nivel bajo de modo que sólo el LED apropiado se establece a nivel alto.
public void Show(string numberString, int ledUnit) { bool[] ledSegmentOnOffValues; numberString = numberString.ToLower(); // en este nivel, se admite la longitud de la cadena, por lo que descarta el resto if (numberString.Length > 1) numberString = numberString.Substring(numberString.Length – 1, 1); // Enviar nivel bajo al ánodo / cátodo común de SevelSegmentLED for (int i = 0; i < ledSegmentUnit.Length; i++) { ledSegmentUnit[i].Write(false); } if (!ledSegmentTable.Contains(numberString)) { // cuando se pasas una letra no soportada muestra «-« ledSegmentOnOffValues = (bool[])ledSegmentTable[«-«]; } else { // consigue el array a true/false ledSegmentOnOffValues = (bool[])ledSegmentTable[numberString]; } for (int i = 0; i < segmentPins.Length; i++) { //poner el pin correspondiente a nivel alto segmentPins[i].Write(ledSegmentOnOffValues[i]); } // solamente envia la señal al catodo o anodo seleccionado ledSegmentUnit[ledUnit].Write(true); }
Valores maximos y/o minimos
Con muy pocas líneas de código podemos ampliar o añadir funcionalidades adicionales como un contador que toma cuenta del valor mínimo al valor máximo. Este contador es un ejemplo muy simple que toma dos argumentos, el valor mínimo y el valor máximo. Un bucle for se puede configurar a partir de este minuto a valor máximo y el método Show que se ha llamado de pasar el incremento de bucle de corriente. Este método nos permite mostrar el contador en nuestros siete segmentos unidad LED
public void Counter(int minValue, int maxValue) { for (int i = minValue; i <= maxValue; i++) { Show(i); Debug.Print(i.ToString()); } }
Pruebas finales
Con nuestra clase SevenSegments, tenemos varias salidas. En primer lugar vamos a ver la salida de nuestro circuito. Aquí podemos ver el valor más bajo en nuestra pantalla cuando LDR está cubierto sin embargo el número aumenta a medida que iluminamos nuestro LDR.
Ahora echemos un vistazo a nuestro métodoque hemos añadido a nuestra clase SevenSegments. Con el siguiente código, po rjemplo vamos a ver los números desde 980 a 1020: sevenSegments.FlickerDelay = 5; sevenSegments.UnitSevenSegmentLedDelay = 1; sevenSegments.UnitRepetition = 5; sevenSegments.RightToLeft = true; while (true) { sevenSegments.Counter(980, 1020); }
Vamos a darle una cadena de más de nuestros Siete unidades LED del segmento y ver qué pasa:
sevenSegments.RightToLeft = false; while (true) { sevenSegments.Show(«-Lab»); }
Y para terminar , es el siguiente video podemos ver el código presentado ejecutándose con la electrónica descrita
Los display leds de 7 segmentos ( o mas ) como se puede ver son bastante sencillos de manejar desde Netduino gracias a la multiplexacion como hemso visto en el ejemplo
Debe estar conectado para enviar un comentario.