Aperture: Analysing Lens Usage

As I’ve mentioned in an earlier post, we are heading to South East Asia for a holiday soon and, as ever, the lens dilemma presents itself: I am fortunate enough to have more lenses than I can fit in my carry-on bag, and I need to decide which l’m going to leave behind.

I didn’t see a huge amount of resources on this  when I searched for it – a plugin for Aperture that you need to pay for, and a command line tool called exiftool for analysing your library seemed to be the primary options. While the latter is feature rich, it wasn’t immediately apparent how to combine EXIF characteristics, such as bounding the usage of a lens by date.

Adding an EXIF based smart album seemed like an easy alternative. This is my usage of my latest lens, the 16-35mm, and my prime candidate for the bench:

EXIF Based Smart Album

EXIF Based Smart Album

Just a few points to note: in the top left, be sure to change the default ‘any’ rule to ‘all’. Also, dates are obviously US format. I haven’t tidied up the default rules on colour, text and keywords, which are all blank and don’t make any difference. Finally, I have my library organised by year. If you do too, all the simpler: just control click on the folder, select smart album from the pop-up, and you’re off to the races.

As I say, this worked for me. Unchecking the the EXIF rule gives me the denominator to calculate the percentage and the result: I took 41% of my pictures with the lens.

Conclusion: I’m taking it…

Location Display – Arduino Based Clock

Once I finally got everything working with the weather station clock, predictably, it started to lose its appeal. So I’ve taken the bones of it and refactored to display my current location. The source of the location data is another little iOS app, this time using background fetch.

I may split the various moving parts of this into a couple of posts. There are 6 in all, most of which I’ve cannibalised from the weather app. I’ll only talk about the new [or what I think are more interesting pieces]. And as I’ve mentioned before, messing with this kind of data has personal privacy implications. While people may not be interested, it’s best to make it difficult. The components are:

  • The iOS app generating the data.
  • This posts to my hosting service via a rest interface called Arrest-MySQL.
  • There is a database behind the REST interface, which is on my hosting service.
  • In order to limit the number of annotations / pins on the iOS app, I trim them with a SQL script embedded in PHP [the latter is a restriction imposed by my hosting service]. I call this as a nightly cron job from the Pi.
  • I then display this via pretty much the same Arduino sketch that for the clock for the weather data.
  • This receives data via Serial USB from the Pi based on a ‘nohup’ Perl script. I start and check this is running every 10 minutes using cron.

There is a 7th: we are going to South East Asia in a while, so I’ve written another little iPad app which my mother in law can use to track us with. My idea; I thought she’d be interested :).

I’ll start with the iOS app. One of the most immediate points to note about the iOS 7 background fetch capability is that, in comparison to using the Significant Change mechanism I’ve implemented before, it’s a lot gentler on the battery. While we are comparing the two, the fetch has two frequency settings: ‘none’ and ‘a lot’. I guess this might be something that Apple might increase the granularity on at some point in the future.

I guess there is a shopping list of features that I’ve picked up along the line which raise this above ‘bare bones’. The first is that if there is no network, I allow a manual ‘pin drop’ which writes the current coordinates to Core Data. Each time the background fetch fires [only when the network is available], I try to post these via the REST interface.

I also attempt to use Google’s GeoCoding API, which converts the latitude and longitude into a string for the given address, which then subsequently appears on the map annotation, or on the clock’s LCD display. I have to admit that in both instances, this is a bit of a dog, due to character limits, and custom annotations with mapping – well, while I’ve done it before, it’s substantially more effort than what this app warrants . I’m also not too sure what Google is going to return if we happen to be dropping location data in a jungle location with fantastic WiFi [!].

One more confession on the Core Data approach: originally I thought I would store failed writers to the database based on Reachability telling me I was offline when the background event fired. Actually, iOS does this for you: no network, no attempt to do a background fetch. While this is obvious, it never occurred to me based on prior experience with the Significant Change functionality which percolates away based on cell tower activity.

One or two more points of interest for the mobile app. There are limits on what you can do with the network in terms of libraries used / delegates available, so no AFNetworking. Actually for what I want to do in the foreground, AFNetworking is much too rich: for instance, I had to Google to find a workaround to its rather sticky caching. Also, something that really stumped me until I thought about it: if you are dynamically returning results [such as from the REST interface] don’t bother trying to plumb in a network progress indicator, unless your server is also setting a Content Length header. That’s a couple of hours of my life I’m not getting back :).

Reliable Serial Read with Arduino

I’ve refactored my weather station project significantly in the last few days, having found the RF based communications between the the two Arduinos too unreliable for my purposes. So I’ve invested in a WiFi shield instead, specifically an Adafruit CC3300. It was quite expensive, but I have to say it’s working fantastically well. I am now posting data directly to my JSON interface from the externally located Arduino. This has freed up the second Arduino [and Raspberry Pi] for what I originally intended: some sort of permanent internal display. I’ve actually got this working pretty well in conjunction with an Adafruit 1.8″ colour TFT [lovely piece of kit]. A Perl script on the Pi is in a constant loop, pulling down various piece of data, such as an RSS feed from the BBC, and the latest weather data. I combine this with the time and, based on string prefixes, position it on the screen accordingly.

It’s brought a problem that I’ve struggled with in the past back into play: the reliability of Serial.Read(), and I’ve found a stable solution which I’ve not come across elsewhere:

char inByte = Serial.read();
if (inByte != '^')
{
   // serialText string is defined earlier, and overwritten each time through the main event loop:
   serialText = serialText + inByte;
   delay(20);
}

That delay() is enough to allow the serial buffer to refill and for me to reliably read the next character, up to the point that I hit the termination symbol I’m using. This has worked consistently for me now with the sending Perl script / receiving sketch merrily interplaying for days on end now, on 9600 baud. The serial comms are extremely sensitive to timing issues: for instance, before I put this delay in I was seeing different results on the Arduino between sending the data from the serial monitor on my Mac versus sending the same data from the Pi, via the Perl script. Suffice to say that your mileage may vary…

One other approach I’ve tried out is with the displaying of text. The TFT library doesn’t appear to support a delete function without zapping the entire display, so when I update the time display, which I send down the serial port every 10 seconds, I hold the prior value in a string, then display that in the background colour [black], display the new value, and finally set that for the buffer for deletion next time round:


// This is the prefix identifying that the string is the time:
String msgCheck = serialText.substring(0,5);
if (msgCheck == “TIME:”)
{
// There is a space so shuffling the substring over 1. Could take the space out but…!
String timeString = serialText.substring(6);
tft.setTextSize(3);
tft.setCursor(0,10);
// delete the displayed time:
tft.setTextColor(ILI9340_BLACK);
tft.println(lastTimeMessage);
tft.setTextColor(ILI9340_BLUE);
tft.setCursor(0,10);
tft.println(timeString);
// set the value to the current time for the next delete operation
lastTimeMessage = timeString;
timeString = “”;
}

A final observations on the TFT library: the very accurate placement of the background colour text for deletion only seems to work if all of the text being displayed is the same size: so a write / delete cycle will only work with the correct placement of the cursor if all other interim writes around the screen are the same size text.