Welcome Guest,Register Now
Log In

ANT Forum

Welcome guest, please Login or Register

   

Problems with Arc and Android

RankRankRankRank

Total Posts: 524

Joined 2012-11-15

PM

I am trying to build an android application that can accept ant data from a number of different sensors. I followed the instructions outlined in the supplied PDF that describes how to build android applications. I also used the existing demo code as a guide and for some reason the "Ant Radio Service" app does not turn on when my code executes. All of the permissions have been added to the manifest and the ant_lib project has been added as a reference project. I have seen some posts on the marketplace site that says this app does not work on the Sony Xperia Arc nor does it work on new versions of android. Has anyone had success writing their own android applications using the Sony Xperia Arc? Is there a fix to get the ant radio working? Thanks in advance.      
RankRankRankRank

Total Posts: 524

Joined 2012-11-15

PM

I am working on a project involving ANT that uses the built-in ANT radio on the Sony Xperia Arc running Android 2.3.4. I followed the directions on your "Creating ANT+ Android Applications" pdf that says to install the ANT Radio Service App from the Android Marketplace.

However, we noticed that users have been saying that the App does not work with the Sony Xperia Arc even though the Marketplace as well as Sony's website claim to support the App.

I am sure that I inserted all of the permissions that you mentioned in your pdf and we leveraged the ANT+ Demo code supplied by your website. So essentially the demo code should function as advertised.

Is anyone out there that can confirm that the ANT Radio Service App does not work with the Sony Xperia Arc? Also, is there anything we may have missed while constructing the application that can cause the app to fail when trying to use the ANT Radio?

Thanks for your help.      
Avatar
Rank

Total Posts: 5

Joined 0

PM

Just a quick update on this issue.

We were able to get the ANT+ demo working with the ANT+ Sensor simulator application.

For developing our own application we have two options: 1) adapt the demo app to suit our needs or 2) write a custom application. The problem with option 1 is that it does not use bi-directional communication and that it is specifically tailored to work with the three demo devices and our efforts to adapt the code have failed miserably. On the other hand some parts of writing a custom application are a little unclear to us:
- Creating a ServiceListener
The library does not include a constructor for creating a ServiceListener and the demo app constructor further confused the issue.
- Channel Setup: the "ant message protocol and usage" pdf does a great job describing the parameters but discusses them in terms of integers (for the most part) and the functions use them as byte inputs. For example when setting the RF frequency to 2450 the parameter should be 50. But is this 0x50 or and integer 50 converted to a byte? just a little clarification is needed here.

Really what we need is some sample code for initializing an app using ANT and sending/receiving data (similar to sample code for writing a socket connection)

Any and all help would be greatly appreciated. Thanks!      
Avatar
RankRankRankRank

Total Posts: 129

Joined 2010-11-30

PM

I do not have an Arc with Android 2.3.4, however I have successfully connected ANT devices with on Arc on versions 2.3 and 2.3.2, and with other devices running 2.3.4 (eg Active) and also 2.3.5.

Jason and seniorproject, do you have your own Arc running 2.3.4? If so, could you please provide some more information on the issue you are having; are you seeing any errors? What is the behaviour of the "ANT+ Demo" application available from ANT Wireless on the Android Market?      
Rank

Total Posts: 2

Joined 0

PM

We do have an Xperia Arc running 2.3.4. We had to go to the next firmware because we are interfacing the phone to an Android ADK board and those require 2.3.4. Anyway, as far as the state of the ANT+ demo application. We were able to successfully connect and send ANT+ sensor data to the Arc using an ANT+ enabled USB stick. Everything operates as expected with the ANT+ Demo Application.

We are trying to write our own Android application that will allow independet ANT transceivers (part ANT ANTAP281M4IB) to send data to the ANT transceiver on the Xperia Arc. We are having problems getting the "ANT Radio Service" App to actually start the radio so we can configure radio to a channel and frequency etc. Every time we try to call we get an exception saying that the ANT radio is not available.

Is it even possible to use the independent ANT transceivers and send data to the ANT transceiver on the Xperia Arc? If so, how do we go about configuring the radio in the Android code?

Thanks for your help.      
Avatar
RankRankRankRank

Total Posts: 129

Joined 2010-11-30

PM

Hi Jason,

Could you provide a log with the exact error? Remember that only one application can control the ANT part at a time - see section 3.10 (Handling multiple applications) in the "Creating ANT+ Android Applications" document available with the Android API download.      
Avatar
Rank

