Shift Register

Whilst you have quite a few outputs to play with on an Arduino board; sometimes there won’t be enough.  One way to get around this is with the use of a shift register.  This is a brilliant way to output eight pin’s worth of outputs – using just three pins.  What’s more – it’s a fascinating insight into some elementary computer science…

I’m using the 74HC595 – purchased from the good folks at Oomlout. Here’s the data-sheet for the chip (also courtesy of Oomlout).  There’s also a really nice article on the Arduino website.

First of all we need to build a circuit.  Although this one is a bit fiddly – there’s nothing too complex here.

We connect pin 15 to +5V, pin 8 to ground.  Pin 15 & pins 1-7 are our output pins – so we connect them to whatever we want to switch on and off (I’m using an LED + a resistor – but you could easily also wire a transistor into each output to drive anything you’d like).  Pin 14 is our data input pin – I’ll connect that to arduino’s output pin 2.  Pins 11 & 12 are the “clock” & “latch” pins – and we’ll connect these to pins 4 & 3 of arduino.  We won’t be using pins 10 or 13 – but we do need to set them to the correct logic state: so connect 10 to +5V & 13 to ground.

Here’s a schematic:

And here’s a drawing of the circuit in breadboard form (both produced using Fritzing):

Note the resistors on the cathode side of each LED.  I’m using 560Ω – as I had a whole box of them around – but anything between 220Ω and 1KΩ ought to be fine (I seem to recall 470Ω being the “correct” value for a 5V circuit and normal LEDs – but as I say, as long as the resistors are there, don’t worry too much).

Okay.  So now onto the fun part.

If you want to try something quickly to check it’s all working, then as this circuit is pin-compatible with Oomlout’s ARDX circuit 5, you can try their code.

If all is well you’ll see the LEDs counting up in binary.

That’s all well & good – but how does it work?  Well the shift register library in Arduino is taking an 8-bit number (a byte – 0-255) – and then setting the output pins of the chip according to the bit values of the eight bits.

Whilst using a byte like this, is an example of a very elegant piece of computer science – bitwise operations can be quite hard to understand.  So let’s simplify things – by using a more familiar “container” for our eight bits: an array of booleans.

Now, this isn’t such an efficient way to work (most, if not all, microprocessors do their most efficient work when using bitwise operations) – but it is a bit easier to understand.

// Shift Register with array of booleans. 
// Code by AJP (cc 2010) – released under 
// Creative Commons Attribution-Share Alike… 
// Pin Definitions 

int data = 2; 
int clock = 3; 
int latch = 4; 

#define bit_count 8  

void setup() 
{ 
    // Set the three pins to output… 
    pinMode(data, OUTPUT); 
    pinMode(clock, OUTPUT); 
    pinMode(latch, OUTPUT); 
}

void loop() 
{ 
    boolean bits[bit_count]; 
    // Set each of the "bits" to 0… 
    for(int i=0;i<bit_count;i++) 
        bits[i]=false; 

    // Now we'll pick one, at random, and set it to a 1 
    int c=random(8); 
    bits[c]=true; 

    // Now we're ready to send the data to the shift 
    // register. We take the "latch" pin 
    // low – to get it ready to recieve… 
    digitalWrite(latch, LOW); 

    // Now we'll simply itterate through the "bits" 
    // and set the data pin either high or low 
    for(int i=0;i<8;i++) 
    { 
        if (bits[i]) 
        { 
            digitalWrite(data, HIGH); 
        }
        else
        {
            digitalWrite(data, LOW); 
        }
        
        // We've sent our bit; now to tell the chip we're 
        // ready to go to the next bit – by pulsing the 
        // clock pin for 1 ms… 
        digitalWrite(clock, HIGH); 
        delay(1); 
        digitalWrite(clock, LOW); 
    }
    
    // Finally we've updated all 8 bits – so we tell 
    // the chip we've done by setting the latch back 
    // to high 
    digitalWrite(latch, HIGH); 
    
    // To finish-up we'll delay for 125ms 
    // before going around again… 
    delay(125); 
}

Creative Commons License


Shift Register with array of booleans code by AJP is licensed under a Creative Commons Attribution-Share Alike 2.0 UK: England & Wales License.


This code makes it much easier to see what’s going on.  Once we’re ready to update the status, we set the latch: and then alternately setting the data pin (with the value of the bit) – and then pulse the clock HIGH for 1ms.

Now that we’ve seen how it works – let’s go back to the library code function:

shiftOut(dataPin, clockPin, MSBFIRST, dataValue);

Note that MSBFIRST is a constant denoting that we’re sending the most-significant bit first (aka big-endian) – we could also use LSBFIRST to send the least-significant bit first (little-endian). For more on the shiftOut function, see here [arduino.cc]; and for more information on big-endian vs. little-endian byte orders, have a look at this article on wikipedia.

