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

 

 18,919 total views,  3 views today

7Shares
Última modificación: julio 21, 2017

Autor

Comentarios

Escribe una respuesta o comentario

Tu dirección de correo electrónico no será publicada.

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