Saturday, May 17, 2014

Make Life Easy, Make it Modular



This is a follow on to a post I wrote back in March 2014.  

As integrated circuits get smaller, and more powerful, it becomes increasingly difficult for the hobbyist to utilise them easily. Soldering tiny SMT parts is a challenge for many - so let's try to find a way to make life easier.

Why not make our microcontrollers modular - so you buy what you need that matches your application, and at a price you can afford. Unbelievably you can now buy an Arduino Nano or Pro-Mini from China, cheaper than you can buy the microcontroller IC from a Western supplier.

So if you want to quickly hack stuff together, standardised modules are one way to go.

A standard module footprint across different manufacturers.

This would really open up the competition between the various microcontroller suppliers.  Whether it's PIC, TI or Atmel, they all release a reference design for a standard module, and an accompanying IDE based on a common standard, so that you can easily, and seamlessly swap between devices.

So let's speculate about a series of standardised modules, which can offer varying degrees of performance, choice of microcontroller and yet are available in a compact, breadboard friendly, dual in line (DIL) footprint. For interchangeability, the power pins, reset and uart pins need to fixed, whilst the remainder of the pins can be general purpose I/O, perhaps arranged into a row of analogue function pins on one side, and a row of digital on the other. SPI interfaces should preferably be assigned to 4 consecutive pins for convenience. 

32 bit versus 8 bit. 

32 bit ARM microcontrollers are now virtually the same cost as older 8 bit devices, yet offer a many fold increase in performance, as a result of their 32 bit architecture and faster clock speed. In addition to this, they come with a rich set of peripherals, making them ideal for more demanding applications.

For the hobbyist who may have first gained exposure to microcontrollers via 8 bit products such as the Arduino, the move to 32 bit may appear a little daunting.  However we all have to progress and keep up with the times, so forget 8 bit and 5V logic and get into the world of 32 bit devices running at 3.3V - or less.

The Arduino shield idea was a good move to gain standardisation and traction within the Maker Community, but as we move to more powerful microcontrollers, the original shield pin-out is no longer appropriate or desirable. Perpetuating the non-standard header spacing this long after the original mistake was made is questionable.

At 68x53mm, the original Arduino form factor is starting to look a lot on the large size - particularly when you want to compact it into a small device, such as a robot. Fortunately this has been addressed, and the very compact Pro-Mini and Nano are clearly a step in the right direction.

In an ideal world we ought to be able to buy standard modules, that come in 28, 32 or 40 pin DIP packages, that offer whatever speed and resources we need. A 40 pin DIP is about the maximum convenient size, and with 35 or 36 I/O pins available it's well suited to the pin-out requirements of 48 pin microcontrollers, and offers nearly twice the I/O of the original Arduino in a footprint that is a quarter of the size. A smaller format uses a lot less pcb material, increases the density of the hardware, and allows manufacturers to focus on supplying a high-end microcontroller in a usable package,

In the Arduino world, the Pro-Mini and Nano, go some way to pin compatibility, at least they have the power pins and most of the I/O lines appearing on the same pins.

All it would take is someone to define a popular standard, and everyone else produces compatible hardware.

There will obviously be a requirement for more sophisticated boards, generally of the Raspberry Pi and BeagleBoard format, where a high-end ARM, running an operating system, is combined with external RAM, flash and a host of external peripheral interfaces. For these devices a different solution will emerge, but first let's focus on the easy stuff.

Keep it Modular - So easy to upgrade.

When your 16MHz ATmega328 module can no longer hack it, you search the suppliers for an upgrade. Do you stick with Atmel, or switch to TI, STM or Microchip? You select a module with the right footprint, Flash and RAM resources and clock frequency and do an instant upgrade.  All of your existing code is easily ported to the new module.

I wanted to explore the module concept further, so set about designing my own.

Getting Started.

The plan was to make a standard plugable component, that gives users the power of a 32 bit ARM, but in an easy to use and breadboard friendly module. I reckoned that a 40 pin DIL module would be about the right format for most small projects.

I elected to use the STM32F3xx range of microcontrollers from ST Microelectronics.  They have a great mix of both digital and high speed analogue ADC peripherals and are good value for money.

