Arduino Mega ADK Project and Basic4Android

CanguroCode

Active Member
Licensed User
Longtime User
Introduction
The search for communication between an embedded system and the outside world is always exciting. Being able to control the environment from the palm has been an interesting topic. In this paper is to explain simply and shortly as Android System communicate with a microcontroller mounted on a card called Arduino.
The project we are working together with a friend electronics expert (Julio-is reserved and not yet part of the forums-) and I (no expert but a little good at programming) and headed to operate this pileup . We share it with you.

Target
  • Send control signals to the digital outputs from Android to Arduino board. This may serve to: turn on or off a led up to a motor on or off (with the appropriate electronic settlement, which will not be addressed in this draft).
  • Wanted monitor temperature and humidity data that are provided by sensors. That is, send data from Arduino to Android.
  • Controlling a servomotor from Android.

Material

Software

Android Code
The code used until now for Android in Basic4Android is:
B4X:
Sub Process_Globals
    Dim Accesorio As UsbAccessory
    Dim Manejador As UsbManager
   Dim AStreams As AsyncStreams
End Sub

Sub Globals
   Dim Button1 As Button
   Dim Label1 As Label
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("Escritorio")
      If FirstTime = True Then
           EncuentraAccesorio
       End If
End Sub

Sub Activity_Resume
    EncuentraAccesorio
End Sub

Sub Activity_Pause (UserClosed As Boolean)
End Sub

Sub EncuentraAccesorio
   Manejador.Initialize
    Dim ListaAccesorios () As UsbAccessory
   ListaAccesorios = Manejador.GetAccessories

      For i = 0 To ListaAccesorios.Length - 1
                 If ListaAccesorios(i).Description = "Prueba" Then
                    Accesorio = ListaAccesorios(i)
               Log(Accesorio.Description)
               Log(Accesorio.Manufacturer)
               Log(Accesorio.Serial)
             End If
        Next
            
      If Accesorio <> Null Then
         Dim Permiso As Boolean
         Dim r As Reflector
         r.Target = Accesorio
         Permiso= Manejador.HasAccessoryPermission(r.GetField("accessory"))

         If Permiso==True Then
            Manejador.OpenAccessory(Accesorio)
            Log (AStreams.IsInitialized)
            If AStreams.IsInitialized==False Then
               Try
                  AStreams.Initialize(Accesorio.InputStream,Accesorio.OutputStream,"AStreams")
               Catch
                  Log("No se inicializo AncyStreams")
               End Try
         End If
         Else 
            Manejador.RequestAccessoryPermission(r.GetField("accessory"))
            Permiso= Manejador.HasAccessoryPermission(r.GetField("accessory"))
            
               If Permiso Then
                  Manejador.OpenAccessory(Accesorio)
               End If
            
               If AStreams.IsInitialized==False Then
                  Try            
                     'AStreams.Initialize(Accesorio.InputStream,Accesorio.OutputStream,"AStreams")
                     AStreams.InitializePrefix(Accesorio.InputStream,False,Accesorio.OutputStream , "AStreams")
                  Catch
                     Log("No se inicializo AncyStreams")
                  End Try
               End If
         End If
      Else
         Log("No hay accesorio reconocido")
      End If
   
End Sub

'Funcion especial de los AStreams////////////////////////////////////
Sub AStreams_NewData (Buffer() As Byte)
    Dim msg As String
    msg = BytesToString(Buffer, 0, Buffer.Length, "UTF8")
    Label1.Text=msg
   'ToastMessageShow(msg, False)
    Log(msg)
End Sub

Sub AStreams_Error
    ToastMessageShow(LastException.Message, True)
End Sub
'///////////////////////////////////////////////////////////////////


Sub Button1_Click
   If AStreams.IsInitialized=False Then Return
   Dim Cadena As String
   Cadena="Hola"
   AStreams.Write(Cadena.GetBytes("UTF8"))
End Sub
The initial idea of ​​the code I got from the post created by the user Diego:
http://www.b4x.com/forum/basic4android-updates-questions/18292-arduino-uno-usb-host.html#post105928


Arduino Code
Before compiling the code the libraries should be placed in the Libraries folder Arduino Compiler. But the code will not compile and mark errors. The code used until now for Arduino:

B4X:
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>

#define ARRAY_SIZE 25

AndroidAccessory acc("Google, Inc.",
           "Prueba",
           "Prueba",
           "1.0",
           "http://www.android.com",
           "0000000012345678");

char hello[ARRAY_SIZE] = {'H','o','l','a',' ',
'M','u','n','d','o',' ', 'd', 'e', 's', 'd', 'e ',' ',
'A', 'r', 'd', 'u', 'i', 'n', 'o', '!'};