Total Posts: 5

Joined 0

PM

Update:

So far we have tried two separate approaches:
1) use the AntPlusManager class from the demo app to initialize the service, get the AntInterface object using getAntReceiver() and then create a channel using this interface and try to transmit to an ANT USB stick.
2) implement the ServiceListener interface ourselves and then call initService() on a new AntInterface object.

The first approach does bind to the Ant Radio Service but when we try and transmit over the created channel, the ANT USB device does not see the transmission. The second approach fails to bind to the Ant Radio Service. I have attached our code to assist in debugging.

At this point we are will to go either route that we can get working. Any and all help would be very much appreciated.

-Matt
Team SPARTA      
Avatar
Rank

Total Posts: 5

Joined 0

PM

package sdsu.sparta.arc_ant_demo;

import com.dsi.ant.AntInterface;
import com.dsi.ant.AntInterfaceIntent;
import com.dsi.ant.AntInterface.ServiceListener;
import com.dsi.ant.AntDefine;
import sdsu.sparta.arc_ant_demo.AntPlusManager;
import sdsu.sparta.arc_ant_demo.AntPlusManager.Callbacks;
import com.dsi.ant.exception.AntInterfaceException;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class 
Arc_ant_demo extends Activity //implements View.OnClickListener, AntPlusManager.Callbacks
{
    Button ant_send
;
    
AntInterface antInterface;
    
AntPlusManager antManager;
    
TextView sent_msg;
    
TextView rec_msg;
    
boolean ServConnected false;
    
byte network = (byte)0x00;
    
byte channel = (byte)0x00;
    
short device 33// 33
    
byte deviceType = (byte)0x01// 1
    
byte txType = (byte)0x01// 1
    
byte radioFrequency = (byte)0xFF// 255
    
short period 8192// 8192
    
byte channel_type = (byte)0x10// 0x10 master 0x00 slave
    
    /** Pair to any device. */
       
static final short WILDCARD 0;
    public static final 
String TAG "arc_ant_demo";
    
    
    
/** Called when the activity is first created. */
    /* (non-Javadoc)
     * @see android.app.Activity#onCreate(android.os.Bundle)
     */
    
@Override
    
public void onCreate(Bundle savedInstanceState)
    
{
        super
.onCreate(savedInstanceState);
        
setContentView(R.layout.main);
        
        
//ant_enable_disable = (Button) findViewById(R.id.ant_enable);
        
ant_send = (ButtonfindViewById(R.id.ant_send_msg);
        
sent_msg = (TextViewfindViewById(R.id.sent_msg);
        
rec_msg = (TextViewfindViewById(R.id.rec_msg);
        
//        antManager = (AntPlusManager) getLastNonConfigurationInstance();
//        antManager = null;
//        if (antManager == null)
//        {
//            antManager = new AntPlusManager(this, savedInstanceState, this);
//        }
//        else
//        {
//            antManager.resetCallbacks(this, this);
//        }
//        
//        antManager.start();
//        antInterface = antManager.getAntReceiver();
        
        
ServiceListener listener = new ServiceListener()
        
{

            
@Override
            
public void onServiceConnected()
            
{
                
// TODO Auto-generated method stub
                
Log.d(TAG"ServiceListener onServiceConnected()");
                
                try
                
{
                    antInterface
.enable();
                    
                    
boolean temp;
                    
temp antInterface.hasClaimedInterface();
                    
                    if(
temp)
                    
{
                        
// allow tx and rx of messages
                        
ServConnected true;
                    
}
                    
else
                    
{
                        antInterface
.requestForceClaimInterface("Arc Ant Demo");
                    
}
                }
                
catch (Throwable e)
                
{
                    error_message
(e.toString());
                
}
            }

            
@Override
            
public void onServiceDisconnected()
            
{
                
// TODO Auto-generated method stub
                
Log.d(TAG"ServiceListener onServiceDisconnected()");
                
                
// do not allow tx and rx of messages
                
ServConnected false;
            
}
            
        }
;
        
        
antInterface = new AntInterface();
        
antInterface.initService(getApplicationContext(), listener);
        
        try
        
{
            Boolean state 
antInterface.isServiceConnected();
            
error_message("isServiceConnected() returns " state.toString());
        
}
        
catch (Throwable e)
        
{
            error_message
(e.toString());
        
}
        
        Log
.d(TAG"On Create Exit");
    
}
    
    
public void ant_send(View view)
    
{
        
if(ServConnected)
        
{
            
try
            
{
                byte[] txBuffer 
{(byte0x00, (byte0x11, (byte0x22, (byte0x33, (byte0x44, (byte0x55, (byte0x66, (byte0x77, (byte0x8A};
                
// Tx Data
                //antInterface.ANTTxMessage(txBuffer);
                
                // Send Broadcast Data
                
antInterface.ANTSendBroadcastData(channeltxBuffer);
                
                
// Send Ack'd data
                //antInterface.ANTSendAcknowledgedData(channel, txBuffer);
                
                // Receive Broadcast data
            
}
            
catch (Throwable e)
            
{
                error_message
(e.toString());
            
}
        }
        
else
        
{
            error_message
("Service not connected");
        
}
    }

    
public void ant_channel_open(View view)
    
{
        
try
        
{
            Boolean state
;
            
            
state antInterface.hasClaimedInterface();
            
//error_message(state.toString());
            
if(!state)
            
{
                state 
antInterface.claimInterface();
            
}
            
if(!state)
            
{
                antInterface
.requestForceClaimInterface("Arc Ant Demo");
            
}
            
            
// Assign Channel
            
antInterface.ANTAssignChannel(channelchannel_typenetwork);
            
            
// Set Channel ID
            
antInterface.ANTSetChannelId(channeldevicedeviceTypetxType);
            
            
// Set RF Frequency
            
antInterface.ANTSetChannelRFFreq(channelradioFrequency);
            
            
// Set Channel Period
            
antInterface.ANTSetChannelPeriod(channelperiod);
            
            
// Open Channel
            
antInterface.ANTOpenChannel(channel);
        
}
        
catch (Throwable e)
        
{
            error_message
(e.toString());
        
}
    }
    
    
public void ant_channel_close (View view)
    
{
        
try
        
{
            
// Close Channel
            
antInterface.ANTCloseChannel(channel);
        
}
        
catch (Throwable e)
        
{
            error_message
(e.toString());
        
}
    }
    
    
private void error_message(String msg)
    
{
        
new AlertDialog.Builder(this)
        .
setTitle("Error")
        .
setMessage(msg)
        .
setNeutralButton("Ok", new DialogInterface.OnClickListener()
        
{
            
public void onClick(DialogInterface dialogint which)
            

                
// do nothing
            
}
        }
)
        .
show();
    
}

//    @Override
//    public void errorCallback()
//    {
//        // TODO Auto-generated method stub
//        
//    }
//
//    @Override
//    public void notifyAntStateChanged()
//    {
//        // TODO Auto-generated method stub
//        
//    }
//
//    @Override
//    public void notifyChannelStateChanged(byte channel)
//    {
//        // TODO Auto-generated method stub
//        
//    }
//
//    @Override
//    public void notifyChannelDataChanged(byte channel)
//    {
//        // TODO Auto-generated method stub
//        
//    }
//
//    @Override
//    public void onClick(View v)
//    {
//        // TODO Auto-generated method stub
//        
//    }
    
     
Rank

Total Posts: 2

Joined 0

PM

For some reason I made a simple change and it fixed the error. However, I am still having problems configuring the ANT interface.

I, simply, want to configure the ANT radio to listen on a specific channel and can accept data from a stand-alone ANT radio. I will not be connecting any ANT+ sensors to my android application.

Is it possible to configure the ANT radio to do what I stated above? If so, do I still follow the basic instructions in the "Creating ANT Android Applications" PDF? What functions will I need in the ANT API?

Thanks.      
Avatar
RankRankRankRank

Total Posts: 662

Joined 2012-10-09

PM

Jason,

Standard ANT functionality as described in the "ANT Message Protocol and Usage" document is available in Android (with the few differences outlined in the documentation accompanying the Android SDK). I would highly recommend using ANTwareII to mock up your setup while you are getting familiar with ANT.      
Avatar
RankRankRankRank

Total Posts: 129

Joined 2010-11-30

PM

Matt,

The way you are implementing ServiceListener is correct.

The most noticeable issue is that you are never requesting to claim the ANT interface (antInterface.claimInterface()), and then only sending messages if you have claimed it (which is never true).

Another issue is your channel configuration. Even if you are only interested in transmitting ANT messages, you still need to parse the ANT_RX_MESSAGE_ACTION Intents. Then are able to check the ANT response to your channel configuration commands. From the "RF Frequency" section of the "ANT Message Protocol and Usage" document, acceptable values for RF frequency are in the range 0 to 124.

Also, if you are failing to bind to the ANT Radio Service; ensure you have the ANT permissions in your AndroidManifest.xml.      
Avatar
Rank

Total Posts: 5

Joined 0

PM

Martin,

Thanks for you help. I fixed those issues and changed the channel period to 5Hz works and now everything works.

Code will be uploaded for anyone who wants to take a look.

-Matt
Team SPARTA      
Avatar
Rank

Total Posts: 5

Joined 0

PM

package sdsu.sparta.arc_ant_demo;

import com.dsi.ant.AntInterface;
import com.dsi.ant.AntInterfaceIntent;
import com.dsi.ant.AntMesg;
import com.dsi.ant.AntInterface.ServiceListener;
import com.dsi.ant.AntDefine;
import com.dsi.ant.exception.AntInterfaceException;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class 
Arc_ant_demo extends Activity
{
    Button ant_send
;
    
AntInterface antInterface;
    
TextView sent_msg;
    
TextView rec_msg;
    
boolean ServConnected false;
    
byte network 0;
    
byte channel 0;
    
short device 33;
    
byte deviceType 1;
    
byte txType 1;
    
byte radioFrequency 60;
    
short period 6554// = 5 Hz
    
byte channel_type = (byte)0x00// 0x10 master 0x00 slave
    
    /** Pair to any device. */
    
static final short WILDCARD 0;
    public static final 
String TAG "arc_ant_demo";
    
    
/** Called when the activity is first created. */
    /* (non-Javadoc)
     * @see android.app.Activity#onCreate(android.os.Bundle)
     */
    
@Override
    
public void onCreate(Bundle savedInstanceState)
    
{
        super
.onCreate(savedInstanceState);
        
setContentView(R.layout.main);
        
        
//ant_enable_disable = (Button) findViewById(R.id.ant_enable);
        
ant_send = (ButtonfindViewById(R.id.ant_send_msg);
        
sent_msg = (TextViewfindViewById(R.id.sent_msg);
        
rec_msg = (TextViewfindViewById(R.id.rec_msg);
        
        
ServiceListener listener = new ServiceListener()
        
{

            
@Override
            
public void onServiceConnected()
            
{
                Log
.d(TAG"ServiceListener onServiceConnected()");
                
                try
                
{
                    Boolean temp
;
                    
                    
antInterface.enable();
                    
                    
temp antInterface.claimInterface();
                    
//error_message(temp.toString());
                    
                    
if(temp)
                    
{
                        
// allow tx and rx of messages
                        
ServConnected true;
                    
}
                    
else
                    
{
                        antInterface
.requestForceClaimInterface("Arc Ant Demo");
                    
}
                }
                
catch (Throwable e)
                
{
                    error_message
(e.toString());
                
}
            }

            
@Override
            
public void onServiceDisconnected()
            
{
                Log
.d(TAG"ServiceListener onServiceDisconnected()");
                
                
// do not allow tx and rx of messages
                
ServConnected false;
            
}
        }
;
        
        
antInterface = new AntInterface();
        
antInterface.initService(getApplicationContext(), listener);
        
        
this.getApplicationContext().registerReceiver(AntMsgReceiver, new IntentFilter(AntInterfaceIntent.ANT_RX_MESSAGE_ACTION));
        
        
Log.d(TAG"On Create Exit");
    
}
    
    
public void ant_send(View view)
    
{
        
if(ServConnected)
        
{
            
try
            
{
                byte[] txBuffer 
{(byte0x00, (byte0x11, (byte0x22, (byte0x33, (byte0x44, (byte0x55, (byte0x66, (byte0x77, (byte0x8A};
                
// Tx Data
                //antInterface.ANTTxMessage(txBuffer);
                //sent_msg.setText("Tx: " + getHexString(txBuffer));
                
                // Send Broadcast Data
                
antInterface.ANTSendBroadcastData(channeltxBuffer);
                
sent_msg.setText("Broadcast: " getHexString(txBuffer));
                
                
// Send Ack'd data
                //antInterface.ANTSendAcknowledgedData(channel, txBuffer);
                //sent_msg.setText("Acknowledged: " + getHexString(txBuffer));
                
                // Receive Broadcast data
                
            
}
            
catch (Throwable e)
            
{
                error_message
(e.toString());
            
}
        }
        
else
        
{
            error_message
("Service not connected");
        
}
    }

    
public void ant_channel_open(View view)
    
{
        
try
        
{
            Boolean state
;
            
            
state antInterface.hasClaimedInterface();
            
//error_message(state.toString());
            
if(!state)
            
{
                state 
antInterface.claimInterface();
            
}
            
if(!state)
            
{
                antInterface
.requestForceClaimInterface("Arc Ant Demo");
            
}
            
            
// Assign Channel
            
antInterface.ANTAssignChannel(channelchannel_typenetwork);
            
            
// Set Channel ID
            
antInterface.ANTSetChannelId(channeldevicedeviceTypetxType);
            
            
// Set RF Frequency
            
antInterface.ANTSetChannelRFFreq(channelradioFrequency);
            
            
// Set Channel Period
            
antInterface.ANTSetChannelPeriod(channelperiod);
            
            
// Open Channel
            
antInterface.ANTOpenChannel(channel);
        
}
        
catch (Throwable e)
        
{
            error_message
(e.toString());
        
}
    }
    
    
public void ant_channel_close (View view)
    
{
        
try
        
{
            
// Close Channel
            
antInterface.ANTCloseChannel(channel);
        
}
        
catch (Throwable e)
        
{
            error_message
(e.toString());
        
}
    }
    
    
private BroadcastReceiver AntMsgReceiver = new BroadcastReceiver()
    
{
        
@Override
        
public void onReceive(Context contextIntent intent)
        
{
            
//Context mContext = context;
            
String AntIntent intent.getAction();
            
Log.d(TAG"enter onReceive: " AntIntent);
            if (
AntIntent.equals(AntInterfaceIntent.ANT_RX_MESSAGE_ACTION)) 
              
{
                 Log
.d(TAG"onReceive: ANT RX MESSAGE");
                 
                 
byte[] ANTRxMessage intent.getByteArrayExtra(AntInterfaceIntent.ANT_MESSAGE);

                 
Log.d(TAG"Rx:"getHexString(ANTRxMessage));

                 switch(
ANTRxMessage[AntMesg.MESG_ID_OFFSET])
                 
{
                     
case AntMesg.MESG_STARTUP_MESG_ID:
                         break;
                     case 
AntMesg.MESG_BROADCAST_DATA_ID:
                         
rec_msg.setText("Broadcast: " getHexString(ANTRxMessage));
                         break;
                     case 
AntMesg.MESG_ACKNOWLEDGED_DATA_ID:
                         
rec_msg.setText("Acknowledged: " getHexString(ANTRxMessage));
                         break;
                     case 
AntMesg.MESG_BURST_DATA_ID:
                         
rec_msg.setText("Burst: " getHexString(ANTRxMessage));
                         break;
                     case 
AntMesg.MESG_RESPONSE_EVENT_ID:
                         
//rec_msg.setText("Msg Response Event: " + getHexString(ANTRxMessage));
                         
break;
                     case 
AntMesg.MESG_CHANNEL_STATUS_ID:
                         break;
                     case 
AntMesg.MESG_CHANNEL_ID_ID:
                         break;
                     case 
AntMesg.MESG_VERSION_ID:
                         break;
                     case 
AntMesg.MESG_CAPABILITIES_ID:
                         break;
                     case 
AntMesg.MESG_GET_SERIAL_NUM_ID:
                         break;
                     case 
AntMesg.MESG_EXT_ACKNOWLEDGED_DATA_ID:
                         break;
                     case 
AntMesg.MESG_EXT_BROADCAST_DATA_ID:
                         break;
                     case 
AntMesg.MESG_EXT_BURST_DATA_ID:
                         break;
                 
}
              }
            
        }
        
    }
;
    
    private 
void error_message(String msg)
    
{
        
new AlertDialog.Builder(this)
        .
setTitle("Error")
        .
setMessage(msg)
        .
setNeutralButton("Ok", new DialogInterface.OnClickListener()
        
{
            
public void onClick(DialogInterface dialogint which)
            

                
// do nothing
            
}
        }
)
        .
show();
    
}

    
public static String getHexString(byte[] data)
    
{
        
if(null == data)
        
{
            
return "";
        
}

        StringBuffer hexString 
= new StringBuffer();
        for(
int i 0;data.lengthi++)
        
{
           hexString
.append("[").append(String.format("%02X"data[i] 0xFF)).append("]");
        
}

        
return hexString.toString();
    
}