Initially I bought a Discovery F3 development board, which uses a 100 pin STM32F303 processor and has  compass, accelerometer and gyro devices on the board. It was exceptionally good value at under $11 from Newark.  However, whilst it provided a platform to get me started writing code and getting the framework to support my application built, it was just too big and the double row headers are not the friendliest of connectors to use. I didn't need all of the 80 lines of I/O provided by the 100 pin device, so I settled on the 48 pin part, offering 35 I/O lines, which was somewhat smaller, cheaper and more manageable in terms of pcb layout.





My solution was to create a 51mm x 19mm  double sided pcb, which mounts the STM32F303 microcontroller,  its clock and reset circuits and USB/programming connectors. This small breakout pcb, converts the pins from the 48 pin LQFP to an easier to use 40 pin dual in line module, and provide the minimum of features to get the STM32 to load and run code.  

This approach is not new and has been used in minimalist products such as the Maple Mini, Teensy and the Arduino Pro Mini and Nano, all of which have been around for some time.

I decided to name the board "ARMiGo" in respect to its user friendliness and I designed the ARMiGo to be as open and flexible as possible, so that it can be used as a core for incorporation into other designs.  The essential parts of that core are the microcontroller, the 8MHz crystal, the reset circuit, USB connection and programming header. 


The first of the prototypes arrived this week, and now working running some simple test code.

ARMiGo uses the STM32F303 Cortex M4 ARM device which runs at a maximum of 72MHz.  The pcb will also support the cheaper STM32F103 which is based on the M3 core and does not have such a rich mix of analogue peripherals.

The board is the same size as a standard 40 pin DIL format IC - making it ideal for breadboarding, and small enough to be used as a plug in module in a 40 pin socket, on a larger board.

All 35 I/O lines of the ARM chip are brought out to standard 2.54mm spaced headers.

The 5 pin right angle header on the left accepts the clock and data signals from the "ST-Link" programmer/debugger device.  These are available very cheaply from ebay/taobao/deal xtreme etc.
However it is relatively simple to use the embedded STM bootloader and program it via either the mini-B USB connector on the right or via one of the USART channels.

There is a really rich mix of on-chip peripherals, particularly analogue ADCs, op amps, comparators and programmable gain apmplifiers, which gives these small ARM parts tremendous flexibility - including the following:

Full speed USB interface on chip - no need for FTDI or equivalent

4  Fast (5 Msps)  12bit ADCs, each with up to 4 input channels

4 Programmable gain op-amps and 7 comparators

2  12 bit DACs

3   USARTS

3   SPI

2   I2C

RTC with 32768 Hz oscillator and dedicated output pin for "alarm"

10 timer channels,  2 basic,  6 general purpose and 2 advanced:5  General purpose  16 bit timer channels with up to 4 outputs for PWM generation, timing, counting etc.

1 general purpose 32 bit counter/timer - for optical encoder reading etc

2 advanced 16 bit timers for complimentary PWM generation etc.

In addition, the analogue section of the IC contains programmable gain op-amps and comparators which feed the ADC channels, and can be used to replace external analogue circuitry.

This small 48 pin packaged part contains 128KB of Flash and 40KB of SRAM - of which 8K can be battery backed up when the rest of the IC is powered down.

In the attached picture, most of the lower row of pins is the analogue I/O, and the upper row is mostly digital, although there are many options for allocating the peripheral functions to different pins.

With 5MHz 12 bit analogue interfaces it offers greater resolution and much faster sampling speed than Arduino. Additionally the 72MHz clock and 32bit wordsize will all make for a much faster data thoughput.

The combination of 35 I/O lines, on chip USB and a user friendly module, should make ARMiGo the starting point for a wide variety of new projects. Prototypes can now be breadboarded or easily built on stripboard, and the module just plugged straight in.

If you want more details about ARMiGo - please drop a comment.  I expect to release the upated EagleCAD files shortly.

Sunday, May 11, 2014

SIMPL Revisited

SIMPL

SIMPL stands for Serial Interpreted Minimal Programming Language.

It provides a quick means of programming microcontrollers for I/O interaction, using short text strings.

What this means is that a block of code or function can be invoked by sending a single serial character. Text strings are interpreted, character by character, to produce a complex program flow.

A few characters typed in to the serial terminal can be used to set output ports, read inputs or create accurately timed, complex sequences of I/O interaction. Operations can be chained together, stored in RAM and given a single uppercase alpha identity, which when typed will execute the whole sequence of instructions.

SIMPL is an interpreted language, which although this gives a minor speed disadvantage over compiled code, is fast enough for most experimentation - but to it's advantage, massively increases interactivity with the code.  Commands are easily retyped, modified and re-executed immediately, without having to go through the edit - recompile - reload process, which even on the Arduino slows down iterative development to every couple of minutes or so.

