Freelance iOS Developer, Rapidly Aging Punk

Matrix Pen

Jun 26, 2015 at 02:42PM

I've been working on my first Mac app for a few weeks and I'm launching it today. It's super-niche and solves a really specific problem: Drawing pictures to an 8x8 LED matrix breakout board from an Arduino. Let's say you wanted to draw a smiley face. In code, that looks like this:

byte smile[8] = { B00111100,
                  B01000010,
                  B10100101,
                  B10000001,
                  B10100101,
                  B10111101,
                  B01000010,
                  B00111100 };

Doing this by hand is obviously a pain. With Matrix Pen you just click to draw, like this: A screenshot of Matrix Pen Matrix Pen is $5. You can read more about it here and buy a copy here.


Replace @NSApplicationMain or @UIApplicationMain with main.swift

May 16, 2015 at 02:00PM

Let's say you want to run some code before your AppDelegate launches in a Swift application (like receipt validation.)

First, get rid of the @NSApplicationMain or @UIApplicationMain from your AppDelegate.swift file:

import UIKit

//@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

Next, File->New->File... to create a Swift file and name it main.swift. Here's how it should look for an iOS app:

import UIKit

//Pre-launch code here.

UIApplicationMain(Process.argc, Process.unsafeArgv, NSStringFromClass(UIApplication), NSStringFromClass(AppDelegate))

And Mac:

import Cocoa

//Pre-launch code here.

NSApplicationMain(Process.argc, Process.unsafeArgv)

Connecting a Push Button to an Arduino Uno with Two Wires

Mar 02, 2015 at 03:04PM

This isn't as complicated as some tutorials make it seem. You don't need a resistor and each push button just needs one wire to an input pin and one wire to ground. Wire up your button to your Uno like this:

A push button connected to an Arduino Uno

In the setup() function of your code set the input pin to INPUT_PULLUP:

void setup() {
    pinMode(8, INPUT_PULLUP);
}

To determine if your button is being pushed you do a standard digitalRead on the pin. The only tricky part with this is that you aren't looking for a HIGH signal like you might assume – your button will give off LOW when it's pressed. You'll also want to add a delay statement to limit the amount of reads per second you perform on the button. This keeps your code from executing over and over when your button is held down. Here's the code:

void loop() {
    if (digitalRead(8) == LOW) {
        //The button is pressed!
 }

    delay(100);
}

Multiple Buttons

It's easy to expand out to more buttons – just make sure they share a common ground. Here's an example with two buttons:

Multiple push buttons connected to an Arduino Uno

void setup() {
    pinMode(12, INPUT_PULLUP);
    pinMode(11, INPUT_PULLUP);
}

void loop() {
    if (digitalRead(12) == LOW) {
      //Button one is pressed!
 }

    if (digitalRead(11) == LOW) {
      //Button two is pressed!
 }

    delay(100);
}

Bonus Pins

If you're out of digital pins on your Uno, the analog input pins can be used as bonus digital pins – great if you've already used all your digital pins up through something with a lot of wiring like a seven-segment display.


Fixing Invalid Parameters in BBEdit Text Filters

Feb 11, 2015 at 01:32PM

This blog post from Crisp is the only example of a JSON Pretty Print BBEdit text filter I could find and unfortunately I was only able to get it to work about 25% of the time – the other 75% I would get this error message from BBEdit:

Invalid parameters were detected for an operation (MacOS Error code: -50)

There's not a lot going on in the script so I banged my head against it until I figured out how to fix it: Aggressively insisting on UTF-8 string encoding. Here's the modified script:

#!/usr/local/bin/python
import fileinput
import json

if __name__ == "__main__":
  json_string = ''
  for line in fileinput.input():
    json_string = json_string + ' ' + line.strip()
  json_object = json.loads(json_string.encode('utf-8'))
  print json.dumps(json_object, sort_keys=True, indent=2).encode('utf-8')

Coding for the Spark Core in BBEdit

Feb 05, 2015 at 04:29PM

Call me old-fashioned if you want, but when I write code I want to do it in a Cocoa window, like a dignified human being. So I was pretty disappointed to find out that the primary IDE for the Spark Core is a text box on a web site:

Spark Web IDE

Obviously that's not gonna do. I dug a little deeper and it turns out that there is a Spark desktop app called Spark Dev – but it's a fork of Atom, Github's web-based text editor. No thanks.

There's a light at the end of this JavaScript tunnel: Spark has an excellent command line app – Spark CLI. It can handle everything the web IDE does including compiling code and flashing your Spark over wifi. With that component in place, it's just a matter of writing some Applescript to get BBEdit pounding out Spark code. Here's my (mostly ripped off from the web) Compile for Spark script:

set theFile to missing value

tell application "BBEdit"
    set activeWindow to front window

    if (class of activeWindow is project window) then
        set projectDocument to project document of activeWindow

        if ((count of items of projectDocument) > 0) then
            set firstFileItem to item 1 of projectDocument as alias
        else
            set firstFileItem to file of document of activeWindow as alias
        end if

        if (on disk of projectDocument) then
            set theProjectFile to file of projectDocument as alias

            tell application "Finder"
                set theProjectDir to container of theProjectFile
                set firstFileDir to container of firstFileItem
            end tell

            if (firstFileDir is equal to theProjectDir) then
                -- Use project file
                set theFile to theProjectDir as alias
            else
                -- External project file -> use first item to set context
                set theFile to firstFileItem
            end if
        else
            -- BBEdit doesn't provide direct access to the Instaproject root
            -- Use the first node from the project list
            set theFile to firstFileItem
        end if
    end if
end tell


tell application "Terminal"
    if (the first window whose busy is false) exists then
        set win to the first window whose busy is false
        set frontmost of win to true
        do script "spark compile " & the quoted form of the POSIX path of theFile
    else
        do script "spark compile " & the quoted form of the POSIX path of theFile
    end if
    activate
end tell

And here's my Flash to Spark script:

set theFile to missing value

tell application "BBEdit"
    set activeWindow to front window

    if (class of activeWindow is project window) then
        set projectDocument to project document of activeWindow

        if ((count of items of projectDocument) > 0) then
            set firstFileItem to item 1 of projectDocument as alias
        else
            set firstFileItem to file of document of activeWindow as alias
        end if

        if (on disk of projectDocument) then
            set theProjectFile to file of projectDocument as alias

            tell application "Finder"
                set theProjectDir to container of theProjectFile
                set firstFileDir to container of firstFileItem
            end tell

            if (firstFileDir is equal to theProjectDir) then
                -- Use project file
                set theFile to theProjectDir as alias
            else
                -- External project file -> use first item to set context
                set theFile to firstFileItem
            end if
        else
            -- BBEdit doesn't provide direct access to the Instaproject root
            -- Use the first node from the project list
            set theFile to firstFileItem
        end if
    end if
end tell


tell application "Terminal"
    if (the first window whose busy is false) exists then
        set win to the first window whose busy is false
        set frontmost of win to true
        do script "spark flash THE_NAME_OF_YOUR_CORE " & the quoted form of the POSIX path of theFile
    else
        do script "spark flash THE_NAME_OF_YOUR_CORE " & the quoted form of the POSIX path of theFile
    end if
    activate
end tell