Bluetooth Arduino + Xamarin.Android

Arduino + Xamarin.Android



Que tal estos últimos dias he estado trabajando un poco con la placa Arduino debido a la escasa información que hay principalmente para el desarrollo de aplicación para Xamarin que interactuen con el bluetooth sobre Arduino les comparto esto que espero les sea de utilidad.

Para empezar les pasare el diagrama que utilizaremos en el Arduino que es muy sencillo:


Una vez esto continuamos con el Sketch:
int led=13, msg=0;
void setup()
{
  pinMode(led,OUTPUT);
  Serial1.begin(9600); 
}
void loop()
{
  while(Serial1.available()>0)
  {
    msg=Serial1.read();
    if(msg=='e')
    {
      digitalWrite(led,HIGH);
      Serial1.write('H');
      delay(1000);
      digitalWrite(led,LOW);
      Serial1.write('E');
      delay(1000);
      digitalWrite(led,HIGH);
      Serial1.write('L');
      delay(1000);
      digitalWrite(led,LOW);
      Serial1.write('L');
      delay(1000);
      digitalWrite(led,HIGH);
      Serial1.write('O');
      delay(1000);
      digitalWrite(led,LOW);
      delay(500);
      digitalWrite(led,HIGH);
      delay(500);
      digitalWrite(led,LOW);
      delay(500);
      digitalWrite(led,HIGH);
      delay(500);
      digitalWrite(led,LOW);
      delay(500);
      digitalWrite(led,HIGH);
      delay(500);
      digitalWrite(led,LOW);
      delay(500);
      digitalWrite(led,HIGH);
      delay(500);
      digitalWrite(led,LOW);
      delay(500);
      digitalWrite(led,HIGH);
      delay(500);
      digitalWrite(led,LOW);
      delay(500);
      Serial1.write(' ');
      Serial1.write("OK");
    }
  }
}
A continuación seguimos con nuestra aplicación en Xamarin.Android antes que nada tendremos que registrar los permisos de uso de bluetooth en nuestro AndroidManifest.xml:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
Seguimos con nuestra interfaz grafica:
<linearlayout android:layout_height="fill_parent" android:layout_width="fill_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android">
    <togglebutton android:id="@+id/toggleButton1" android:layout_height="wrap_content" android:layout_width="match_parent" />
    <textview android:gravity="center_horizontal" android:id="@+id/textView1" android:layout_height="match_parent" android:layout_width="match_parent" android:text="..." android:textappearance="?android:attr/textAppearanceLarge" />
</linearlayout>
Ahora continuamos con nuestro código principal:
 using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using System.IO;
