Plataforma de sensores e-Health V1.0 para Arduino y Raspberry Pi [aplicaciones biométricas / medicina]


En agosto de 2013 Cooking Hacks lanzó la nueva versión del primer escudo biométrica para Arduino y Raspberry Pi: la plataforma  e-Health Sensor. Gracias a la retroalimentación de la comunidad y varios proyectos que han sido creados con esta, han mejorado la plataforma de e-Health con nuevas características tales como:

  • Nuevo sensor de músculo
  • Sensor de presión de la sangre nueva
  • Glucómetro actualizado
  • Nuevas posibilidades de conexión

En este post  vamos a explicar cómo trabajar cplataforma  e-Health Sensor.V2.0.

E-Health Sensor Shield V2.0 permite a los usuarios de Arduino y Raspberry Pi realizar aplicaciones biométricas y médicas donde la supervisión del cuerpo sea necesaria mediante el uso de 10 sensores diferentes: pulso, oxígeno en sangre (SPO2), flujo de aire (respiración), temperatura corporal, Electrocardiograma (ECG), glucómetro, respuesta galvánica de la piel (GSR – sudoración), presión arterial (esfigmomanómetro), posición del paciente (acelerómetro) y sensor de músculo/eletromyography (EMG).

Esta información puede utilizarse para monitorizar en tiempo real el estado de un paciente o para obtener datos sensibles para ser analizados posteriormente para el diagnóstico médico. La información biométrica obtenida puede enviarse sin cables usando cualquiera de las 6 opciones de conectividad: Wi-Fi, 3 G, GPRS, Bluetooth, 802.15.4 y ZigBee dependiendo de la aplicación.

Si para  el diagnóstico de la imagen en tiempo real es necesaria una cámara puede conectarse el módulo 3G para enviar fotos y videos del paciente a un centro de diagnóstico médico.

Los datos pueden enviarse a la nube para almacenamiento permanente o visualizarlos en tiempo real enviando los datos directamente a un ordenador portátil o Smartphone. También  hay desarrollado  varias aplicaciones iPhone y Android  para poder ver fácilmente la información del paciente.

La privacidad es uno de los puntos clave en este tipo de aplicaciones. Por esta razón, la plataforma incluye varios niveles de seguridad:

    • En la capa de enlace de comunicación: AES 128 para 802.14.5 / ZigBee y WPA2 para Wifi.
    • En la capa de aplicación: mediante el protocolo HTTPS (seguro) nos aseguramos de un túnel de seguridad de punto a punto entre cada nodo de sensor y el servidor web (este es el mismo método utilizado en las transferencias bancarias).

e-Health protector del Sensor sobre Arduino (izquierda) frambuesa Pi (derecha)

Importante: La plataforma de e-Health Sensor ha sido diseñada por Cooking Hacks (la división de hardware abierto de Libelium) para ayudar a los investigadores, desarrolladores y artistas para medir datos de sensor biométrico para fines de experimentación, diversión y prueba proporcionando una alternativa barata y abierta en comparación con las soluciones propietarias  debido al precio prohibitivo de llas profesionales usadas por el  mercado médico. Precisamente por esta razon, como la plataforma no tiene certificaciones médicas no puede  ser utilizada para monitorizar pacientes críticos que necesitan un control médico preciso o aquellos cuyas condiciones deben medirse con precisión para un diagnóstico profesional ulterior.
Gracias a la comunidad Arduino y Raspberry  Pi ,es  posible  una rápida prueba de concepto y servir de  base de una nueva era de productos médicos de código abierto.

El paquete que vamos a utilizar en este tutorial se basa en la plataforma de Sensor de eHealth de Cooking Hacks. La E-Health protector del Sensor es totalmente compatible con las nuevas y viejas versiones de Arduino USB, Duemilanove y Mega y Rsapberry.

  • 8 sensores médicos no invasiva + 1 invasoras
  • Almacenamiento y uso de las mediciones de glucosa.
  • Monitoreo de señales ECG.
  • Señales de monitorización EMG.
  • Control de flujo de aire del paciente.
  • Control de flujo de aire del paciente.
  • Datos de la temperatura del cuerpo.
  • Medidas de respuesta galvánica de la piel.
  • Detección de la posición del cuerpo.
  • Funciones de pulso y oxígeno.
  • Dispositivo de control de la presión arterial.
  • Múltiples sistemas de visualización de datos.
  • Compatible con todos dispositivos UART.

Características eléctricas:

La placa puede ser alimentada por el PC o por una fuente externa. Algunos de los puertos USB en los ordenadores no son capaces de dar toda la corriente para que el módulo pueda  trabajar, si el módulo tiene problemas cuando funcione, se puede utilizar una fuente externa (12V – 2A) en el Arduino/RasberryPi

El escudo

 

Escudo de e-Health sobre Raspberry Pi

Para conectar el protector del Sensor e-Health para Raspberry Pi es necesario un  adaptador que haga de puente de conexión .

La idea detrás del  puente de conexión Arduino shields es permitir utilizar cualquiera de los escudos, placas y módulos diseñados para Arduino en Raspberry Pi. También incluye la posibilidad de conectar sensores analógicos y digitales, utilizando el mismo pinout de Arduino pero con la potencia y capacidades de Raspberry Pi

La conexión puente es compatible con Raspberry Pi, Raspberry Pi (modelo B +), Raspberry Pi 2 y el Raspberry Pi 3.

Para hacer completa la compatibilidad han creado la biblioteca de arduPi que permite el uso de frambuesa con el mismo código utilizado en Arduino. Para ello, han implementado funciones de conversión de modo que usted puede controlar de la misma manera como en Arduino la entrada-salida interfaces: i2C, SPI, UART, analógica, digital, en Raspberry Pi.

