Mostrando entradas con la etiqueta MICROCONTROLADORES. Mostrar todas las entradas
Mostrando entradas con la etiqueta MICROCONTROLADORES. Mostrar todas las entradas

viernes, 3 de enero de 2014

Basic ECG con Arduino y C#


Introduction

El proyecto completo puede ser descargado por SVN usando: https://proyect-general-es.googlecode.com/svn/branches/Main/ECG_Basic/
Esta página de la wiki está diseñada con el propósito de dar a conocer una manera sencilla y práctica de hacer un ECG muy pero muy básico que sirva como una pequeña introducción al mundo de las señales mioeléctricas.
Dos presentaciones en PPTX fueron desarrolladas, estas contienen mucha información útil:
(El circuito final mostrado en dichas presentaciones está desactualizado, favor de leer esta página completa o la Tesis para comprender a detalle el proyecto)
Todo el trabajo realizado durante el semestre se reduce a la pequeña Tesis a continuación, esta contiene todo lo presentado en esta página y más: Tesis
Así queda al final
Posición de los electrodos

Objetivo

El objetivo de este proyecto bien podría ser el diseño y la creación de un aparato capaz de poder registrar las variaciones eléctricas del corazón por medio de métodos no invasivos, es decir, hacer un electrocardiógrafo fiable, portátil y que pueda ser vendido en el creciente mercado de la medicina. Por desgracia en la universidad el equipo necesario para desarrollar este tipo de investigaciones es muy limitado y la disposición del mismo no es para tiempos flexibles (solo podemos usar el equipo en horarios establecidos y eso que estamos hablando de un simple osciloscopio y una computadora), el presupuesto que destina la universidad para proyectos de este estilo es nulo, es decir no existe (cabe mencionar que el alumno mismo costea todo el proyecto). Con todas estas limitantes no se puede esperar a que el alumno logre un proyecto exitoso al 100% ni mucho menos una investigación a conciencia, M´exico no está preparado aun para nada de esto.

Para ver el proyecto completo accede a mi wiki: https://code.google.com/p/proyect-general-es/wiki/ECG_Basic

Glucómetro. Detector de glucosa sanguínea por medio de Infrarrojos con Arduino y C#

Si deseas descargar el proyecto completo usa: https://proyect-general-es.googlecode.com/svn/branches/Main/Glucometro/

Se pretende crear un dispositivo medidor de glucosa (al que llamaremos Glucómetro) que sea capaz de comunicarse con una PC, con un dispositivo Android o que pueda ser usado de manera independiente.

La conexión a la PC se piensa manejar por medio de USB as´ı como con Android. Para que nuestro Glucómetro sea capaz de funcionar de manera independiente sin una PC o dispositivos Android conectados es necesario que posea una interfaz, dicha interfaz se ha propuesto crearla por medio de componentes que se tengan ya a la mano, es decir push-buttons.

El sistema completo constará de dos placas, una Shield para el Arduino y una placa que llamaremos "Placa IR" donde irán montados los LED's IR y el Transistor IR (esta última placa irá montada junto con la parte "mecánica" es decir, el soporte para las laminillas con la muestar de sangre)


Para ver el proyecto completo consultalo en mi wiki:

jueves, 16 de mayo de 2013

Control de Motores (AC y DC) por medio de la Computadora

Control de Motor Monofásico, On/Off por medio de una Computadora Personal.
Control de 2 Motores DC, On/Off y sentido de giro por medio de una Computadora Personal

Introducción
En el presente proyecto tuvo como finalidad de dejar al laboratorio un dispositivo capaz de permitir el controlar varios motores eléctricos por medio de la computadora, se construyo un driver con micro-controlador  se hizo uso de comunicación USB-Serial, se desarrollo una Interfaz Hombre-Maquina echa en C#, se uso un motor de AC y dos de DC.