Now that we have a feel for manipulating bits (by way of the analogous process of manipulating the array): how do we do it for real?

How do we, for example, tell the shiftOut function to turn on pins 4 & 6?

The best way is to return to those bitwise operators I mentioned earlier.

If we want to turn all eight pins on – then we need to send a bit pattern consisting of eight 1’s … 111111111 – which in decimal is 255 (i.e. 1+2+4+8+16+32+64+128).

For each pin we don’t want to turn on – we simply reduce this value by the corresponding binary value.  So if we only wanted to turn on all of the pins, except pins 0 & 7 – then we’d send 255-128-1 = 126.

Subtraction isn’t very efficient, or very elegant though: so instead – let’s use a bitwise OR…

The OR operator (which in C, uses this symbol: | ) works by comparing two bit patterns – and for each bit sets the output to 1 – if either one of the bit’s it’s looking at is 1 – or 0 if they’re both 0.

Using this, we can mask the bits we don’t want to change: if we OR  any pattern against 00001000 (for example), then the outcome will be to leave seven of the bits unchanged – and to set the 3rd bit as 1 (if it wasn’t already).

The last thing we need to do is work out which bit pattern corresponds to the bit we want to turn on.  The easy way is to remember some elementary mathematics.

To set bit 0 – we want 00000001 = 1, bit 1 is 00000010 = 2, 2 is 00000100 = 4, 3 is 00001000 = 8, and so on…  Using this we can see that 2^n will give us the value we want (2^0=1, 2^1=2, 2^2=4 … etc).

Given that we’re dealing with powers of two – there’s on last trick we can use, to avoid having to multiply: bit shifting…

Bit shifting does exactly what it sounds like – if moves (shifts) the bits either up or down…  So if we shift 00000001 two places to the left – we get 00000100.  So if we shift 1 by 0 places we 1, if we shift 1 by 1 we get 2, and so on: exactly what we want: and (critically) bit shifting is another very efficient operation.  In C the operator to shift to the left is <<.

Putting all of that together we get the following code:

state |= 1 << bitNum; shiftOut (data, clock, MSBFIRST, state);

That works for turning bits on – what about turning them off?

We can use a very similar trick: except that this time we need to use an AND operator (& in C), and the complement of the value we used last time.

AND works by setting the output to a 1 – if (and only if) both bits of the two bit patterns it’s comparing are a 1 – and 0 otherwise.

If all eight bits are turned on (11111111) and we want to turn 0th and 1st bits off – then we AND 11111111 with 11111100.  Again this works by masking: the bits that are set to 1 in the mask will be unaffected (if the corresponding bits in the original bit pattern were 1’s then the result will be a 1 – and it will be a 0, if they were a 0…).

So to turn off bit 4 – we need 11110111: the complement of 00001000 (8 in decimal).  To get the complement we use the complement operator (~ in C).

state &= ~ (1 << bitNum); shiftOut (data, clock, MSBFIRST, state);

Pulling all of this together, we get the following code:

// Shift Register with bitwise operators 
// Code by AJP (cc 2010) – released under 
// Creative Commons Attribution-Share Alike… 

//Pin Definitions 
int data = 2; 
int clock = 3; 
int latch = 4; 

void setup() 
{ 
    pinMode(data, OUTPUT); 
    pinMode(clock, OUTPUT); 
    pinMode(latch, OUTPUT); 
} 

void loop()
{
    int state=0; 
    for (int i=0;i<8;i++) 
    {
        state=setBit (state, i, true); 
        delay(125); 
    }
}

int setBit(int state, int bitNum, bool value) 
{ 
    digitalWrite(latch, LOW); 
    if (value) 
        state |= 1 << bitNum; 
    else 
        state &= ~ (1 << bitNum); 
    shiftOut (data, clock, MSBFIRST, state); 
    digitalWrite(latch, HIGH); 
    return state; 
}

Creative Commons License


Shift Register with bitwise operators by AJP is licensed under a Creative Commons Attribution-Share Alike 2.0 UK: England & Wales License.


And that’s all there is to it!

One last thing.  You can extend the circuit shown here – by adding one (or more) additional shift register chips – giving you an additional eight outputs for each one – and still only using three pins on arduino!  But that’s a subject for another post…

Introduction to Arduino…

Something that I really want to write about here, is Arduino.  Arduino, if you’re not familiar with it, is a really splendid, simple, low-cost, open-source micro-controller based board, originally created to be an easy to use platform: specifically to permit “designers & artists” to create projects with embedded micro-controller devices.  There’s a really good introduction on the Arduino website.

Although it was created with designers & artists in mind, there’s absolutely no reason why it can’t be used by more traditional users: such as computer scientists & engineers.