Vamos a resumir lo que podemos hacer con este escudo junto con la biblioteca de arduPi:

ADVERTENCIAS:

  • Los módulos LCD, esfigmomanómetro y comunicación utilizan el puerto UART y no pueden trabajar al mismo tiempo.
  • El glucómetro es ahora compatible con otros dispositivos UART y tiene su propio conector. Pero no puede trabajar con el esfigmomanómetro conectado.
  • El sensor de EMG y el ECG no pueden trabajar al mismo tiempo. Utilizar los puentes integrados en el tablero para utilizar uno u otro
  • Para utilizar el sensor de EMG, usted tiene que tener los puentes en la posición de EMG. Para utilizar el sensor de ECG, usted tiene que tener los puentes en la configuración de ECG.

El escudo

Versión 2 del escudo:

  • Esta versión incluye un conmutador Digital para activar/desactivar la toma de corriente para módulos inalámbricos usando GPIO23 (Digital Pin 3).

Versión 1 del escudo:

  • 8 pines digitales.
  • Conector para módulos inalámbricos.
  • Pernos de RX/TX.
  • pasadores de i2C (SDA, SCL).
  • Pasadores de SPI (SCK MISO, MOSI, CS). Puede utilizarse también como GPIO.
  • 8 canales convertidor analógico a digital.
  • Interruptor para activar la fuente de alimentación externa.

 La biblioteca: arduPi

arduPi es una librería C++ que permite escribir programas para Raspberry Pi como si estuvieras escribiendo un programa de arduino. Todas las funciones para el control de comunicaciones del puerto serie, i2C, SPI y GPIO pins están disponibles mediante la sintaxis de arduino.

arduPi ha sido probado en una distribución Raspbian. Para grabar una imagen de Raspbian a la tarjeta SD se pueden descargar los NOOBS aquí y siga estas instrucciones.

Una vez instalado Raspbian, descargue e instale arduPi biblioteca en una carpeta nueva, por ejemplo: «página de inicio/pi/ardupi»

Para Rasberry Pi:

wget http://www.cooking-hacks.com/media/cooking/images/documentation/raspberry_arduino_shield/raspberrypi.zip && unzip raspberrypi.zip && cd cooking/arduPi && chmod +x install_arduPi && ./install_arduPi && rm install_arduPi && cd ../..
Para Raspberry Pi 2 y 3:
wget http://www.cooking-hacks.com/media/cooking/images/documentation/raspberry_arduino_shield/raspberrypi2.zip && unzip raspberrypi2.zip && cd cooking/arduPi && chmod +x install_arduPi && ./install_arduPi && rm install_arduPi && cd ../..

Descargar arduPi biblioteca para Raspberry Pi

Descargar biblioteca de arduPi de frambuesa Pi 2 y 3

Usted puede encontrar una biblioteca de cambios aquí.

Funciones generales de Arduino:

  • Delay()
  • delayMicroseconds()
  • Millis()
  • pinMode()
  • digitalWrite()
  • digitalRead()
  • analogRead() (en pines de A0 a A7. Ejemplo: analogRead(5) leerá A5)
  • shiftIn()
  • shiftOut()
  • attachInterrupt() *
  • detachInterrupt()

[*] Podemos detectar interrumpe el ascenso y descenso. Cualquier pin digital (de 2 a 13) puede ser utilizado en attachInterrupt(). Por ejemplo, si queremos estar al tanto de eventos de levantamiento en el pin 6 que podemos hacer attachInterrupt(6,function_to_call,RISING).

Biblioteca  serie:

  • available()
  • begin()
  • end()
  • Flush()
  • Peek()
  • Print()
  • println()
  • Read()
  • readBytes()
  • readBytesUntil()
  • Find()
  • findUntil()
  • parseInt()
  • parseFloat()
  • setTimeout()
  • Write()

Biblioteca wire:

  • begin()
  • requestFrom()
  • beginTransmission()
  • endTransmission()
  • Write()
  • Read()

Biblioteca SPI:

  • begin()
  • end()
  • setBitOrder()
  • setClockDivider()
  • setDataMode()
  • Transfer()

Uso de la biblioteca arduPi:

En la carpeta de biblioteca encontrarás 3 archivos: arduPi.cpp, arduPi.h y arduPi_template.cpp
el archivo arduPi_template.cpp está destinado a ser utilizado como punto de partida para crear programas con el mismo comportamiento como un programa de arduino.

Aquí puede ver el código de plantilla:

//Include arduPi library
    #include "arduPi.h"

    /*********************************************************
     *  IF YOUR ARDUINO CODE HAS OTHER FUNCTIONS APART FROM  *
     *  setup() AND loop() YOU MUST DECLARE THEM HERE        *
     * *******************************************************/

    /**************************
     * YOUR ARDUINO CODE HERE *
     * ************************/

    int main (){
        setup();
        while(1){
            loop();
        }
        return (0);
    }

Como se puede ver en la función main() la función setup() es llamada una vez y luego la función loop() se llama contínuamente hasta que el programa se ve obligado a terminar.

Ya sea si están empezando a escribir un nuevo programa, o si usted tiene un programa de arduino escrito que utiliza las funciones portadas puede utilizar la plantilla (ardupi_template.cpp) y poner el código de arduino donde dice: el código de ARDUINO aquí. Recuerde que el programa que está escribiendo un programa C++ para que todas las bibliotecas de C++ pueden utilizarse.

También recordar, como se puede leer en la plantilla que si el código de arduino utiliza otras funciones setup() y loop() debe declararlos en el área indicada.

 Habilitación de Interfaces:

