Raspberry Flavored Time (A NTP server on your Pi, tethered to a GPS unit)

 On 2012-10-18 and filed under: raspberry pi rpi adafruit ntp time gps


2014/11/12: This article’s is in the process of being revisited. Please keep in mind that it is very old before using its instructions and resources.

GPS module connected to a Raspberry Pi (for accurate time keeping):

Adafruit Ultimate GPS v3

A primer on time

Watch this brief video by Bill Hammack, aka engineerguy on YouTube. It covers the complexities of keeping very accurate time in a short video!

Where NTP fits in

Being on synchronized time is pretty important. Is your office clock faster or slower than the one on your watch? What about your phone? What if you turn it off for a month? A year?

In other to get time from very accurate sources, some devices and services use the Network Time Protocol (NTP for short) to keep their time synchronized. Your device is probably using NTP as you read this!

How it works: Periodically, your computer will connect to servers that speak NTP. After getting the time, your system does some math (to account for transmission delays, and bad clocks), and adjusts the system clock. This periodic synchronization keeps a clock from drifting too far behind, or too far ahead from the world standard.

By itself though, NTP does not provide accurate time information. This the job of a dedicated reference clock.

A reference clock is a precise source of time, and these are connected to a computer which transmit their data over a network using NTP.

In our case, we can (ab)use a GPS unit as a reference device (in GPS, accurate positioning requires very accurate time). While not a lab quality reference clock, it has enough accuracy for most applications.

Strata

In NTP parlance, time systems are arranged into different strata. Each level (starting from zero), determines how far away you are from a clock source. [1]

Stratum 0: Cesium/Rubidium-based clocks, radio and GPS clocks. Depending on precision, these can be very, very, very accurate (and really expensive too)!

Stratum 1: Computers attached to Stratum 0 sources. They expose the data from Stratum 0 to the world.

Stratum 2: Collector of stratum 1 time over a network. May punt bad stratum 1 clocks (e.g. stop listening to them).

Stratum N: N level away from 0, does the same as 2.

Stratum 16: Considered to be unsynchronized.

Most consumers of NTP data collect information from stratum 2 (or higher) sources.

For instance, Apple’s time.apple.com server is a stratum 2 time source. It might be connected to a bunch of stratum 1 time sources. In turn, the stratum 1 computers would be connected to a gaggle of stratum 0 reference clocks.

Being a stratum 2 source, it figures out which stratum 1 time source(s) it can trust and aggregates all the data between those. Using a bit of math, it figures out which sources seem bad, and kicks those results to the curb.

% ntpq -p
     remote           refid      st
====================================
*time.apple.com  17.168.198.148   2

GPS Clock-o-Bot

That brings us to setting up our own GPS-sourced clock. Why?

  • Perhaps you are stuck on a remote island without a reliable Internet connection.

  • You have some sort of experiment that needs to have great timing.

  • You’re going to use the GPS hookup for something else entirely (like a phone home device), and want the meat on how to do that. (Sure!)

  • You feel like abusing a NTP server for some reason, or policy prevents you from getting accurate time through the Internet.

  • Having your own time server is cool.

  • Say this in an Australian accent, or with an accent that features a high rising terminal so it sounds more awesome: “Why the heck not!”

Difficulties

Beyond this point, this becomes a slightly advanced article. You’ll most likely be comfortable with a bit of prior Raspberry Pi/Linux/Electronics experience under your belt.

I try to explain steps throughly, and provide links to external sources which should help even if you are a beginner.

Parts List

All of these parts are available from one vendor, so you don’t have to order and coordinate shipping times. The vendor used here is Adafruit. They’re well regarded with very reasonable policies and good people.

  • Raspberry Pi - The brains of the project! Raspberry Pis sell out fast, so buying from another vendor may be the only possible way of acquiring one.

  • Adafruit Ultimate GPS Breakout, v3 a very compact GPS unit with 1PPS output. (Note: If you have a v1 or v2, you can still get a 1PPS signal – you’ll need to solder a small wire to the exposed pad. See the PDF documentation for a pinout.)

