Simple REST with .Net

I have recently been working on a website that integrates with various cloud storage sites including Dropbox, SkyDrive, and GoogleDocs. All of these provide great REST APIs (although GoogleDocs uses atom feeds which are ugly!); however, few provide a good SDK for .Net. There are a few good libraries for doing REST in .Net, and I decided to give RestSharp try. Although this is a great library, it did not do everything I needed, and it did a lot more than I needed as well.

I figure that there are many other people like me that want to take advantage of the great REST services that are available, so I’d like to share a simple REST class that I created that has been a HUGE help for me. I really like how RestSharp worked, so my API is similar; however, my version has only the features that I needed, so it is much smaller. If you are interested, feel free to give it a try. This code uses Json.NET to serialize the JSON objects. Here is the complete code as well as a few examples for connecting with popular REST services.

using System;
using System.IO;
using System.Net;
using System.ServiceModel.Syndication;
using System.Text;
using System.Xml;
using Newtonsoft.Json;

namespace Freedom.Data.Cloud.Rest
{
    public enum Method
    {
        GET, POST, PUT
    }

    public struct ContentTypes
    {
        // Just a few content types that I used
        // This struct can obviously be extended for whatever your needs are!
        public const string APPLICATION_JSON = "application/json";
        public const string APPLICATION_ATOM_PLUS_XML = "application/atom+xml";
        public const string APPLICATION_X_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded";
        public const string IMAGE_JPEG = "image/jpeg";
    }

    public class RestException : Exception
    {
        public RestException() : base() { }
        public RestException(string message) : base(message) { }
        public RestException(string message, Exception ex) : base(message, ex) { }
    }

    /* This is a simple class that only exposes the methods and properties
     * that I needed.  Feel free to extend this for whatever your needs might be. */
    public class RestRequest
    {
        /* I have not needed to expose the actual HttpWebRequest object
         * however that would be simple to do if you needed to.  Another
         * option is to just wrap the properties that you need as I have
         * done with the Uri. */
        private HttpWebRequest _request;

        public string Uri
        {
            get { return _request.Address.AbsoluteUri; }
        }

        public WebResponse Response { get; private set; }

        public RestRequest(string uri, Method method)
        {
            _request = (HttpWebRequest)WebRequest.Create(uri);
            _request.Method = method.ToString();
        }

        public void SetContentType(string value)
        {
            _request.ContentType = value;
        }

        public void SetContentLength(long value)
        {
            _request.ContentLength = value;
        }

        public void AddHeader(string name, string value)
        {
            _request.Headers.Add(name, value);
        }

        public void AddBody(string value)
        {
            byte[] bytes = Encoding.ASCII.GetBytes(value);
            AddBody(bytes);
        }

        public void AddBody(byte[] bytes, int chunkSize = 1024)
        {
            using (Stream stream = _request.GetRequestStream())
            {
                int offset = 0;
                while (offset < bytes.Length)                 {                     int count = (chunkSize > bytes.Length - offset ? bytes.Length - offset : chunkSize);
                    stream.Write(bytes, offset, count);
                    offset += count;
                }
            }
        }

        public void AddBody(object value)
        {
            AddBody(JsonConvert.SerializeObject(value));
        }

        public string GetResponseHeader(string name)
        {
            return Response.Headers[name];
        }

        public string Execute()
        {
            try
            {
                Response = _request.GetResponse();
                string content = null;
                using (StreamReader reader = new StreamReader(Response.GetResponseStream()))
                {
                    content = reader.ReadToEnd();
                }
                return content;
            }
            catch (WebException ex)
            {
                Response = ex.Response;

                string error = null;
                using (StreamReader reader = new StreamReader(Response.GetResponseStream()))
                {
                    error = reader.ReadToEnd();
                }
                throw new RestException(error, ex);
            }
        }

        public T ExecuteJson<T>() where T : class
        {
            string content = Execute();
            return JsonConvert.DeserializeObject(content);
        }

        public SyndicationFeed ExecuteSyndicationFeed()
        {
            string content = this.Execute();

            SyndicationFeed feed = null;
            using (StringReader sr = new StringReader(content))
            {
                using (XmlReader reader = XmlReader.Create(sr))
                {
                    feed = SyndicationFeed.Load(reader);
                }
            }

            return feed;
        }

