Archive

Monthly Archives: July 2013

In developing the GClient (detailed in the preceeding post), I discovered for myself that the method to be implemented for some interfaces and object types (such as run() in a Runnable object) are done by declaring them as ‘abstract’ methods. This means when a programmer creates a new instance of that object, the abstract method that needs to be implemented is shown to be ‘filled up’ with context specific code. Below is an example:

This is an abstract method from my ‘PythonConnection’ class:


/**
  * Implement this to act on data received
  * @param data String containing the data received from the remote python host
  */
	public abstract void onReceive(String data);

When a new PythonConnection object is created, the opportunity to implement onReceive() is shown as below:


PythonConnection pyCon = new PythonConnection() {

			@Override
			public void onReceive(String data) {
				//Put code to use the 'data' String here!
				//Update UI, send a response etc...

			}
		};

Where does the ‘data’ String come from, you ask? Well when the underlying Thread receives data from the BufferedReader, it calls onReceive(), supplying the String read from the Reader and continues listening once onReceive() returns. Here is where that occurs in a typical server (such as in the GClient):


/**
  * Start the receiving thread that will call onReceive() when it has data
  */
	private void startListening() {

		receiveThread = new Thread(new Runnable() {

			@Override
			public void run() {
				listening = true;
				System.out.println("Ready to receive.");

				while(listening) {
					try {
						String packet = fromPython.readLine();
						if(packet != null) {
							onReceive(packet);
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		});

		receiveThread.start();
	}

Previously to get around this ‘sending data across classes’ problem (which got especially nasty when Threads came into it) I would either pass the object creating the abstract object or use some sort of ‘shared static class’, which wasn’t ideal and generated problems of its own.

This is an example of one of the joys of exploring a language by using it! I foresee much use for this functionality.

Advertisements

GClientLOgoWhile developing a number of different minor projects that involved communication between Android and my laptop, Pebble or Raspberry Pi I found myself almost writing a new app for each project, with names like ‘PebbleButtonDemo’ or ‘AndroidTestClient’.

It occurred to me ‘why keep inventing the wheel?’, meaning that this was a wasted practice. The vast majority of these situations simply called for a TCP Socket connection that sent pre-defined commands as text strings. With that in mind, I conspired to create a general purpose app that did these things and did them well.

But in order to solve the problem of writing a new app for every application when the underlying mechanism remained the same, it needed more ‘customisability’ than simply an EditText for address and port. The next logical step to this is to allow each project/application (server, that is) to customize the general client on the Android phone to it’s purpose, and in this first incarnation offers the following ‘customisables’:

  • Android Activity title in the Action bar by sending “TITLE” + the new title String
  • A set of three customizable Buttons by sending ‘BUTTON” followed by the button number, button text and the command it should trigger to be sent back to the application server.
  • Protocols agreed for these actions in both Java and Python servers I’ve written.

More features are possible with a more advanced protocol, such as sending vectors to draw on the remote Canvas, or even images, but those will have to come later when a specific project calls for it.

So, upon opening the app, this is what is seen:

Screenshot_2013-07-25-22-37-13The key UI elements to note are:

  • The customizable Activity title.
  • The ‘I/O Traffic’ section, which contains a customized SurfaceView element (actually a subclass of my Android Game Engine), which fills up green when a connection is established and animates blue ‘bits’ left and right whenever data is sent or received.
  • The ‘Connection Settings’ section, which contains EditText fields for host address and port number, a Spinner for language selection on the application server side, and connect/disconnect Buttons.
  • The ‘Log History’ section contains a ScrollView housing a TextView that shows all events that take place, be they received data, sent commands or local events such as IOExceptions and disconnects.
  • The ‘Custom Buttons’ section, which houses the three customizable Buttons that can be setup from the application server side with details I’ll now detail below.

To continue the spirit of a general purpose app, I created static methods for setting up these customizable UI elements, shown below:

public class GClientTools {
	//Protocol configuration
	private static final String PROTOCOL_TITLE = "TITLE";
	private static final String PROTOCOL_BUTTON = "BUTTON";
	private static final String PROTOCOL_SEP_1 = ":";
	private static final String PROTOCOL_SEP_2 = ";";
	private static final String PROTOCOL_SEP_3 = ".";

	/**
	 * Use the GClient syntax to set the GClient Activity title
	 * @param inStream 	Established output stream.
	 * @param inTitle	Title to set to.
	 */
	public static void setTitle(PrintStream inStream,String inTitle) {
		String packet = PROTOCOL_TITLE + PROTOCOL_SEP_1 + inTitle;
		inStream.println(packet);
		System.out.println("Title now '" + inTitle + "'. (" + packet + ")");
	}

	/**
	 * Configure a GClient custom button
	 * @param inStream		Established output stream.
	 * @param inButtonNumber	Which button to customise. No range checking.
	 * @param inText		Text to display on the button.
	 * @param inCommand		Command the button will send back to this server.
	 */
	public static void setCustomButton(PrintStream inStream, int inButtonNumber, String inText, String inCommand) {
		String packet = PROTOCOL_BUTTON + PROTOCOL_SEP_1 + inButtonNumber + PROTOCOL_SEP_2 + inText + PROTOCOL_SEP_3 + inCommand;
		inStream.println(packet);
		System.out.println("Button " + inButtonNumber + " now '" + inText + "' --> <" + inCommand + ">. (" + packet + ")");
	}

}

As a test case, I wrote a quick application server that accepts the GClient connection and makes use of these static methods to set the Activity title and one custom Button. The I/O Traffic bar has filled up green and the Log History shows all events:

Screenshot_2013-07-25-22-36-50That’s it for now. The major things I learned writing this app were:

  • A much more stable and UI friendly threaded approach to networking, using four threads (UI, sending, receiving and connecting)
  • Precise Android XML UI design including nested layouts and more features of the RelativeLayout.
  • Setting Android UI views to use 9-Patch images and custom background styles and colours.

First version source code is available here! The GClientTestServer port is a constant field in the class file. The GClientTestServer also contains the GClientTools class in the util package, which I’ll be next using for adapting current project servers and eliminating a few test apps altogether!

Previous Tutorial Sections

All six previous parts of this tutorial series can be found on the ‘Pebble SDK Tutorial’ page link at the top of the page. Please read them if you are not already up to speed!

Introduction

By request, this part of the tutorial will focus on using the ScrollLayer structure provided by the Pebble SDK. This is the Layer type used for menus, such as the main menu or settings menu. In fact, the MenuLayer itself contains a ScrollLayer!

The features of a ScrollLayer are thus:

  • It can be controlled with the up and down buttons to show more content that can fit on the screen at any one time.
  • It automatically shows ‘shadows’ at the top and bottom of the screen to indicate there is more to see in both the up and down direction.
  • It can contain all the Layers that it scrolls, making parent-child layer management easier.

Lets get started!

Using a ScrollLayer

To make use of this Layer type in a watch app, you will need something to display inside it. For this example, I’ll be using a snippet of text from getpebble.com, in a char array as shown below (using the fiendishly hidden WordPress code tags!):

char scrollText[] = "Pebble is the first watch built for the 21st century. It's infinitely customizable, with beautiful downloadable watchfaces and useful internet-connected apps. Pebble connects to iPhone and Android smartphones using Bluetooth, alerting you with a silent vibration to incoming calls, emails and messages. While designing Pebble, we strove to create a minimalist yet fashionable product that seamlessly blends into everyday life.";

You can use other Layer types, but this is good for simplicity.

As is usual for the Pebble SDK, we call functions to initialize and setup our Window and Layers, in the handle_init() function. I’ll show this process below, but first here are the constants and globals that will be making an appearance:

//Globals
Window window;
ScrollLayer sLayer;
TextLayer tLayer;

//Maximum dimensions
static int WIDTH = 144;
static int MAX_HEIGHT = 1000;

//Compensate for top window bar
static int TOP_BAR_PADDING = 20;

And now the main code segment:

/**
	* Resource initialisation handle function
	*/
void handle_init(AppContextRef ctx) {
	(void)ctx;

	//Init window
	window_init(&window, "Main window");
	window_set_background_color(&window, GColorWhite);
	
	//Init ScrollLayer and attach button click provider
	scroll_layer_init(&sLayer, GRect(0, 0, 144, 168));
	scroll_layer_set_click_config_onto_window(&sLayer, &window);
	
	//Init TextLayer
	text_layer_init(&tLayer, GRect(0, 0, WIDTH, MAX_HEIGHT));
	text_layer_set_text(&tLayer, scrollText);
	text_layer_set_background_color(&tLayer, GColorClear);
	text_layer_set_text_color(&tLayer, GColorBlack);
	text_layer_set_text_alignment(&tLayer, GTextAlignmentLeft);

	//Get size used by TextLayer
	GSize max_size = text_layer_get_max_used_size(app_get_current_graphics_context(), &tLayer);
  
	//Use TextLayer size
	text_layer_set_size(&tLayer, max_size);
  
	//Use TextLayer size for ScrollLayer - this has to be done manually for now!
	scroll_layer_set_content_size(&sLayer, GSize(WIDTH, max_size.h + TOP_BAR_PADDING));
	
	//Add TextLayer to ScrollLayer to Window
	scroll_layer_add_child(&sLayer, &tLayer.layer);
	layer_add_child(&window.layer, (Layer*)&sLayer);

	//Show Window
	window_stack_push(&window, true);
}

Read through the code above line by line and see the new additions that you might not have seen before. Below are the ones of note:

  • scroll_layer_init() – This does the same sort of actions as window_init() or text_layer_init() and initializes the ScrollLayer supplied as the first argument.
  • scroll_layer_set_click_config_onto_window() – This gives the ScrollLayer the button click information from the containing window, so that it can respond to button pressed while in this window.
  • text_layer_get_max_size_used() – This returns a GSize that is the dimensions that the TextLayer that the ScrollLayer contains uses. The alternative here is to find the point size of the font and find by trial and error the vertical height from the number of lines the text ends up using – a waste of time!
  • scroll_layer_set_content_size() – This function uses the GSize created before to set the size of the ScrollLayer. Without this information it would not be able to tell how far to be able to scroll up or down. At the moment this must be done manually.
  • scroll_layer_add_child() – This function does the same as the layer_add_child() function we’ve used before for TextLayers being added to the Window, but this time the Layer supplied as an argument is added to the layout inside the ScrollLayer, and will therefore be scrollable.

Finally, after using layer_add_child() to add the ScrollLayer to the Window, you should be all set!

Conclusion

The ScrollLayer can be useful for showing a lot of information or a list. It does require some extra thinking about and setup, but it is worth it for the convenience!

Full source code for a sample watch app (derived from the ‘demos’ supplied with the SDK) can be found here.

Happy scrolling!

In an almost biblical revelation, I have found it IS indeed possible to post source code in a proper fashion on WordPress, making a virtual mockery of my Pebble SDK Tutorial pages, which I might update, but not for now. The code segments are available in source links in each post.

So, what better reason to make a new post using this newly discovered feature than to write about my latest Raspberry Pi escapade. I have a cheap HC-SR04 ultrasonic sensor that I used with an Ultrasonic library with my Arduino. Having since obtained a Pi, why not have it work with this new piece of kit?

After observing the timing requirements, it seemed simple enough to replicate that behavior with a short C program, shown below in all it’s copyable glory!

#include <stdio.h>
#include <stdlib.h>
#include <wiringPi.h>

#define TRUE 1

#define TRIG 5
#define ECHO 6

void setup() {
        wiringPiSetup();
        pinMode(TRIG, OUTPUT);
        pinMode(ECHO, INPUT);

        //TRIG pin must start LOW
        digitalWrite(TRIG, LOW);
        delay(30);
}

int getCM() {
        //Send trig pulse
        digitalWrite(TRIG, HIGH);
        delayMicroseconds(20);
        digitalWrite(TRIG, LOW);

        //Wait for echo start
        while(digitalRead(ECHO) == LOW);

        //Wait for echo end
        long startTime = micros();
        while(digitalRead(ECHO) == HIGH);
        long travelTime = micros() - startTime;

        //Get distance in cm
        int distance = travelTime / 58;

        return distance;
}

int main(void) {
        setup();

        printf("Distance: %dcm\n", getCM());

        return 0;
}

Which results in this output:

ultrasonic

So now I know the distance to the ceiling!

So a few days ago I acquired a Raspberry Pi. This amazing board is a SoC (System on a Chip) that runs a version of Debian Linux called Raspbian. Since then I’ve been poking around and finding out how to do my favourite useful stuff (networking, Arduino etc), aided in a way by the basic knowledge of Linux commands obtained from dabbling in Ubuntu.

After learning how to send and receive data on a network with Python, and controlling the GPIO pins in the same way as Arduino using wiringPi, I decided to try and find a project to complete.

As I’ve said to people before when they ask me about leaning to program, a good motivator to learn new features and possibilities of a language is to set a small goal that is just out of reach. For example, say you’d learned enough Java to know how an object is constructed, data stored inside and methods called from it, the stretch goal might be to use a simple object provided by someone else.

In this spirit I decided to use a combination of Python, wiringPi and scripts to solve a problem I might have had in the near future. Using SSH, I can connect to and command the Pi from another computer, eliminating the need for a mouse, keyboard, HDMI display etc, leaving just ethernet and power connected. In order to do this, I need to know the Pi’s IP address. This piece of information is presented to the user when the board is booted, on either the RCA or HDMI display outputs.

The difficulty here is that the first time the Pi is connected, the IP address it is given will be pseudo-random, and unknown.

But what if you don’t have a TV or monitor in reach? When I move house in a few weeks time, what if the router is too far from the TV? I won’t be able to use this method to get the IP. I could connect to the Wi-Fi gateway, but that relies on the service provider implementing a mechanism for doing so, which I can’t rely upon.

This brings us back to finding a project to do. As I’ve posted on this very blog, I managed to use an Arduino to show short messages on a standard LCD display, using the LiquidCrystal library. Why not use this display to show the IP address? No TV needed!

As I quickly found, the LiquidCrystal library didn’t appear to be included in wiringPi. Luckily, the author had implemented their own version, the lcd.h header file, with similar functions. So, after making the requisite connections between the boards, and being careful to note these for later use, I had a simple C file that sends a string to the LCD display, when presented as an argument from the terminal. If the argument is too long ( > 16 characters), it is not accepted, and the display instead shows “Too long!”. If it is between 8 and 16 characters, then it is copied into two buffers each 8 characters in size, then displayed alternately.

Once this was done, I wrote a Python script (with help from here) that determined the IP address, and then called the compiled executable that took the address as the argument and send it to the LCD display.

So far so good. But the main purpose of this exercise was to get around the combined problem of not knowing the IP address assigned by DHCP when the Pi is first introduced to a LAN, and having to TV guaranteed to be within reach. The final step therefore was to have the Python script run on boot. The final process is summed up below:

  1. Boot script /etc/rc.local executes the Python script.
  2. The Python script in turn finds the IP address and calls the LCD executable, supplying the address as an argument.
  3. The LCD executable sends the IP address to the LCD display
  4. I use the IP address now visible to the world to connect using SSH, saving it for later use in the process.

I think that’s mission accomplished! Here is a photo of the finished system in action:

IP cutoutAs is usual for this type of post, you can find the C and Python source files, as well as a built C executable here. The LCD display pin map is included as a comment in the C file. The Raspberry Pi pins used by the wiringPi library can be found here.

Previous Tutorial Sections

All five previous parts of this tutorial series can be found on the ‘Pebble SDK Tutorial’ page link at the top of the page. Please read them if you are not already up to speed!

Introduction

One of the main selling points of the Pebble smartwatch is the fact that it can run apps that communicate with a companion app on an iPhone or Android smartphone. Indeed, it is impossible to get started without one. In the spirit of openness that is also a major selling point, this part of the tutorial series will describe how to accomplish such a task, enabling a much richer watch app experience.

Thanks to the remarkable amount of example code and documentation provided in the relatively early Pebble SDK v1.12, a lot of the code I will be using and showing here is derived from these examples. No need to fix what isn’t broken, and all that! They’ve done an excellent job on this one already.

As I have mentioned previously, I will only be covering the phone app side from an Android perspective, due to the fact I don’t own an iOS device or agree with Apple’s pricing policy to enter the ecosystem, but that’s just personal opinion.

It is assumed that the reader is already familiar with basic Android app development and the application lifecycle. If not, I could write an Android primer, which would in turn require a working knowledge of Java. We’ll see if that is required! Please let me know so I can gauge demand.

AppMessage system overview

On the Pebble platform, this is done using the AppMessage system. On the watch and on the phone, data is stored inside data structures called Dictionaries. When data is send or received, it is stored in data structures called Tuples. A Tuple contains a key and the data itself in what is known as a key-value pair. The key is a ‘label’ for that data and is constant.

For example, if you were writing an app to show the weather, you might have an int to store the temperature. You create a key (number) to identify this data, and all these keys are the same on both the watch app and the phone app. Lets set the key for the temperature variable to a value of ‘5’. The phone sends a Dictionary consisting of a tuple with the temperature data contained within, with a key value of ‘5’. When this data arrives on the watch app, because the key identifying the temperature variable is the same as on the phone app, the Dictionary is searched for the tuple with key value ‘5’, and knows the accompanying data is the temperature to be displayed.

If that explanation leaves you wanting, here’s an diagram that will hopefully make it clearer:

key and data life

Common App Features

In order to make sure that the phone app sends data to the correct watch app, both apps must use the same UUID to identify them. This has already been covered for the watch app, so here is how this is done on the phone app:

UUID member

Here is how the phone app would store the keys. Remember that these should be identical to those declared on the watch app!

KEYS

Watch App Specifics

On the watch app side of things, as predicted there is a use of handler functions to manage the following events:

  • Send successful – AppMessage was sent successfully
  • Send failed – AppMessage failed to send (or was not Acknowledged by phone app)
  • Receive successful – AppMessage received from phone app
  • Receive failed – AppMessage received but dropped due to lack of space or some other error

The first stage to implement this new functionality is to add the following lines to the PebbleAppHandlers in pbl_main():

pbl_main additions

Next, create the handler functions with matching names to those referenced in the ‘.message_info’ callbacks section in pbl_main() for each of the four callback scenarios in the bullet points above. Four blank handlers are shown below:

blank handlers

Sending data to the phone app

To send data to the phone app, a Dictionary is constructed and filled with the tuples describing the data to be sent, using the appropriate keys. Here is an example function that takes an int and sends it to the phone app (adapted from the one provided in the SDK examples):

send_cmd

The argument sent here would be matched with a corresponding action on the phone app. In this example project (link to the source code will be at the end) each of the three buttons is given a key of 0, 1 or 2 (Select, Up, Down). When the up button is pressed,  the watch app sends ‘1’ to the phone app. Because the keys are the same on both sides, when the phone app receives ‘1’ it can use that to perform the action the programmer wants to perform upon an up button press.

Receiving data from the watch on the phone

On the phone app side, the Dictionary is received in a callback method which is registered with the Android system when the app starts, in onResume():

onResume

Hopefully you can see that when the callback is triggered, the data is identified by the key, again it must correspond to the key on the watch app. This value is then used in a switch statement to decide what action to take. The phone app must first acknowledge (ACK) the data so the watch app doesn’t report a timeout.

Another important note is that the callback must be unregistered in onPause() when the phone app is closed to prevent events being missed. Here is how that is done:

onPause

Sending data back to the watch app

Going back in the opposite direction, data is sent to the watch app by making use of a PebbleDictionary and key-value tuples. The methods used for this are provided by the PebbleKit SDK packages, which you can use and import by copying the packages into the ‘src’ folder of your Android project (shown here in Eclipse IDE for Java Developers):

packages

The process for sending data from the phone app to the watch app is largely similar to the same process started from the watch app:

  1. Create the Dictionary (or PebbleDictionary in this case)
  2. Populate it with key-value tuples containing the data to be sent
  3. Send the Dictionary using the UUID (same as the watch app UUID)

This process is summarised in the image below, with comments for clarity:

send to pebble

Receiving data on the watch app

The final part of this process is receiving data from the phone app. This is done by (you guessed it!) extracting data from a Dictionary sent from the phone app and provided by the callback handler as an argument.

  1. A DictionaryIterator is used to search the Dictionary for data using the pre-defined key for that identifies the data received.
  2. This data is stored in a tuple
  3. The tuple contents can then be used as you wish

In the example below, the Dictionary is searched for the string data associated with the DATA_KEY, which was send from the phone app using the same key. This string is then displayed in a TextLayer for the user to see that the data has arrived successfully. Note that the Pebble OS automatically ACKs the received AppMessage:

using received data on watch

Conclusion

So there you have it! Sending data from watch, receiving it on the phone, then sending data from the phone to the watch and using it. I’ll admit, this is the most complicated part of this tutorial series so far, and I hope to provide a bit more of a bridge from API Documentation to understanding the examples.

The example project source code can be found here!

Please feel free to post any questions here on in my Pebble Forum thread, and I’ll do my best to answer. If there is a lot of demand, I may write an Android primer too, but that’s probably another series in itself, and there are plenty of superb ones just a Google search away!

Lots going on at the moment, so here’s a list of what’s coming soon (also a personal reminder!):

  1. Pebble SDK Tutorial Part 6 is written, just needs images. 2 Way Communications.
  2. Java <-> Pebble text bridge Android Service.
  3. Raspberry Pi obtained, working on Java <-> Pi text bridge using Pi Python.

Got to do my best not to lose sight of a current project!