Hardware voltage warning: If you are using another GPS, please mind the GPIO pin voltages as they are only 3.3v tolerant. There is no over-voltage protection on the board. This means a bad connection could easily kill a pin or worse.

  • Wires - If you will be using the Pi Cobbler below along with a standard breadboard, the wires should just be solid core wire. If you will be wiring the GPS up directly (using the provided header), they should probably be Female/Female jumpers.

  • Ethernet Cable - Or wireless adapter to connect. Definitely check old router boxes for this.

  • SD Card - For loading a distribution. You probably have one of these already lying around.

  • Power Adapter - The power adapter should terminate to a micro USB cable (these are the slimmer “phone charger” cables). Be sure to look for an adapter with a current rating of around 850mA (or more).

Optional

Distribution

Starting from scratch, you will need Occidentalis, a fork of Raspbian.

Download by following a few links here.

After downloading, write the image to the SD card.

If you have forgotten how to write images (it happens even to the best of us), try this guide on elinux.org.

Initial Setup

After flashing your SD card, insert the card and boot the Raspberry Pi by plugging it in.

Edit /boot/cmdline.txt, along with /etc/inittab to free up the UART (which shows up on /dev/ttyAMA0) so that the NMEA “serial” data can be read on the Pi.

$ sudo nano /boot/cmdline.txt

# Remove these in cmdline.txt:
# `console=ttyAMA0,115200`
# and `kgdboc=ttyAMA0,115200`.
# Mine looks like this:

dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

Hold CTRL+o and hit [Enter] to save. Then hold CTRL+x to exit.

Next, edit /etc/inittab and comment out, or remove the last line in this file (page down till you see it):

$ sudo nano /etc/inittab
#Spawn a getty on Raspberry Pi serial line
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

Once you are done, power off the Pi and begin connecting things to it!

$ sudo poweroff

# Remove the power connector when only the PWR LED remains lit/screen
# goes blank and begin attaching things.

Connect the following pins (Raspberry Pi is on the right, GPS on the left):

Here is a really boring pin out diagram:

GPS     RPI
---     ---
RX  --> TXD
TX  --> RXD
PPS --> GPIO #23
GND --> GND
VIN --> 5V0

Wiring for the Adafruit Ultimate GPS v3 (RX->TXD isn’t connected):

Adafruit Ultimate GPS v3

