Android Question Android BOX + Arduino connected with serial port

FrancescoS

Member
Licensed User
Longtime User
Hi Erel,
I need to connect an android BOX (ie: rikomagic: http://www.rikomagic.com/en/product/showpro_id_59_pid_19.html ) with arduino.
I would like to use the serial port to connect Android BOX and Arduino, like Your raspberry+arduino example (https://www.b4x.com/android/forum/threads/arduino-raspberry-pi.65820/#content).
You have used B4J on raspberry to activate and use the USB port.
I think I need to use b4A to do the same thing on my android box (android version 4.4.2). Correct ?
May You show me how should I do it ?
Many thanks
Francesco
 

FrancescoS

Member
Licensed User
Longtime User
Thankyou Erel for the examples.

Now I'm able to connect my Arduino UNO with My Android BOX via OTG USB.
But I have noticed that sometimes not all the bytes sent from Arduino to Android are catched.
Sometimes the word I sent was truncated in 2 word and sometimes I loose some bytes.
This is the Arduino code:
B4X:
#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize: 300
#End Region

Sub Process_Globals
   Public Serial1 As Serial
   Private astream As AsyncStreams
   Private lcd As LiquidCrystal_I2C
   Private pin7 As Pin
   Private pin13 As Pin
   Private lastButtonState As Boolean = False
   Private TimerMain As Timer
End Sub

Private Sub AppStart
   Serial1.Initialize(115200)
   astream.Initialize(Serial1.Stream, "astream_NewData", "astream_Error")
   lcd.Initialize(0x27, 16, 2)
   lcd.Backlight = True
   lcd.Write("Arduino-Android v 1.0.5")
   pin7.Initialize(7, pin7.MODE_INPUT_PULLUP)
   pin13.Initialize(13,pin13.MODE_OUTPUT)
   TimerMain.Initialize("timerMain_Tick",100)
   TimerMain.Enabled = True
End Sub

private Sub timerMain_Tick
    Dim buttonState As Boolean = pin7.DigitalRead
       If buttonState = False Then
        If lastButtonState <> buttonState Then
            'send message to android only if the button state is changed
            astream.Write("pressed")
            lastButtonState = buttonState
        End If
    Else
        If lastButtonState <> buttonState Then
            'send message to android only if the button state is changed
            astream.Write("released")
            lastButtonState = buttonState
        End If
    End If
End Sub

Sub AStream_NewData (Buffer() As Byte)
   lcd.Clear
   lcd.Write(Buffer)
End Sub

Sub AStream_Error
  
End Sub

When I press or release the pin 7 of arduino, it send the string "pressed" or "released" to android that show this word in a test box.

this is the android code:
B4X:
#Region  Project Attributes
    #ApplicationLabel: USB Serial Example
    #VersionCode: 1
    #VersionName:
    #SupportedOrientations: unspecified
    '#CanInstallToExternalStorage: false
    '#DebuggerForceStandardAssets: true
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    Dim usb As UsbSerial
    Dim astreams As AsyncStreams
End Sub

Sub Globals

    Dim btnSend, btnOpen, btnClose As Button
    Dim label1 As Label
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("1")
    btnClose.Enabled = False
    btnSend.Enabled = False
End Sub

Sub btnOpen_Click
    If usb.UsbPresent = usb.USB_NONE Then
        Log("Msgbox - no device")
        Msgbox("No USB device or accessory detected!", "Error")
        Log("Msgbox - returned")
        Return
    End If
    Log("Checking permission")
    If (usb.HasPermission) Then
        Msgbox(usb.DeviceInfo, "Device Information")
        Dim dev As Int
        dev = usb.Open(115200)       
        If dev <> usb.USB_NONE Then
            Log("Connected successfully!")
            btnOpen.Enabled = False
            btnClose.Enabled = True
            btnSend.Enabled = True           
            astreams.Initialize(usb.GetInputStream, usb.GetOutputStream, "astreams")
        Else
            Log("Error opening USB port")
        End If
    Else
        usb.RequestPermission
    End If
End Sub

Sub Astreams_NewData (Buffer() As Byte)
    Dim testo As String
    testo = BytesToString(Buffer,0,Buffer.Length,"UTF8")
    Log("NewData")
    Log(testo)
    label1.Text = ""
    label1.Text = testo
End Sub

Sub btnClose_Click
    astreams.Close
    btnOpen.Enabled = True
    btnClose.Enabled = False
    btnSend.Enabled = False   
End Sub

Sub btnSend_Click
    astreams.Write("abcde".GetBytes("UTF8"))
End Sub

Sub btnExit_Click
    ExitApplication
End Sub

Sub AStreams_Error
    Log("Error: " & LastException)
    astreams.Close
End Sub
Sub Astreams_Terminated
    Log("Terminated")
    astreams.Close
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

If You run this code, You can notice that sometimes in the android screen or in the LOG field of the IDE appear "pressed" or "released" like "pre" - "ssed" or "ressed" or "essed".
Anyone can help me ?
thanks
francesco
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Messages will be split (or merged). You should expect it.

The best solution, as you are also implementing the Arduino side, is to send binary values instead of strings.
You can send 1 for released and 2 for pressed.

If you do want to work harder then you can use AsyncStreamsText and add an end of line character to each of the messages.
https://www.b4x.com/search?query=AsyncStreamsText
 
Upvote 0

FrancescoS

Member
Licensed User
Longtime User
I think that it is better to send the header so I'm sure that the message is correct. With single binary value is not simple to verify it.
I think wrong ?
Also I need to estabilish a bidirectional communications between B4R and B4A. Ok to send end of line in B4R, but when I receive from B4A AsyncStreamsText ? I must intercept the header in B4R ?
Thanks
Francesco
 
Upvote 0

FrancescoS

Member
Licensed User
Longtime User
Also if I would like to use the AsyncStreams in "prefix mode", I have noticed that in B4R the "InitializePrefix" method is not implemented.
It is very usefull to have the "AsyncStreams" and "AsyncStreamsText" fully implemented also in B4R.
Thanks to anyone will do it.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I think wrong ?
Yes. Use binary values. It will be much simpler. You can send 2 bytes. Start with a value that describes the message and the second byte will be the message itself.

Prefix mode is not implemented in B4R. B4R works with microcontrollers with very limited RAM. Anything that needs to collect data internally is problematic.

Don't work with strings and everything will be simple.
 
Upvote 0

FrancescoS

Member
Licensed User
Longtime User
Thankyou Erel !
My goal is to use Android BOX as main computer and Arduino as simple input/output peripheral. So the communications between Android and Arduino is only to command I/O pins, get analog/digital pin values and so on.
To have analog values I need 2 bytes (0 - 1024 correct ?), so, following Your recommended method, I need to handle at least 3 bytes and I need to implement a procedure like "AsyncStreamsText" (binary version) to have the entire message fully received. Correct ?
Do You know if someone has implemeted my same necessity ?
thanks
Francesco
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Upvote 0
Top