        public SyndicationItem ExecuteSyndicationItem()
        {
            string content = this.Execute();

            SyndicationItem item = null;
            using (StringReader sr = new StringReader(content))
            {
                using (XmlReader reader = XmlReader.Create(sr))
                {
                    item = SyndicationItem.Load(reader);
                }
            }

            return item;
        }
    }
}

Now for a few examples. One of my main requirements was to upload files. This was typically done by setting the content of the request to the raw file bytes.

SkyDrive:

I created a simple object for the Json to serialize to (only using the properties I needed):

    public class UploadResponse
    {
        public string Id { get; set; }
        public string Source { get; set; }
    }

And here is how I actually uploaded the file:

        public string UploadFile(string accessToken, string folderId, string fileName, byte[] bytes)
        {
            RestRequest request = new RestRequest(
                string.Format("{0}{1}/files/{2}?access_token={3}",
                Settings.Default.APIUrl,
                folderId,
                fileName,
                accessToken), Method.PUT);

            request.AddBody(bytes);
            UploadResponse ur = request.ExecuteJson<UploadResponse>();
            return ur.Id;
        }

Getting a list of files or folders is equally as easy. First I created a few classes for the Json to serialize to:

    public class SkyDriveFileList
    {
        public List Data { get; set; }
    }

    public class SkyDriveFile
    {
        public string id { get; set; }
        public string name { get; set; }
        public string upload_location { get; set; }
        public DateTime? when_taken { get; set; }
        public string type { get; set; }
        public string source { get; set; }
        public DateTime created_time { get; set; }
        public DateTime updated_time { get; set; }
        public List images { get; set; }
    }

    public class SkyDriveImage
    {
        public string source { get; set; }
        public int width { get; set; }
        public int height { get; set; }
        public SkyDriveImageType type { get; set; }
    }

And here is the actual request:

        public SkyDriveFileList GetFolders(string accessToken, string folderId)
        {
            RestRequest request = new RestRequest(
                string.Format("{0}{1}/files?filter=folders&access_token={2}",
                Settings.Default.APIUrl,
                folderId,
                accessToken), Method.GET);

            return = request.ExecuteJson<SkyDriveFileList>();
        }

GoogleDocs:

GoogleDocs isn’t quite as pretty because is uses atom, but here is the code to get and create a collection:

        public SyndicationItem GetCollection(string collectionId)
        {
            RestRequest request = new RestRequest(string.Format("{0}/feeds/default/private/full/{1}", GoogleDocsAPIURL, HttpUtility.UrlEncode(collectionId)), Method.GET);
            request.AddHeader("Gdata-Version", "3.0");
            request.AddHeader("Authorization", string.Format("Bearer {0}", _accessToken));
            return request.ExecuteSyndicationItem();
        }

        public SyndicationFeed GetCollection(string parentId, string name)
        {
            RestRequest request = new RestRequest(string.Format("{0}/feeds/default/private/full/{1}/{2}?title={3}", GoogleDocsAPIURL, HttpUtility.UrlEncode(parentId), parentId == "-" ? "folder" : "contents", HttpUtility.UrlEncode(name)), Method.GET);
            request.AddHeader("Gdata-Version", "3.0");
            request.AddHeader("Authorization", string.Format("Bearer {0}", _accessToken));
            SyndicationFeed feed = request.ExecuteSyndicationFeed();
            return feed.Items.FirstOrDefault();
        }

        public SyndicationFeed CreateCollection(string parentId, string name)
        {
            string uri = string.Format("{0}/feeds/default/private/full", GoogleDocsAPIURL);
            if (parentId != null) uri = string.Format("{0}/{1}/contents", uri, parentId);

            RestRequest request = new RestRequest(uri, Method.POST);
            request.AddHeader("Gdata-Version", "3.0");
            request.AddHeader("Authorization", string.Format("Bearer {0}", _accessToken));
            request.SetContentType(ContentTypes.APPLICATION_ATOM_PLUS_XML);
            request.AddBody(CreateCollectionAtom(name));
            return request.ExecuteSyndicationItem();
        }

        private string CreateCollectionAtom(string title)
        {
            SyndicationItem item = new SyndicationItem() { Id = string.Empty };
            item.Title = new TextSyndicationContent(title);

            SyndicationCategory category = new SyndicationCategory() { Scheme = "http://schemas.google.com/g/2005#kind" };
            category.AttributeExtensions.Add(new System.Xml.XmlQualifiedName("term"), "http://schemas.google.com/docs/2007#folder");

            item.Categories.Add(category);

            StringBuilder sb = new StringBuilder();

            using (XmlWriter atomWriter = XmlWriter.Create(sb))
            {
                Atom10ItemFormatter atomFormatter = new Atom10ItemFormatter(item);
                atomFormatter.WriteTo(atomWriter);
            }

            string atom = sb.ToString();
            atom = atom.Remove(atom.IndexOf(""), 6);

            return atom;
        }