For the v2, with a wire soldered onto the 1PPS pad (the 1PPS wire goes to the blue one off image, which then leads to GPIO #23):

Adafruit Ultimate GPS v2

If you need background on where GPIO pin 23 is located when connecting directly, see this page at elinux.org. Otherwise, GPIO #23 is just #23 if you’re using the Pi Cobbler.

Once everything is connected and you’ve verified everything twice, connect the power.

1PPS

You may be wondering about the PPS pin!

While NMEA data is good enough for synchronizing time to within a few hundred milliseconds, it can be bad for applications that require precision timing, or just plain bad if you’re obsessed with getting precise time.

This is where the PPS pin we connected earlier comes into play. 1PPS or One Pulse Per Second, is a signal that says “here is the precise start of a second!” A PPS signal is usually accurate to a few nanoseconds give or take whatever is in the path between sender and receiver.

1PPS signal

Alone, 1PPS can only tell you the precise start of a second, so anything that wants to set time accurately needs both NMEA data and 1PPS information.

To effectively utilize 1PPS, we’ll have to patch the kernel and add support.

Switching The Kernel

Doing this isn’t particularly hard. However, keep in mind that it will overwrite any special modifications you’ve already done to the kernel, and will break on upgrades to the kernel.

In order to keep things simple, I have a repository with pre-made kernel modules and kernel image. If you’d like to view the source this is based on, click here. [2]

To grab the pre-compiled kernel and modules:

$ sudo apt-get install git
$ git clone https://github.com/davidk/adafruit-raspberrypi-linux-pps.git

Back up and copy the kernel image:

$ cd adafruit-raspberrypi-linux-pps
$ sudo mv /boot/kernel.img /boot/kernel.img.orig
$ sudo cp kernel.img /boot

Move the modules over:

$ sudo mv modules/* /lib/modules

Finally, add the pps-gpio module to /etc/modules.

# Run this command in a sub-shell so appending works
$ sudo sh -c "echo 'pps-gpio' >> /etc/modules"

By default, our setup isn’t usable by the NTP server since it expects data to be present at specific locations. By adding a few rules to udev, we can automatically make symbolic links (aliases, shortcuts, etc) from our NMEA serial and 1PPS data, to a place where NTP can read and interpret it.

If we didn’t create these rules, the NTP driver would get no data to process.

$ sudo nano /etc/udev/rules.d/80-gps-to-ntp.rules
# Change MODE of ttyAMA0 so it is readable by NTP and provide a symlink to
# /dev/gps0
KERNEL=="ttyAMA0", SUBSYSTEM=="tty", DRIVER=="", SYMLINK+="gps0", MODE="0666"
# Symlink /dev/pps0 to /dev/gpspps0
KERNEL=="pps0", SUBSYSTEM=="pps", DRIVER=="", SYMLINK+="gpspps0", MODE="0666"

Hold CTRL+o to write the file, tap [Enter] and then hold CTRL+x to exit.

Installing and Configuring NTP

To install NTP, we abuse the default install a bit since the repository version doesn’t really pick up on 1PPS. It will also take some time to do all of this since we’re compiling from scratch.

$ sudo apt-get install ntp
$ sudo apt-get remove ntp
$ sudo apt-get update
$ sudo apt-get install libcap-dev
$ sudo apt-get install pps-tools
$ wget http://www.eecis.udel.edu/~ntp/ntp_spool/ntp4/ntp-dev/ntp-dev-4.2.7p319.tar.gz
$ tar -xvf ntp-dev-4.2.7p319.tar.gz
$ cd ntp-dev-4.2.7p319

$ ./configure --prefix=/usr --enable-all-clocks --enable-parse-clocks \
--enable-SHM --enable-debugging --sysconfdir=/var/lib/ntp --with-sntp=no \
--with-lineeditlibs=edit --without-ntpsnmpd --disable-local-libopts \
--disable-dependency-tracking && make
$ sudo make install

Be sure to edit /etc/init.d/ntp and change the DAEMON line:

$ sudo nano /etc/init.d/ntp
DAEMON=/usr/bin/ntpd
#DAEMON=/usr/sbin/ntpd

Once you have been dropped back to the terminal, edit /etc/ntp.conf and add the following (be sure to change the broadcast line if it differs for you):

$ sudo nano /etc/ntp.conf

# http://www.eecis.udel.edu/~mills/ntp/html/drivers/driver20.html explains
# these settings
# Slightly modified, but credit to:
# Paul Kennedy @ (http://www.raspberrypi.org/phpBB3/viewtopic.
#	php?f=41&t=1970&start=80)
server 127.127.20.0 mode 17 minpoll 3 iburst true prefer
fudge 127.127.20.0 flag1 1 time2 0.496

For a general setup with an Internet connected Pi, leaving these uncommented is generally considered good practice.

server 0.debian.pool.ntp.org iburst
server 1.debian.pool.ntp.org iburst
server 2.debian.pool.ntp.org iburst
server 3.debian.pool.ntp.org iburst

What do the bits in the server line do? [3]

server 127.127.20.0 mode 17 minpoll 3 iburst true prefer

  • 127.127.20.0: Specify the GPS_NMEA driver.

  • mode 17: This sets the line speed (bit 4, dec: 16) to 9600 bps. Additionally, $GPRMC is processed (bit 0, dec: 1). We get a total sum of 17 when adding the decimal parts together (hence “mode 17”).

  • minpoll: Minimum polling interval for NTP messages in a power of 2. Here, 3 = 8 seconds.

  • iburst: If a server is unreachable, send a burst of eight packets instead of one.

  • true: Let the server survive NTP’s algorithmic weeding.

  • prefer: If we have a choice among good hosts (post-determination, etc), use this one for syncing.

fudge 127.127.20.0 flag1 1 time2 0.496

The fudge options are driver dependent. [4]

  • 127.127.20.0: Specify the GPS_NMEA driver.

  • flag1 1: Activate PPSAPI, and process the PPS signals we get.

  • time2: Compensate slightly for transmission delays. Instructions for tuning this are located on the driver home page. Specifically, look for 7 (bit) / 128 (decimal) in the mode section.

A complete explanation of the flags used is provided at the website above. You can also just click here to be taken there as well.

Reboot

Now that the kernel is updated, udev makes links properly, and NTP is installed+configured.. all that is left to do is pray to your local noodly appendage (or other $x of choice) and reboot.

$ sudo reboot

Checking the time

Once you’re back up, wait for your GPS to lock (give it a view of the sky to make this process faster).

When your GPS is locked to a sufficient number of satellites (the Adafruit GPS module will blink intermittently), type ntpq -p into your Raspberry Pi’s console, and you’ll get something like this:

$ ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
oGPS_NMEA(0)     .GPS.            0 l    8    8  377    0.000   -0.025   0.002

Unit Calibration (skip if not using Adafruit’s GPS module)

To get the best out of the Adafruit GPS unit, we will tune it so that it outputs only the sentences we need. In particular, we’re interested only in the $GPRMC lines.

Before continuing, ensure that the RX (GPS) to TXD (Raspberry Pi) line is connected. Add an extra wire if it isn’t.

Note that these changes are not permanent; they will be lost during a power cycle (install a battery to prevent this from happening), or reverted using another command. [5]

$ echo -e '$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29\r\n' > /dev/ttyAMA0

This command squelches all of the other NMEA sentences and only outputs $GPRMC, making everything tick a little more efficiently. To verify that the proper sentences are being output, run:

# Tap CTRL+C to exit
$ cat /dev/ttyAMA0
$PGTOP ....
$GPRMC ....

In certain cases, it may take several tries in order to get the unit to recognize the command properly.

If you’re interested in playing around with the outputs, check out this PDF, and use this checksum calculator to get the value at the end (this means that if we change the line above, the *29 value changes when the command changes.. so we would need to calculate a new checksum!).

Lights!

On a system with ntpdate (a Linux or OS X system usually has this utility), we can query the Raspberry Pi to get and/or set the time.

$ ntpdate -vdq 192.168.1.101
24 Dec 04:13:42 ntpdate[8390]: ntpdate [email protected] Fri Apr 27 08:36:47 UTC 2012 (1)
Looking for host 192.168.1.101 and service ntp
host found : 192.168.1.101
transmit(192.168.1.101)
receive(192.168.1.101)
transmit(192.168.1.101)
receive(192.168.1.101)
transmit(192.168.1.101)
receive(192.168.1.101)
transmit(192.168.1.101)
receive(192.168.1.101)
server 192.168.1.101, port 123
stratum 1, precision -19, leap 00, trust 000
refid [GPS], delay 0.02612, dispersion 0.00000
transmitted 4, in filter 4
reference time:    d482c575.72b3b105  Mon, Dec 24 2012  4:13:41.448
originate timestamp: d482c57c.9e9ef4c5  Mon, Dec 24 2012  4:13:48.619
transmit timestamp:  d482c57c.9d24334c  Mon, Dec 24 2012  4:13:48.613
filter delay:  0.02621  0.02617  0.02612  0.02620
         0.00000  0.00000  0.00000  0.00000
filter offset: 0.005206 0.005221 0.005233 0.005197
         0.000000 0.000000 0.000000 0.000000
delay 0.02612, dispersion 0.00000
offset 0.005233

24 Dec 04:13:48 ntpdate[8390]: adjust time server 192.168.1.101 offset 0.005233 sec

If the last line says “Server dropped: Leap not in sync” – it may take some time for trust in the time to be established. This tends to be on the order of minutes; if it happens, wait around 26 to 30 minutes and try again.

Integration

Ideally, this itself would be automated somehow. Each system has a time setting that allows you to set the time sync source.

OS X

Click the time at the top right, and click Date & Time Preferences. Type in your Raspberry Pi’s address next to “Set date and time automatically.”

Linux

If using a desktop, this tends to be handled in a GUI menu. If not, check to see if you have, or can install a NTP daemon. Then edit ntp.conf (usually located in the /etc/ directory) and set the server stanza as appropriate.

Windows

Windows users can also right click the time, click the Adjust Date/Time option, click on Internet Time (tab), then Change settings, and type their Raspberry Pi’s address into the box. Click Update now for effect.

Thanks & Updates

This will be a perpetually updating post as I fine-tune and discover new things to do.

Special thanks to everyone in this thread over on the Raspberry Pi forums who paved the way for this lengthy documentation.

Note: No consideration (except for great customer service) was given to me by Adafruit for writing this. I did win an unrelated prize a few days ago that I should dig into though (OHS bag of swag).

11/12/12: Thanks to @karldyson for reporting that PPS was not being picked up properly by the repository packages. Looks like that bug is still there!

12/24/12: Added information on calibrating Adafruit’s GPS module (including references) and updated offset in configuration. Clobbered the introduction and added more spelling errors/walls of text to confuse/clarify things a bit.

1/15/13: Changed the hardware voltage warning (fixed non-serious typo). Also tried to un-break formatting for note #5 and redirected help to a more proper place.

02/05/13: Added a reminder to connect the proper line before working on the Adafruit GPS module.

02/06/13: The DAEMON line in /etc/init.d/ntp had a typo, and should be /usr/bin/ntpd (due to the prefix used).

03/03/13: Thanks to both Sven Wunder and @davidmonro_ for reporting that pps-tools needs to be installed during a compile of NTP from source.

05/09/13: Collapsed the configure line (it was tested to be cut and paste friendly), and reduced the amount of make by one.

Extra Information on NTP

This includes a discussion about how a proper NTP setup should look like (having three servers to sync time is a good idea).

Notes & References

  1. http://en.wikipedia.org/wiki/Network_Time_Protocol#Clock_strata
  2. The kernel fork I used and modified is available here. Look under the ppsgpio branch. You can clone it or download the entire thing by clicking around.
  3. http://doc.ntp.org/4.2.6p5/confopt.html
  4. http://www.eecis.udel.edu/~mills/ntp/html/drivers/driver20.html
  5. Note that this disables select sentences, so if you’ll be re-purposing your Adafruit GPS unit in the future, you may use this command to reset it to its default sentences:
$ echo -e '$PMTK314,-1*04\r\n' > /dev/ttyAMA0

If that fails, removing the battery and unhooking the power for your unit will usually revert it to its old behavior.

cheers!

AVR Programming with Adafruit's Atmega32u4

 On 2012-10-01 and filed under: avr programming lufa usb avrisp


Introduction

This guide will help you build your own LUFA AVRISP-MKII clone using the Adafruit Atmega32u4 breakout board.

Build Materials

Linux

You will need Linux as a base for programming and compiling the LUFA project’s code. Using another operating system is possible, but won’t be covered here (sorry!) If you don’t have a dedicated Linux installation, try a Linux live CD and install the packages below to program.

Installation of AVR tools are provided for the Ubuntu and Fedora Linux distributions.

Adafruit Atmega32u4 breakout

A modified LUFA CDC bootloader comes pre-installed on these. This allows the chip to be programmed without an external programmer (at the cost of some memory space).

Atmega32u4 with ISP and programming reset line connected

For programming breakout boards, a 6-pin cable is attached to the programmer. A wire is hooked up to B4 (which connects to the target AVR’s RESET pin).

Note that without modification, the RESET line will trigger on the 6-pin cable as a part of the programming process through B4. Since the 6-pin cable connects RESET between both target and programmer, the programmer itself will reset when B4 is asserted (which ends the attempt). This gets worked around a little bit later by splicing into the wire.

This method is mostly optional, but useful since some breakouts are only programmed easily through the header.

Breadboard, wires, and maybe a ZIF socket

It is also possible to use a breadboard to program a chip. A completed layout looks something like this.

Breadboard Atmega32u4 ISP programmer targeting ATmega328P

There are problems with this setup:

  1. Removing the programmed chip may be difficult/annoying. A ZIF (zero insertion force) socket may be appropriate if programming a large quantity of chips.

  2. Depending on fuse settings, the recovery clock (or, as seen in the picture, a resonator) may be needed in order to program the chip properly. Breakout boards usually have some sort of clock source installed.

For most, it may be better to program using a dedicated PCB that has the 6-pin header broken out. This might be an Arduino for Atmega328Ps, or the BB313 for ATTiny chips.

Here are the necessary connections from the Atmega32u4 breakout to the chip being programmed (if using a breadboard):

Connections for breadboard

32u4 -to-> Target chip
B1   ----> SCK    (Arduino Digital Pin: 13)
B3   ----> MISO   (Arduino Digital Pin: 12)
B2   ----> MOSI   (Arduino Digital Pin: 11)
B4   ----> RESET  (Arduino Analog  Pin: A6)

GND  ----> GND    (Note: 1)
VCC  ----> VCC    (Note: 1)

Recovery Clock    (Note: 2)
B5   ----> XTAL1  (not needed for Arduino boards)


1. There may be extra tie in points for these.
   Check the datasheet to be sure.
2. The recovery clock can be used if your fuses are set incorrectly.

   If using the recovery clock, be sure to set the programing speed to 125KHz
   1/125000Hz = 8x10^-6 seconds (or 8 microseconds, since 1 microsecond -> 1x10^-6 seconds)  
   For avrdude add this as a parameter to set the microsecond bitclock period:
            -B 8
  • Optional (for a more compact setup): 6-pin IDC cable

A 6-pin cable will stop the programmer from becoming a bundled mess of wires. This works since most of the necessary pins (MISO/SCK/VCC/MOSI/GND) are broken out to the header. However, since both RESET lines are connected, the programmer itself will be reset if connected without modification.

Modified 6-pin IDC cable

Here is an example of the 6-pin cable which has been cut with a sharp knife. The line to cut is the 5th wire, starting from the red line as shown in the picture. If you aren’t sure, verify with a multimeter that the line is indeed the one used for RESET.

To verify: With your spare Arduino or other breakout board, just plug a wire into the RESET line (connected to a lead on your multimeter in continuity test mode – aka ‘beep beep beep’ mode), and connect the 6-pin header (red stripe to small dot, or box connector “tab” to the proper place). Poke the small wires coming out of the box to check. You may need to press with a bit of force.

Probing 6-pin IDC cable

For the absolutely paranoid, pulling apart the box connector may be a good idea.

Other ways around cutting up your cable: fuse manipulation, designing your own PCB (as some have), cutting header pins, etc. If you end up using this particular method, soldering up a detachable wire to the cable’s RESET (then connecting to the programmer’s B4 pin) might be a worthwhile project.

  • Female/Female jumper wire(s) (Female/Male, Male/Male, etc)

A wire to connect the reset line (B4) and other pins. You might need a single piece of male header to tie the jumper wire to your destination board. The RESET line is triggered using this connection.

Finding your board

Linux

I’m using Linux, so when I plug in the board this shows up after typing dmesg into a terminal:

[15138.776119] usb 3-1: new full-speed USB device number 51 using xhci_hcd
[15138.791800] usb 3-1: New USB device found, idVendor=239a, idProduct=0001
[15138.791806] usb 3-1: New USB device strings: Mfr=0, Product=1, SerialNumber=0
[15138.791808] usb 3-1: Product: AVR CDC Bootloader
[15138.793350] cdc_acm 3-1:1.0: ttyACM0: USB ACM device

ttyACM0: USB ACM device on the last line is where data gets accepted. There are a myriad of other ways to figure that out, but parsing dmesg will tell us if it failed to enumerate somehow.

Download LUFA (Linux)

The next step from here is to download the files necessary to load the programmer. Run the following (after acquiring git [1]).

$ git clone https://github.com/davidk/lufa.git
Cloning into 'lufa'...
remote: Counting objects: 52669, done.
remote: Compressing objects: 100% (10637/10637), done.
remote: Total 52669 (delta 42901), reused 51050 (delta 41412)
Receiving objects: 100% (52669/52669), 9.49 MiB | 497 KiB/s, done.
Resolving deltas: 100% (42901/42901), done.

This is a small fork of Dean Camera’s LUFA project (a framework for developing USB-enabled AVRs). Of interest is Dean’s clean-room copy of the AVRISP-MKII programmer, which turns the Atmega32u4 breakout into a programmer for other AVRs (egg, meet chicken). Run the following from outside the lufa directory.

$ cd lufa/Projects/AVRISP-MKII/
$ git checkout atmega32u4-avrisp
  Branch atmega32u4-avrisp set up to track remote branch
  atmega32u4-avrisp from origin.
  Switched to a new branch 'atmega32u4-avrisp'

Once you’re in the branch, ensure that your avr utilities are installed.

For Fedora users:

$ sudo yum install avr-binutils avr-gcc avr-libc avrdude

Ubuntu users:

$ sudo aptitude install gcc-avr avr-libc avrdude

Programming (check to see if your boot light is fading in and out, if not, press the white button and run the following):

$ sudo make avrdude AVRDUDE_PROGRAMMER=avr109 AVRDUDE_PORT=/dev/ttyACM0

Connect the programmer

If it all went well, you now have a programmer.

ISP programming Arduino Uno

Remember: The single red wire goes from B4 to the Arduino’s RESET pin.

Start your engines

At this point, all the hard work is done! Before programming, make sure that the RESET line is connected to B4. avrdude can be used to program a board by running it as such:

# For Atmega328P chips
$ sudo avrdude -patmega328p -cavrispmkii -Pusb -Uflash:w:Blink.cpp.hex

# For an Attiny4313
$ sudo avrdude -pattiny4313 -cavrispmkii -Pusb -Uflash:w:blinky.hex

An example session (targeting an Attiny4313 with the blink program from the bb313 website):

$ sudo avrdude -pattiny4313 -cavrispmkii -Pusb -Uflash:w:blinky.hex
[sudo] password for davidk: hunter2

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e920d
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
 To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "blinky.hex"
avrdude: input file blinky.hex auto detected as Intel Hex
avrdude: writing flash (60 bytes):

Writing | ################################################## | 100% 0.02s

avrdude: 60 bytes of flash written
avrdude: verifying flash memory against blinky.hex:
avrdude: load data flash data from input file blinky.hex:
avrdude: input file blinky.hex auto detected as Intel Hex
avrdude: input file blinky.hex contains 60 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.02s

avrdude: verifying ...
avrdude: 60 bytes of flash verified

avrdude: safemode: Fuses OK

avrdude done.  Thank you.

programming a bb313

Programming without using ‘sudo’ or root (Linux)

Running avrdude as root is kind of excessive, even temporarily. To run it as a normal user, we can eck out the following to make it work properly:

First run groups to get the list of groups your user currently belongs to:

$ groups
davidk dialout wheel

This determines what we set in the GROUP=“” field below (in this case i’ve picked wheel):

$ sudo su
# echo 'ATTR{idVendor}=="03eb", ATTR{idProduct}=="2104", GROUP="wheel", MODE="0666"'
>> /etc/udev/rules.d/60-avrispmkii.rules
# udevadm trigger

Thanks

Special thanks to Dean Camera, who saw that I was making changes to my fork on Github (which is a mirror of his SVN repo) and stopped by my lowly branch to suggest a small change. Good guy (he did it again too, on an unrelated branch).

Problem?

Tack on something here. I will try to help or spin you in the right direction.

Reference(s)

[1] Get git via your preferred package manager, or check out http://git-scm.com.

Updates

01-15-13: Added information on using avrdude in a non-root fashion for Linux. Also threw in some magic to make console stuff pretty.

music

 On 2012-09-16 and filed under: offtopic


A bit of Ruby to start things off (I guess I should say ‘test’ in here too).

#!/usr/bin/env ruby

class Music
  attr_accessor :id, :artist, :title, :album
end

songs = Array.new

ARGV.each do |m|
  f = File.open(m)
  while (l = f.gets)
    info = l.split(';')

    if info.length > 0
      song = Music.new
      song.id = info[0]
      song.title = info[1]
      song.artist = info[2]
      song.album = info[3]
      songs << song
    end
  end
  f.close()
end

songs.each do |s|
  puts "#{s.artist} - #{s.title} - #{s.album}"
end

eh?