Control de Motor AC
En la clase se estudia cómo se controlan diferentes tipos de motores, en el salón se dispone de un motor monofásico, a este no se nos fue posible controlar el sentido de giro ya que los 2 embobinados, el de arranque y el trabajo, están unidos en los cables de sus “neutros” por lo que no se puede invertir las terminales, como no se pudo controlar la dirección, se agregaron dos motores de corriente directa para demostrar que el sentido de giro puede ser cambiado en un motor.
Cabe mencionar que el trabajo anterior, tenía un tablero para cambiar el sentido de giro del motor monofásico; pero se hacía un corto circuito y esto ocasionaba que el motor empezara a fallar y producir humo, puesto que esa operación forzada pudiera dañar al motor, se cambió el circuito que traía puesto que los dispositivos no trabajaban como debían así como los interruptores de cambio de giro.

Desarrollo
Figura 1.- Diagrama de Subsistemas de la función controlar un motor.

Matariales:

                 1) Motor de Corriente Alterna:
Para saber cómo funciona el motor se hicieron diferentes pruebas, al motor encontrando la siguiente información:
• Motor, 3-3358-4 333584 del secador de Maytag
• Modelo S58NXEET-2895
• Potencia, 1/4B
• Voltaje 115 AC
• RPM 1725
• 60 Hz.
• 6 Amperes.
• CL B 40 °C

Figura 2.- Etiqueta de datos del fabricante del motor monofásico.

Figura 3.- Fotografía del motor monofásico del laboratorio.

Como se aprecia en las fotografías se tienen 3 cables de diferentes colores, los cuales se identificaron como:
• Amarillo -> Fase del embobinado de trabajo
• Azul -> Neutro del embobinado de trabajo
• Negro -> Fase del embobinado de arranque

Figura 4.- En la imagen de arriba se muestra como se cree que es el arreglo de las terminales de las bobinas del motor de AC.

El trabajo anterior tenía dos interruptores de palanca, uno de encendido y otro de dirección, los cuales al hacer girar el motor a favor de las manecillas del reloj no había problema, pero al momento de hacerles girar en contra se ponía al cable azul sin conectar, el amarillo se llevaba a la fase y el negro al neutro; si se seguía con esta operación se quemaría el motor puesto que sacaba humo después de un rato.

Figura 5.- Diagrama de conexiones cuando se forzaba a girar en sentido contrario al motor de AC.

Se podía hacer girar el motor desconectando el bobinado de arranque, desconectando el cable negro, dejando alimentados los demás con CA; pero se requería girar el eje manualmente hacia el lado deseado.
Para poder invertir su sentido de giro hay que invertir solo las terminales del bobinado de trabajo sin invertir las de arranque pero con lo anteriormente expuesto no se podía controlar el motor de AC.
Para poder controlarlo, por medio de la computadora; solo se requiere decirle al micro-controlador que encienda al motor, como este solo trabaja a 5V requerirá de otro dispositivo que lo encienda para ello se hizo uso de un relevador activado por el micro-controlador, que al cerrarse alimentara al motor con 127 AC ~.

Figura 6.- Arriba parte del esquemático donde se muestra al micro-controlador activando y desactivando al relevador, en el circuito se puso en paralelo e invertido un diodo con respecto a la bobina del relevador para evitar que las contracorriente dañen al dispositivo.

                 2)  Control de motor DC:

Como no se pudo hacer el cambio de giro del motor AC, se anexaron dos motores de DC para demostrar el sentido de cambio todo controlado por la computadora. Para esto se hizo uso de un puente H, en circuito integrado sin diodos de rodada estos se tuvieron que poner externos.

Figura 7.- Arriba se muestra la sección del esquemático para el control de 2 motores de DC, se hizo uso del circuito integrado L293. Las señales de sentido de giro son mandadas desde el micro-controlador.

                 3) Micro-controlador:

Se eligió para este trabajo el uso del micro-controlador PIC16F877P para mandar los pulsos de señal, así como recibir las instrucciones de la computadora por medio de puerto serial.

Figura 8.- Esquemático del micro-controlador usado.

Figura 9.- Arriba se muestran las conexiones al PIC para primero hacer el parpadeo de un led que nos asegurara que el PIC trabaja bien y segundo unas terminales para poder reprogramar al PIC In Circuit Program

Figura 10.- En la imagen de arriba se muestran las conexiones de la comunicación serial echa por medio de un MAX233.