Los siguientes pasos han sido probados con Raspbian Jessie: 4.4.9 (Linux versión 4.4.9-v7+ (dc4@dc4-XPS13-9333) (gcc versión 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #884 SMP el viernes 6 de mayo 17:28:59 BST 2016)

Raspberry Pi 2:

  • Abrir un terminal en la Raspberry Pi, o conecte al Raspberry Pi a través de SSH.
  • Abra el archivo /boot/config.txt: sudo nano /boot/config.txt
  • Agregue las líneas siguientes al archivo:
#enable uart interface
enable_uart=1

#enable spi interface
dtparam=spi=on

#enable i2c interface
dtparam=i2c_arm=on
  • Presione CTRL + X para salir y guardar el archivo.
  • Actualizar el sistema operativo con los últimos parches.
sudo apt-get update
sudo apt-get upgrade
  • Reiniciar la Raspberry Pi.
sudo reboot

Raspberry Pi 3:

  • Abrir un terminal en la Raspberry Pi, o conecte al Raspberry Pi a través de SSH.
  • Abra el /boot/config.txt archivo <:sudo nano /boot/config.txt
  • Agregue las líneas siguientes al archivo:
#map mini-UART to internal bluetooth an free-up main UART to handle CookingHacks modules
dtoverlay=pi3-miniuart-bt

#enable uart interface
enable_uart=1

#enable spi interface
dtparam=spi=on

#enable i2c interface
dtparam=i2c_arm=on
  •  Presione CTRL + X para salir y guardar el archivo.
  • Abra el archivo /boot/cmdline.txt:sudo nano /boot/cmdline.txt
  • Este archivo contiene algo similar a esto (el contenido puede variar):
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
  • Eliminar los parámetros que hacen referencia al puerto serie UART (ttyAMA0):
dwc_otg.lpm_enable=0  console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait ip=192.168.1.160:::255.255.255.0
  • Presione CTRL + X para salir y guardar el archivo.
  • Actualizar el sistema operativo con los últimos parches.
sudo apt-get update
sudo apt-get upgrade
  • Reiniciar la Raspberry Pi.
sudo reboot
    

Ejecución de su programa

Para ejecutar el programa debe tener los permisos adecuados para utilizar GPIO (/ dev/mem debe accederse en la frambuesa). Puede ejecutar el programa con sudo:

sudo ./MY_PROGRAM

 Circuitos básicos.

ADVERTENCIA: los niveles de voltaje GPIO 3.3 V y no 5 V tolerantes. No hay ninguna protección de sobretensión en el tablero. Entradas digitales utilizan un nivel de lógica de 3V3 y no son tolerantes de niveles 5V, como se podría encontrar en un Arduino 5V alimentado.Tenga extrema precaución cuando trabaje con GPIO, puede dañar su Raspberry Pi, su equipo y potencialmente a sí mismo y otros. Si lo hace es bajo su propio riesgo!

4.1 GPIO de entrada

Periféricos GPIO varían bastante. En algunos casos, son muy simples, por ejemplo un grupo de pines pueden activarse como un grupo a la entrada o salida. Los voltajes de entrada y de salida son por lo general limitado a la   tensión de alimentación del dispositivo con los GPIOs por lo que pueden resultar dañados por una mayor tensión.

Algunos GPIOs tienen 5 entradas tolerantes V: incluso en los voltajes de la fuente baja, el dispositivo puede aceptar 5V sin daño.

Para Raspberry Pi, presentamos un ejemplo de cómo adaptar el nivel de voltaje de una medida de sensor de 5V para evitar posibles daños.

Componentes para este ejemplos y circuito de adaptación de tensión pueden fundados en el Starter Kit para Raspberry Pi.

Cuando un pin GPIO se configura como una entrada con un ejemplo de botón básico, podemos tener estos problemas de incompatibilidad de voltajes.

Este circuito es malo porque cuando usted presiona el botón de la entrada GPIO está conectada a 5 voltios, por lo tanto nuestro dispositivo puede dañarse.

Sin embargo, esto puede evitarse utilizando simplemente una resistencia en el cable del pulsador. El valor de la resistencia se determina por la corriente de la salida de los pines GPIO (la corriente por el circuito solía para leer el pin) y la cantidad de caída de voltaje que crea como resultado de ello. Con el resistor de 5K se obtiene 3, 3V en lo GPIO de entrada.

Vgpio = 5V· (10K/(10K+5K)) = 3, 3V

 medición del Sensor GPIO

Tenemos el mismo problema si utilizamos un sensor funcionando a 5 voltios.

Aquí está un ejemplo usando un sensor PIR.

Como se muestra en la imagen, utilizamos el mismo divisor resistivo utilizado para adaptar el nivel de tensión.

 ADC.

El escudo incluye a un ADC de 12b de la resolución que permite para conectar cualquier sensor a frambuesa con mayor precisión que Arduino. La comunicación entre la Raspberry Pi  y el ADC del escudo se realiza vía i2C.

La información de cada canal se puede obtener dos bytes de lectura de i2C, pero previamente un byte (que corresponde a la dirección de canal) debe enviar a través de i2C dependiendo del canal que queremos seleccionar. Aquí está una lista con las direcciones de canal:

Canal Dirección
0 0xDC
1 0x9C
2 0xCC
3 0x8C
4 0xAC
5 0xEC
6 0xBC
7 0xFC

Veremos un ejemplo de un programa que lee cada canal continuamente esperando 5 segundos entre repeticiones.

Con un cable de conexión el pin de 5V con algunos de los pines del ADC un valor cerca de 5.000000 debe leerse.

Todos los ejemplos en esta guía utilizan la biblioteca arduPi

//Include arduPi library 
#include "arduPi.h" 

char selected_channel[1];
char read_values[4];

int channel_0 = 0; 
int channel_1 = 0; 
int channel_2 = 0; 
int channel_3 = 0; 
int channel_4 = 0; 
int channel_5 = 0; 
int channel_6 = 0; 
int channel_7 = 0; 

float analog_0 = 0.0; 
float analog_1 = 0.0; 
float analog_2 = 0.0; 
float analog_3 = 0.0; 
float analog_4 = 0.0; 
float analog_5 = 0.0; 
float analog_6 = 0.0; 
float analog_7 = 0.0; 

void setup() 
{ 
  Wire.begin(); // join i2C bus (address optional for master) 
} 

void loop() 
{ 
  // channel 0 
  Wire.beginTransmission(8); 
  selected_channel[0] = 0xDC;
  Wire.read_rs(selected_channel, read_values, 2);
  Wire.read_rs(selected_channel, read_values, 2);
  channel_0 = int(read_values[0])*16 + int(read_values[1]>>4); 
  analog_0 = channel_0 * 5.0 / 4095.0;
  printf("Channel 0:\n");
  printf("Digital value = %d / Analog value = %fV\n\n", channel_0, analog_0); 


  // channel 1 
  Wire.beginTransmission(8); 
  selected_channel[0] = 0x9C;
  Wire.read_rs(selected_channel, read_values, 2);
  Wire.read_rs(selected_channel, read_values, 2);
  channel_1 = int(read_values[0])*16 + int(read_values[1]>>4); 
  analog_1 = channel_1 * 5.0 / 4095.0;
  printf("Channel 1:\n");
  printf("Digital value = %d / Analog value = %fV\n\n", channel_1, analog_1); 
  
 
  // channel 2 
  Wire.beginTransmission(8); 
  selected_channel[0] = 0xCC;
  Wire.read_rs(selected_channel, read_values, 2);
  Wire.read_rs(selected_channel, read_values, 2);
  channel_2 = int(read_values[0])*16 + int(read_values[1]>>4); 
  analog_2 = channel_2 * 5.0 / 4095.0;
  printf("Channel 2:\n");
  printf("Digital value = %d / Analog value = %fV\n\n", channel_2, analog_2); 
  
  
  // channel 3 
  Wire.beginTransmission(8); 
  selected_channel[0] = 0x8C;
  Wire.read_rs(selected_channel, read_values, 2);
  Wire.read_rs(selected_channel, read_values, 2);
  channel_3 = int(read_values[0])*16 + int(read_values[1]>>4); 
  analog_3 = channel_3 * 5.0 / 4095.0; 
  printf("Channel 3:\n");
  printf("Digital value = %d / Analog value = %fV\n\n", channel_3, analog_3); 
  
  
  // channel 4 
  Wire.beginTransmission(8); 
  selected_channel[0] = 0xAC;
  Wire.read_rs(selected_channel, read_values, 2);
  Wire.read_rs(selected_channel, read_values, 2);
  channel_4 = int(read_values[0])*16 + int(read_values[1]>>4); 
  analog_4 = channel_4 * 5.0 / 4095.0; 
  printf("Channel 4 (vertical header):\n");
  printf("Digital value = %d / Analog value = %fV\n\n", channel_4, analog_4); 
  
  
  // channel 5 
  Wire.beginTransmission(8); 
  selected_channel[0] = 0xEC;
  Wire.read_rs(selected_channel, read_values, 2);
  Wire.read_rs(selected_channel, read_values, 2);
  channel_5 = int(read_values[0])*16 + int(read_values[1]>>4); 
  analog_5 = channel_5 * 5.0 / 4095.0; 
  printf("Channel 5 (vertical header):\n");
  printf("Digital value = %d / Analog value = %fV\n\n", channel_5, analog_5); 
  
  
  // channel 6 
  Wire.beginTransmission(8); 
  selected_channel[0] = 0xBC;
  Wire.read_rs(selected_channel, read_values, 2);
  Wire.read_rs(selected_channel, read_values, 2);
  channel_6 = int(read_values[0])*16 + int(read_values[1]>>4); 
  analog_6 = channel_6 * 5.0 / 4095.0; 
  printf("Channel 6 (vertical header):\n");
  printf("Digital value = %d / Analog value = %fV\n\n", channel_6, analog_6); 
  
  
  // channel 7 
  Wire.beginTransmission(8); 
  selected_channel[0] = 0xFC;
  Wire.read_rs(selected_channel, read_values, 2);
  Wire.read_rs(selected_channel, read_values, 2);
  channel_7 = int(read_values[0])*16 + int(read_values[1]>>4); 
  analog_7 = channel_7 * 5.0 / 4095.0;
  printf("Channel 7 (vertical header):\n");
  printf("Digital value = %d / Analog value = %fV\n\n", channel_7, analog_7); 
  
  
  printf("***********************************\n"); 



  delay(1000); 

} 


int main (){ 
    setup(); 
    while(1){ 
        loop(); 
    } 
    return (0); 
}
                

Aquí está la salida de este programa que se conecta al pin de 5V de la Raspberry  Pia la entrada analógica 0:

UART.

Acceso al UART con arduPi biblioteca es tan simple como hacerlo con Arduino.

Necesita incluir arduPi.h en el código y crear una instancia de clase SerialPi nombrarlo serie.

Nombre de la instancia como serie le permite utilizar la sintaxis de arduino. (Todo esto está ya hecho si utilizas la plantilla proporcionada para crear sus programas).

Las funciones disponibles son:

  • Serial.Available()
  • Serial.Begin()
  • Serial.end()
  • Serial.Flush()
  • Serial.Peek()
  • Serial.Print()
  • Serial.println()
  • Serial.Read()
  • Serial.readBytes()
  • Serial.readBytesUntil()
  • Serial.Find()
  • Serial.findUntil()
  • Serial.parseInt()
  • Serial.parseFloat()
  • Serial.setTimeout()
  • Serial.Write()

Todas estas funciones tienen la misma funcionalidad que el arduino unos. Puede encontrar más información en:http://Arduino.CC/en/Reference/serial

Un ejemplo de código que se pueden encontrar en el tutorial de frambuesa Pi XBee acess el UART

 i2C.

Un ejemplo de uso de i2C puede encontrarse en la sección de ADC .

Aquí mostramos otro ejemplo usando lo BlinkM RGB i2C controlado dirigido.

BlinkM utiliza una alta calidad, poder más elevado LED RGB y un pequeño Microcontrolador AVR para permitir que un usuario de una interfaz i2C simple digital control de un LED RGB.

En el ejemplo vamos a cambiar el color led usando fade transiciones y también cambiando directamente. Más información sobre lo LED y los comandos que podemos enviar a él puede encontrarse en la hoja de datos.

Conectar la clavija (-) del led con el pin GND del escudo.

Conecta (+) del pin del led con el pin de 5V de la pantalla.

Conectar la clavija d del led con el pin SDA del escudo.

Conectar la clavija c del led con el pin SCL del escudo.

Aquí está el código:

/*  
 *  Raspberry Pi to Arduino Shields Connection Bridge
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program 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 General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           2.0
 *  Design:            David Gascón 
 *  Implementation:    Jorge Casanova & Luis Martín
 */


//Include arduPi library
#include "arduPi.h"


void setup(){
    Wire.begin();
    Wire.beginTransmission(9);
    Wire.write('o'); //End the current Light script
    Wire.endTransmission();
}

void loop(){
    for (int i=0;i < 5;i++){
        Wire.beginTransmission(9);
        Wire.write('n'); //Change to color
        Wire.write(byte(0xff)); //Red component
        Wire.write(byte(0x00)); //Green component
        Wire.write(byte(0x00)); //Blue component
        Wire.endTransmission();

        delay(500);
        
        Wire.beginTransmission(9);
        Wire.write('n'); //Change to color
        Wire.write(byte(0x00)); //Red component
        Wire.write(byte(0x00)); //Green component
        Wire.write(byte(0xff)); //Blue component
        Wire.endTransmission();
        
        delay(500);
    }
    
    for (int i=0;i < 10;i++){
        Wire.beginTransmission(9);
        Wire.write('c'); //Fade to color
        Wire.write(byte(0xff)); //Red component
        Wire.write(byte(0x00)); //Green component
        Wire.write(byte(0x5a)); //Blue component
        Wire.endTransmission();

        delay(150);
        
        Wire.beginTransmission(9);
        Wire.write('c'); //Fade to color
        Wire.write(byte(0x55)); //Red component
        Wire.write(byte(0x20)); //Green component
        Wire.write(byte(0x5a)); //Blue component
        Wire.endTransmission();

        delay(150);
    }
}

int main (){
    setup();
    while(1){
        loop();
    }
    return (0);
}

Este código alternativo de rojo a azul cinco veces y luego hacer unas transiciones suaves entre colores violáceos.

 SPI.

Es posible comunicar con dispositivos SPI usando las funciones arduPi.

En este ejemplo utilizamos las funciones SPI para imprimir mensajes en la ST7920 LCD12864 (LCD SPI)

En primer lugar, tenemos que poner el interruptor de la pantalla LCD en modo SPI.

Ahora procedemos con la conexión entre el LCD y el Raspberry Pi a arduino shield:

VCC de la LCD a 5v del escudo

GND de la LCD a GND del escudo

SCK de lo LCD a SCK del escudo

SID de la LCD a MOSI del escudo

CS de la pantalla LCD al pin 8 del escudo

Como puedes ver estamos utilizando el número pin 8 del escudo frambuesa Pi como chip select. Así que cuando tenemos que seleccionar la pantalla LCD como el dispositivo de destino para la comunicación SPI tenemos poner el pin 8 a alta.

Aquí está el código

/*  
 *  Raspberry Pi to Arduino Shields Connection Bridge
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  a
 *  This program 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 General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           2.0
 *  Design:            David Gascón 
 *  Implementation:    Jorge Casanova & Luis Martín
 */

//Include arduPi library
#include "arduPi.h"

int latchPin = 8;
unsigned char char1[]=" Cooking Hacks  ";
unsigned char char2[]="  SPI LCD for   ";
unsigned char char3[]="  Raspberry Pi  ";

void initialise();
void displayString(int X,int Y,unsigned char *ptr,int dat);
void writeCommand(int CMD);
void writeData(int CMD);
void writeByte(int dat);
void clear();

void setup(){
    SPI.begin();
    SPI.setBitOrder(MSBFIRST);
    SPI.setDataMode(SPI_MODE0);
    SPI.setClockDivider(SPI_CLOCK_DIV128);

    initialise();
}

void loop(){
    displayString(0,0,char1,16);
    delay(2000);
    clear();
    displayString(1,0,char2,16);
    displayString(2,0,char3,16);
    delay(2000);
    clear();
}

void initialise(){
    pinMode(latchPin, OUTPUT);     
    digitalWrite(latchPin, LOW);

    delayMicroseconds(80);

    writeCommand(0x30);
    writeCommand(0x0c);
    writeCommand(0x01);
    writeCommand(0x06);
}


void displayString(int X,int Y,unsigned char *ptr,int dat){
    int i;

    switch(X){
        case 0:  Y|=0x80;break;

        case 1:  Y|=0x90;break;

        case 2:  Y|=0x88;break;

        case 3:  Y|=0x98;break;

        default: break;
    }

    writeCommand(Y);

    for(i=0;i < dat;i++){ 
        writeData(ptr[i]);
    }

}

void writeCommand(int CMD){
    int H_data,L_data;
    H_data = CMD;
    H_data &= 0xf0;
    L_data = CMD;
    L_data &= 0x0f;
    L_data <<= 4;
    writeByte(0xf8);
    writeByte(H_data);
    writeByte(L_data);
}

void writeData(int CMD){
    int H_data,L_data;
    H_data = CMD;
    H_data &= 0xf0;
    L_data = CMD;
    L_data &= 0x0f;
    L_data <<= 4;
    writeByte(0xfa);
    writeByte(H_data);
    writeByte(L_data);
}

void writeByte(int dat){
    digitalWrite(latchPin, HIGH);
    delayMicroseconds(80);
    SPI.transfer(dat);
    digitalWrite(latchPin, LOW);
}

void clear(){
    writeCommand(0x30);
    writeCommand(0x01);
}


int main (){
    setup();
    while(1){
        loop();
    }
    return (0);
}

Este programa mostrará los mensajes «Cooking Hacks» y «SPI LCD para Raspberry Pi» con un retraso de 2 segundos en el medio.

 Mas ayuda

Se puede obtener ayuda en la sección específica creada en este  foro.

Fuente cooking-hacks

Ajustes efecto Ambilight con Raspberry Pi


En un post anterior   vimos como  emular un sistema “ambiligt”  usando únicamente una Raspberry Pi 2  o 3  equipada con una distribución compatible ( Openelec)   y el software de control de  leds Hyperion, con el que podemos conseguir todo hecho  gracias a la distribución Lightberry. 
Además de controlar los leds, la combinación de la Raspberry Pi junto con Kodi constituye un excelente Media Center capaz de reproducir todo tipo de contenidos de audio, vídeo e imagen, de reproducir nuestra colección multimedia almacenada en el PC o en un disco externo, e incluso de reproducir directamente contenidos on-line si se posee  las  subscripción en el hogar  y por supuesto cuenta con la conexión  de suficiente ancho de banda como por ejemplo con ftth.

 La propuesta se completa  con una económica  capturadora  de vídeo  que permitirá  que la emulación no solo funcione con el contenido multimedia que reproducimos desde la Raspberry Pi  , también  responderá a la señal de video externa que le introduciremos  procedente de una fuente externa de video como por ejemplo puede ser la señal de video procedente de un descodificador de Imagenio .

 

Por desgracia a veces la respuesta del Hypercon que  produce en la tira de leds ws2801 no se corresponde  con la imagen capturada , señal que el el fichero obtenido por el asistente (hypercon.config.son ) deberíamos mejorarlo ¿pero cómo?
Pues gracias al programa en java  HyperCon   podemos indicar  la posición exacta de nuestros leds en el caso de que la configuración realizada desde el menu de Hyperion Config Creator   no haya  ofrecido un resultado esperado .

Este software permite entre otras cosas establecer el número de leds que hay que controlar, la posición del primer led, la orientación, el chipset, etc…permitiendo un ajuste muy preciso del comportamiento de cada led de forma individual

Antes de seguir, quiero aclarar para que HyperCon.jar funcione, es necesario tener instalada la ultima version de  Java ,asi que si no la tiene  instalada puede descargarlo aquí

Recordamos que con el menu basico de  Hyperion Config Creator   podemos  definir la instalación de nuestra  Lightberry en nuestra TV   definiendo simplemente 5 parámetros:
  • Tipo de tira de leds: en nuestro casi   podemos elegir  Lightberry HD for Rasperry pi (ws2801)
  • Numero de leds horizontales ( deben ser idéntico numero de leds  en ambos lados)
  • Numero de leds  verticales   ( deben ser idéntico numero de leds  en ambos lados)
  • Donde comienza el primer led (Right/button corner and goes up)
  • Confirmación  de  que tenemos un capturadora de TV conectada

Puede ocurrir que aunque  veamos el arco iris con la configuración obtenida  no se correspondan los colores de los leds con los de la imagen , indicio de que debemos ajustar la configuración manualmente  de forma mas  precisa  por medio del archivo hyperion.config.json  generado por el asistente  de un modo mas exhaustivo usando  el programa en java  HyperCon  o bien de forma manual.

Obviammente para ejecutar dicha aplicacion, como se ha mencionado ,debemos tener instalado en nuestro equipo java

Una vez descomprimido el  pquete de Hypercon , simplemente ejecutaremos el archivo HyperCon_Sssj.jar  ( este fichero estará por ejemplo  en la ruta C:\Users\xx\Downloads\hypercon-master\hypercon-master\debug\)

hypercon

Una vez lanzado el hypercon veremos el interfaz  gráfica con una configuración por defecto que debemos personalizar   con respecto a nuestra instalación.

Debe recodar donde puso el primer led (el que está al lado del conector hembra con los jumpwires).

pantalla

En este ejemplo personal ,el primer led   ha quedado en la esquina inferior derecha cuando se mira la TV de frente ( o a la izquierda abajo si ve por atras), así que el recorrido de los leds va desde la esquina inferior  derecha hasta la izquierda (sentido horario).

Configuramos de este modo:

  •  Direction: clockwise
  •  Led top corner: false
  •  Led bottom corner: false
  •  Horizontal #: 28
  •  Vertical #: 14
  •  Bottom Gap: 0
  •  1st Led offset: -42

En nuestro caso tiene que salir un Led count = 84 (o el número de leds que haya instalado).

Si en su configuración  empezó  por la otra esquina, cambie el desplegable  direction.

En el caso del ejemplo  no se han situado leds en las esquinas, así que hay que especificar  top/bottom a false.

En bottom gap hay que poner el mismo numero de leds que en la parte superior, así lo puede dejar «vacío».

Muy importante : en  el desplegable  1st Led offset hay que ir aumentando o disminuyendo hasta que el led número 0 quede en la esquina inicial (en este ejemplo en la esquina inferior derecha).

pantalla.png

Una vez configurado según los leds que tenga, vaya a la pestaña External y en el apartado Effects Engine Directory  escriba lo siguiente: /storage/hyperion/effects lo cual  hará que hyperion encuentre el directorio de los efectos.

Asimismo puede ajustar el tiempo en ms que permanezca el efecto al arrancar  en Length ( por defetco 9000ms)

rain

Una vez configurado haz clic en el botón Create Hyperion Configuration para crear el fichero de configuración hyperion.config.json que hay que copiar  en la Raspberry PI en el directorio /storage/.config     (   no confundir  con  la ruta /storage/hyperion/configuration/)

hyperion .

Una vez copiado el fichero  hyperion.config.json en storage/.config reinicie la RPI y si todo ha ido bien deberías ver un efecto de arcoiris.

Configuracion inicial

La configuración del dispositivo contiene los siguientes campos:

  •  ‘name’: El nombre de usuario del dispositivo (sólo se utiliza para fines de visualización)
  •  ‘type’: El tipo del dispositivo o leds (los tipos conocidos por ahora son ‘ws2801’, ‘ldp8806’, ‘ ‘lpd6803’, ‘sedu’, ‘adalight’, ‘lightpack’, ‘test’ y ‘none’)
  • output : La especificación de salida depende del dispositivo seleccionado. Esto puede ser, por ejemplo, el especificador de dispositivo, número de serie del dispositivo o el nombre del archivo de salida
  • rate’: El baudrate de la salida al dispositivo
  • colorOrder’: El orden de los bytes de color (‘rgb’, ‘rbg’, ‘bgr’, etc.).Es muy  importante destacar que si no ajustamos este valor  se pueden cambiar el borde de los colores .Por ejemplo muchas tiran son del t tipo BGR, lo cual significa que si dejamos marcado por defecto en RGB  cambiará en todas las visualizaciones el rojo por el azul y biceversa

Ejemplo de configuración  de la sección  device correspondiente al post anterior  :

«device»: {
«colorOrder»: «bgr»,
«rate»: 500000,
«type»: «ws2801»,
«name»: «MyPi»,
«output»: «/dev/spidev0.0»
},

Color

Podemos manipular la  configuración de manipulación de color utilizada para ajustar los colores de salida a un entorno específico.
La configuración contiene una lista de transformaciones de color. Cada transformación contiene  los  siguientes campos:

  •  ‘id’: El identificador único de la transformación de color (p. Ej. ‘Device_1’)
  • ‘leds’: Los índices (o índices) de los leds a los que se aplica esta transformación de color  (por ejemplo, ‘0-5, 9, 11, 12-17’). Los índices son basados ​​en cero.
  •  ‘hsv’: La manipulación en el dominio de colores Valor-Saturación-Valor con lo siguiente  parámetros de ajuste:
    •  ‘saturationGain’ El ajuste de ganancia de la saturación
    • ‘valueGain’ El ajuste de ganancia del valor
  • ‘rojo’ / ‘verde’ / ‘azul’: La manipulación en el dominio de color Rojo-Verde-Azul con los  siguientes parámetros de sintonización para cada canal:
    •  ‘umbral’ El valor de entrada mínimo requerido para que el canal esté encendido
      (más cero)
    •  ‘gamma’ El factor de corrección de la curva gamma
    •  ‘blacklevel’ El valor más bajo posible (cuando el canal es negro)
    •  ‘whitelevel’ El valor más alto posible (cuando el canal es blanco)

Al lado de la lista con transformaciones de color también hay una opción de suavizado.
‘Suavizado’: Suavizado de los colores en el dominio del tiempo con la siguiente sintonización  parámetros:

  • ‘type’ El tipo de algoritmo de suavizado (‘linear’ o ‘none’)
  •  ‘time_ms’ La constante de tiempo para el algoritmo de suavizado en milisegundos
  •  ‘updateFrequency’ La frecuencia de actualización de los leds en Hz

Ejemplo de configuración  de la seccion color  correspondiente al post anterior  

«color»: {
«transform»: [
{
«blue»: {
«threshold»: 0.050000000000000003,
«blacklevel»: 0.0,
«whitelevel»: 0.84999999999999998,
«gamma»: 2.0
},
«leds»: «0-81»,
«hsv»: {
«saturationGain»: 1.0,
«valueGain»: 1.0
},
«green»: {
«threshold»: 0.050000000000000003,
«blacklevel»: 0.0,
«whitelevel»: 0.84999999999999998,
«gamma»: 2.0
},
«id»: «leds»,
«red»: {
«threshold»: 0.050000000000000003,
«blacklevel»: 0.0,
«whitelevel»: 1.0,
«gamma»: 2.0
}
},
{
«blue»: {
«threshold»: 0.050000000000000003,
«blacklevel»: 0,
«whitelevel»: 0,
«gamma»: 2.0
},
«leds»: «82-149»,
«hsv»: {
«saturationGain»: 0,
«valueGain»: 0
},
«green»: {
«threshold»: 0.050000000000000003,
«blacklevel»: 0,
«whitelevel»: 0,
«gamma»: 2.0
},
«id»: «ledsOff»,
«red»: {
«threshold»: 0.050000000000000003,
«blacklevel»: 0,
«whitelevel»: 0,
«gamma»: 2.2000000000000002
}
}
],

Leds

La configuración para cada led individual. Contiene la especificación del área  promediado de una imagen de entrada para cada led para determinar su color. Cada elemento de la lista  contiene los siguientes campos:

  •  index: El índice del led. Esto determina su ubicación en la cadena de leds; cero
    Siendo el primer led.
  •  hscan: La parte fraccional de la imagen a lo largo de la horizontal utilizada para el promedio  (mínimo y máximo inclusive)
  •  vscan: La parte fraccional de la imagen a lo largo de la vertical utilizada para el promedio  (mínimo y máximo inclusive)
  •  ‘updateFrequency’ La frecuencia de actualización de los leds en Hz


«leds» :
[
{
«index» : 0,
«hscan» : { «minimum» : 0.0000, «maximum» : 0.0500 },
«vscan» : { «minimum» : 0.0000, «maximum» : 0.0800 }
},
{
«index» : 1,
«hscan» : { «minimum» : 0.0000, «maximum» : 0.0357 },
«vscan» : { «minimum» : 0.0000, «maximum» : 0.0800 }
},

…………………..

{
«index» : 87,
«hscan» : { «minimum» : 0.0000, «maximum» : 0.0500 },
«vscan» : { «minimum» : 0.0000, «maximum» : 0.0714 }
}
],

Configuracion Bordes

La configuración de borde negro, contiene los siguientes elementos:

  •  enable: true si el detector debe ser activado
  •  Umbral: valor por debajo del cual un píxel se considera negro (valor entre 0,0 y 1,0)
    «Blackborderdetector»:

Ejemplo de configuración  de la seccion blackborderdetector correspondiente al post anterior  

«blackborderdetector»: {
«threshold»: 0.10000000000000001,
«enable»: true
},

EFECTOS

La configuración del motor de efectos, contiene los siguientes elementos:

  • paths: Una matriz con ubicaciones absolutas de directorios con efectos
  • bootsequence: El efecto seleccionado como ‘secuencia de arranque’. Es importante cambiar a su valor en OpenElec  «/storage/hyperion/effects»

Ejemplo de configuración sección  effects correspondiente al post anterior  :

«effects»: {
«paths»: [
«/storage/hyperion/effects»
]
},

CAPTURADORA

La configuración del captador de tramas, contiene los siguientes elementos:

  •  width: El ancho de los marcos grabados [pixels]
  •  height: La altura de los marcos grabados [pixels]
  • frequency_Hz: La frecuencia de la toma de marco [Hz]

La configuración de la conexión XBMC utilizada para habilitar y deshabilitar el captador de tramas. Contiene los siguientes campos:

  •  xbmcAddress: La dirección IP del host XBMC
  •  xbmcTcpPort: El puerto TCP del servidor XBMC
  • grabVideo: Flag  que indica que el captador de fotogramas está activado (true) durante la reproducción de vídeo
  •  grabPictures: Flag que indica que el captador de fotogramas está activado (true) durante la presentación de imágenes
  •  grabAudio: Flag que indica que el captador de fotogramas está activado (true) durante la reproducción de audio
  •  grabMenu: Flag que indica que el captador de fotogramas está activado (true) en el menú XBMC
  •  grabScreensaver: Flag que indica que el captador de fotogramas está activado (true) cuando XBMC está en el salvapantallas
  •  enable3DDetection: Indicador que indica que el captador de fotogramas debe cambiar a un modulo compatible con 3D si se está reproduciendo un video en 3D

Ejemplo de configuración sección  effects correspondiente al post anterior  :

 «framegrabber»: {
«width»: 64,
«frequency_Hz»: 10.0,
«height»: 64
},
«xbmcVideoChecker»: {
«grabVideo»: true,
«grabPictures»: true,
«xbmcTcpPort»: 9090,
«grabAudio»: true,
«grabMenu»: false,
«enable3DDetection»: true,
«xbmcAddress»: «127.0.0.1»,
«grabScreensaver»: true

NOTAS

Si no quiere reiniciar lar RPI cada vez que modifique el fichero de configuración hyperion.config.json, puede reiniciar sólo el servicio con los siguientes comandos:

killall hyperiond
/storage/hyperion/bin/hyperiond.sh /storage/.config/hyperion.config.json /dev/null 2>&1 &

Hay que añadir la siguiente línea dtparam=spi=on al archivo config.txt  editando el fichero o bien a través con los siguientes comandos:

mount -o remount,rw /flash
nano /flash/config.txt (se abrirá el archivo, añadimos la línea y guardamos con Ctrl+X)

reboot

Pruebas

Para comprobar el correcto funcionamiento del sistema para Android existe una app que te permite controlar los leds estableciendo un color o aplicando efectos bastante vistosos. La puede descargar aquí

hype

Otra forma de probar es ejecutando el siguiente comando que hará que todos los leds se iluminen en rojo durante 5 segundos, puedes probar varios colores, green, blue entre otros.

/storage/hyperion/bin/hyperion-remote.sh –priority 50 –color red –duration 5000

O este otro que mostrará un efecto de arcoiris

/storage/hyperion/bin/hyperion-remote.sh  –effect “Rainbow swirl fast” –duration 3000

Por ultuio en youtube puede encontrar vídeos de test para probar que los colores se corresponden con la imagen.