Tag Archives: ARDUINO 101

RFID Usando RDM6300 y Arduino 101, TinyTILE o ARDUINO UNO

7 Ago , 2017,
Jose Nunez
, , , ,
No Comments

(!) Antes de seguir estas instrucciones asegúrese de entender las Condiciones de Uso de nuestro sitio.

El RDM6300 es un módulo bastante sencillo de utilizar en el entorno de ARDUINO gracias a la librería RDM6300 que se puede descargar de acá.

El módulo tiene tres conectores:

P1 (6 contactos): que contiene los pines para realizar comunicaciones. En este experimento utilizaremos solamente el pin 1 ubicado en la esquina que lo conectaremos al pin 6 del Arduino 101. Básicamente este es el único pin que se conecta al microcontrolador.

P2 (2 contactos) que es donde se conecta la antena (bobina)

P3 (3 contactos) que es donde se alimenta el sistema y donde se pude agregar un LED (todavía no tengo claro para qué exactamente) el punto es que de este solo utilizaremos el pin 2 y 3 que son +5V  y GND respectivamente.

El programa que utilizamos simula la apertura de un sistema mediante un pulso a un LED verde conectado al pin 3 de Arduino, y un pulso para cerrar simulado por un LED amarillo conectado al pin 2 del Arduino.