Figura 11.- Esta parte del esquemático muestra que la alimentación de todos los dispositivos a 5 V será interrumpida por un interruptor de palanca, para hacer el encendido y apagado.


Figura 12.- En la imagen de arriba se muestran las entradas que tendrá el PIC para ser controlado por un tablero y así tener una botonera para controlar los motores cuando no se disponga de una computadora, en el dibujo no se aprecia pero todas las 8 conexiones tienen un diodo que va a un 9° pin del micro este es para hacer que lea el estado del teclado.

Interfaz Hombre-Maquina
Se desarrollo una interfaz de manera que simulara los tipos de tableros que se manejan físicamente para control de maquinas rotativas o en lineas de producción, algunas de las características de la interfaz se basaron en las recomendaciones del los estándares de la <<referencia 1>>. La interfaz es gráfica y hace uso de imágenes para su manejo, el usuario puede interactuar con ella para el control de los motores, también presenta bloqueos de seguridad (los botones de inhabilitan) dependiendo de las operaciones. En el vídeo del final se pueden apreciar las funciones de todo el proyecto.

En la imagen de arriba, se muestra el primer prototipo de la interfaz para el usuario final.

En la imagen de arriba, se muestra la interfaz aprobada para su uso.

Vídeo del Proyecto:

Conclusiones:
  1. Interfaz H-M. Vemos que el resultado final es mas amigable que el prototipo presentado, los botones son mas fáciles de diferenciar, la consola de comunicación se coloco por debajo del área del trabajo, ya que en sí no es necesaria para el operador, es importante para los desarrolladores de la interfaz para saber si ocurre algún error con la comunicación serial; también esta la parte que comienza la comunicación serial, que sera usada por operarios y desarrolladores.
Referencias:

1.- NFPA 79: Electrical Standard for Industrial Machinery, 2002 Edition
2.- http://esp.ebay.com/viewItem?item=110766848335&v=gbh
3.- http://html.rincondelvago.com/motores-de-induccion-monofasicos-asincronos.html


Anexo A (Programas Utilizados):
  1.         Microsoft Visual Studio 2010
  2.     PIC C Compiler (PCWHD Compiler, CCS inc.)
  3.     Eagle PCB Software
  4.         Solid Works 2010

jueves, 4 de abril de 2013

HCS08 - Motorola Freescale - Contador 0 a 99 en 2 Display 7 Segmentos

Para ayudar a varios compatriotas en mi Universidad me he dispuesto a crear esta entrada.. bla bla bla

A lo bueno.

NOTA: Se seguirá usando para programar el microcontrolador el debugger ICSP tan usado en anteriores entradas (BDM).

Descripción del Proyecto.

Crear una cuenta de 0 a 99, la cual se incrementará en una unidad cada segundo, esta cuenta será en sistema decimal y los resultados de la misma serán mostrados en dos display de 7 segmentos, uno por digito.
Se usaran dos transistores 2N3906 como conmutadores para activar cada uno de los display de 7 conectando el común de estos al transistor los cuales por medio de un pulso en su Base activaran o desactivaran el display a conveniencia.
Se usan también dos Buffers de corriente CD4050 para que la corriente demandada por cada display se cargue sobre estos y no sobre los microcontroladores y que este ultimo solo tenga la acción de mandar pulsos lógicos de voltaje.


Contador digital

                Un contador digital es básicamente un circuito electrónico que muestra un cambio cada cierto periodo de tiempo establecido, este periodo de tiempo es común que sea ajustable.
Estos cambios se pueden manifestar de diferentes maneras de acuerdo a lo que se desee lograr, como por ejemplo, mostrar una cuenta de números en cualquier tipo interfaz visual, o activar cierto relé que a su vez crear más cambios.
También son usados como una manera sencilla de realizar acciones cada cierto tiempo.
En nuestro caso, nuestro contador mostrara una cuenta de números decimales del 0 al 99 mostrado en dos display de 7 segmentos, esta cuenta se incrementara en intervalos de una unidad cada segundo que pase.


Display de 7 segmentos

Los Display de 7 segmentos son básicamente un arreglo de leds ordenados de tal forma que encendiendo unos cuantos de estos puedes formar números y algunas letras, en otros símbolos.