SIMPL builds up an interactive programming environment, the framework of which can be re-used from project to project, either for debugging, experimentation, or interacting with the microcontroller with the minimum of overheads.

The Arduino is essentially a serial connected device, as are many other microcontroller dev-boards, and as a simple, low overhead means of controlling the micro from a serial terminal program SIMPL provides a framework onto which more elaborate applications can be built. Blocks of code can be exercised in turn using serial commands, and debug sent to a terminal.

At the heart of SIMPL is an interpreter written in Arduino (or other microcontroller) using standard C code - for ease of portability.  I have recently ported SIMPL to the 32 bit ARM STM32F407, STM32F303, and the 16 bit MSP430 in order to illustrate it's versatility.

SIMPL is an ongoing project that was inspired by Ward Cunningham's Txtzyme interpreter.  If you want to learn more about Txtzyme - here's the link, and the Txtzyme Github page, where you can download the Arduino sketch version of Txtzyme. If you are new to this, it's worthwhile playing with Txtzyme, and studying the interpreter code to get a better understanding of it's operation.

For more background on SIMPL - please look at my blog posts from May 2013 onwards - starting here.

The Interpreter

At the centre of SIMPL is the interpreter, derived directly from Ward Cunningham's Txtzyme, which is just 90 lines of code.  It is a series of switch/case statements contained within a loop.  ASCII characters are allocated a function, which is executed by a small block of code, and then program control is returned to the main loop, to fetch the next character.

The original Txtzyme interpreter handles the following commands:

0-9    Numerical characters are enumerated to a 16 bit integer variable x
{}     Code within the braces is executed repeatedly controlled by a loop counter
m      A blocking delay of 1 millisecond
u       A blocking delay of 1 microsecond
p       Print the value contained in variable x to the serial terminal
_ _    Print the text contained within the underscores to the serial terminal
d       Allocate a digital port pin
o       output to the allocated port pin
i        read input from the allocated port pin
s       read the analogue input
k       A variable which is decremented on each iteration of the loop


Txtzyme interprets a character into an action, and that action may be controlled using a single numerical 16 bit integer parameter x.  It is the equivalent of passing an integer variable to a function in C code.

Numerical characters are enumerated into a 16 bit integer x.  The value of x is used as a control parameter for the next instruction. For example

100{}    this sets x to 100 and then repeats the commands within the braces 100 times

10m       this sets up a delay of 10mS before the next instruction is executed

13d        this allocates digital pin 13 as the one that will be handled by the next instruction

1o          Set logic high (output) on the previously allocated pin

0o          Set logic low on the allocated pin

So by combining these commands we can produce a simple LED flasher - on Arduino the LED is on digital pin 13

13d100{1o100m0o100m}  

Turn the LED on, wait 100mS, turn it off, wait 100mS and repeat this 100 times.

If however you wanted a very accurate on and off time, you could incorporate the u microsecond delay command into the above.

13d100{1o100m250u0o100m350u}

This sets the on time to 100.25mS and the off time to 100.35mS

As you can see, Txtzyme used a mix of lower case alpha characters and punctuation symbols as the instructions.  A Txtzyme interpreter running on any microcontroller, should be able to decode any string of these characters and produce the same overall action. This will give the language portability between microcontrollers. As there are only 26 lower case characters and 32 punctuation characters, this limits the scope of the language to something manageable. The alpha characters are chosen to act as mnemonics, so that the instructions are easy to remember.  This mix of lowercase alpha and punctuation characters are known as the primitives.

Txtzyme was great and a lot of fun to use, but I wanted to extend it into a more capable language, which allowed more than just a few I/O and printing operations to be performed.

I chose to add some arithmetic operators to Txtzyme, and in doing so added a second 16-bit integer variable - called y.

Then it became obvious that the ascii strings typed in via the serial terminal could be stored in RAM, and executed at any time.

I found a simple way of  allowing them to be addressed and executed, by using an upper case alpha character to act as a label to the address where the strings were stored.

This allowed the very short programs to be stored in RAM and executed just by typing a single uppercase character.  These characters could be concatenated, formed into loops, or called recursively from within Txtzyme strings. Whilst only 26 of these micro-programs were available, it is sufficient to build up some quite sophisticated operations - the sort of thing that could be used for teaching programming techniques to a young audience.