Algo interesante es que el Arduino 101 opera a 3.3V pero es tolerante a señales de 5V lo cual lo hace particularmente versatil (esto también aplica para TinyTILE. Con Arduino UNO también funciona.

Conexiones:

ARDUINO
PIN  2 ==> amarillo ====> LED Amarillo ===> Resistencia 150 Ohm ==> GND
PIN  3 ==> verde =======> LED Verde ======> Resistencia 150 Ohm ==> GND
PIN  6 <== café <======== PIN 1 del conector P1 del RDM6300 (TX)
PIN 13 ==> naranja =====> LED Verde ======> Resistencia 150 Ohm ==> GND
5V ======> rojo ========> Puerto + del protoboard
GND =====> negro =======> Puerto - del protoboard

RDM6300
PIN 2 del conector P3 (Vin) <===== Puerto + del protoboard (operando a 5V)
PIN 3 del conector P3 (GND) <===== Puerto - del protoboard

PIN 1 del conector P1 (TX) ======> PIN 6 del ARDUINO

Conector P2 =====< ANTENA (bobina)

 

Programa de ejemplo:

La versión oficial de este sketch se puede encontrar acá: https://github.com/janunezc/robotics/tree/master/rfid/rfid_rdm630_open_then_close

(!) También, será necesario que los archivos de la librería RDM6300 estén disponibles para compilar el sketch. Se puede copiar ambos archivos (rdm630.h y rdm630.cpp) en la misma carpeta del sketch, o en la carpeta de librerías del ARDUINO IDE (c:\user\myusername\documents\Arduino\libraries\rdm630\***). Es importante asegurarse que la librería RDM630 solo está copiada una vez en las diferentes rutas.

/*
 * Programa escrito por Jose Nunez como ejemplo didáctico del uso del RDM6300 con un ARDUINO 101.
 * Use bajo su propio riesgo.
 * Ejemplo de dominio público.
 *
*/
#include "rdm630.h"

rdm630 rfid(6, 0);  //TX-pin of RDM630 connected to Arduino pin 6
int led_yellow_close = 2;
int led_green_open = 3;
int led_signal = 13;
long OPEN_PULSE_WIDTH = 800;
long CLOSE_PULSE_WIDTH = 1000;
long OPEN_STATE_DURATION = 5000; 
long CODE_READ_DELAY = 10000;
long codeReadDelayMaxMillis = millis();

void setup()
{
    Serial.begin(115200);  // start serial to PC
    pinMode(led_yellow_close, OUTPUT);
    pinMode(led_green_open, OUTPUT);
    pinMode(led_signal, OUTPUT);
    rfid.begin();
    ledSignal(5,500);
    setMessage("READY!");
}

void loop()
{
  unsigned long rfidTagCode = 0;  
  
  if(rfid.available()){
    setMessage("RFID Data is available! reading it...");
    rfidTagCode = readRFIDCode();
    setMessage("Data: " + String(rfidTagCode));
    if(millis() > codeReadDelayMaxMillis) {
      if(rfidTagCode == 7598635) {
        setMessage("OPEN");
        openPulse();//This involves a closePulse() call inside the openPulse() function.
        codeReadDelayMaxMillis = millis() + CODE_READ_DELAY;
      } else {
        setMessage("I DONT KNOW YOU!");
        closePulse();
      }
    } else {
      setMessage("SkippingNewReads");
      delay(500);
    }   
  }
}

void openPulse(){
  setMessage("SENDING OPEN PULSE");
  digitalWrite(led_green_open, HIGH);
  delay(OPEN_PULSE_WIDTH);
  digitalWrite(led_green_open,LOW);
  setMessage("OPEN PULSE DONE! Waiting for OPEN STATE DURATION...");
  delay(OPEN_STATE_DURATION);
  setMessage("OPEN STATE COMPLETE");
  closePulse();
}

void closePulse(){
  setMessage("SENDING CLOSE PULSE");
  digitalWrite(led_yellow_close, HIGH);
  delay(CLOSE_PULSE_WIDTH);
  digitalWrite(led_yellow_close, LOW);
  setMessage("CLOSE PULSE DONE!");
}

unsigned long readRFIDCode(){
  byte data[6];
  byte length;

  rfid.getData(data,length);
  Serial.println("Data valid");
  for(int i=0;i<length;i++){
      Serial.print(data[i],HEX);
      Serial.print(" ");
  }
  Serial.println();
  //concatenate the bytes in the data array to one long which can be 
  //rendered as a decimal number
  unsigned long result = 
    ((unsigned long int)data[1]<<24) + 
    ((unsigned long int)data[2]<<16) + 
    ((unsigned long int)data[3]<<8) + 
    data[4];              
  Serial.print("decimal CardID: ");
  Serial.println(result);
  return result;  
}

void ledSignal(int times, int milliseconds){
  for(int i=0; i<times; i++){
    digitalWrite(led_signal, HIGH);
    delay(milliseconds);
    digitalWrite(led_signal, LOW);
    delay(milliseconds);
  }
}

void addToMessage(String message){
  setMessage(message, false);
}

void setMessage(String message){
  setMessage(message, true);
}

void setMessage(String message, bool newLine){
  String timeStamp = String(millis());
  String finalMessage = timeStamp + " - " + message;
  if(newLine){
    Serial.println(finalMessage);
  } else {
    Serial.print(message);
  }
}

Acá un ejemplo de la ejecución:

Espero que les sea de utilidad.

Comandos por BLE – (Parte 2 de 2) – El Transmisor (TX)

22 Jul , 2017,
Jose Nunez
, , , , , ,
No Comments

Como lo prometido es deuda, acá está la 2da entrega referente a controlar cosas con telefonos celulares mediante Bluetooth Low Energy (BLE) usando IONIC 3.

En esta segunda parte, implementaremos una App (Android y IOS) usando IONIC 3 que le envía comandos al micro-controlador mediante el sistema BLE del teléfono.

Para ver la Parte 1 haz clic acá

(!) Antes de seguir estas instrucciones asegúrese de entender las Condiciones de Uso de nuestro sitio.

Programando el App

En resumen:

  1. IONIC 3 es un sistema para crear aplicaciones móviles usando tecnologías híbridas (cordova, angularjs 4, typescript, html, css, etc.)
  2. Necesitaremos configurar IONIC3 en nuestro computador; esto incluye NodeJS, NVM, NPM y IONIC.
  3. También necesitaremos un muy buen editor de código para TypeScript. Puedo recomendarles Visual Studio Code o Atom.
  4. Descargamos el código del app de ejemplo de mi repositorio de Github y lo abrimos con el IDE de ARDUINO.git clone https://github.com/janunezc/robotics.gitEl código se ubica en ~/robotics/intel_curie/ble_command_app/
  5. En el celular podemos utilizar el sistema Ionic View (descargado del App Store o Google Play) y previsualizar el app 03B50F88Las siguientes imágenes muestran la operación del app

 

Seguidamente mostramos las partes más importantes del código original del programa con los comentarios detallados sobre su funcionamiento. Es realmente sencillo; podemos resumirlo en:

  1. El tab “SCAN” implementa un proceso básico de búsqueda de dispositivos Bluetooth. No vamos a detallar mucho en este tutorial sobre ese tab.
  2. El tab “LED” implementa la búsqueda de un dispositivo específico y una vez que lo encuentra permite interactuar con el LED para encenderlo y apagarlo.
    1. Los componentes (tabs) de la aplicación IONIC3 se dividen en 3 elementos principales: una vista o view (led.html), un controlador (led.ts) y un modelo que corresponde a los datos que va a manejar la aplicación y que se ubican en el objeto this y sus propiedades públicas.
    2. El archivo led.html es realmente simple. Aparte de los párrafos de texto expicativo y títulos, posee un botón que tiene algunas características importantes de AngularJS como lo son el atributo [disabled] ligado a una variable del modelo denominada “ejecutandoComando”. Cuando la variable tiene un valor verdadero (true) el atributo disabled se activa y el botón se deshabilita. A su vez tiene una directiva (click) que ejecuta la función “Command()” del controlador.
    3. Una parte importante del archivo led.html es el último párrafo en la línea 11. Este utiliza una directiva *ngFor para iterar sobre la variable “messages” y mostrar cada mensaje como un párrafo ( <p> ) individual. Esto nos permite mostrar mensajes de aclaración conforme se ejecutan los procesos en el controlador.
  3. Exploremos ahora el archivo led.ts. Se trata de un script escrito en TypeScript. Un pseudo-lenguaje basado en JavaScript que permite una orientación a objetos más elaborada.
    1. Lo primero que se realiza en led.ts es importar las librerías necesarias. Dos de las más notorias serán BLE y ApplicationRef. La primera permite comunicación BLE, y la segunda permite manipular el framework de Angular para refrescar la pantalla cuando sea necesario.
    2. La siguiente parte super importante es el constructor, el cual implementa una serie de inyecciones de dependencia que vale la pena mencionar.
    3. Nótese la forma en que se inyectan en el constructor tanto la librería BLE como la librería de Angular ApplicationRef. En el constructor también se inicializan variables importantes tales como el ID de servicio y el ID de Característica que se van a manipular.
    4. Las funciones más interesantes en este archivo son:
      1. findDevice() que busca un dispositivo particular y una vez que lo encuentra cambia el modo de comandos para encender o apagar un LED. Para esto usa la funcion de BLE nativo denominada ble.scan()
      2. txData() que utiliza ble.connect y ble.write para conectarse al dispositivo y hacerle llegar un mensaje.
      3. SetMessage() tambien merece ser mecionado como la forma que tenemos de agregar mensajes de control que nos permitan entender cómo se está ejectuando el programa.

Espero que este artículo les sea de utilidad junto con el anterior para aprender a enviar comandos a un dispositivo BLE basado en Intel Curie, mediante el teléfono celular.

Los dejo con estos enlaces de utilidad:

  1. Aprender TypeScript: https://www.typescriptlang.org/docs/home.html
  2. Aprender Ionic 3: https://ionicframework.com/
  3. Aprender Angular 4: https://www.youtube.com/watch?v=kFTmoLm9Jwg

Que estén bien!


led.html

<ion-header>
   <ion-navbar>
   <ion-title>LED</ion-title>
   <p>Acá podemos operar el LED que está implementado en TinyTILE</p>
   <button ion-button [disabled]="ejecutandoComando" (click)="Command()">{{ComandoTXT}}</button>
</ion-navbar>
</ion-header>
<ion-content padding>
   <p>Histórico de Ejecución: ({{myCount}} | {{test}})</p>
   <hr />
   <p *ngFor="let message of messages">{{message}}</p>
</ion-content>

led.ts

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { BLE } from '@ionic-native/ble';
import { ApplicationRef } from '@angular/core';

@Component({
  selector: 'page-led',
  templateUrl: 'led.html'
})

export class LEDPage {

  public messages = []; //Histórico de ejecución
  public ejecutandoComando = false;
  public BLE;
  public ComandoTXT = "";
  public Value = "";
  public TargetDevice;
  private appRef;

  /**
   * CONSTANTES que serán usadas a lo largo del controlador
   */
  public constants  = {
      DEVICE_NAME: "COMANDO LED",
      CMD_FIND_DEVICE:"FIND DEVICE",
      CMD_STOP_SCAN:"Escaneando... (Clic para parar)",
      CMD_TOGGLE_LED:"CAMBIAR LED",
      ON:"ON",
      OFF:"OFF"
    };

  /**
   * Constructor para el controlador. Todo comienza acá...
   */
  constructor(public navCtrl: NavController, private ble: BLE /*Librería BLE nativa*/, private applicationRef : ApplicationRef /*Librería ApplicationRef de Angular*/ ) {
    this.appRef = applicationRef; //Referencia a la aplicación ANGULAR
    this.SetMessage("Constructor: Iniciado!");
    this.BLE = ble; //Acceso a la librería BLE Nativa
    this.ComandoTXT = this.constants.CMD_FIND_DEVICE;
    this.Value = "ON"; //VALOR PARA ENVIAR
    this.TargetDevice = {}; //Dispositivo al cual conectarse. Inicialmente vacío... se llenará cuando se encuentre el dispositivo en el escaneo.
    this['service_id'] = "db938b80-f010-44b6-8aa9-1835adf9419a"; //Identificador del servicio BLE a conectarse
    this['characteristic_id'] = "9906064e-9bbe-4eba-b415-bbd223f7d3d9"; //Identificador de la característica BLE a conectarse
    this.SetMessage("Constructor: Finalizado!");
  }

  /**
   * This is triggered when the button is clicked.
   */
  public Command(){
    this.ejecutandoComando = true;
    this.SetMessage("Command() - Comando recibido!");
    this.SetMessage(this["ComandoTXT"]);
    this.SetMessage("Interpretando comando...");

    if(this['ComandoTXT']===this.constants.CMD_FIND_DEVICE) {
      this.SetMessage("Ejecutando Comando: FIND DEVICE");
      this['ComandoTXT'] = this.constants.CMD_STOP_SCAN;
      this.findDevice();

    } else if (this['ComandoTXT']===this.constants.CMD_STOP_SCAN) {
      this.SetMessage("Ejecutando Comando: STOP SCAN");
      clearInterval(this['intervalHandle']);
      this['ComandoTXT'] = this.constants.CMD_FIND_DEVICE;
      this.ejecutandoComando = false;

    } else if(this['ComandoTXT']=== this.constants.CMD_TOGGLE_LED){
      this.SetMessage("Ejecutando Comando: TOGGLE LED: " + this.Value);
      this.SetMessage("Acá es donde enviamos un valor al dispositivo BLE");
      this.txData();
    }
  }

  /**
   * This searches for DEVICE in the AIR using SCAN technique.
   */
  private findDevice(){
      this.SetMessage("FindDevice() - INICIO!");
      let  ble = this.BLE;

      this.SetMessage("FindDevice() - ENABLE!");
      ble.enable();

      this.SetMessage("FindDevice() - SET INTERVAL!");
      this['intervalHandle'] = setInterval(() => { // PROGRAMAR UN TIMER DE 2.1 SEGUNDOS
        this.SetMessage("INTERVAL: INICIO! LLAMANDO A BLE SCAN...");
        ble.scan([], 2 /*seconds (0) */).subscribe( data => { //REALIZAR SCAN BLE POR 2 SEGUNDOS
          this.SetMessage("BLE SCAN CALLBACK: " + data['id'] + ' | ' + data['name'] + ' | ' + data['rssi']);
          if(data['name']==this.constants.DEVICE_NAME){
            this.SetMessage(this.constants.DEVICE_NAME + " HA SIDO ENCONTRADO!!");
            clearInterval(this["intervalHandle"]);
            this.TargetDevice = data;
            this["ComandoTXT"] = this.constants.CMD_TOGGLE_LED;
            this.ejecutandoComando = false;
          }
          this.appRef.tick();
        });
      },2100);//FIN DE LA DEFINICIÓN DEL TIMER
      this.ejecutandoComando = false;
    }

  /**
   * Transmitir datos al dispositivo BLE
   */
  private txData(){
    this.SetMessage("txData(): INICIO! Llamando a BLE CONNECT...");

    let id = this.TargetDevice.id;
    this.SetMessage("ID DE DISPOSITIVO: " + id);

    this.ble.connect(id).subscribe(datos=>{
      this.SetMessage("BLE CONNECT CALLBACK: INICIO!. Llamando a BLE WRITE..." + this.Value);

      this.ble.write(this.TargetDevice.id, this['service_id'],this['characteristic_id'], this.StringToBytes(this.Value) ).then(()=>{
        this.SetMessage("BLE WRITE CALLBACK: INICIO! Cambiando valor... " + this.Value);
        if(this.Value==this.constants.ON){
          this.Value = this.constants.OFF;
        } else {
          this.Value = this.constants.ON;
        }
        this.SetMessage("Nuevo valor... " + this.Value);

        this.SetMessage("Llamando a BLE DISCONNECT...");
        this.ble.disconnect(id);
        this.ejecutandoComando = false;
        this.appRef.tick();
      },(error)=>{
        this.SetMessage("BLE Write ERROR!");
        this.SetMessage(error);
        this.SetMessage("Llamando a BLE DISCONNECT...");
        this.ble.disconnect(id);
        this.ejecutandoComando = false;
        this.appRef.tick();
      });
    },error=>{
      this.SetMessage("BLE Connect ERROR!");
      this.SetMessage(error.message);
      this.ejecutandoComando = false;
      this.appRef.tick();
    });
  }

  /**
   * Agrega mensajes de ejecución al histórico
   */
  public SetMessage(message){
    var count = this['messages'].length;
    message = count + ':' + message;
    this['messages'].unshift(message);

    /*
      ESTA LINEA ES IMPORTANTE PARA REFRESCAR LA PANTALLA CUANDO SE GENERAN EVENTOS
      FUERA DEL CONTROL DE ANGULAR. POR EJEMPLO CUANDO SE LLAMA A UN CALLBACK EN
      UN PROCESO DE BLE SCAN.
    */
    this.appRef.tick();
  }

  // ASCII only. Convierte el valor a escribir a un arreglo de BYTES
  public StringToBytes(string) {
     let array = new Uint8Array(string.length);
     for (let i = 0, l = string.length; i < l; i++) {
         array[i] = string.charCodeAt(i);
      }
      return array.buffer;
  }

  // ASCII only
  public BytesToString(buffer) {
      return String.fromCharCode.apply(null, new Uint8Array(buffer));
  }
}

Robot de dos llantas + acelerómetro/giroscópio > Una experiencia de Aprendizaje

13 Ene , 2017,
Jean Paul Jimenez
, , , , , , , , , , ,
No Comments

robot-willieResumen

Les confieso que esta es mi primera publicación; por pura insistencia de mi editor estamos acá escribiendo. En esta primera entrada discutiremos mi experiencia en Intel en la investigación de cómo programar un robot de dos ruedas mediante diversos micro-c0ntroladores, incluyendo el S4A-EDU, Arduino UNO, Aruduino 101 y Sparkfun Thing.

Detalle

A principios de este año 2017. tuve la bendición de poder pasar unos días en Intel en una experiencia “ad-hoc” de aprendizaje de tecnología, investiación, desarrollo, auspiciada por el Centro de Innovación de Intel y por José Núñez.

En esta experiencia pudimos explorar las diferentes reacciones que que tenia el robot cuando instalábamos diferentes programas (en ARDUINO IDE) con  diferente controladores para realizar rutinas como por ejemplo: movilidad hacia adelante y atrás, movimientos con giros con duración específica y también pudimos ver funcionar el acelerometro y giroscópio del chip Intel Curie.

En el fondo nos concentramos en tratar de entender cómo hacer que se mueva el robot (descrito acá) en distintas direcciones y cómo hacer que este pueda tener un movimiento rectilineo preciso, controlado utilizando el giroscopipo disponible en el Intel Curie.

Experiencia con el Acelerómetro de Intel Curie

Comenzamos aprendiendo sobre las diferentes funciones del Intel Curie. Para esto realizamos diversos experimentos descritos en este artículo de Jose Nunez acá en CostaRicaMakers.com.

La verdad me resultó sencillo de utilizar y muy útil para aprender a hacer las lecturas de los diferentes sensores (acelerómetro y giroscópio) y la utilización de las funciones de Blue Tooth Low Energy (BLE)

Experiencia con el Robot de dos llantas y el controlador S4-EDU

La verdad es que comencé con esta experiencia con altas expectativas de lo que podría aprender y hacer. Al principio el primer problema que enfrenté fue aprender un poco de programación, creo que tengo un largo camino por recorrer en esta área.

El robot en sí permite realizar movimientos de manera muy versatil gracias a su sistema de dos llantas independientes sobre las que podemos controlar dirección individual y velocidad.

Como mencioné antes fuimos probando diversos controladores, comenzando por el original del kit del robot (el S4A-EDU) que cuenta con un circuito muy interesante denominado “Puente H” (H-Bridge) que nos permite controlar la dirección y velocidad de los motores.

Una vez que pudimos hacerlo moverse usando el controlador original (S4A-EDU) nos dimos a la tarea de reemplazar dicho controlador (parcialmente) con un ARDUINO101 que como dijimos tiene sensores de movimiento (acelerómetro y giroscopio). Para esto pudimos facilmente desconectar el puente H del S4A-EDU y conectarlo al ARDUINO 101.

Como dije antes, el principal reto que enfrentamos fue la programación. Realizamos diferentes tipos de programa usando el ambiente integrado de desarrollo (IDE) de ARDUINO.

Una vez controlado por el ARDUINO 101 para realizar los movimientos básicos, el siguiente reto era comenzar a utilizar el giroscopio para leer cuanto se desviaba hacia un lado u otro el robot al caminar en una misma dirección. Para poder extraer los datos (que son muchos) de las lecturas del giroscopio, tratamos inicialmente de subirlos por WiFi a un servidor en Internet. Pare este fin introducimos un controlador más: el SPARKFUN THING.

La programación del SPARKFUN THING es algo “truculenta” ya que requiere una interfase serial para conectar la laptop donde uno escribe el programa y subirla al micro-controlador. Intentamos con un cable tipo FTDI, pero no tuvimos suerte. En resumen no funcionó por que el cable que teníamos no cuenta con línea DTR… (eso me queda pendiente de entenderlo mejor). Al día siguiente conseguimos otra interfase denomiada “FOCA V1.2” la cual permite comunicación serial con diversas opciones, con y sin línea DTR, a diferentes voltajes (3V, 5V) etc.

Ahora bien, subir datos por via WiFi a un servidor en Internet, el tiempo minimo que toma son 3 o 4 segundos… y el giroscopio generaba datos cada 200ms o menos… o sea, no nos servía la opción del WiFi… fue entonces cuando decidimos cambiar la solución. En vez de guardar los datos en Internet nos avocamos a graficarlos en mi celular usando una conexion Bluetooth Low Energy (del ARUDINO 101). Para esto fue necesario instalar una app en mi celular denominada nRF Toolbox descrita en el artículo mencionado sobre ARDUINO 101.

En este punto logramos que el robot se moviera en una misma dirección durante dos segundos y graficar durante ese tiempo las lecturas del giroscópio cada 200ms.

Control de Velocidad

Aprendí que la velocidad del robot se puede controlar mediante un método que se llama PWM (Pulse Width Modulation) y la idea es utilizar ese principio para ajustar la velocidad de cada rueda para compensar micro-desviaciones del movimiento rectilineo que queriamos lograr. Desafortunadamente no nos dio tiempo de implementar esa parte correctiva.

Conceptos Relacionados

Quiero listar acá algiunos conceptos que me parece importante profundizar en el futuro para mi propio aprendizaje en el área de robótica, tecnología y mecatrónica:

  • Variables y Constantes
  • Funciones y Métodos
  • Pasos e Instrucciones
  • Condicionales
  • Vibración
  • Frecuencia
  • Ancho de Pulso
  • Voltaje
  • Corriente/Amperaje

Agradecimientos

Quiero agradecer a el Señor Jose Núñez por permitirme esta oportunidad de estar en Intel aprendiendo mediante estos experimentos. Sinceramente me ha servido de mucho, tanto para mis estudios como para mi futuro.

Arduino 101 – Tutorial

2 Abr , 2016,
Jose Nunez
, , , , , , ,
No Comments

Bienvenido al tutorial introductorio de la placa Arduino 101; sin duda una tarjeta especial para aprender y para prototipar usando conceptos de movimiento (aceleración, rotación) y sistemas de comunicación de red de área personal (PAN) para el desarrollo de ideas de tecnología vestible.

Al momento de escribir este tutorial, el Arduino 101 tenia un costo de $30, mientras que el Arduino UNO convencional un costo de $25.


(!) Antes de seguir estas instrucciones asegúrese de entender las Condiciones de Uso de nuestro sitio.


Contenido:

  1. ¿Qué es el Arduino 101 y qué es Intel Curie?
  2. Ejercicios:
    1. Acelerómetro y Giroscopio
    2. Acelerómetro y BLE: Contador de Pasos
    3. Bluetooth Low Energy (BLE): Monitor de Batería
    4. RTC / EEPROM
  3. ¿Dónde encontrar más información?

¿Qué es un Arduino 101 y qué es un Intel Curie?

El Arduino 101 es una de las más recientes creaciones de la familia de placas Arduino. Es una placa para prototipado y aprendizaje que implementa el nuevo chip SoC (Sistema en un solo chip) de Intel denominado Intel Curie(r)

¿Intel Curie?

Se trata del sistema en un solo chip más reciente de Intel, orientado al “mercado maker” que tiene como objetivo traer mayores capacidades computacionales y de sensado y comunicación al mundo maker y el mercado de la computación vestible y embebida.

Dentro de las especificaciones y funcionalidades de Intel Curie encontramos:

  • Voltaje de operación de 3.3V
  • Memoria Flash (no volatil) de 384Kb
  • Memoria SRAM (volatil) de 80Kb
  • Sistema on-chip QUARK-SE
  • Capacidad de comunicación Bluetooth Low Energy (BLE)
  • Combo integrado de sensores: acelerómetro + giroscópio 6 ejes.

Al implementar Intel Curie, el Arduino 101 presenta las siguientes ventajas comparativas con respecto del Arduino UNO

  • 196 Kb de memoria no volatil (flash). 6 veces más memoria que el Arduino UNO que trae 32Kb.
  • 24 Kb de memoria volatil (SRAM). 12 veces más memoria que el Arduino UNO que trae 2Kb.
  • 32MHz de velocidad de reloj; lo que representa el doble de los 16MHz del Arduino UNO
  • Alimentación (barril) de 7-12V
  • Sistema Operativo de Tiempo Real (RTOS) instalado en el Curie
  • Reloj de tiempo real (RTC)
  • Corriente por pin: 20mA
  • Sensores de Movimiento de 6 ejes: Acelerómetro (x,y,z) y giroscopio (roll, jaw, pitch)

La siguiente imagen ilustra los 6 ejes de movimiento sensables:

ejes_acc_gyro

Figura 1 – Ejes detectables de movimiento.


EJERCICIOS

En estos cuatro ejercicios exploraremos las diferentes funciones del Arduino 101, en lo referente a sensores de movimiento, comunicación Bluetooth BLE y uso de la memoria no volatil del sistema.

Para todos los ejercicios utilizaremos este programa base:

/*
 Copyright (c) 2015 Intel Corporation. All rights reserved.

 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 2.1 of the License, or (at your option) any later version.

 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

 Modified by Jose Nunez @ intel corporation on April 2 2016

 https://www.arduino.cc/en/Tutorial/Genuino101CurieBLEHeartRateMonitor
 
*/

/*
 This sketch example demonstrates how the BMI160 on the
 Intel(R) Curie(TM) module can be used to read accelerometer data
*/

#include "CurieIMU.h"
#include <CurieBLE.h>

int EXERCISE = 1;


/****************** BLE HEARTRATE GLOBALS **************************/
BLEPeripheral blePeripheral; // BLE Peripheral Device (the board you're programming)
BLEService heartRateService("180D"); // BLE Heart Rate Service

// BLE Heart Rate Measurement Characteristic"
BLECharacteristic heartRateChar("2A37", // standard 16-bit characteristic UUID
 BLERead | BLENotify, 2); // remote clients will be able to get notifications if this characteristic changes
 // the characteristic is 2 bytes long as the first field needs to be "Flags" as per BLE specifications
 // https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml

int oldHeartRate = 0; // last heart rate reading from analog input
long previousMillis = 0; // last time the heart rate was checked, in ms
/****************** END OF BLE HEARTRATE GLOBALS **************************/

void setup() {
 delay(3000);
 Serial.begin(9600); // initialize Serial communication
 pinMode(13, OUTPUT); // initialize the LED on pin 13 to indicate when a central is connected
 while (!Serial); // wait for the serial port to open
 Serial.println("SETUP...");
 // initialize device
 Serial.println("Initializing IMU device...");
 CurieIMU.begin();

 // Set the accelerometer range to 2G
 CurieIMU.setAccelerometerRange(2);

/****************** BLE HEARTRATE SETUP **************************/
 /* Set a local name for the BLE device
 This name will appear in advertising packets
 and can be used by remote devices to identify this BLE device
 The name can be changed but maybe be truncated based on space left in advertisement packet */
 blePeripheral.setLocalName("HeartRateSketch");
 blePeripheral.setAdvertisedServiceUuid(heartRateService.uuid()); // add the service UUID
 blePeripheral.addAttribute(heartRateService); // Add the BLE Heart Rate service
 blePeripheral.addAttribute(heartRateChar); // add the Heart Rate Measurement characteristic

 /* Now activate the BLE device. It will start continuously transmitting BLE
 advertising packets and will be visible to remote BLE central devices
 until it receives a new connection */
 blePeripheral.begin();
 Serial.println("Bluetooth device active, waiting for connections...");
/****************** END OF BLE HEARTRATE SETUP **************************/

 Serial.println("SETUP COMPLETE");
 
}

void loop() {
 switch(EXERCISE){
 case 1: 
 readAndReportAccelerometer();
 break;
 case 2:
 readAndReportGyroscope();
 break;
 case 3:
 monitorHeartRate();
 break;
 }
}

float pax, pay, paz, dax, dayy, daz;
void readAndReportAccelerometer(){
 int axRaw, ayRaw, azRaw; // raw accelerometer values
 float ax, ay, az;

 // read raw accelerometer measurements from device
 CurieIMU.readAccelerometer(axRaw, ayRaw, azRaw);

 // convert the raw accelerometer data to G's
 ax = convertRawAcceleration(axRaw);
 ay = convertRawAcceleration(ayRaw);
 az = convertRawAcceleration(azRaw);

 dax = abs(ax-pax);
 dayy = abs(ay-pay);
 daz = abs(az-paz);
 
 if(dax>0.02 || dayy>0.02 || daz>0.02){

 // display tab-separated accelerometer x/y/z values
 Serial.print("a:\t");
 Serial.print(ax);
 Serial.print("\t");
 Serial.print(ay);
 Serial.print("\t");
 Serial.print(az);
 Serial.println();

 pax = ax;
 pay = ay;
 paz = az;
 } 
}

float prev_gx, prev_gy, prev_gz, diff_gx, diff_gy, diff_gz;
float relevancyTrigger = 0.3;
void readAndReportGyroscope() {
 int gxRaw, gyRaw, gzRaw; // raw gyro values
 float gx, gy, gz;

 // read raw gyro measurements from device
 CurieIMU.readGyro(gxRaw, gyRaw, gzRaw);

 // convert the raw gyro data to degrees/second
 gx = convertRawGyro(gxRaw);
 gy = convertRawGyro(gyRaw);
 gz = convertRawGyro(gzRaw);

 diff_gx = abs(prev_gx-gx);
 diff_gy = abs(prev_gy-gy);
 diff_gz = abs(prev_gz-gz);

 if(diff_gx>relevancyTrigger || diff_gy>relevancyTrigger || diff_gz>relevancyTrigger){

 // display tab-separated gyro x/y/z values
 Serial.print("g: \t");
 Serial.print(gx);
 Serial.print("\t");
 Serial.print(gy);
 Serial.print("\t");
 Serial.print(gz);
 Serial.println( "");

 prev_gx = gx;
 prev_gy = gy;
 prev_gz = gz;
 }

}

void monitorHeartRate(){
 // listen for BLE peripherals to connect:
 BLECentral central = blePeripheral.central();

 // if a central is connected to peripheral:
 if (central) {
 Serial.print("Connected to central: ");
 // print the central's MAC address:
 Serial.println(central.address());
 // turn on the LED to indicate the connection:
 digitalWrite(13, HIGH);

 // check the heart rate measurement every 200ms
 // as long as the central is still connected:
 while (central.connected()) {
 long currentMillis = millis();
 // if 200ms have passed, check the heart rate measurement:
 if (currentMillis - previousMillis >= 200) {
 previousMillis = currentMillis;
 updateHeartRate();
 }
 }
 // when the central disconnects, turn off the LED:
 digitalWrite(13, LOW);
 Serial.print("Disconnected from central: ");
 Serial.println(central.address());
 }
}

void updateHeartRate() {
 /* Read the current voltage level on the A0 analog input pin.
 This is used here to simulate the heart rate's measurement.
 */
 int heartRateMeasurement = analogRead(A0);
 int heartRate = map(heartRateMeasurement, 0, 1023, 0, 100);
 if (heartRate != oldHeartRate) { // if the heart rate has changed
 Serial.print("Heart Rate is now: "); // print it
 Serial.println(heartRate);
 const unsigned char heartRateCharArray[2] = { 0, (char)heartRate };
 heartRateChar.setValue(heartRateCharArray, 2); // and update the heart rate measurement characteristic
 oldHeartRate = heartRate; // save the level for next comparison
 }
}

float convertRawAcceleration(int aRaw) {
 // since we are using 2G range
 // -2g maps to a raw value of -32768
 // +2g maps to a raw value of 32767
 
 float a = (aRaw * 2.0) / 32768.0;

 return a;
}

float convertRawGyro(int gRaw) {
 // since we are using 250 degrees/seconds range
 // -250 maps to a raw value of -32768
 // +250 maps to a raw value of 32767
 
 float g = (gRaw * 250.0) / 32768.0;

 return g;
}

 

EJERCICIOS #1 y 2 – ACELERÓMETRO Y GIROSCOPIO

En este ejercicio realizaremos lecturas del acelerómetro y del giroscopio y mostraremos el resultado en el monitor serial.

A su vez, implementamos una lógica de detección de cambios relevantes que nos permitirá observar con mayor claridad los cambios ocurridos en las medidas de los sensores.

PASO 1 – Cargue el programa del tutorial en su Arduino 101

PASO 2 – Utilizando la Figura 1 como guía, verifique en el Monitor Serial del IDE ARDUINO si los ejes mencionados son correctos para el acelerómetro (x,y,z)

PASO 3 – Modifique el programa, comentando la línea 32 para darle el valor de 2 a la variable EXERCISE.

ex02

PASO 4 – Cargue el programa modificado al Arduino 101 y verifique  los ejes de giro tal y como se ilustran en la Figura 1

PASO 5 – Preste atención a las líneas de la 110 a la 114; esta es la lógica de detección de cambios relevantes. Trate de explicarla.

110-114

PASO 6 – Ahora preste atención a las líneas de la 145 a la 149, es una implementación más limpia / autoexplicable de la lógica de detección de cambios relevantes. Trate de explicarla.

145-149

PASO 7 – Reto: Modifique la lógica de detección de  cambios relevantes para que detecte cualquier cambio.


EJERCICIO #3 – SIMULACION DE BLE HEARTBEAT SERVICE

En este ejercicio vamos a utilizar la comunicación Bluetooth/BLE para simular un mecanismo de detección de ritmo cardiaco y graficarlo en el celular.

Para esto necesitaremos un celular con capacidad BLE. En este descargaremos una aplicación llamada “nRF Toolbox” la cual hace una implementación de varios esquemas de servicio BLE. Utilizaremos entonces el servicio “HRM” (Heart Rate Monitor) para graficar datos provenientes del Arduino 101.

PASO 1 – Instale nRF Toolbox en su celular

PASO 2 – Re-configure el sketch base de este tutorial para ejecutar el ejercicio 3. En la línea 32 modifique la variable EXERCISE para que tenga un valor de 3.

arduino101_ex3

 

PASO 3 – Descargue el programa hacia la placa Arduino 101

PASO 4 – Abra el Monitor Serial (SHIFT + CTRL + M)

PASO 5 – En su celular, abra la aplicación “nRF Toolbox” y abra el servicio HRM. Allí pulse el botón “Connect” y elija “HeartRateSketch”

4 screens

PASO 6 – Observe cómo se grafican los datos

PASO 7 – Explicación

Esta simulación toma el valor de uno de los puertos analógicos del Arduino 101 (A0) y envia los datos a través de un servicio BLE estandard de tipo “Heart Rate Service”. Si se deja el pin A0 de la placa sin conexion, este tendrá valores “aleatorios” que serán graficados igual.

 


Recursos Adicionales

https://www.arduino.cc/en/Guide/Arduino101

http://www.intel.com/content/www/us/en/wearables/wearable-soc.html

 

Un Vistazo al ARDUINO 101 / GENUINO 101

23 Feb , 2016,
José Núñez
, , , ,
No Comments

Desde hace más de un año Intel Corp se ha estado esfor101zando para traer productos compatibles con ARDUINO, basasdos en su arquitectura x86 al mundo Maker. Fue así como vimos la llegada de Intel Galileo, Intel Galileo GEN2 e Intel Edison.

Este año nos trae un nuevo miembro de la familia Intel: El Intel Curie que es la base para la nueva tarjeta de prototipado Arduino/Genuino llamada el ARDUINO 101.


En Resumen:

Pros: Mayor poder computacional, sensores adicionales de movimiento y comunicación BLE a un bajo costo y bajo consumo eléctrico. Perfecto para… ¿drones? Flexibilidad en el GPIO para 3.3V y 5V.

Cons: Solución de prototipado no aprovecha las capacidades para computación vestible del Intel Curie.


En Detalle:

Curie es la nueva solución SoC x86 (System on Chip) de Intel para computación vestible. Está orientado a aplicaciones que necesiten una capacidad computacional superior y que sean de bajo consumo eléctrico, para prototipado de soluciones embebidas y vestibles. Trae integrado comunicación Bluetooth BLE así como giroscopio de 6 ejes y acelerómetro.

El Arduino 101 es la primera tarjeta de prototipado lanzada por ARDUINO con Intel Curie dentro.

El precio actual varía. Lo hemos visto disponible en Amazon a $35 así como en Mouser.com a $30. Al parecer su venta aun está restringida a los Estados Unidos.

Dentro de las principales características podemos resaltar:

  1. Voltage de operacion de I/O de 3.3V (tolera 5V)
  2. Dos núcleos de procesamiento: un x86 Quark Curie y un ARC de 32Bits
  3. Voltaje Recomendado de Alimentación: 7V – 12 V
  4. Voltaje Máximo de Alimentación: 7V-20V
  5. Pines Digitales I/O: 14 de los cuales 4 son PWM
  6. Pines Analógicos de Entrada: 6
  7. Corriente DC por Pin: 20mA
  8. Memoria Flash: 196Kb for sketches out of 384Kb total.
  9. Memoria SRAM: 24Kb for sketches out of 80Kb total.
  10. Velocidad de Reloj: 32MHz
  11. Funciones Integradas:
    1. Bluetooth BLE
    2. Acelerómetro/Giroscopio de 6 ejes
    3. Dimensiones: 68.6mm x 53.4mm

Pronto estarems evaluando este dispositivo en la práctica.

Fuentes:

  1. Intel Curie Fact Sheet
  2. Arduino 101 Spec @ Arduino.CC