Hay dos distintos, ya sea cátodo común o ánodo común, esto debido a que los leds dentro de los mismo tienen todos interconectados a un mismo punto el cátodo o el ánodo.
Por tanto conectando este punto común a una fuente de voltaje (para el caso del ánodo común) se puede encender cada led interno mandando un estado lógico bajo o a tierra (para el caso del cátodo común) y mandándole un pulso lógico alto.


Transistor PNP 2N3906

El transistor es un dispositivo semiconductor que cumple varias funciones, entre ellas están las de amplificador, oscilador, conmutador o rectificador. En este caso lo usaremos de conmutador para crear la acción de barrido en los display de 7 segmentos.







Esquematicos



Descarga: pdf

CODIGO
;*******************************************************************
;* This stationery serves as the framework for a user application. *
;* For a more comprehensive program that demonstrates the more     *
;* advanced functionality of this processor, please see the        *
;* demonstration applications, located in the examples             *
;* subdirectory of the "Freescale CodeWarrior for HC08" program    *
;* directory.                                                      *
;*******************************************************************

; Include derivative-specific definitions
            INCLUDE 'derivative.inc'
;
; export symbols
;
            XDEF _Startup
            ABSENTRY _Startup

;
; variable/data section
;
            ORG    RAMStart         ; Insert your data definition here
ExampleVar: DS.B   1
contador:    equ  $90
unidades:   equ   $92
unidadesA:  equ   $93          
decenas:    equ   $94
decenasA:   equ   $95
tope:       equ   $96

;
; code section
;
            ORG    ROMStart

_Startup:
            LDHX   #RAMEnd+1        ; initialize the stack pointer
            TXS
            CLI                     ; enable interrupts

PROG_PORTS:  
            MOV   #$FF,PTBDD         ;puerto B salida
            MOV   #$FF,PTCDD         ;declaramos puerto C como salida            
            MOV   #$64,RTCMOD        ;declaramos timer a un segundo, con tope el 100=$64
            MOV   #%1111,RTCSC
            
            MOV   #$00,contador       ;iniciamos el contador con cero
            MOV   #$00,unidades       ;inicializamos unidades y decenas
            MOV   #$00,decenas
            
                        ;cargamos el valor de ajuste a disp 7 segm en las memorias
            MOV   #111111,$80      ;ajuste del 0
            MOV   #000110,$81      ;ajuste del 1
            MOV   #%01011011,$82
            MOV   #%01001111,$83
            MOV   #%01100110,$84
            MOV   #%01101101,$85
            MOV   #%01111101,$86
            MOV   #000111,$87
            MOV   #%01111111,$88
            MOV   #%01100111,$89      ;ajuste del 9
            
main:
            feed_watchdog
            BSR   checa_cuenta        ;vamos a la subrutina que lleva la cuenta en unidades y decenas
            BSR   ajusta_unidades             ;subrutina que ajusta el valor de unidades y decenas para desplegarlo en el disp 7 segm
            BSR   ajusta_decenas
            LDA   unidadesA           ;cargamos unidades y decenas ajustadas y las mostramos en el display
            STA   PTBD
            MOV   #%10,PTCD
            BSR   retardo
            LDA   decenasA
            STA   PTBD
            MOV   #%01,PTCD
            BSR   retardo
            LDA   contador            ;checamos si se paso del 99
            CBEQA #$64,hacercero 
            BRA   main
;subrutina que regresa a cero todo
;-------------------
hacercero:
            MOV   #$00,unidades
            MOV   #$00,unidadesA
            MOV   #$00,decenas
            MOV   #$00,decenasA
            MOV   #$00,contador
            BRA   main


            
;--------------------------------
            
;--------------Rutina checa cuenta
checa_cuenta:
                LDA   RTCCNT
                CMP   contador
                BNE   incrementa_cuenta             ;si no es el mismo numero, es decir, ya cambio (ya paso el tiempo programado)
                RTS                                 ;si es el mismo, regresamos
                
