Adding SATA 3 Support to a Mac Pro

Caveat: be careful with your expensive, delicate computer. This has all the characteristics of a hack, but it was wildly successful for me. There may also be a much more sensible way of doing this out there. YMMV.

I have a mid 2010 spec Mac Pro, with the 6 core Westmere chip. I’ve been running out of disk space for about half of the elapsed time since I upgraded to a SATA 2 SSD about 3 years ago. Amazon are doing a pretty good deal on a Samsung SATA 3 SSD at the moment so I thought I’d take a punt on upgrading.

The long and short of it is that I’ve hacked together a pretty cheap option, which has given me a 13x speed up on sustained write speeds.

I went for this card [which appears to have risen in price by a couple of quid since last week], on the basis of seeing a reference to a particular chipset [ASM1061] on a forum somewhere along the line.

I have to admit straight off the bat that I’d never worked with PCIE before, and it took me a while to work out that the card was missing a power supply. This led me on a merry dance to figure out how to get power into my SSD. There are a couple of raised interfaces on the card which may be power outlets, but I’ve never seen anything like them before. Having looked at a tutorial on how to install a USB 3 device, I thought I was going to end up having to take the fan out, and get some sort of MOLEX to Mac 4 pin style power adapter cable. Having then hit on the fact that your stock Mac Pro [of my era at least] comes fitted with a single occupied bay of 4 designed for hard drives with SATA [2] interfaces, I bought one of these. Here’s the really hacky bit: the extender cable comes with a couple of clips either side to stabilise the connection. You have to clip one of them off, and plug it into the SATA interface of your choice.

And it works. And it’s bootable [a gotcha for some PCIE cards], and it handles resurrection from sleep. I verified that it was registered as a SATA 3 [look for the negotiated link speed of 6 Gb/sec] and used BlackMagic Disk Speed Test to verify a sustained write speed of 354 Mb/sec.

While there are integrated cards that you slot your SSD straight into, this turned out to be cheaper. That said, the new SSD is currently sitting loose inside the machine. There are integrated ‘sleds’ that you can screw the SSD into, and then slide into one of the four disk bays. I haven’t seen one that’s less than about £20. I also haven’t experimented with any of the 3 spare interfaces [2 of which are external] on the card: I’ve no idea if you can RAID up two SSDs on the same card, for instance. I’d be interested to find out!

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.