Uploading a file with GoogleDocs is a little more tricky because it uses a resumable link:

        public string UploadImage(string collectionId, string fileName, byte[] bytes)
        {
            SyndicationItem item = GetCollection(collectionId);
            string atom = CreateUploadAtom(fileName);
            string resumableLink = item.Links.Where(p => p.RelationshipType.Contains("#resumable-create-media")).Single().Uri.ToString();

            RestRequest request = new RestRequest(string.Format("{0}?convert=false", md.ResumableCreateMedia), Method.POST);
            request.AddHeader("Gdata-Version", "3.0");
            request.AddHeader("Authorization", string.Format("Bearer {0}", _accessToken));
            request.SetContentLength(atom.Length);
            request.SetContentType(ContentTypes.APPLICATION_ATOM_PLUS_XML);
            request.AddHeader("X-Upload-Content-Type", ContentTypes.IMAGE_JPEG);
            request.AddHeader("X-Upload-Content-Length", bytes.Length.ToString());
            request.AddBody(atom);
            string content = request.Execute();
            string location = request.GetResponseHeader("Location");

            RestRequest putRequest = new RestRequest(location, Method.PUT);
            putRequest.SetContentLength(bytes.Length);
            putRequest.SetContentType(ContentTypes.IMAGE_JPEG);
            putRequest.AddBody(bytes);
            SyndicationItem item = putRequest.ExecuteSyndicationItem();

            return item.Id.Substring(item.Id.LastIndexOf("/") + 1);
        }

        private string CreateUploadAtom(string title)
        {
            SyndicationItem item = new SyndicationItem() { Id = string.Empty };
            item.Title = new TextSyndicationContent(title);
            item.AttributeExtensions.Add(new XmlQualifiedName("docs", XNamespace.Xmlns.ToString()), "http://schemas.google.com/docs/2007");

            StringBuilder sb = new StringBuilder();
            using (XmlWriter atomWriter = XmlWriter.Create(sb))
            {
                Atom10ItemFormatter atomFormatter = new Atom10ItemFormatter(item);
                atomFormatter.WriteTo(atomWriter);
            }

            string atom = sb.ToString();
            atom = atom.Remove(atom.IndexOf(""), 6);

            return atom;
        }

Obviously these are just a few examples of what you may need; however, hopefully it is enough to get you going. Actually, just in case you were interested, I’ll give you one more example! All of these APIs require authentication, typically OAuth V1 or V2. Here is the authentication code for connecting with SkyDrive:

First a class to represent the OAuth token:

    public class OAuthV2Token
    {
        public string Access_Token { get; set; }
        public string Refresh_Token { get; set; }
        public string Authentication_Token { get; set; }
        public int Expires_In { get; set; }
        public string Scope { get; set; }
    }

Here is a typical process for authorizing a client with OAuth V2:

  1. Send client to service for them to authorize your application.
  2. Service responds by redirecting back to your size with an authorization code
  3. Use authorization code to request a refresh token and access token
  4. Store refresh token to use for future authorization

