img_7333.jpg

SevSeg Arduino and Easy Driver Stepper Motor

This is a continuation of my previous post. When we left off, I was trying to figure out which pins on the Sparkfun SevSeg display I could repurpose for my own purposes as digital out pins.

I did some research on the ATMega chip, and it is pretty clear that most of the pins on the top row of the SevSeg could be used for other purposes. Having identified which (Arduino) pins were connected to the display, I was able to figure out which pins were connected to the top row of solder points by using a simple programs that displayed a number on the LCD while simultaneously toggling that pins state to high and low. I had some trial and error — for example my multimeter takes about 4 seconds to register a change in voltage and my initial script was changing the voltages faster than that… at first it seemed like nothing was happening! But finally I figured out the pin numbers for the solder points. Only after I did all that did I look in the header file provided by the Sparkfun “board” for the SevSeg and see that they’d provided convenient macros for those points! All in all I found 6 available digital I/O pins.

I decided to connect five pins to the Easy Driver — Enable, Step, Dir, MS1 and MS2. I left MS3 disconnected. This will allow me to control the direction of rotation, turn off power to the motor, and use half, quarter and one-eight stepping modes for slow speeds.

That left one pin for a button. I verified that I could make inputs work by simply connecting one output pin to one input pin by sliding a resistor between the two solder points. When I programmatically set one of them to output HIGH while putting the other into INPUT_PULLUP, I verified that I could read a state change.

Next I soldered connections between the buttons and the EasyDriver and the SevSeg. I’m also using the EasyDriver as a power supply for the SevSeg.

I found some example code for how to drive the stepper motor by sending alternating HIGH and LOW pulses to the STEP pin, each with some delay. This worked perfectly, on the first try. However, when I tried adding the digital display to show how many rotations are left, I ran into a problem. The SevSeg.cpp uses delays internally to rapidly illuminate each digit in succession. I also needed carefully timed delays between each STEP I send to the stepper. Arduino doesn’t have any threading support. I was facing having to build some kind of scheduler to allow these two tasks to do small bits of work offset by time delays. Ugh.

But then I discovered the clever pt.h “threads” library by Adam Dunkels. This imposes some pretty strict limitations on your “C” code — e.g. locals are not persistent across WAITs. But the solution to that was the (normally frowned upon) practice of using static/globals for everything! The original SevSeg library was built around a C++ object, which I had to refactor to be a static “C” function — easily done once I made all its member fields public (another no-no, normally!).

The end result: I can control both the motor and the display simultaneously without one (significantly) interfering with the other.

And here is a demo of the finished project:

Using Sparkfun 7-Segment Display as an Arduino : Part 1

Today I opened my new Sparkfun 7-Segment display and tried my hand at using it as a general purpose Arduino controller. My ultimate plan is to use it to drive a stepper motor and to respond to the input of a push button. However, this item interested me because it has 4 7-segment LED displays attached to it, which means my project could provide some minimum visual feedback.

First, I opened the package and soldered 6 header pins onto the end — put them inside where the package is silk screened with a little white line. I plugged in a FTDI connector and plugged that into my Mac. It displayed a zero on the first of the LED displays.

Next I installed the Arduino IDE and the FTDI driver for my Mac. The instructions for FTDI driver installer said to run a command `sudo kextunload –b com.apple.driver.AppleUSBFTDI` but that just gave me an error message (“Can’t create –b. Can’t create com.apple.driver.AppleUSBFTDI.”) so I don’t know if it did anything.

Next I tried running some sample SevSeg.cpp files but had trouble.

I realized I needed to program this device using a definition provided by Sparkfun. I followed the instructions in this repo’s readme file to install those definitions: https://github.com/sparkfun/Arduino_Boards and then selected “Sparkfun Serial 7-Segment Display” from the Arduino IDE Tools -> Board menu.

I found the SevSeg project and copied the files (SevSeg.cpp and SevSeg.h) next to my Arduino project file (SayHello.ino). Word of warning: This library just emits a blank character for letters that don’t have any mapping into LCD (e.g. K, V, W, M…) I guess it’s cool that it even tries to draw any letters at all…

Finally I had to figure out the pin order for this particular display. The SevSeg project requires about 18 integer parameters when it is initialized… and I had trouble mapping pinouts (for example from this spec for the display: http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Components/LED/Serial-7-Segment-Display-v31.pdf) to the parameters. One of the things I’m immediately finding myself annoyed with in Arduino is the lack of transparency around what pins are called…. apparently each board renames the ATMega pins (which already have names like PB0 or PC4) to a new number. Finally I was able to solve this by looking at the firmware for the Sevseg display and copying the key values from there:

int digit1 = 16; // DIG1 = A2/16 (PC2)
int digit2 = 17; // DIG2 = A3/17 (PC3)
int digit3 = 3; // DIG3 = D3 (PD3)
int digit4 = 4; // DIG4 = D4 (PD4)

