Arduino without the arduino environment (a minute guide)

The only way to learn a new programming language is by writing programs in it. The first program to write is the same for all languages:

Print the words
hello, world

This is the big hurdle; to leap over it you have to be able to create the program text somewhere, compile it successfully, load it, run it, and find out where the output went. With these mechanical details mastered, everything else is comparatively easy.

–Kernighan & Ritchie, 1978

This quote is annoyingly true in the world of microcontrollers. “Hello, world” is considered to be flashing an LED, and it’s more a case of learning the microcontroller rather than a language, though there’s often not that much different, due to the idiosyncrasies of microcontrollers.

This time, I’m diving in to Atmel, via Arduino. Today I came to the conclusion that I needed some reasonably precise timing on some I/O lines. So, I went off to Maplin to see what they had and perhaps not very surprisingly they had a selection of Arduinos (they no longer stock PICKIT in store), so I picked one up. The device consists of an Atmega328p MCU, another Atmega acting as a USB-serial device, a USB port, some bootloader software and some headers including in circuit programming ones.

Essentially the Arduino is everything you need to do to get started with microcontrollers (except the USB cable), a standard breakout layout and an easy to use programming environment. The Arduino environment is not suitable for me today. This is not a criticism, but the trade of simplicity for flexibility means it deals with all the interrupts and timers and good control over them is precisely what I need.

Without the nice environment, the main problem is figuring out the correct magic incantations to go from some C code to a blinking LED. It of course also took me far longer than it ought to have done to figure out, which is why I’m writing about it here.

Here’s the C++ program (test.cc) which I want to run. Note that avr-gcc comes with some nice utilities like time delays, and the Arduino UNO (and most other arduinos) have an LED wired up to what is labelled as pin 13 on the board which corresponds to B5 for the UNO.

#include <avr/io.h>
#include <util/delay.h>
int main()
{
    // DDRB  Data Direction Register for port B
    // 1 corresponds to output. 0 for input.
    // _BV is Bit Value, i.e. BV(x) is 1<<x
    DDRB |= _BV(DDB5); 

    while(1) 
    {
	PORTB^=_BV(PB5);
        _delay_ms(100);
    }
}

And here are the magic incantations in the form of a Makefile:

#This is the form of names cross compilers usually have
CXX=avr-g++
CC=avr-gcc
LD=avr-g++

#atmega328p is used on the Arduino Uno
#It needs to be specified in several places so it's in the 
#Makefile, not the source code.
MCU=atmega328p

#serial port for programmer
#Find this by typing "dmesg" after plugging in the cable
PORT=/dev/ttyACM0

#Specify the CPU frequency in Hz
#Required for the delay() function in the C source.
F_CPU=16000000UL

#Specify optimizations:t's more common to optimize for size
#not speed (-Os) due to limited flash. We need to tell the compiler
#what the MCU is (of course), and F_CPU needs to be #defined before
#the util header is included.
FLAGS=-Os -mmcu=$(MCU) -DF_CPU=$(F_CPU)

#Set these flags so they're picked up by the implicit C and C++ 
#compiler rules.
CXXFLAGS=$(FLAGS)
CFLAGS=$(FLAGS)


OBJECTS=test.o

#Bog standard linker line
test:$(OBJECTS)
	$(LD) -o $@ $<


# Programmers expect HEX files not ELF files.
# Copy the text and data sections to make a hex file.
# .text is the machine code. .data is all the static data
# I don't believe we need anything else
%.hex: %
	avr-objcopy -j .text -j .data -O ihex $< $@

clean:
	rm -f *.o *.hex test

# "make upload" target to program the MCU
# -p specify MCU
# -c progrmmer type.
# -e erase
# -U actions which are flash memory write test.hex
# -P perial port
upload:test.hex
	avrdude -p $(MCU) -c arduino -e -U flash:w:test.hex  -P $(PORT)

And that’s it. It was as simple as I expected/hoped. Other than a bit of Make guff and some verbosification to make it a bit more managable and obvious, there’s 4 lines of active code, one of which is a completely standard linker instruction. How many LOC per day would that make it? 🙂

I’d like to thank Micah Carrick and Sudar Muthu for their guides/tools which is where I got most of the information from in the end.

Custom cable boots

Commercially manufactured cables typically come with moulded boots. These are very useful because they protect any internal solder or crimp joints from flexing (which is typically a very weak point) and act as a strain relief. The strain releiving is so good that normally the cable itself is the weak point and will snap before the connector breaks. There are plenty of companies that will make any custom cables you want at a reasonable price per cable, provided that you want to order them by the palette load. If you want a few tens or fewer, one’s options are somewhat limited.

I needed to make a cable that could hook into an EMG (electro myography) machine. It turns out that surface EMG electrodes use a somewhat standardised connector that closely resembles snap buttons on used on a lot of clothing. It further transpires that the “Prym”/”Dritz” brand size 3 sewing snaps (note, not size 3/0 which is much smaller) are exactly the right size. There’s also a metric size one that fits that’s available in the UK which I believe is 12mm. Either way, the sewing snaps fit, so that’s what I used.

The connection between the wire and snap was simply made by soldering with a small amount of extra, non-corrosive flux added. If the cable in the pictures below looks suspiciously like an earthing cable, that’s because it is :).

The cable boot itself is made from polycaprolactone (specifically the instamorph brand) which is a plastic which melts at 60 degrees C. The plastic has a few very nice properties.

First it melts at 60 degrees, so not only is is mouldable at easily achieved temperatures, when heated in boiling water, it stays mouldable for quite a long time. Secondly it’s quite sticky and bonds very well to other plastics and a little bit to metal. This makes it ideal for cable boots as the good bonding means it takes the strain.

The temperature is low enough that you can actually just blob some plastic over the cable by hand and make a respactably robust if rather rough looking cable boot. For a somewhat more professional look, you need a mould. Here’s what the mould looks like:

mould

It was printed on a Form 1 printer. For these purposes, the Form 1 is rather superior to an FDM printer. It’s a small piece, so we really need the high resolution. Also, the Form 1 resin is impervious to many glues and doesn’t stick to polycaprolacetone at all, so de-moulding is very easy, whereas polycaprolacetone sticks very well to the more common FDM plastics (ABS, PLA and particularly HIPS).

To use, you solder a wire to a snap stud and push the stud into the hole in the left hand mould, making sure the wire goes between the two alignment cones. You then put a blob of hot plastic into the cavity on the right hand mould and clamp the two halves together very hard in a vice. The alignment cones and holes make the moulds self-aligning in practice to around a tenth of a milimeter on these peices.

You can then lever the moulds apart (the chamfered edges make that easy to do with a screwdriver) and trim any flashing and risers. Note that the right hand mold has a hole as well which goes through to the outside and provides an exit path for excess material, much like a riser. The results look very nice:

BOOT

The detail reproduction is remarkable. It’s not possible to see it in the photo, but careful examination of the piece reveals that it’s actually reproduced the very fine faceting that you can see in the 3D rendering of the mould.

They are also strong. Destructively testing them shows that the cable itself breaks before the connector.

The main downside is that the air coming out of a beefy laptop’s side vent can easily reach 60 degrees, so these can melt if you leave them in the wrong place…