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