using Java.Util;
using Android.Bluetooth;
using System.Threading.Tasks;
namespace Tablet
{
    [Activity (Label = "Tablet", MainLauncher = true)]
    public class MainActivity : Activity
    {
        //Creamos las variables necesarios para trabajar
        //Widgets
        ToggleButton tgConnect;
        TextView Result;
        //String a enviar
        private Java.Lang.String dataToSend;
        //Variables para el manejo del bluetooth Adaptador y Socket
        private BluetoothAdapter mBluetoothAdapter = null;
        private BluetoothSocket btSocket = null;
        //Streams de lectura I/O
        private Stream outStream = null;
        private Stream inStream = null;
        //MAC Address del dispositivo Bluetooth
        private static string address = "00:13:01:07:01:59";
        //Id Unico de comunicacion
        private static UUID MY_UUID = UUID.FromString("00001101-0000-1000-8000-00805F9B34FB");
        protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);
            SetContentView (Resource.Layout.Main);
            //Asignacion de widgets
            tgConnect = FindViewById<ToggleButton>(Resource.Id.toggleButton1);
            Result = FindViewById<TextView>(Resource.Id.textView1);
            //Asignacion de evento del toggle button
            tgConnect.CheckedChange += tgConnect_HandleCheckedChange;
            //Verificamos la disponibilidad del sensor Bluetooth en el dispositivo
            CheckBt();
        }
        //Metodo de verificacion del sensor Bluetooth
        private void CheckBt() {
            //asignamos el sensor bluetooth con el que vamos a trabajar
            mBluetoothAdapter = BluetoothAdapter.DefaultAdapter;

            //Verificamos que este habilitado
            if (!mBluetoothAdapter.Enable()) {
                Toast.MakeText(this, "Bluetooth Desactivado",
                    ToastLength.Short).Show();
            }
            //verificamos que no sea nulo el sensor
            if (mBluetoothAdapter == null) {
                Toast.MakeText(this,
                    "Bluetooth No Existe o esta Ocupado", ToastLength.Short)
                    .Show();
            }
        }
        //Evento de cambio de estado del toggle button
        void tgConnect_HandleCheckedChange (object sender, CompoundButton.CheckedChangeEventArgs e)
        {
            if (e.IsChecked) {
                //si se activa el toggle button se incial el metodo de conexion
                Connect();
            } else {
                //en caso de desactivar el toggle button se desconecta del arduino
                if (btSocket.IsConnected) {
                    try {
                        btSocket.Close();
                    } catch (System.Exception ex) {
                        Console.WriteLine (ex.Message);
                    }
                }
            }
        }
        //Evento de conexion al Bluetooth
        public void Connect() {
            //Iniciamos la conexion con el arduino
            BluetoothDevice device = mBluetoothAdapter.GetRemoteDevice(address);
            System.Console.WriteLine("Conexion en curso" + device);

            //Indicamos al adaptador que ya no sea visible
            mBluetoothAdapter.CancelDiscovery();
            try {
                //Inicamos el socket de comunicacion con el arduino
                btSocket = device.CreateRfcommSocketToServiceRecord(MY_UUID);
                //Conectamos el socket
                btSocket.Connect();
                System.Console.WriteLine("Conexion Correcta");
            } catch (System.Exception e) {
                //en caso de generarnos error cerramos el socket
                Console.WriteLine (e.Message);
                try {
                    btSocket.Close();
                } catch (System.Exception) {
                    System.Console.WriteLine("Imposible Conectar");
                }
                System.Console.WriteLine("Socket Creado");
            }
            //Una vez conectados al bluetooth mandamos llamar el metodo que generara el hilo
            //que recibira los datos del arduino
            beginListenForData();
            //NOTA envio la letra e ya que el sketch esta configurado para funcionar cuando
            //recibe esta letra.
            dataToSend = new Java.Lang.String("e");
            writeData(dataToSend);
        }
        //Evento para inicializar el hilo que escuchara las peticiones del bluetooth
        public void beginListenForData()   {
            //Extraemos el stream de entrada
            try {
                inStream = btSocket.InputStream;
            } catch (System.IO.IOException ex) {
                Console.WriteLine (ex.Message);
            }
            //Creamos un hilo que estara corriendo en background el cual verificara si hay algun dato
            //por parte del arduino
            Task.Factory.StartNew (() => {
                //declaramos el buffer donde guardaremos la lectura
                byte[] buffer = new byte[1024];
                //declaramos el numero de bytes recibidos
                int bytes;
                while (true) {
                    try {
                        //leemos el buffer de entrada y asignamos la cantidad de bytes entrantes
                        bytes = inStream.Read(buffer, 0, buffer.Length);
                        //Verificamos que los bytes contengan informacion
                        if(bytes>0)
                        {
                            //Corremos en la interfaz principal
                            RunOnUiThread(()=>{
                                //Convertimos el valor de la informacion llegada a string
                                string valor = System.Text.Encoding.ASCII.GetString (buffer);
                                //Agregamos a nuestro label la informacion llegada
                                Result.Text = Result.Text+"\n"+valor;                    
                            });
                        }
                    } catch (Java.IO.IOException) {
                        //En caso de error limpiamos nuestra label y cortamos el hilo de comunicacion
                        RunOnUiThread(()=>{
                            Result.Text = string.Empty;                    
                        });
                        break;
                    }
                }
            });
        }
        //Metodo de envio de datos la bluetooth
        private void writeData(Java.Lang.String data) {
            //Extraemos el stream de salida
            try {
                outStream = btSocket.OutputStream;
            } catch (System.Exception e) {
                System.Console.WriteLine("Error al enviar"+e.Message);
            }

            //creamos el string que enviaremos
            Java.Lang.String message = data;

            //lo convertimos en bytes
            byte[] msgBuffer = message.GetBytes();

            try {
                //Escribimos en el buffer el arreglo que acabamos de generar
                outStream.Write(msgBuffer, 0, msgBuffer.Length);
            } catch (System.Exception e) {
                System.Console.WriteLine("Error al enviar"+e.Message);
            }
        }
    }
} 
Pueden acceder al ejemplo completo desde mi github:


Espero que les sea de utilidad esta información les dejo un video de la aplicación funcionando