incrementa_cuenta:
                LDA   RTCCNT                        ;como no son iguales, los hacemos iguales
                STA   contador
                INC   unidades                      ;si las unidades completa una decena
                LDA   unidades                      ;regresamos a cero unidades y decenas +1
                CMP   #$A
                BEQ   una_decena_mas
                RTS                
una_decena_mas:
                MOV   #$00,unidades
                INC   decenas
                RTS
;--------------termian rutina checa cuenta            
;---------------------*******Subrutina de retardo                
retardo:       
            LDHX  #$0000
RET1:        
            feed_watchdog
            AIX   #$01
            CPHX  #$FF            ;Se incrementa este valor para hacer un retardo mas largo
            BNE   RET1
            RTS
;-----------------------****Termian el retardo

;.---------------------------Subrutinas de ajuste            
ajusta_unidades:
                LDHX    #$80                    ;apuntamos a la memoria $80, que es donde empiezan los valores de ajuste
                MOV     #$80,tope               ;colocamos $80 en la memoria que servira de tope
                LDA     unidades
                ADD     tope                    ;cargamos las unidades y las sumamos a tope obteniendo asi ($80+unidades) la direccion del numero para ajustar
                STA     tope                
ciclo_unidades:                             
                feed_watchdog                   ;recorremos desde la memoria $80 hasta que llegemos a la memoria tope($80+unidades)
                CPX     tope  
                BEQ     salir_unidades
                INCX
                BRA     ciclo_unidades               
salir_unidades:                                
                LDA   ,X
                STA   unidadesA                 ;el valor de la memoria tope la guardamos en unidadesA el cual sera el valor ajustado de la unidad
                RTS
                
ajusta_decenas:
                LDHX    #$80                    ;misma explicacion que para unidades pero con decenas
                MOV     #$80,tope
                LDA     decenas
                ADD     tope
                STA     tope                
ciclo_decenas:
                feed_watchdog
                CPX     tope  
                BEQ     salir_decenas
                INCX
                BRA     ciclo_decenas               
salir_decenas:                                
                LDA   ,X
                STA   decenasA        
                RTS            
;--------------Terminan las subrutinas de ajuste            
            

;**************************************************************
;* spurious - Spurious Interrupt Service Routine.             *
;*             (unwanted interrupt)                           *
;**************************************************************
spurious:                           ; placed here so that security value
            NOP                     ; does not change all the time.
            RTI

;**************************************************************
;*                 Interrupt Vectors                          *
;**************************************************************
            ORG   $FFFA

            DC.W  spurious          ;
            DC.W  spurious          ; SWI
            DC.W  _Startup          ; Reset





Descarga .asm: aqui
Descarga el proyecto para CodeWarrior: aqui



REVISION

Este codigo que coloco fue desarrollado hace mucho tiempo por mí, así que por el momento no recuerdo del todo sí es 100% funcional o si falta ajustar algo (tengo varias versiones del mismo proyecto y coloqué aquí la mas reciente).

Pido a cualquier persona que se atreva a probarlo a comentar su funcionalidad.

tchao

sábado, 15 de diciembre de 2012

SitePlaye y Arduino. Hola Mundo por Puerto Serie

Bueno, antes que nada, hola a todos!.... Bah, pura palabrería, vamos directo a lo que entraste a esta página...

SitePlayer, si si, es el Wervidor Web mas pequeño del mundo, si bla bla... más info aqui.

Bueno, un modulo de estos no nos sirve de mucho si no poseemos algo que procese datos de mejor manera, así que comunicaremos el SitePlayer con un Arduino y al Arduino con nuestra PC, ambos por medio del Puerto UART Serial.

NOTA: Carga el SitePlayer con la pagina de ejemplo que viene en el software de desarrollo (SiteLinker)

Material:

  • Arduino (El que sea que posea dos puertos Serie Ejemplo: Mega, Due)
    • Para este caso yo estoy usando un chipKit Max32, que en pocas palabras es lo mismo que un Mega pero con mayor velocidad de reloj =D.
  • SitePlayer completo.
  • Router (o LAN a la que conectarse, o en su defecto un cable CrossOver para conectar el SitePlayer directo al PC)

Esquemático:
Esquemático en Vivo
En pdf 
Esquemático con mas rollo.
En pdf