byte rcvmsg[255];
byte sntmsg[ARRAY_SIZE];

void setup() 
{
Serial.begin(115200);
acc.powerOn();
}

void loop() {
if (acc.isConnected()) {
 //read the sent text message into the byte array
 int len = acc.read(rcvmsg, sizeof(rcvmsg), 1);
  if (len > 0) 
  {
    
       for(int x = 0; x < 4; x++) 
       {
       Serial.print((char)rcvmsg[x]);
       delay(250);
       }
       Serial.println();
       delay(250);
     
    
   }

 for(int x = 0; x < ARRAY_SIZE; x++) 
  {
  sntmsg[x] = hello[x];
  }
 acc.write(sntmsg, ARRAY_SIZE);
 delay(250);
 }//Fin del if que verifica si el accesorio esta conectado
}


Conclusions
To date September 13 has managed to send a string ("Hola") to Arduino which can be viewed via the Serial monitor. Also been sent from Arduino to Android the same chain and can be seen in a Label from Android. Thanks to the data type AnsyncString sending and receiving of data can be simultaneously (or so it appears to the end user) and the system will not lock -Correct me if I'm wrong-.

Other comments and Earrings
This code is not yet finalized and is in development, so it is not optimized, maybe you can make a better way, for now it works this way. Lack implement appropriate communication protocol (I'm thinking of using the same Google uses in its Demokit). As I said, I will upload progress to the page.

Acknowledgements

Erel. For providing the correction to obtain permits for accessory
Jerel.For providing the correction in the code to write and send data

Brief bibliography and links
Connect via USB Sockets

AsyncStreams Tutorial

USB Library information

Sorry for the spelling, I'm from mexico and I have little knowledge of the English language, If you have any mistake or any comments, please let me know, this will be welcome.

Regards.
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
You are correct. The method signature is wrong. It will be fixed.
For now you can use this code (requires Reflection library):
B4X:
Dim r As Reflector
r.Target = Accesorio
Manejador.HasAccessoryPermission(r.GetField("accessory"))

This issue is fixed in the library provided with B4A V2.20. The reflection code should not be used with that version.
 
Upvote 0

CanguroCode

Active Member
Licensed User
Longtime User
You are correct. The method signature is wrong. It will be fixed.
For now you can use this code...

Thank you for your quick response, I was a big help and solve the problem. Update you gave me to the main post. I managed to make the Arduino to connect and ask permission to Android. I'm at the part of sending a data byte, but do not know what command to use.
I researched and Java you declare a variable as follows:

B4X:
private FileInputStream mInputStream;
private FileOutputStream mOutputStream;

And to send the data in java would be:

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

In B4A am doing as follows:

B4X:
Dim Dato As String
   Dim Buffer (3) As Byte
        Dim DatoOutput As OutputStream
   Dato=48
   Buffer=Dato.GetBytes("UTF8")
   DatoOutput.InitializeToBytesArray(3)
   Try
      DatoOutput.WriteBytes(Buffer,0,3)
      Log(Accesorio.OutputStream)
   Catch
      Log("Dato no enviado")
   End Try

But the sentence "DatoOutput.WriteBytes (Buffer, 0,3)" does not run and immediately executes the code CATCH. And therefore failed to receive anything on the side of the Arduino. I have reached the conclucion that the variable is not adequate OutputStream. What is the proper way to send this byte?

Thanks in advance
Greetings from Mexico
 
Upvote 0

PaulR

Active Member
Licensed User
Longtime User
I had a problem sending raw data over UDP - my problem was the encoding type.

UTF-8 changes the bytes you "think" you are sending, or even the number of bytes you think you are sending - eg there is no such thing as a 0xFF for the first byte in UTF-8 so you can never send that. I used "US-ASCII" for my raw data.
 
Upvote 0

CanguroCode

Active Member
Licensed User
Longtime User
I had a problem sending raw data over UDP - my problem was the encoding type.

UTF-8 changes the bytes you "think" you are sending, or even the number of bytes you think you are sending - eg there is no such thing as a 0xFF for the first byte in UTF-8 so you can never send that. I used "US-ASCII" for my raw data.

Tanks for the tip! Testing......
 
Upvote 0

CanguroCode

Active Member
Licensed User
Longtime User
After being reviewing in detail the Forum I found information that has been helpful.
Right now, I'm trying to use the library Random Access File, AnsyncStreams data type. When the Arduino sends data to Android, no problem and displays perfectly. But when Android wants to send data on error: "Bad File Number" and unable to send the data to the Arduino.
To initialize the variable of type AnsyncStreams do so:

B4X:
Manejador.OpenAccessory(Accesorio)

If AStreams.IsInitialized==False Then
Try
AStreams.Initialize(Accesorio.InputStream,Accesorio.OutputStream,"AStreams")
Catch
Log("No se inicializo AncyStreams")
End Try
End If

Do not use "AStreams.InitializePrefix" By closing the application without indicating the type of exception, so use "AStreams.Initialize".
To send write now I do so:

B4X:
Sub Button1_Click
   If AStreams.IsInitialized=False Then Return
   Dim Dato As String
   Dim Buffer () As Byte
   Dato="Hola"
   Buffer=Dato.GetBytes("UTF8")
   AStreams.Write2(Buffer,0,Buffer.Length)
End Sub


But pressing the button sends me an exception with the message: "Bad File Number"

I updated all the code I am using in the main post to see the problem in detail.
Any idea? Thank you very much for the help.
 
Upvote 0

CanguroCode

Active Member
Licensed User
Longtime User
Still working with the same type of data but still can not get pass the error "Bad File Number". I searched the forum but have not been successful. Does anyone know anything about this error?

thanks
 
Upvote 0

Jonas

Member
Licensed User
Longtime User
I'm looking forward to see your running the Arduino ADK with B4A. I have some projects of my own I'm planning to use the Arduino ADK or the IOIO.

For your problem I cant say much but I see in my apps using asynstreams i use Astreams.Write(Bufferstring)

so in your case

B4X:
Sub Button1_Click    
If AStreams.IsInitialized=False Then Return
    Dim Dato As String
'    Dim Buffer () As Byte
    Dato="Hola"
'    Buffer=Dato.GetBytes("UTF8")
    AStreams.Write(Dato.GetBytes("UTF8"))
' or     AStreams.Write(Dato)
End Sub

I'm not sure if this going to help but its how I solve the Astream write when using Bluetooth communication.

/Jonas
 
Upvote 0

CanguroCode

Active Member
Licensed User
Longtime User
I'm looking forward to see your running the Arduino ADK with B4A. I have some projects of my own I'm planning to use the Arduino ADK ...
Thanks Jonas! That was exactly the problem. I do not know the reason why the compiler and acts well, since he's having a data of the same type (Byte). You saved the day. :sign0098:.

In a few moments I update the main post with the code working properly. And later I'll upload the Arduino code.

greetings
 
Last edited:
Upvote 0

Jonas

Member
Licensed User
Longtime User
I think the problem with your code using Write2 is the length of buffer you supply.

Try

B4X:
Sub Button1_Click
    If AStreams.IsInitialized=False Then Return
    Dim Dato As String
    Dim Buffer () As Byte
    Dato="Hola"
    Buffer=Dato.GetBytes("UTF8")
    AStreams.Write2(Buffer,0,Buffer.Length -1)
End Sub

I added Buffer.Length - 1


Do you have to use custom firmware in the Mega ADK or is it preloaded?
 
Upvote 0

CanguroCode

Active Member
Licensed User
Longtime User

Hi, thanks for the help. Yes, it worked. I managed the communication between Android and Arduino successfully!. Thanks for your support and advice. I updated the code in the main post Basic4Android. Please review it and give me your feedback. The code is not optimized, but it works. As I improve the code, I'll upload the post.

I have the same Arduino Mega ADK, and is equal to your samples page. Success in your project.
regards
 
Last edited:
Upvote 0

bluedude

Well-Known Member
Licensed User
Longtime User
Where can I find these two?

Two libraries for Arduino: USB_Host_Shield and AndroidAccesory (outstanding links)

Cheers,
 
Upvote 0

bluedude

Well-Known Member
Licensed User
Longtime User
Mm, I see this code does not do anything with sensors etc. It seems not to be finished?

Do you have a sensor reading sample?
 
Upvote 0

CanguroCode

Active Member
Licensed User
Longtime User
Mm, I see this code does not do anything with sensors etc. It seems not to be finished?

Do you have a sensor reading sample?

Hello, the code is not finished yet. But if you already manage to send data between Android and Arduino sensor reading is simple. Yes I have the code to read data from a temperature sensor. Later it will integrate the project and I'll upload the code.

Thanks for the comments, Greetings
 
Upvote 0

bluedude

Well-Known Member
Licensed User
Longtime User
Not sure why you provide the whole Arduino compiler, don't need that. Which Google ADK libraries do you use? ADK2011 or ADK2012?

I just downloaded the USB host and Accessory of ADK2011.

Would be nice to have a sensor sample.

Cheers,
 
Upvote 0
Top