With the extensions I have added to Txtzyme, the program is still only about 260 lines of C code or just over 6.1k when compiled for the Arduino.

The main loop of SIMPL consists of just 3 functions:

txtRead
txtChk
txtEval

txtRead simply reads a character from the serial input buffer.

txtChk looks at the first character to see if it is a colon : and if so, writes the remainder of the text buffer to an area of RAM, with the store address based on the value of the uppercase alpha character that follows the colon. This takes case of colon definitions.

txtEval is the heat of the interpreter. It does one of three things:

It takes each character in turn, if it is a number it forms a 16 bit integer which it stores in variable x.

If it is a lower case alpha or punctuation character, it looks it up in a switch/case structure, and executes any code associated with it.

If it is an uppercase alpha character, it transfers the attention of the interpreter to the area of RAM addressed by that character, and continues to interpret characters from there.

I have deposited this latest version of SIMPL at this Github Gist  It compiles on Arduino 1.0.4.

FYI

There have been a few minimalist interpreted languages over the years, one notable example Mouse, was developed to operate within the acute memory limitations of an early minicomputer, intended for electronic music composition on a PDP-8. If you want to delve deeper - the full Mouse history is here.

Monday, May 05, 2014

A little more shifty....

Recap

In the previous post, I quickly reviewed the techniques for interfacing shift registers to Arduino based hardware and highlighted some simple code for reading and writing to the external shift registers.

Whilst to some, this may have appeared to be a whistle-stop tour, there is however a wealth of similar information available online and I felt that it would have been of little overall value just repeating the excellent examples and documentation provided by others.

Instead I wanted to get something up and running quickly which would extend the Arduino and act as the basis of a variety of projects, requiring additional input output devices such as LEDs, switches, and actuators such as stepper motors and hobby servos.

I am using the SIMPL language to control the shift registers.  If you have not come across SIMPL yet - please see my related blog post, and those going back to May of 2013.

Output to Shift Registers

With my recent experiments with shift registers, I wanted to send a 16 bit word out to a pair of output shift registers to selectively illuminate an array of LEDs.

In SIMPL, I chose the lower case ascii character "r" to represent this output to register function using the following Arduino code:

      case 'r':            // Send an 16 bit byte to the shift register using shiftOut
   
      PORTB &= ~_BV(0);
      shiftOut(dataPin, clockPin, MSBFIRST, x,8);      // shift out the high bits:
      shiftOut(dataPin, clockPin, MSBFIRST, x);        // shift out the low bits:
      PORTB |= _BV(0);
      break;

To use this function, you need to supply the 16 bit integer x immediately preceding the r character,

so 0r will turn off all the LEDs and 65535r will turn them all on.

Light Chasers

These are very simple to set up just by turning on the LEDs in a sequence. SIMPL is ideal for this.

We have a SIMPL command "r" which does a 16 bit write to the pair of shift registers.

128r will turn on LED 7, 64r will turn on LED 6 and so on.  We can use the millisecond command m, to keep the LEDs lit for, say 100mS.

128r100m64r100m and so on.

So let's define a LED sequence that counts down from the left - ie moves to the Right. We do this using the colon to start a definition - called R

:R 128r100m64r100m32r100m16r100m8r100m4r100m2r100m1r100m

And similarly a LED sequence that moves to the Left

:L 1r100m2r100m4r100m8r100m16r100m32r100m64r100m128r100

Now you can use L and R to make chase sequences

10{LR}  - 10 iterations of the Left-right chaser sequence

Stepper Motors

From creating a moving light chaser display, it is a very simple step to controlling the motion of a stepper motor.  Rather than turning the LEDs on in a sequence, it is simply a matter of energising the windings of the stepper motor in the correct sequence.

The hardware we will use is available cheaply on ebay, and consists of a small unipolar 5V stepper motor with 64:1 reduction gearbox, and a small circuit board that contains a power driver IC (ULN2003) and usually 4 LEDs.

The stepper motor coils are energised in the following sequence for forwards motion. This sequence of 8 steps is known as a half step sequence :

1
1 and 2
2
2 and 3
3
3 and 4
4
4 and 1

So let's code these into a number sequence that can be sent to the shift register and driver.

1
3
2
6
4
12
8
9

Now let's define a Pause statement, so that we don't have to keep changing the 100m delay when we want to change speed.  100mS may be OK for testing, so as you can see what is going on, but for the real miniature stepper motors, this delay should only be about 1mS.