Here is the code I used to accomplish this feat:

        public OAuthToken GetOAuthTokenFromRefreshToken(string refreshToken, string callback)
        {
            string parameters = String.Format("client_id={0}&redirect_uri={1}&client_secret={2}&refresh_token={3}&grant_type=refresh_token",
                HttpUtility.UrlEncode(Settings.Default.ClientId),
                HttpUtility.UrlEncode(callback),
                HttpUtility.UrlEncode(Settings.Default.ClientSecret),
                HttpUtility.UrlEncode(refreshToken));

            return GetAccessToken(parameters);
        }

        public OAuthToken GetOAuthTokenFromAuthCode(string authorizationCode, string callback)
        {
            string parameters = String.Format("client_id={0}&redirect_uri={1}&client_secret={2}&code={3}&grant_type=authorization_code",
                HttpUtility.UrlEncode(Settings.Default.ClientId),
                HttpUtility.UrlEncode(callback),
                HttpUtility.UrlEncode(Settings.Default.ClientSecret),
                HttpUtility.UrlEncode(authorizationCode));

            return GetAccessToken(parameters);
        }

        public string GetAuthenticationURL(string callbackURL)
        {
            return string.Format("{0}{1}?client_id={2}&scope={3}&response_type=code&redirect_uri={4}",
                Settings.Default.OAuthAPIUrl,
                "authorize",
                HttpUtility.UrlEncode(Settings.Default.ClientId),
                HttpUtility.UrlEncode(Settings.Default.Scope),
                HttpUtility.UrlEncode(callbackURL));
        }

        private static OAuthV2Token GetAccessToken(string parameters)
        {
            RestRequest request = new RestRequest(string.Format("{0}{1}?{2}", Settings.Default.OAuthAPIUrl, OAuthAction.token.ToString(), parameters), Method.GET);
            return request.ExecuteJson<OAuthV2Token>();
        }

Hopefully this has been helpful. As I mentioned, my Rest class is very simple and only served to fulfill my personal needs; although, I imagine this class will be easy to extend to fulfill your needs as well. Have fun!

Tutorial: Android to Microcontroller via Bluetooth (Part 2)

It has been a while since I worked on this so hopefully I still remember the important parts.  Let me know if you have questions.

The first think you will need to do is pair your bluetooth device with your Android phone.  This will be a little different depending on what bluetooth chip you are using.  For the BluSmirf, make sure it is powered up and scan for devices from your phone.  You should see something starting with “FireFly”.  When you request to pair you will be asked for a pin, enter “1234″.

Now that your paired, you will need to write the code for your Android application.  A lot of this code came from the Android documentation for bluetooth which is pretty good.  You will essentially create two threads, one for connecting, and one for writing.  The next two sections of code were part of a class called BluetoothService in our project.  Here is the code we used for the threads:

public class ConnectThread extends Thread {

		public final BluetoothDevice mmDevice;
		public final BluetoothSocket mmSocket;

		public ConnectThread(BluetoothDevice device, UUID uuid){
			Log.i(TAG, "CREATE ConnectThread");
			mmDevice = device;

			BluetoothSocket tmpSocket = null;
			try {
				tmpSocket = device.createRfcommSocketToServiceRecord(uuid);
			} catch (Exception createException) {
				Log.e(TAG, "Socket create failed: " + createException.getMessage());
			}
			mmSocket = tmpSocket;
		}

		public void run(){
			Log.i(TAG, "BEGIN ConnectThread");

			try {
				mmSocket.connect();
			} catch(IOException connectException){
				try {
					Log.e(TAG, "Socket connect failed: " + connectException.getMessage());
					mmSocket.close();
				} catch(IOException closeException){
					Log.e(TAG, "Socket close failed: " + closeException.getMessage());
				}
				connectionFailed();
			}
			connected(mmSocket);
		}

		public void cancel(){
			Log.i(TAG, "CANCEL ConnectThread");

			try {
				mmSocket.close();
			} catch(IOException closeException) {
				Log.e(TAG, "Socket close failed: " + closeException.getMessage());
			}
		}

	}

	public class ConnectedThread extends Thread {

		private final InputStream mmInStream;
		private final OutputStream mmOutStream;
		private final BluetoothSocket mmSocket;

		public ConnectedThread(BluetoothSocket socket){
			Log.i(TAG, "CREATE ConnectedThread");
			mmSocket = socket;

			InputStream tmpIn = null;
			OutputStream tmpOut = null;

			try {
				tmpIn = socket.getInputStream();
				tmpOut = socket.getOutputStream();
			} catch(IOException streamException){
				Log.e(TAG, "Failed to get input and output streams: " + streamException.getMessage());
			}

			mmInStream = tmpIn;
			mmOutStream = tmpOut;
		}

		public void run(){
			Log.i(TAG, "BEGIN ConnectedThread");
			byte[] buffer = new byte[1024];
			int bytes = 0;

			while(true){

				try {
					bytes = mmInStream.read(buffer);
					if(bytes >= 0){
						mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
					}

				} catch(IOException readException){
					Log.e(TAG, "Failed to read from input stream: " + readException.getMessage());
					connectionLost();
					break;
				}
			}
		}

		public void write(byte[] buffer){

			try {
				for(byte b : buffer){
					mmOutStream.write(new byte[] { b });
					Thread.sleep(20);
				}
				mmOutStream.flush();
				mHandler.obtainMessage(MESSAGE_WRITE, -1, -1, buffer).sendToTarget();

			} catch(Exception writeException){
				Log.e(TAG, "Failed to write to output stream: " + writeException.getMessage());
				connectionLost();
			}

		}

		public void cancel(){
			try {
				mmSocket.close();
			} catch(Exception closeException){
				Log.e(TAG, "Failed to close socket connection: " + closeException.getMessage());
			}
		}
	}