Código de Arduino:


void setup()
{
  Serial.begin(115200);
  Serial1.begin(9600);  
}

void loop()
{
  if(Serial1.available())
  {
     Serial.write(Serial1.read()); 
  }
}


Imágenes de Muestra:
Mostrando la Pagina del SitePlayer y la IDE del arduino (Modificada para chipKit MPIDE, no te asustes es lo mismo que Arduino IDE)

Mostrando la Pagina del SitePlayer y el Serial Monitor después de enviar un "Hola Mundo"
Estos son mis cacharros

Bien, eso fue todo. A seguir desarrollando!!!

domingo, 9 de diciembre de 2012

1.- Arduino Mega ADK y Android Tutorial "Como Comenzar"

Hello World Arduino Mega ADK y Android


Esta entrada está desactualizada, para ver la información más reciente favor de ver mi nueva wiki: https://code.google.com/p/proyect-general-es/wiki/ArduinoADK_Android

Enciende y apaga un led (led pin 13) de tu Arduino Mega ADK por medio de un dispositivo Android.



Que rollo!!,, compraste un Arduino Mega ADK pensando que sería fácil programar algo, que en media hora estarías controlando ya la placa por medio de tu celular o de tu tablet?
Ooo decepción!!
Si eres nuevo en Android y en Arduino a la vez, esto si que es una jalada, pero bueno para eso está hecho este tutorial.
La página de Google ADK es bonita y explicativa? O claro que lo és (para una persona que llevo mínimo unos 5 años trabajando en este rollo), pero si queremos comenzar no nos sirve, bueno, al menos hasta que nos motivemos viendo que hicimos algo bien, ya de allí despegamos solos.

Material:

  1. Un Arduino Mega ADK
  2. Un dispositivo Android (tu celular!!!!)
  3. Los cables para conectar =P

Vista preliminar



Y así se supone debe quedar todo

Sip, así mero

Software Necesario


  1. IDE de Arduino (mínimo la 1.0.2) la cual incluye ya las librerias necesarias (Max3421e.h y Usb.h). link
  2. Obtener las librerías del ADK (Google Tuto) o si bien no deseas descargar todo el repositorio con repo, aquí te coloco lo único necesario para este tutorial y más: android_accessories_descarga. Debo aclarar que ese código viene directo del repositorio de google y no ha sido modificado.
  3. Eclipse. Si ya tienes Eclipse instala bien el plugin para programar Android o si eres novato en esto recomiendo que descargues mejor el ADT Bundle (Version de Eclipse ya lista), o si ya eres master en esto saltatelo LOL!!!.
    1. Debes tener las APIS de Google tal y como indica aqui.


APIS de Google instaladas





Comienza lo divertido.

Librearías para Arduino.
Del repositorio que descargaste de Google copia las librerías necesarias al directorio de librearías de Arduino IDE:


Copia los directorios:
*android-accesories/adk1/board/AndroidAccesory
*android-accesories/adk1/board/USB_Host_Shield
a
.../arduino-1.0.2/libraries/



Nuevo proyecto y APIS necesarias

Crea un nuevo Android Application Project y ponle de nombre ArduinoBlinkLED, haz clic en Next, Next, Finish hasta terminar.


Nuevo Proyecto Android

Deberías tener mínimo:

  • Un layout principal llamado activity_main.xml
  • Un archivo de actividad java principal llamado MainActivity.java dentro del paquete com.example.arduinoblinkled
  • Un archivo manifest llamado AndroidManifest.xml



Que bonito Código!!! Manos a la obra

Así es como se verá tu Package Explorer en Eclipse:






0
Agrega las APIS de Google al proyecto.

  1. Clic derecho a la carpeta del proyecto, propiedades
  2. Resource/Android y selecciona Google APIs como Project Buil Target






1
Cambia el código de nuestro activity_main.xml por este:

Archivo: layout/activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_width="fill_parent"
       android:id="@+id/relativeLayout1"
       android:layout_height="fill_parent"
       android:layout_weight="0.72" xmlns:android="http://schemas.android.com/apk/res/android">
       <ToggleButton
       android:text="ToggleButton"
       android:id="@+id/toggleButtonLED"
       android:layout_width="500px"
       android:layout_height="200px"
       android:layout_centerVertical="true"
       android:layout_centerHorizontal="true"
       android:textSize="50px"
       android:onClick="blinkLED"></ToggleButton>