:P  1m

Now let's code these numbers into definitions F, for Forwards and B for Backwards

:F 1rP3rP2rP6rP4rP12rP8rP9rP

:B 9rP8rP12rP4rP6rP2rP3rP1rP

So we can now use a sequence of F or B to provide forwards or backwards motion

512{F} will produce one complete turn of the motor shaft, because there are 512 steps to a full rotation of the gearbox shaft, and each iteration of "F" produces 4 steps.

At the end of each sequence t might be wise to send a 0r - in order to turn off all of the windings whilst the stepper is idle.

There are other sequences of coil energisation, which are used, sometimes when more torque is needed. A useful link here.

step-fig-3-1.gif (5087 bytes)


step-fig-4-1.gif (10593 bytes)

Input from Shift Registers

To complement the output command q, I wrote a short function to read the input shift registers. Command "t" is used to test the input registers and put the resultant value into x.

In order to display the value x, you need the print command p.  So the following construct was used

tp   test the input register and print the value to the serial monitor

tq   test the input register and display the value on the output LEDs

The code behind the "t" function is as follows:

     case 't':     // test the inputs from 74HC165 shift registers
   
      digitalWrite(loadPin, LOW);
      digitalWrite(loadPin, HIGH);
      x = shiftIn(sinPin, sclkPin, MSBFIRST);  // Read incoming word from 74HC165
      digitalWrite(sclkPin,HIGH);
   
      break;

In the next part, I'll be looking at the high power TPIC6B595 and using it to control a pair of stepper motors using SIMPL.



Friday, May 02, 2014

A little bit shifty

Experimenting with Shift Registers and Arduino

Shift registers are probably the least understood class of devices used in microcontroller and hardware design, yet they are central to so many common interfacing techniques, so I thought I would spent a few evenings getting to know how to use them.

There are some very good online tutorials regarding the use of shift registers, so I will not try to improve upon the wealth of good material that is already available, instead I will attempt to document some of my recent findings, in the hope that someone finds it useful. Everyone can type Arduino and shift register into Google and come up with a whole bunch of useful information.

My experiments have been done with an Arduino, or rather a low cost clone that uses the ATmega328P microcontroller, but could equally be applied to any other microcontroller, as the firmware is written in C or C++.

Here are 10 facts about shift registers that make them very useful.

1. They convert serial data to parallel, and parallel data to serial.
2. They can be easily chained together, generally 8 bits at a time to make longer wordlengths.
3. They are cheap and readily available - about £0.30 for an 8 bit shift register.
4. They can be used for storing data
5. They are used in UARTs for serial communication
6. They are used in I2C and SPI interfaces
7. They can be used to extend the simple I/O capabilities of small pin-limited microcontrollers
8. They can come with power drivers stages for driving lamps, relays and stepper motors
9. They are ease to wire up, using few pins and easy to control with simple firmware
10. They often form the basis of many segment LED drivers

I will be looking at some very common types:

74HC595  - this is the ubiquitous 8 bit series to parallel shift register, used for outputing parallel data. It requires just 3 pins on the Arduino to control it, and can be chained together to make much larger word sizes. It is available as a breadboard friendly 16 pin DIP, but also as compact SOIC, TSSOP and QFN packages.  As a HC device is is compatible with both 3V3 and 5V logic and can be powered from 2V to 6V. Each output can supply 20mA - which is ideal for driving LEDs with a suitable series resistor. Available from several manufacturers the world over. Datasheet here

74HC165 - this performs the complimentary function to the '595 which is parallel to series conversion. It also requires 3 pins to drive, can be chained to make larger word sizes and is very often used to provide additional input lines on small microcontrollers. These are very useful for reading switches (such as DIP switches used for configuration), or any other parallel input data. Again the HC logic allow a wide range of supply voltages, and available in a 16 pin DIP or several other compact packages.  Datasheet here

TPIC6B595 - this is an 8-bit serial to parallel shift register followed by a DMOS power driver stage, capable of 500mA of drive. It can be used for driving higher current, inductive loads directly such as relays, solenoids and small stepper motors. Available as a 20 pin DIP (or smaller) package, it can be used to replace the popular combination of a 74HC595 followed by a ULN2803 octal darlington driver.  If you are short of pcb space - this device is worth considering.  About £1 each in 10 off quantity.  A typical application would be driving a "fruit machine" where a few hundred lamp drivers are needed. Datasheet here