And here is the code we used to wire it all up:

	private final Handler mHandler;
	private int mState;

	private ConnectThread mConnectThread = null;
	private ConnectedThread mConnectedThread = null;

	public static final int STATE_NONE = 0;
	public static final int STATE_CONNECTING = 2;
	public static final int STATE_CONNECTED = 3;

	public static final int MESSAGE_STATE_CHANGE = 4;
	public static final int MESSAGE_TOAST = 5;
	public static final int MESSAGE_READ = 6;
	public static final int MESSAGE_WRITE = 7;

	public static final String TOAST = "toast";

	public BluetoothService(Handler handler){
		mHandler = handler;
	}

	public synchronized void setState(int state){
		mState = state;

		// pass new state to handler so UI can update
		mHandler.obtainMessage(MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
	}

	public synchronized int getState(){
		return mState;
	}

	public void connect(BluetoothDevice device, UUID uuid){
		cancelConnectThread();
		mConnectThread = new ConnectThread(device, uuid);
		mConnectThread.start();
		setToast("Connecting...");
		setState(STATE_CONNECTING);
	}

	public void close(){
		cancelConnectThread();
		cancelConnectedThread();
		setState(STATE_NONE);
	}

	public void connected(BluetoothSocket socket){
		cancelConnectedThread();
		mConnectedThread = new ConnectedThread(socket);
		mConnectedThread.start();
		setToast("Connection successfull!");
		setState(STATE_CONNECTED);
	}

	public void write(byte[] buffer){
		if(mConnectedThread != null && mState == STATE_CONNECTED){
			mConnectedThread.write(buffer);
		}
	}

	private void cancelConnectThread(){
		if(mConnectThread != null) mConnectThread.cancel();
	}

	private void cancelConnectedThread(){
		if(mConnectedThread != null) mConnectedThread.cancel();
	}

	private synchronized void setToast(String toast){
		Message message = mHandler.obtainMessage(MESSAGE_TOAST);
		Bundle bundle = new Bundle();
		bundle.putString(TOAST, toast);
		message.setData(bundle);
		message.sendToTarget();
	}

	private synchronized void connectionFailed(){
		setToast("Device connection failed.");
		setState(STATE_NONE);
	}

	private synchronized void connectionLost(){
		setToast("Device connection lost.");
		setState(STATE_NONE);
	}

To use this service you will need to scan for bluetooth devices, find the one you are interested in, and start talking!  The service uses a handler to communicate with the calling class. Notice in the code above the method setState(STATE). This will send the state change and associated message data to the handleMessage(msg) function from the calling class. This allows the service to communicate asynchronously.

private boolean findDevice(){
	setStatus("Searching for device...");
	Set pairedDevices = mAdapter.getBondedDevices();
	if(pairedDevices.size() > 0){
		for(BluetoothDevice device : pairedDevices){
			if(device.getAddress().equals(DEVICE_MAC_ADDRESS)){
				mDevice = device;
				return true;
			}
		}
	}
	return false;
}

private void connectToDevice(){

	if(mDevice == null) findDevice();

	if(mDevice != null) {
		setStatus("Connecting to device...");
    	// if the service has already been connected then close the connection
    	if(mService != null) mService.close();

    	// cancel discovery to speed up the connection to bluetooth device
		mAdapter.cancelDiscovery();

		UUID uuid = UUID.fromString(UUID_SPP);
		mService = new BluetoothService(mHandler);
		mService.connect(mDevice, uuid);
	} else {
		setStatus("Device not found");
	}
}

private Handler mHandler = new Handler(){

	@Override
	public void handleMessage(Message msg){
		switch(msg.what){
    		case BluetoothService.MESSAGE_STATE_CHANGE:
    			switch(msg.arg1){
	    			case BluetoothService.STATE_NONE:
	    				setStatus("Not Connected");
	    				mCurrentState = STATE_DISCONNECTED;
	    				break;
	    			case BluetoothService.STATE_CONNECTING:
	    				setStatus("Connecting");
	    				break;
	    			case BluetoothService.STATE_CONNECTED:
	    				setStatus("Connected");
	    				mCurrentState = STATE_CONNECTED;
	    				break;
    			}
    			break;
    		case BluetoothService.MESSAGE_READ:
    			byte[] readBuf = (byte[]) msg.obj;
    			//float f = Helpers.byteArrayToFloat(readBuf);
    			setStatus("Sensor Reading: "+readBuf[0]+"°");
    			break;
    		case BluetoothService.MESSAGE_WRITE:
    			mIsWriting = false;
    			break;
    		case BluetoothService.MESSAGE_TOAST:
    			Toast.makeText(getApplicationContext(), msg.getData().getString(BluetoothService.TOAST), Toast.LENGTH_SHORT)
    			.show();
    			break;
		}
	}
};

Once your devices are connected, data from the bluetooth device to the phone will be received as a byte[] in the handleMessage(msg) function, case MESSAGE_READ. Sending data from the phone to the device is as simple as calling the write(byte[]) function from the BluetoothService as long as the devices are connected. Hopefully this is helpful. I’d be happy to help if you have any specific questions.

What’s all this fuss about agile?

I was recently tasked with writing a one page paper on agile.  Having been a software developer for years, this was a simple paper to write.  Although short and most likely incomplete, here it is.  Please add comments to this if you have additional thoughts.

Agile is somewhat of a buzz word in the software development industry.  It seems that every developer makes a point to include experience with agile on their resume.  So what’s all the fuss about?  Well, coming from a software development and business background, it is rather simple to see, and hopefully just as simple to explain.  Agile is defined by Dictionary.com as “Able to move quickly and easily,” and that just about sums it up.  Agile as a software development methodology is all about continuous customer involvement and quick response to change.

Someone coming from traditional waterfall methodologies might be uneasy with the somewhat lackadaisical upfront work that is expected for an agile project; however, it is important to understand why this works so well for software development.  For projects in many industries, it is possible and important to fully collect and document requirements.  The end result is well known, and strict adherence to the initial requirements is usually the most effective way to manage the project.  The problem with software is that the customer typically does not know what they want.  Technology is advancing at a rapid rate and it is unlikely that non-technical people are even aware of what is feasible.  Even if the customer does know exactly what they want, it is near impossible to transfer that knowledge in complete detail upfront to the developers.  This typically results in a software application that does not provide a solution or only a partial solution to the initial problem.

Agile solves this dilemma by providing a way to manage software projects that can be adapted and quick to respond to customer needs as they become evident.  Agile encourages continuous customer involvement, working prototypes, and quick response to change.  Requirements are only partially gathered in the beginning, and working software is made available to the customers on a frequent basis so that the development continues to advance in the right direction.  This approach allows communication errors in the requirements to be discovered quickly, and therefore resulting in large time and money savings in the long run.

Hopefully this quick summary on agile may enlighten those that are unfamiliar with the methodology, or lack a full understanding of the benefits that it offers.  From my experience, the end result of an agile software project is much more likely to fully satisfy customer requirements and remain within budget constraints than software projects that adhere to traditional waterfall methodologies.

Tutorial: Android to Microcontroller via Bluetooth (Part 1)

I recently worked on a project for school that required a bluetooth interface between my Droid X and a MC9S12C microcontroller. I was not able to find a single source of information to help me accomplish this, but after awhile of hacking at it, I finally got them to talk. Hopefully you will find this tutorial helpful, it definitely would have been for me!

1. Choose a bluetooth device for your microcontroller.

The first thing you need to do is decide which bluetooth device you want to use for your microcontroller. You will want a device that you can communicate with via the serial protocol.  I used the BlueSmirf Gold modem from Sparkfun.

You will probably have to solder some headers to the chip, I used male headers to make it simple to plug into my breadboard.

2.  Connect the bluetooth device to the microcontroller

To connect the bluetooth device, you will need to find the Rx and Tx pins on your microcontroller.  Make sure that you cross the wires by connecting the Rx pin from your bluetooth device to the Tx pin on the microcontroller, and the Tx pin from your bluetooth device to the Rx pin on the microcontroller.  You will want to look in your datasheet to make sure you are using the right pins.  If you are using an Arduino, the diagram below may be helpful.

3.  Configuring the Bluetooth Device

To configure the bluetooth device from a computer, it is helpful to have a USB to serial breakout board.  I use the following from Sparkfun:

The simplest way to hook this up to the bluetooth modem is by using the 4 pins located along the front. Make sure you cross the Tx and Rx wires.  The board above has a 3.3v pin that is powered via the USB when plugged into the computer.  The BlueSmirf above can also operate on 3.3v, so powering the BlueSmirf is as easy as running a wire from the 3.3v output of the USB device to the BlueSmirf.  Also, make sure you run a wire from the ground pin of the USB device to the BlueSmirf to give them a common ground.

Now that everything is connected you can use a program such as Hyperterminal or Tera Term to communicate with the bluetooth modem.  HyperTerminal may already be installed on your computer if you are using Win XP.  Whichever application you are using, create a new connection.  Make sure to select Serial Port and the desired COM port.  If you do not know which COM port to use, you should be able to find it by looking in the device manager.  Mine says USB to Serial Port (COM3).  You also need to configure the serial port connection to use the corect baud rate.  Remember, the default baud rate of the BlueSmirf is 115200.  If you are using a different bluetooth device you will want to check your data sheet to determine what the default baud rate is.

The following instructions are specific to the BlueSmirf.  If you have a different bluetooth device you will want to refer to your datasheet.

Now that everything is configured, type $$$ in the prompt.   If everything is wired up correctly, you will received a response of CMD.  If you are using the BlueSmirf, the status LED will start blinking rapidly.  Now type D and press enter.  This will display the current configuration settings.

If you want to change the baud rate (to 9600 for example) type SN,96 and press enter.  You should receive a response of AOK which signifies that the change was successful.  Again, type D to see the settings and verify that the baud rate is now 9600.

Once you have completed the change, type — to exit command mode and terminate the connection.  If you desire to make additional changes to the configuration that I have not covered here, you should be able to find detailed commands for the bluetooth device that you are using in the documentation.  For the BlueSmirf you can look here.

4.  Writing code for the microcontroller

Depending on the microcontoller you are using, this may or may not be a daunting task.  You will want to refer to your data sheet for specifics on how to set this up for your microcontoller.  One thing to remember is that you must use the baud rate that your device is configured to use.

Use the settings you have configured above to initialize the serial driver on your microcontroller.  If you are using an Arduino, this is as simple as writing Serial.begin(baudRate); in your setup function.

That’s it for Part 1.  At this point you should have a bluetooth device connected to your microcontroller and be able to read/write to it using a USB to serial breakout board such as the one I discussed above.  In Part 2 I will discuss how to interface this bluetooth device with an Android phone.  Hopefully the information above has been helpful, let me know if you have any questions.

Betsy finds a new home

After 3 weeks of restless nights of coding and troubleshooting, Betsy(my inverted pendulum robot) still didn’t work! Luckily, our project was still impressive because, although appearing somewhat drunk, Betsy could still communicate over bluetooth with my Droid X.

Although the class is now over, I am still determined to make her work. The microcontroller that we were using was checked out from the school, so I decided to port her over to an Arduino, mainly because I wanted to learn what the hype was all about, and I didn’t want to spend countless more hours porting all of the drivers over to a new microcontroller.

So far I have spent about 4 or 5 hours and accomplished the following:

  1. Built a breadboard Arduino (there is a good tutorial here)
  2. Connected the BlueSmirf and established communication with my Droid X
  3. Connected the IMU and ported over the complementary filter
  4. Connected the H-Bridge and started to test-drive the motors

For a quick DIY project, the Arduino is fantastic! At this point I have to port the PID controller over, build the robot, and then start tuning. I’ll keep you posted on my progress!

ComboBox validation in Silverlight Jetpack theme

I have been working on a Silverlight project recently and I needed to do form validation.  Silverlight has some great built-in functionality to support this; however, for some reason the red box that normally surrounds the form elements did not work on the ComboBox.  I ignored this for a while, but finally it annoyed me to the point where I had to fix it.  I soon found out that the lack of validation styling was not a problem with Silverlight, but the Jetpack theme that I was using.  So if you are running into the same problem, the solution below works great.

The reason you do not see a red box around the ComboBox is because the Jetpack template for ComboBox does not have the visual state management set up to support it (which is odd because most of the other controls do).  You can resolve this by adding some code to the ComboBox template in CoreStyles.xaml.
Under the visual state group for “FocusedStates” add the following XAML.

<VisualStateGroup x:Name="ValidationStates">
    <VisualState x:Name="Valid" />
    <VisualState x:Name="InvalidUnfocused">
        <Storyboard>
            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ValidationErrorElement">
                <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>
    </VisualState>
    <VisualState x:Name="InvalidFocused">
        <Storyboard>
            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ValidationErrorElement">
                <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
            </ObjectAnimationUsingKeyFrames>
            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsOpen" Storyboard.TargetName="validationTooltip">
                <DiscreteObjectKeyFrame KeyTime="0">
                    <DiscreteObjectKeyFrame.Value>
                        <System:Boolean>True</System:Boolean>
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>
    </VisualState>
</VisualStateGroup>

Now copy this XAML and paste below the main content presenter in the template.

<Border x:Name="ValidationErrorElement" BorderBrush="{StaticResource ErrorBrush}" BorderThickness="1" CornerRadius="3" Visibility="Collapsed">
    <ToolTipService.ToolTip>
        <ToolTip x:Name="validationTooltip" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" Placement="Right" PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}" Template="{StaticResource ValidationToolTipTemplate}">
            <ToolTip.Triggers>
                <EventTrigger RoutedEvent="Canvas.Loaded">
                    <BeginStoryboard>
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsHitTestVisible" Storyboard.TargetName="validationTooltip">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="True" />
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </ToolTip.Triggers>
        </ToolTip>
    </ToolTipService.ToolTip>
    <Grid Background="Transparent" HorizontalAlignment="Right" Height="12" Margin="1,-4,-4,0" VerticalAlignment="Top" Width="12">
        <Path Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z" Fill="{StaticResource ErrorBrush}" Margin="1,3,0,0" />
    </Grid>
</Border>

As long as you did everything right this should now work :) Don’t forget to add “NotifyOnValidationError=True” to the binding.