</RelativeLayout>




2
Crea una carpeta dentro de "res" llamada xml y dentro de ella crea un nuevo archivo llamado accessory_filter.xml, coloca el siguiente codigo en el archivo:

Archivo: xml/accessory_filter.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <usb-accessory manufacturer="Manufacturer" model="Model" version="1.0" />
</resources>


3
Modifica el código de AndroidManifest.xml de tal manera que te quede algo parecido a esto:

Archivo: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.arduinoblinkled"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="13"
        android:targetSdkVersion="16" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.arduinoblinkled.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
           
            <intent-filter>
                           <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
                    </intent-filter>
           
            <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
                           android:resource="@xml/accessory_filter" />
           
        </activity>
       
        <uses-library android:name="com.android.future.usb.accessory"></uses-library>
       
    </application>

</manifest>


En este ultimo paso se declara que se usaran las librearías USB accessory y también se pide permiso de que cuando conectes el dispositivo al aparato android nuestra aplicación comience por default. Recuerda usar el minSdkVersion adecuado a tus librerías, para estar seguro puedes verificar las referencias de google.

Referencias de google:



4
Cambia el codigo del archivo MainActivity.java por este:

Archivo: com.example.arduinoblikled/MainActivity.java
package com.example.arduinoblinkled;

import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.view.View;
import android.widget.ToggleButton;

import com.android.future.usb.UsbAccessory;
import com.android.future.usb.UsbManager;

public class MainActivity extends Activity {

       // TAG is used to debug in Android logcat console
       private static final String TAG = "ArduinoAccessory";

       private static final String ACTION_USB_PERMISSION = "com.google.android.DemoKit.action.USB_PERMISSION";

       private UsbManager mUsbManager;
       private PendingIntent mPermissionIntent;
       private boolean mPermissionRequestPending;
       private ToggleButton buttonLED;

       UsbAccessory mAccessory;
       ParcelFileDescriptor mFileDescriptor;
       FileInputStream mInputStream;
       FileOutputStream mOutputStream;

       private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
                    String action = intent.getAction();
                    if (ACTION_USB_PERMISSION.equals(action)) {
                           synchronized (this) {
                                  UsbAccessory accessory = UsbManager.getAccessory(intent);
                                  if (intent.getBooleanExtra(
                                               UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                                        openAccessory(accessory);
                                  } else {
                                        Log.d(TAG, "permission denied for accessory "
                                                      + accessory);
                                  }
                                  mPermissionRequestPending = false;
                           }
                    } else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
                           UsbAccessory accessory = UsbManager.getAccessory(intent);
                           if (accessory != null && accessory.equals(mAccessory)) {
                                  closeAccessory();
                           }
                    }
             }
       };


       @Override
       public void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);

             mUsbManager = UsbManager.getInstance(this);
             mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
             IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
             filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
             registerReceiver(mUsbReceiver, filter);

             if (getLastNonConfigurationInstance() != null) {
                    mAccessory = (UsbAccessory) getLastNonConfigurationInstance();
                    openAccessory(mAccessory);
             }

             setContentView(R.layout.activity_main);
             buttonLED = (ToggleButton) findViewById(R.id.toggleButtonLED);
            
       }

       @Override
       public Object onRetainNonConfigurationInstance() {
             if (mAccessory != null) {
                    return mAccessory;
             } else {
                    return super.onRetainNonConfigurationInstance();
             }
       }

       @Override
       public void onResume() {
             super.onResume();

             if (mInputStream != null && mOutputStream != null) {
                    return;
             }

             UsbAccessory[] accessories = mUsbManager.getAccessoryList();
             UsbAccessory accessory = (accessories == null ? null : accessories[0]);
             if (accessory != null) {
                    if (mUsbManager.hasPermission(accessory)) {
                           openAccessory(accessory);
                    } else {
                           synchronized (mUsbReceiver) {
                                  if (!mPermissionRequestPending) {
                                         mUsbManager.requestPermission(accessory,mPermissionIntent);
                                        mPermissionRequestPending = true;
                                  }
                           }
                    }
             } else {
                    Log.d(TAG, "mAccessory is null");
             }
       }

       @Override
       public void onPause() {
             super.onPause();
             closeAccessory();
       }

       @Override
       public void onDestroy() {
             unregisterReceiver(mUsbReceiver);
             super.onDestroy();
       }

       private void openAccessory(UsbAccessory accessory) {
             mFileDescriptor = mUsbManager.openAccessory(accessory);
             if (mFileDescriptor != null) {
                    mAccessory = accessory;
                    FileDescriptor fd = mFileDescriptor.getFileDescriptor();
                    mInputStream = new FileInputStream(fd);
                    mOutputStream = new FileOutputStream(fd);
                    Log.d(TAG, "accessory opened");
             } else {
                    Log.d(TAG, "accessory open fail");
             }
       }


       private void closeAccessory() {
             try {
                    if (mFileDescriptor != null) {
                           mFileDescriptor.close();
                    }
             } catch (IOException e) {
             } finally {
                    mFileDescriptor = null;
                    mAccessory = null;
             }
       }

       public void blinkLED(View v){

             byte[] buffer = new byte[1];

             if(buttonLED.isChecked())
                    buffer[0]=(byte)0; // button says on, light is off
             else
                    buffer[0]=(byte)1; // button says off, light is on

             if (mOutputStream != null) {
                    try {
                           mOutputStream.write(buffer);
                    } catch (IOException e) {
                           Log.e(TAG, "write failed", e);
                    }
             }
       }

}