If you follow the links to the datasheets, you will see that 2 of them are via the Sparkfun site, showing the popularity of shift register devices amongst hobbyists. Indeed, shift registers are available on breakout boards and Arduino Shields, like this 48 Channel Output shield that uses six of the 74HC595 devices.

My experiments are slightly less ambitious. I decided to breadboard two 74HC595 devices and two 74HC165 devices to make a 16 bit output LED display, and a 16-bit switch input in order to expand the capabilities of the Arduino. Additionally I wanted to explore the use of the TPIC6B595 device as a means of driving a pair of small stepper motors - as the basis of some robotics and automation projects.

Wiring Up

74HC595 Output

Connecting a pair of shift registers on a breadboard to make a 16 bit word size is fairly straightforwards - here is a circuit from a French tutorial. It has nice clear diagrams of the breadboard layout too.

You will need 3 spare pins on the Arduino, referred to as latch, data and clock.  If you use the Arduino ShiftOut() function, these can be any three spare pins, but I chose to use 8,9 and 10 in order to leave 11,12 and 13 spare for future SPI work. If you follow the tutorial above and the code example provided it is very simple, and you will be up and running in no time.

I wanted to speed up the time that the latch signal was present, so in order to lower the latch I substituted the usual digitalWrite() function for the direct port command

PORTB &= ~_BV(0);  // This lowers digital pin 8

and to raise it

PORTB |= _BV(0);      // This raises digital pin 8

Doing this small code change allows the shift register to be updated at about 8000 times per second.


74HC165 Input

Wiring this up was also fairly straightforward.  Again you will need 3 lines to control the shift registers. I used digital lines 5,6 and 7 - again to avoid the SPI pins.  Again this  French wiki provides nice neat circuit diagrams in EagleCAD format.  However, I used pull down resistors, rather than pull-ups, and I used the Arduino shiftIn() function.  At first I noticed some very odd behaviour, where the register appeared to be multiplying the input number by 2. I had had a past experience of this, and realised that it was caused by clocking on the wrong edge of the clock.  This was easily corrected by making sure that the clock line is raised after the shiftIn(), so that it idles in the HIGH state, not the low state.

Code

Now we look at the code to combine the reading of the input shift registers with writing to the output registers. First we need to define the 6 various pins that carry the control signals:

   int sinPin = 5;            // Serial input pin from 74HC165
   int sclkPin = 6;          // Clock pin to 74HC165
   int loadPin = 7;         // Parallel load pin of 74HC165  
   int latchPin = 8;        // Pin connected to ST_CP of 74HC595
   int dataPin = 9;         // Pin connected to DS of 74HC595
   int clockPin = 10;     // Pin connected to SH_CP of 74HC595

and then within setup() - set them up as INPUT or OUTPUT

    pinMode(d,OUTPUT);
    pinMode(loadPin, OUTPUT);
    pinMode(sclkPin, OUTPUT);
    pinMode(sinPin, INPUT);
    pinMode(latchPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
    digitalWrite(sclkPin,HIGH);    // initialise the clock HIGH


Once you have set up the pins it's just 4 lines of code to read the inputs

// Read incoming word from 74HC165

digitalWrite(loadPin, LOW);
digitalWrite(loadPin, HIGH);
int incoming = shiftIn(sinPin, sclkPin, MSBFIRST);
digitalWrite(sclkPin,HIGH);

and 3 lines of code to write to the outputs

// and write it out to 74HC595

PORTB &= ~_BV(0);
shiftOut(dataPin, clockPin, MSBFIRST, incoming);  // shift out the bits:
PORTB |= _BV(0);

This sketch is available in full at this Github Gist

Once the signals have been defined and initialised, the code to read and write to the registers is really very trivial.  Whilst I have used the shiftIn() and shiftOut() functions provided by Arduino, these functions are also fairly simple and can readily be substituted for routines that directly control the I/O pins - if additional speed is needed.

In the next part I will look at how this shift register functionality can be incorporated into real applications such as stepper motor driving.


More Information

Nick Gammon's tutorial on using the '595

Nick Gammon's tutorial on using the '165

These outline using the shift registers with the SPI bus. This is the next step if you need the fastest speed data transfer.

The flawed Arduino tutorial - do not connect the 1uF capacitor there!! It's supposed to be a 100nF capacitor across the 5V and 0V power pins!