File -> New Project… Betsy.mcp

One of the most exciting parts about being a software developer is creating a new project!! I must say, I am little nervous about this one though. The hardware has not arrived, but I am going to try to get some of the initial coding done anyway. My goal for tonight is to do the following:

  1. Wire up the analog to digital interrupts for the IMU
  2. Wire up the real time interrupts (RTI) for puse width modulation
  3. Get a good start on a PID controller

I’ll post some code samples as things start to come together.

Balancing Betsy

‘”Balancing Betsy” is the name of a robot that Jake Erramouspe  and I are going to build for our final project in Embedded Systems 6780.  Betsy will drive around on two wheels and balance her self accordingly.  We only have about two weeks to complete the project so there will be many sleepless nights for me in the near future.

The microcontroller (uC) we are going to use is the Freescale MC9S12C.  I would not use this uC if it was not a requirement for the class.  The board is fine (not great), and the IDE is less than ideal…  We have ordered the following additional hardware from Sparkfun:

Product Desc Quantity Price
Product COM-00315
H-Bridge Motor Driver 1A
2 $4.70
($2.35 each)
Product ROB-10077
Wheel 90x10mm Pair – Black
1 $9.95
Product ROB-00319
Dual Motor GearBox
1 $10.95
Product SEN-09249
IMU Combo Board – 3 Degrees of Freedom – ADXL203/ADXRS614
1 $34.95

*Basically the above hardware includes a gearbox and transmission, wheels, a couple h-bridge chips to drive the motor, and a 3 degree of freedom IMU (2 axis accelerometer, 1 axis gyro).

I will continue to post updates on our progress.  For now, if you are not familiar with an inverted pendulum robot, this video is a great demonstration, and was part of our inspiration in choosing the project.