The free, Java-based IDE is very simple, and easy to use – but if you want to, you can use other tools – or the command-line.  The programming language itself is a subset of C++ – so it’s perfectly possible to write quite sophisticated code; or you could program it in native C++ using the avr-g++ compiler.

As I say: you can write good code for Arduino, but the biggest problem with the vast majority of the programming examples that you’ll find on the internet is that they are often quite poorly written (at least, from the point of view of a professional computer scientist and software engineer like myself)…  But it doesn’t have to be that way.  There’s no reason why “good” coding practices cannot be adopted; and writing good code doesn’t have to be any harder than writing bad code.

Arduino is also the perfect toy (or do I mean “tool”?) for someone with a software background, to learn something about hardware & electronics; and have some fun building some things.  That’s why I wanted one.  The problem is, that as with the software side, a great many (though not all) of the websites I’ve found about Arduino are written from that same (distinctly non-technical) standpoint – and as such, aren’t great reading for someone who is technical…  For example: whilst lots of the material I’ve seen will tell you what to do (that is how to build a particular circuit) – it doesn’t cover the why…  And I don’t mean they miss out detailed stuff, like “Why is that resistor 220Ω?”; but rather the fundamentals like why is it there, in the first-place!

Having said that, not every website is bad – and in particular I can recommend Oomlout; who not only have some good training materials – but who also have an excellent online store in the UK: where you can buy an Arduino “Starter Kit”

Whilst I can legitimately claim expertise with software, I don’t claim to be an electronics expert, (by any means) – but what I’d like to do in this blog, is to share with you what I have learnt: and to try to produce some learning materials, specifically written from the point of view of engineers & software people, to try to help pass that on…   (I don’t want to seem elitist here – I’m delighted that traditionally non-technical people want to learn about computers & software: and indeed I would encourage them to do so – it’s a fascinating subject: and a device like Arduino makes it possible to create all kinds of cool thing…  It’s just that “engineers” and “normal people” do rather need things explaining in rather different ways!)

Ed Roberts (1941-2010)

I was saddened today to hear (albeit rather belatedly) about the death of the some-time pioneering micro-computer engineer Ed Robterts.  Roberts died on 1st April 2010: aged just 68.