4
Carga el siguiente sketch a tu Arduino Mega ADK:

sketch:
____________________________________________________________
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
#define  LED_PIN  13
AndroidAccessory acc("Manufacturer",
  "Model",
  "Description",
  "1.0",
  "http://example.com",
                "0000000012345678");
void setup()
{
  // set communiation speed
  Serial.begin(115200);
  pinMode(LED_PIN, OUTPUT);
  acc.powerOn();
}
 
void loop()
{
  byte msg[0];
  if (acc.isConnected()) {
    int len = acc.read(msg, sizeof(msg), 1); // read data into msg variable
    if (len > 0) {
      if (msg[0] == 1) // compare received data
        digitalWrite(LED_PIN,HIGH); // turn on light
      else
        digitalWrite(LED_PIN,LOW); // turn off light
    }
  } 
  else
    digitalWrite(LED_PIN , LOW); // turn off light
}
____________________________________________________________



5

  • Carga la aplicación android a tu dispositivo androi (dígase celular, tableta...)
  • Conecta el Arduino a tu PC y abre un SerialMonitor
  • Conecta el dispositivo Android al Arduino
  • Listo!!!!!!!!!!!



Video de muestra


Descargas:

Proyecto de eclipse aqui.
Sketch arduino aqui.

Error Comun:
error: WProgram.h: No such file or directory






Si la IDE de Arduino te tira ese error es porque a partir de la versión 1.0.1 WProgram.h que contiene declaraciones para la API de Arduino fue cambiada por Arduino.h.

Parece que Arduino se le olvido mencionarle a Google que había cambiado su API, bueno este error se soluciona fácil basta con cambiar en todos los archivos que contengan ese error WProgram.h por Arduino.h y ya.

En nuestro caso solo debería ser en el archivo de librería AndroidAccessory.h como muestra el compilador.







Fuentes:
Especial agradecimiento a esta Web, todo el código presentado en esta entrada es de su propiedad, yo sólo me estoy encargando de colocar tips en español.

http://allaboutee.com/2011/12/31/arduino-adk-board-blink-an-led-with-your-phone-code-and-explanation/




Aquí encontré la solución del error:
https://github.com/adafruit/DHT-sensor-library/issues/1






TAGS:



  • Arduino Mega ADK Tutorial
  • Android ADK Tutorial
  • Arduino y Android
  • Arduino ADK Tuto
  • Arduino Hellow World
  • How to Begin Tutorial
  • WProgram.h error