//Declare what pins are connected to the segments
int segA = 8; // A = D8 (PB0)
int segB = 14; // B = A0 (PC0)
int segC = 6; // C = D6 (PD6), shares a pin with colon cathode
int segD = A1; // D = A1 (PC1)
int segE = 23; // E = PB7 (not a standard Arduino pin: Must add PB7 as digital pin 23 to pins_arduino.h)
int segF = 7; // F = D7 (PD6), shares a pin with apostrophe cathode
int segG = 5; // G = D5 (PD5)
int segDP= 22; //DP = PB6 (not a standard Arduino pin: Must add PB6 as digital pin 22 to pins_arduino.h)

int digitColon = 2; // COL-A = D2 (PD2) (anode of colon)
int segmentColon = 6; // COL-C = D6 (PD6) (cathode of colon), shares a pin with C
int digitApostrophe = 9; // APOS-A = D9 (PB1) (anode of apostrophe)
int segmentApostrophe = 7; // APOS-C = D7 (PD7) (cathode of apostrophe), shares a pin with F

int numberOfDigits = 4; //Do you have a 2 or 4 digit display?

int displayType = COMMON_ANODE; //SparkFun 10mm height displays are common anode

//Initialize the SevSeg library with all the pins needed for this type of display
myDisplay.Begin(displayType, numberOfDigits,
digit1, digit2, digit3, digit4,
digitColon, digitApostrophe,
segA, segB, segC, segD, segE, segF, segG,
segDP,
segmentColon, segmentApostrophe);

My next objective is to see if I can repurpose the pins on the top of the display to control a stepper motor and read a button. Those are silk screened on the display as A7, A6, GND, VCC, SD0, SCK, RST, SD1, SS (with a bar), and RX. I haven’t yet figured out what those pins are called in arduino-speak, nor what their ATMega names are either. Stay tuned…

Use Xvnc to configure CrashPlan on Linux

I have found numerous posts suggesting that using ssh to open a forwarded port and manually reconfiguring the CrashPlan client is the best way to configure. I wasn’t successful using that technique. (Later I realized it’s because my server was on CrashPlan 4.3.3 and my client was on version 4.4.x.)

Instead I installed Xvnc by typing `sudo apt-get install vnc4server` then I created a password file called vncpassword.file like this: `vncpasswd vncpassword.file`. Finally I started the VNC server with `Xvnc -PasswordFile vncpassword.file` and let that run.

Then in a second ssh connection to my server I enabled X by typing `export DISPLAY=:0.0`. Then I started CrashPlanDesktop with `/usr/local/bin/CrashPlanDesktop`.

Now on my Mac I connected to my server by going to the Finder, choosing Command-K (The “Goto” menu) and entering “vnc://my.server.name” (My server has a DNS entry — you could also use the IP address).

Then I saw the CrashPlan UI over VNC. That’s also where I noticed that it was having trouble updating to the latest version. I found a log dir in `/usr/local/crashplan/log` and one of the recent files had this message: `This client requires one of these JREs: 1.7 1.8. Exiting upgrade`. I was able to install Java 7 using `sudo apt-get install openjdk-7-jre` and then `sudo update-alternatives –config java`. Finally, restart the CrashPlan back-end with `sudo /usr/local/crashplan/bin/CrashPlanEngine restart` I haven’t (yet) uninstalled Java 6.

Note: When you’re all done, be sure to kill your VNC server. I suspect it’s a security hole to leave it running…

How to create a git repo with the SQLite amalgamation source