Comentarios

  1. Muy bueno, estoy trabajando en mi PFC con tecnología similar... Placa de adaptación de señales diseñada y fabricada or mi + Arduino + BT + Xamarin.

    Aún estoy muy al comienzo de la fase Android, pero... le importaría que contactase cuando me surjan dudas?

    Saludos

    Muy buen trabajo

    ResponderEliminar
    Respuestas
    1. Claro que si cualquier duda puedes contactarme en cualquiera de las redes sociales o por correo

      Eliminar
  2. Hola, primero que nada muchas gracias por tu ejemplo me ayudo bastante, solo tengo una duda, espero me puedas ayudar, lo que pasa es que en mi celular al recibir los datos del bluetooth no se agregan a la vista de la aplicación, solo muestra algunos caracteres juntos y ya no hace nada, ya intente hacer ciclos para actuaizar la pantalla pero no logro hacer que se vea como en tu video. Espero me puedas ayudar por fiss, Saludoss!!

    ResponderEliminar
    Respuestas
    1. Que tal isabel estas recibiendo los datos del bluetooth del arduino ¿? hay veces que necesitas modificar el puerto serial por el cual envias los datos del arduino dependiendo del modelo hay algunos modelos que tienen mas de un puerto serial incluso hay librerias que le dan encoding a dato enviado que eso tambien es un factor muy importante debido a que al momento de recibir los datos en android (Xamarin) dependiendo de la codificiacion enviada desde Arduino http://arduino.cc/en/Serial/Print puedes leer un poco en la documentacion de arduino de igual manera si pudieras hacerme llegar tu codigo a mi correo podria darle una revisada elgoberlivel@gmail.com

      Eliminar
    2. Hola muchas gracias estuve checando lo que me dijiste y ya pude solucionar el error, resulta que lo que me estaba provocando el error era precisamente lo del serial n.n muchas gracias por tu ayuda =D

      Eliminar
    3. Que bien de igual manera tengo un ejemplo de codigo para comunicacion mediante cable OTG de manera sencilla puedes acceder al ejemplo directamente desde este link https://github.com/AlejandroRuiz/Mono/tree/master/Arduino

      Eliminar
    4. Este comentario ha sido eliminado por el autor.

      Eliminar
  3. primero que nada muy bien explicado muchas gracias en segunda tendras algun ejemplo en donde este buscando los dispositivos de bluetooth y los ponga ya sea en un textview o listview?

    ResponderEliminar
    Respuestas
    1. Claro lo estas bucando para bluetooth standard o para bluetooth LE

      Eliminar
    2. Ajam si si no es mucha molestia en que lo compartieras estoy trabajando con Android plot y gráficando los datos obtenidos por el bluetooth

      Eliminar
  4. This is great. Thank you very much
    Please .. if you Can you translate your comments to english :( it would be awesome.
    And more useful to a lot of people world wide. Thank you very much

    Now I can do this in xamarin.froms Droid via DependencyService. is it doable in iOS?

    ResponderEliminar
    Respuestas
    1. Hello sure i believe that i need to create an english version of the tutorial it also has a lot of legacy code this will work only for Android since iOS doesn't support Bluetooth 2.0 to make it work for both platform you will need to use Bluetooth LE

      Eliminar
  5. Hello, Thank you for this great example..
    I'm trying to read the data and trigger some action from a specific byte received? can you help me to figure it out? (i.e. Change Image view... if byte received == "A")

    ResponderEliminar
    Respuestas
    1. yes is really easy only check in this part of code

      RunOnUiThread(()=>{
      string valor = System.Text.Encoding.ASCII.GetString (buffer);
      if(valor.ToUpperCase().Contains("A")){
      yourImageView.SetImageDrawable(Resource.Id.myImage);
      }
      });

      Eliminar
  6. Hello.
    In my arduino Sketch, I don't have any serial available, BUT
    I CAN connect with arduino bluetooth from my android app.
    Any ideias?
    Thank you!

    ResponderEliminar
    Respuestas
    1. for this example purposes the serial communication is mandatory, ill get an Arduino to create a new english and updated version of this example for both Bluetooth 2.0 and Bluetooth LE for iOS, Android and Xamarin.Forms

      Eliminar
  7. Hola muchas gracias por el aporte, por favor ayudame con este error [BluetoothUtils] isSocketAllowedBySecurityPolicy start : device null

    ResponderEliminar
    Respuestas
    1. Que tal miguel perdón no había visto los mensajes del post aun sigues teniendo el problema?

      Eliminar
  8. I'm getting the error "Error al enviarsocket closed" can you help me, please?

    ResponderEliminar
    Respuestas
    1. Sure please contact me at alejandro@alejandroruizvarela.com to review your code

      Eliminar
    2. I sent an e-mail with the code on October, 13th. Did you received it?

      Eliminar
  9. Really great, exacly what i was trying to do.
    I can deploy your app but nothing is arriving to the android device; strange.
    Any thought on that!?
    Regards

    ResponderEliminar
  10. Hola excelente tutorial.
    No logro conectar mi hc-05 me dice un mensaje "Imposible vincular con hc-05, pin o contraseña incorrectos"
    Podras ayudarme??
    .

    ResponderEliminar
  11. Tutoriales Arduino y puerto serie.

    https://www.slideshare.net/Metaconta2/entrada-digital-con-arduino-y-visual-studio-2015

    https://es.slideshare.net/Metaconta2/apagar-y-encender-led-con-arduino-y-visual-studio-2015

    Saludos.

    ResponderEliminar
  12. I wish your comment used the International Language so anyone could easily understand your code comments.

    ResponderEliminar

Publicar un comentario

Entradas populares de este blog

Simple ListView with Xamarin.Forms

Xamarin.Forms: Get native image from ImageSource