In this article I will walk you through the process of developing a little Xamarin.iOS app to control a BeeWi car using Bluetooth and the External Accessory Framework. If you are interested in doing so with Android, I have already covered this topic in Ein BeeWi Car mit Xamarin.Android steuern - unfortunately in German.

Before I start, this is my first article I published in English, so please feel free and leave some feedback.

Create the project

Open up Xamarin Studio and create a new iOS project by choosing the project template you want to use. I use and recommend the "Single View Application"-template from the Unified API iPhone folder. The new Unified API provides, besides some other things, 32bit and 64bit support, which Apple requires for all apps in February 2015.

User Interface

Inside the newly created project you will find a Mainstoryboard.storyboard file. Double click that file brings the Xamarin.iOS UI-designer to the front. Design your user-interface like you wish, but don't forget that we will need to be able to send the following commands:

  • forwards
  • backwards
  • left
  • right.

As you can see by looking at my user interface, I am not a designer. image

External Accessory Framework

By providing an interface that can be used to choose which command should be send to the BeeWi car, it is time to implement the communication between the toy and our device. Therefor iOS provides some APIs that you can choose from depending on what you need.

In this case we need the External Accessory Framework. An accessory represents a device, in this case the car, in iOS, which is paired with an iPad or iPhone. Because it is possible that multiple accessories are available, we have to find the one we want to use.

var connectedAccessories = EAAccessoryManager.SharedAccessoryManager.ConnectedAccessories;
EAAccessory beeWiCar = null;

foreach (var accessory in connectedAccessories)
{
    foreach (var protocolString in accessory.ProtocolStrings)
    {
        protocolString.Contains("com.beewi.controlleur");
        beeWiCar = accessory;
        break;
    }
}

Now that we have found the car, we need to open a communication session. Such a session is represented as EASession in the External Accessory Framework that allows developers to retrieve or send data from and to the accessory. To start a session you have to provide the accessory and the protocol as parameters to the EASession-constructor. After that, you can open the stream to read and write data.

if (beeWiCar != null)
{
    try
    {
        session = new EASession(beeWiCar, "com.beewi.controlleur");
        session.Accessory.Disconnected += delegate
        {
            CloseSession();
            new UIAlertView("BeeWi Car", "BeeWi car disconnected", null, "OK").Show();
        };

        session.InputStream.Schedule(NSRunLoop.Current, NSRunLoop.NSDefaultRunLoopMode);
        session.InputStream.Open();

        session.OutputStream.Schedule(NSRunLoop.Current, NSRunLoop.NSDefaultRunLoopMode);
        session.OutputStream.Open();
    }
    catch (Exception ex)
    {
        new UIAlertView("BeeWi Car", "Ups something went wrong.", null, "OK").Show();
    }
}
else
{
    new UIAlertView("BeeWi Car", "No BeeWi car connected", null, "OK").Show();
}

Sending data

Now that the connection to the BeeWi car is established, it is time to wire up the buttons like the following.

btnForward.TouchDown += delegate
{
    SendCommand(BeeWiCarCommands.Forward_Go);
};

btnForward.TouchUpInside += delegate
{
    SendCommand(BeeWiCarCommands.Forward_Stop);
};

Every time you press a button the command for that button will be send by the SendCommand method. But we also need to send a signal that tells the car to stop doing whatever it does. Keep this in mind.

The SendCommand method will check if the session is still active and the car is connected and then send the command.

void SendCommand(BeeWiCarCommands command)
{
    try
    {
        if (session == null)
        {
            new UIAlertView("BeeWi Car", "No connection established", null, "OK").Show();
            return;
        }

        if (!session.Accessory.Connected)
        {
            new UIAlertView("BeeWi Car", "Car not connected", null, "OK").Show();
            return;
        }

        session.OutputStream.Write(new byte[]{ (byte)command }, 0, 1);
    }
    catch (Exception ex)
    {
        new UIAlertView("BeeWi Car", ex.Message, null, "OK").Show();
    }
}

Register the protocol in Info.plist

One last thing you have to do, to control the BeeWi car with your iPhone or iPad, is to register the com.beewi.controlleur protocol with your app. To do this open the Info.plist file and change the tab to Source. In this window add a new entry and select "Supported external accessory protocols" and insert "com.beewi.controlleur".

Conclusion

Playing with this tiny little toy by controlling it with a self written app is really funny. And it is pretty easy using the External Accessory Framework to play with connected devices on iOS. This is also a good starting point to learn more about sensors. Imagine to control the car by touch or by moving your phone. But this should be part of another article.

The complete code can be found on bitbucket.

comments powered by Disqus