Suppose you use GIT for your source control and would like to include SQLite as a third-party component via `git submodule` or `git subtree`. How does one go about getting access to the SQLite amalgamation as a GIT repo? When I tried this I found one on github.com, but it wasn’t being maintained any longer. It occurred to me that I didn’t need to depend on anyone else — I could do this myself. These steps use the bash command line shell. I’ve tried it on Mac OS, but should also work on Linux or using a bash shell on Windows. SQLite source is kept in a source control management tool called Fossil (http://fossil-scm.org). (It’s written by the authors of SQLite and uses SQLite internally, naturally.) The authors courteously tag each major of release in Fossil. So it’s simply a matter of cloning the SQLite source, checking out each tag, running the makefile to produce the amalgamation and checking in the amalgamated code into a new git repo.

Setup:

  1. Install Fossil from http://www.fossil-scm.org/download.html
  2. Install dev tools necessary for building fossil’s amalgamation (make, etc..)
  3. Install git
  4. Clone the SQLite source repo using fossil:

    mkdir sqlite-fossil
    cd sqlite-fossil
    fossil clone http://www.sqlite.org/cgi/src sqlite.fossil
    fossil open sqlite.fossil
    cd ..
  5. Create a new git repo to hold the amalgamation:

    mkdir sqlite-amalgamation
    cd sqlite-amalgamation
    git init
  6. Optional: Create a README.md file with a copy of these instructions or a link to this page and commit it.

In the future you won’t need to clone from fossil fresh, nor create a new repo — you’ll still have them. To add new SQLite releases to your repo you will use `fossil update` and `git pull` to update the two repos.

Adding one release:

  1. Perform these steps, replacing $1 with the release name — OR just copy this into a file called build-sqlite.sh next to your two repos, make it executable using `chmod +x build-sqlite.sh` and invoke it with the name of the release.
    cd sqlite-fossil
    fossil update $1
    rm -rf ../sqlite_build
    mkdir ../sqlite-build
    cd ../sqlite-build/
    ../sqlite-fossil/configure
    make sqlite3.c
    cd ../sqlite-amalgamation/
    mv ../sqlite-build/sqlite3.c .
    mv ../sqlite-fossil/src/shell.c .
    mv ../sqlite-build/sqlite3.h .
    mv ../sqlite-fossil/src/sqlite3ext.h .
    git commit -a -m $1
    cd ..
  2. For example:


    ./build-sqlite.sh version-3.8.11.1

    Not sure what all the tags are? Use `fossil tags` to display all the tags. Search for the ones that start with 3. as the major releases. Warning: The releases do not sort in alphabetical order (e.g. 3.8.11 sorts before 3.8.9 but is a later release) so use care when picking which tags to build, otherwise your git repo could end up with the commits not in the correct order.

Böx Game

Do you have an iPhone or iPad? Try my new Box Game. It’s inspired by “Uncle Lester”, a magician from the early twentieth century who had a passion for puzzle boxes. My version has a few levels (4 or 5) and no instructions. It’s designed to entertain you for a few minutes and that’s all. Leave comments here if you have feedback.

If you like it: that makes me happy. If it gives you trouble or you don’t like it… well, at least it was free.

Winter words of Wisdom

No matter how tired you are of putting on your long johns and your flannel lined jeans and your down vest and your insulated snow pants and your wool scarf and hand-knit hat and thinsulate gloves and micro-fiber parka and felt-liner muck lucks … Put them on. It’s cold outside.

Use sips and python to create vector-based AppIcon for iOS and OSX

I was surprised to see that Xcode does not make it easy to build all the various icon files for AppIcons for Mac OS and IOS. A few tools have been whipped together, but I’m not a fan of needing to install a whole new GUI app just to solve a simple problem. I’m also not a huge proponent of python, but it’s one of the scripting languages that natively supports JSON — which is part of how Apple’s implemented .xcassets (look inside you’ll see a file called Contents.json). So here is my solution — you’ll need to customize it for your own project. This particular project has two different AppIcon.appiconset entries in the xcassets file.

Note that this script re-writes the Contents.json file, to normalize the file naming. By default if you drag-and-drop files into Xcode it just adds -1 and -2 etc.. to the name, which is lame.

Whenever you update the icon (hardcoded here as a file called ‘icon.pdf’) re-run this script and the icon for you Mac and/or iOS app will update!

import re
import json
from subprocess import call
from pprint import pprint

for iconset in ['Design Show Server/Images.xcassets/AppIcon.appiconset', 'Design Show/Images.xcassets/AppIcon.appiconset']:
	json_data=open(iconset + '/Contents.json')
	newdata = []

	data = json.load(json_data)
	for img in data["images"]:
		size = int(re.sub(r'x.+$','', img["size"]))
		filename='{idiom:s}_{size:d}_{scale}.png'.format(idiom=img["idiom"],scale=img["scale"],size=size)
		filepath='{iconset:s}/{filename:s}'.format(iconset=iconset,filename=filename)
		if img["scale"] == '2x':
			size = size * 2
		newdata.append({ "filename" : filename, "size" : img["size"], "idiom" : img["idiom"], "scale" :img["scale"] })
		print('{filename:s} {size:d}'.format(filename=filename,size=size))
		call(['sips', '-s', 'format', 'png', '-Z', str(size), '-o', filepath, 'icon.pdf'])
	json_data.close()
	contents_file = open(iconset + '/Contents.json', "w")
	contents_file.write( json.dumps({ "images" : newdata, "info" : { "version" : 1, "author" : "andy's python script" }}) )
	contents_file.close()

Here’s a gist:

How to move commits after git filter-branch

I’ve read that you’re supposed to be able to use git rebase to move commits from an old repo to a one after using git filter-branch. But I couldn’t get that to work.

The backstory: Our repo was bloated because we started by forking a different project, and then deleted unneeded parts. This was an easy way to get started, but we ended up with all the history of the old project. So I ran git filter-branch and some other tools to clean up the history and remove empty merge commits. While I was preparing that, the rest of the team kept working on the old repo.

So I had to move those commits the rest of the team made onto the new, filtered repo. I used git format-patch and git am. Like this (assuming cwd is the new repo):


( cd ../old-repo; git format-patch --stdout -k commit id on old-repo of last shared commit ) | git am -k