Roberts’ creation, the Altair 8800 was, arguably, the most important personal micro-computer ever made.  It was the machine that made the dream of a personal computer viable…  Yes, of course, the Apple ][ was the machine that brought “personal” computing to the masses – but there wouldn’t have been the Apple ][, had it not been for the market that the Altair created.

Roberts was a true pioneer – leaving behind the industry he created, long before it became the billion-dollar industry it would become; and instead taking up the white-coat of a doctor of medicine…

RIP

iPad delays…

Wired is now reporting that Apple have now said that the iPad won’t get an “international” (i.e. European) release until the end of May 2010.

This is somewhat disappointing news for Apple fans on this side of the Atlantic.

Apple cite spectacular sales figures in the US as the reason for the delay.  Keeping people waiting doesn’t seem like a terribly clever marketing strategy – so I can only presume that this is down to a real shortage.

I suppose the only upside to this, is that it gives Apple a little longer to develop a firmware fix for the wifi problems that have been experienced by some users.

Why iPad isn’t a laptop killer…

There’s been a lot of comment about Apple’s new iPad – much of it very positive but not universally so

It’s Cory’s point that I want to talk about here.

Before I start, I have to “declare an interest” (as it were) – I am an Apple fanboy; I admit that – but that doesn’t (or at least, I hope it doesn’t, make me unable to take a more dispassionate and reasoned view).

I think that Cory is wrong – because he’s looking at the iPad as a computer…  It’s not; rather it’s the first serious & mass-market “web appliance”.

For as long as I can remember, the editorials in computing magazines have heralded the end “computing” as an activity for the chosen few – and it being for “the masses”.  Even long before my day, there were those who viewed innovations such as “high level languages” as opening up computers for the man in the street.

Sadly, and also for as long as I can remember, those same editorial columns have also been full of stories telling us that computers are just too hard to use.  Even the advent of the GUI, and with the uptake of internet use in the last fifteen-years, mass-market sales, hasn’t really helped.  You still read columns pointing out that washing machines don’t need you to reinstall their operating system every eighteen-months because they’ve gotten a bit slow…

Apple have a great track-record of spotting, and filling, niches in the market (albeit not generally by being the first to do something – but by being the first to do it right).  There were laptops before the PowerBook, MP3 players before the iPod, smart phones before the iPhone, and so-on…  With the iPad the niche is the one currently filled by Netbooks: except (in my opinion) that it isn’t quite that simple.  I don’t think Apple are going after the “ultra-portable” aspect of the market as such (though clearly iPad fits in there): but rather the “portable web browsing” aspect…

And there’s the clever bit; and there’s why Cory is wrong.  The iPad simply isn’t trying to be a “computer” in the sense that we think of them today.  It’s not a laptop without a keyboard – it’s something else entirely.  It’s an information delivery platform – not an information generation platform.  It really isn’t a laptop – but an overblown iPod Touch.  In short – it’s a web appliance.

People think about their computers and their phones different.  Until iPhone (with a few minor exceptions) people didn’t ever think about updating the system software in their phone.  It was what it was…  The iPhone changed that – and make the phone more like a computing platform.  The iPad’s form-factor accentuates this still further; but to think of it that way is to miss the point.

I believe that it’s been designed to be an appliance, in the way that a microwave oven is an appliance.  Yes, you still have to know how to cook to do anything useful with it – but you don’t need to be a radar engineer…

It’s the same with the iPad.  By controlling all of the variables – Apple have produced a device that will “just work”.

Now, none of this is to say that I don’t agree with Cory’s central tenet: that openness of systems is a “good thing”.  Of course it is.  But to apply that to the iPad – is to miss the point.  He writes:

“The way you improve your iPad isn’t to figure out how it works and making it better…”

Well, no, okay.  That’s true.  But neither do I improve my fridge, or my TV, by “figuring out how it works and making it better”…

The truth is that over the last twenty-five years – the complexity of computers has increased exponentially (literally).  Someone keen and interested (with the right background and skills) could (can) understand how a late 1970’s vintage computer works – at the lowest possible level.  Indeed, you can even buy a (replica) of the Apple I in kit form: for home assembly.  But, with the best will in the world, no-hobbist can hope to build 2010 vintage iMac (for example) from scratch.  Miniaturisation and complexity have put pay to that.

This isn’t something that’s unique to computing.  Go back to the 1940’s or 50’s – and you’ll see that it wasn’t at all uncommon for enthusiasts to build their own radios.  Well, sixty or seventy years later – radio has given way to television as the mass-broadcast technology: and I don’t remember the last time I saw someone building their own plasma-screen TV from scratch…

The same is true with software too.  For all the myriad frameworks & libraries that exist today to make things “simpler” – they also (undeniably) add complexity.  Yes, using .net to write a Windows program is easier than writing that same program in C and calling all the APIs by hand; but even easier still is to write for the command-line…  GUIs make it easier to use computers – but harder to program them.

At the end of the day – most people don’t want to write their own code, but rather they want someone else to do it for them.

And, of course – for those that do what to write their own code: there will always be “fully fledged” computers… My suspicion though, is that the folks that buy an iPad instead of a computer – aren’t going to be the folks who want to write their own code.  The app store makes distribution easy – and safe: the installation process couldn’t be easier, and there’s no need to worry about virus and malware.  The lack of the ability to run just “any” code cuts both ways: it makes things safer, but it also limit what can be run to those apps “blessed” by Apple…  Is this a price worth paying?  For many people, honestly, I think it is.

And it’s not as if Apple are the first people to do this.  Take games consoles.  They are (arguably) the first home “computer-based” appliances.  Is there an outcry bemoaning the ability for individuals to write their own for their PS3?  No.  It’s just an accepted part of the way that these “appliances” work.  The iPad will be the same.

I think that the iPad has the potential to become the pattern for the future of computing for “the masses” (in the least pejorative sense of that phrase).  Yes, people will always want fully-fledged computers for “heavyweight” applications – but for mail, web browsing, and the like – I believe that the appliance approach is the way forward: and that iPad is at the vanguard of this coming trend.

Well, it is called “Random Thoughts”…

It’s called “Random Thoughts” – so I figured maybe I should start out with something genuinely random (though I’m not sure you could really call it a thought!), courtesy of the folks at random.org.

0 0 1 0 0 0 0 1 1 1 1 1 0 0
0 1 0 0 0 1 0 0 1 1 1 1 1 1
0 0 1 1 0 0 1 1 1 0 1 1 1 0
1 1 1 1 1 0 1 0 1 1 0 1 0 1
1 1 1 0 0 0 1 1 0 0 1 0 1 1
0 1 0 1 0 1 1 1 1 1 1 0 1 1
1 1 1 1 1 0 0 0 1 1 1 1 0 0
1 0 0 0 0 1 1 0 1 0 1 1 0 0
1 1 1 1 0 1 1 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 1
0 1 1 0 0 0 1 1 1 0 1 1 0 1
0 0 0 0 0 1 0 0 0 0 1 0 1 0
0 0 1 1 1 0 0 0 1 1 0 1 1 0
1 1 0 0 0 1 1 0 1 1 0 0 0 1
1 0 0 0 0 1 1 0 0 0 1 1 1 0
0 0 1 0 0 1 1 0 1 0 0 0 1 1
1 0 1 0 0 0 1 1 1 1 0 0 0 0
0 1 0 0 0 0 0 1 1 1 0 0 1 0