Swarm

We were on our way out of the house today and I'd just got into the car only to see James dash back into the house, slam the door shut and start waving and mouthing madly at me through the window. Eventually I figured out what he was trying to tell me - there was a swarm of insects in the tree behind the car. I got out and took a look, and sure enough there was - you can see the big brown mass in the tree above the back of the car.

swarming bees

I went inside and grabbed my camera and went back for a closer look (yes, I'm daft ;-) I've seen bee swarms on the telly before but never quite such a large one, it must have been nearly three feet long - wow! The bees didn't seem at all aggressive, they just formed a huge, quietly buzzing mass. In fact people walking past only a few meters away didn't even seem to realise they were there.

swarming bees

I was in a bit of a quandary about what to do. The British Beekeepers Association website has a "swarm help" page which gave a contact number for the area, but I didn't get any answer. The site also suggested contacting the local Environmental Health Officers, but today being a Bank Holiday meant that wasn't an option. The local Council website gave a contact number for another Beekeeper, but again, no answer. Hmm. Chris then remembered that she'd bought some honey in the past from a local Beekeper and as we were heading out of town in that direction anyway, we decided to knock on his door and ask for advice. When he came to the door and we explained the story to him, he immediately said that he'd come and collect the bees - wow, didn't quite expect that! Brian asked us to go back home and keep an eye on the bees as he said often they would move on from where they had settled. We duly went home, and about 10 minutes after we arrived, and for no apparent reason, the outer layer of the swarm started to fly off the swarm, and within a couple of minutes the entire swarm were in the air and on the move.

swarming bees

They moved across onto another tree, and then onto another, finally starting to form a bee ball again just as Brian arrived. Unfortunately they'd formed three different clusters in the tree, all over a parked car, which made getting at them rather difficult. Brian fetched an empty hive from his car and placed it as close as possible to the bees. He explained that if he got the queen into the hive the other bees would most probably follow, and that he'd put combs and food in the hive to try and make it a tempting residence for them. I asked him why they swarmed in the first place and he explained that it was how colonies propagated - the colony would hatch a new queen who stayed in the hive whilst the old queen and a good proportion of the flying bees left in a swarm to form a new colony.

swarming bees

You can see two of the bee balls in the tree above the car. I got a ladder from the shed and with the hive in place below, Brian climbed up and, one by one, clipped off the branches with the bee balls on them, collecting a couple of stings for his troubles. By now there was a bit of an audience watching him, several of the neighbours were as fascinated as I was and had come out to see what was happening.

swarming bees

Brian gently cut and carried the branches down to the hive, put the branch inside the hive and shook the bees off. I expected a storm of angry bees as he cut and carried the branches, but they just stayed in the ball and disappeared inside the hive when shaken off. Brian said it was a pretty big swarm, he estimated probably 10,000 bees or more. Once the bees were in the hive and the lid was on, Brian said that he'd leave the hive where it was until dusk, then the bees would all go inside the hive and he could safely plug the entrance and move it. When we got back home this evening the hive had gone, so I guess the rescue was successful.

Bees are having a bit of a hard time at the moment, with colonies dying out for reasons that aren't fully understood - Brian said he'd lost 7 hives over the winter, and that he was expecting some bees from the Isle of Man to see if they will fare any better. It was therefore nice to see the founding of a new colony, and Brian kindly gave me a jar of his honey when he left, so a success all round :-)

Categories : Personal

Bidirectional patterns with the HL1606

Most of the videos on YouTube of the HL1606 being driven with an Arduino have patterns that start of the controller end of the strip and propagate to the far end, for example this one. I'm driving patterns in two directions, and even outwards from the centre of the strip. How's that done?

Very simple really, I model the LED strip in software as an array of bytes, one per LED. I load up the array with whatever LED on/off/up/down transformations are needed to create the next step of the pattern, and then shift the entire array to the strip. With the /SS line held low the pattern isn't displayed as it is shifted onto the strip, then when /SS is pulled high, the entire pattern displays all at once. Do that fast enough and you can create whatever patterns you want.

I'm clocking the data to the strip at 2MHz which means it is taking about 80 microseconds to push out a 20-LED pattern, which is far faster than the response time of the LEDs or indeed of the human eye. It is also above the maximum speed specified in the datasheet which is around 1.7MHz, however I'm only driving 20 LEDS at a time rather than the 200 in a full 5 meter length, I don't expect such a high data clock rate would be possible with 200 LEDs. As ever, the datasheet is pretty confused - it isn't clear if the time it takes to propagate the pattern between each chip is 250 nanoseconds or 100 nanoseconds. Whatever, there will be a propagation delay that gets larger as the strip gets longer, so there will definitely be a limit to the number of LEDs you can drive and still have such high clock rates work reliably. Even so, you should still be able to clock a full length in a couple of milliseconds, which should still be imperceptible.

Categories : Tech, AVR

How the HL1606 REALLY works

I've explained in my last two Arduino posts how I got the HL1606 working with the Arduino's SPI support and hardware timers. If you haven't already read them, I suggest you read at least the first post before this one, otherwise what follows won't make much sense.

The setup I'm building needs to drive four strips at the same time, so the next step was to add another strip. The SPI protocol uses a /SS line for each slave, so that multiple devices can coexist on the bus. To communicate with a particular slave, you pull /SS for that slave low, send the data on the bus, then pull /SS high. The other devices on the bus ignore the traffic as their /SS lines are held high during the transaction. After wiring everything up and making the necessary code changes, I ran my existing text code to make sure the first strip was till working OK. Well, it was, but the new, second strip was going completely nuts, displaying a flickering version of the pattern I was sending to the the first strip - not at all what I expected. I did the usual things of checking the wiring and the code, which was all OK. I even tried tying the /CS line of the second strip to +5V to be sure it was unselected, but it made no difference. Hmm...

After some further thought, I began to suspect that despite what the datasheet said, the HL1606 was not in fact a SPI device. A clue to this was that the datasheet shows a high pulse on the /SS line (labelled L_I on the datasheet) rather than a continuous high level. OK, so what was it doing? As I said in my earlier post, the HL1606 has two shift buffers (A & B) and two output drivers (A & B). Pulling the /SS line low does indeed suppress the copying of the shift buffer contents into the output latches, and pulling it high does indeed result in the shift buffer contents being copied into the output driver to light the LEDS. However there's one vital but missing piece of behaviour - when the /SS line is high the HL1606 should ignore the contents of the data bus, but it doesn't. Instead, if /SS is high the current contents of the shift buffers are copied to the output driver immediately. That explained why the second strip was displaying a manically-flashing version of the pattern displayed on the first strip - as the data was being shifted out to the first strip, the second strip was shifting in and displaying the data as it progressed down the strip. Duh, that is clearly not how SPI works.

OK, that's a big problem. The AVR only has one set of SPI hardware and I didn't have enough pins to implement five SPI buses using bit-banging, as each requires four pins. What I needed was some way of disabling each strip other than using the dysfunctional /SS line. The SPI bus uses clock line supplied by the bus master, with the clock line determining when the data should be sampled. Perhaps if I suppressed the clock, the HL1606 would ignore the data on the bus? That was easy to test, I just disconnected the clock line on the second strip and the mad flashing stopped. Yay.

So now I needed to come up with a way of controlling the SPI clock being supplied to each strip. I could have done that by using another pin per strip to control an external gate on the clock line but I already had such a line, the per-strip /SS line, even though it didn't actually work correctly. All I needed was something that could use an active-low input to gate the clock line. After a little digging I found a 7400 series chip, the 74HC125 quad bus buffers. Each one has four channels - great, I had four strips to control, and at 32p each they weren't going to break the bank. I connected the /CS lines to the /G pin of the 74125, the clock line from the Arduino to the A lines and the clock line of the strips to the Y lines and fired everything up - perfect, the strips now only respond when their particular /SS line was active. The only extra tweak required was the addition of a 20K pull-down resistor - the outputs of the 74HC125 are tri-state when switched off, so the resistors are needed to stop the clock lines to the LED strips from floating (and false-triggering) when the strips are deselected.

Each strip has 20 LEDs so I extended my existing code to generate a 40-LED pattern and then in the output code I split the pattern into two halves, sending each half to one strip so that I could test out patterns that span more than one strip. You can see the results below.

I've still more work to do - I need to drive the SPI radio chipsets I'm going to be using, I need a task management framework to coordinate everything, I need a way of generating the patterns easily and so forth, but the major hurdle of driving multiple strips simultaneously using the minimum number of pins has been solved. I'll be writing further posts as I go, so please check back for more :-)

Categories : Tech, AVR

Driving the HL1606 using the Arduino's hardware support

In my last Arduino post I explained the basics of how the HL1606 works, if you haven't already read that I suggest you read it first.

The google code library that drives the HL1606 does so by bit banging the control lines. That's both slower and more CPU-intensive that doing it in hardware, and in my application, both speed and CPU usage are an issue. The Atmel AVR CPUs used on the Arduino boards have hardware support for SPI, and as I said in my last post, the HL1606 datasheet says it is SPI compatible. The Arduino libraries don't provide support for the CPU's SPI features, I had to implement it directly. To follow the discussion below you'll need a copy of the datasheets for the AVR CPUs, links to the various CPU datasheets are available from the Arduino website. In addition, as speed is of the essence I'm using direct pin I/O rather than using the Arduino digitalWrite() function, which is an order of magnitude slower than direct pin I/O. I'm also not going to delve too deeply into the intricacies of AVR SPI as there are other good tutorials that cover it, such as this one.

I need this code to work on both a Demilanove and a Mega so the first step is to define some macros to access the SPI pins. The SPI pins are predefined by the hardware, so we need to get them from the datasheet. The comments show the corresponding Arduino pin numbers.

// Duemilanove.
#if defined(__AVR_ATmega328P__)
#define SPI_PORT PORTB
#define SPI_DDR  DDRB
#define SPI_PIN  PINB
#define SPI_MOSI 3       // Arduino pin 11.
#define SPI_MISO 4       // Arduino pin 12.
#define SPI_SCK  5       // Arduino pin 13.
#define SPI_SSN  2       // Arduino pin 10.

// Mega.
#elif defined(__AVR_ATmega1280__)
#define SPI_PORT PORTB
#define SPI_DDR  DDRB
#define SPI_PIN  PINB
#define SPI_MOSI 2       // Arduino pin 51.
#define SPI_MISO 3       // Arduino pin 50.
#define SPI_SCK  1       // Arduino pin 52.
#define SPI_SSN  0       // Arduino pin 53.
#endif

The next step is to initialise all the pins and put them into a known state. Note that I'm setting up the MISO pin for completeness, even though the HL1606 strips don't actually output any data.

    // Initialise the SPI pins.
    BIT_HI(SPI_DDR, SPI_MOSI);  // Output.
    BIT_HI(SPI_DDR, SPI_MISO);  // Output.
    BIT_HI(SPI_DDR, SPI_SCK);   // Output.
    BIT_HI(SPI_DDR, SPI_SSN);   // Output.

    BIT_LO(SPI_PORT, SPI_MOSI); // Low.
    BIT_LO(SPI_PORT, SPI_MISO); // Low.
    BIT_LO(SPI_PORT, SPI_SCK);  // Low,
    BIT_HI(SPI_PORT, SPI_SSN);  // High.

The setting of the hardware SPI is controlled by the SPCR register. That's defined for you by the avr-gcc environment along with the appropriate bit values, so we can just access it directly.

    // Initialise SPI.
    SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPR0)
    SPSR = _BV(SPI2X);

The _BV macro maps a bit number (0..7) to the appropriate bitmask. SPE is the SPI enable bit, MSTR is the SPI Master mode bit, as the Arduino will be the bus master, and SPR0 in conjunction with SPI2X sets the hardware SPI to 1/8th of the system clock speed (16MHz), i.e. a SPI clock frequency of 2MHz. The HL1606 datasheet says its maximum SPI clock speed is 600ns which equates to a clock frequency of 1.66MHz which means I'm actually clocking the SPI interface faster than the stated maximum. However this appears to work fine on the short 20-LED segments I'm using, I suspect that for longer strips, clock skew between the HL1601s will probably make such high speeds unreliable.

The last step is to actually write some data to the SPI interface. To do this, we first pull the /SS pin low to select the strip, then write the data, then pull /SS high again.

#define BIT_HI(R, P) (R) |= _BV(P)
#define BIT_LO(R, P) (R) &= ~_BV(P)
:
void output(uint8_t *data, uint8_t len) {
    BIT_LO(SPI_PORT, SPI_SSN);
    data += len - 1;
    for (; len > 0; len--) {
        SPDR = *data--;
        while (! (SPSR & _BV(SPIF))) {
            // Busy loop.
        }
    }
    BIT_HI(SPI_PORT, SPI_SSN);
}

SPDR is the SPI data register, writing to it clocks the data out on the SPI bus, and reading from it gets any data that was put on the bus by the slave during the write operation - there isn't any this case. The while loop polls the SPI status register to wait for the write completion, which in this case will take 16 processor clock cycles. Note also that we write the data in reverse order as the LED strip is in effect a big shift buffer, so the last byte has to be sent first.

That sorts out writing the LED control bytes to the strip, but we still need to provide the fade clock to do the LED fade transitions. The google code library does this bit-banging the fade clock pin up and down which, as I explained earlier, isn't an option for my application. The AVR has a number of hardware timers, we can use one of them to provide the fade clock. Timer0 is used by the Arduino run-time for its timing needs, so the 16-bit Timer1 seems the best bet. The AVR timers are one of the more complex parts of the chip and have many different modes - see the datasheets for details. However for this application, the one we will use is the 'Fast PWM' mode. In this mode the timer counts up from zero to a specified number, toggling an output pin when it reaches the limit. The timer is then reset to zero and the cycle repeats. As before, we set up some macros for the relevant pins and initialise the timer.

// Duemilanove.
#if defined(__AVR_ATmega328P__)
#define CLK_PORT PORTB
#define FAD_DDR  DDRB
#define FAD_PIN  PINB
#define FAD_CLK  1      // Arduino pin 9.

// Mega.
#define CLK_PORT PORTB
#define FAD_DDR  DDRB
#define FAD_PIN  PINB
#define FAD_CLK  5      // Arduino pin 11.
#endif

    // Initialise the LED clock pin.
    BIT_HI(FAD_DDR, FAD_CLK);  // Output.
    BIT_LO(CLK_PORT, FAD_CLK); // Low.

    // Initialise timer 1 - fast PWM, use OCR1A, toggle OC1A, no interrupts.
    TCCR1A = _BV(COM1A0) | _BV(WGM11) | _BV(WGM10);
    TCCR1B = _BV(WGM13) | _BV(WGM12);
    TIMSK1 = 0x00;

To start the clock running we turn on the appropriate bits in the TCCR1B register, to stop it we clear them. That start and stops the clock square wave on the corresponding output pin.

#define PRESCALE (_BV(CS11) | _BV(CS10))  // Prescale by 64

    TCCR1B &= ~PRESCALE;    // Clock off.
    OCR1A = ticks;          // Number of ticks between each output pin toggle.
    TCCR1B |= PRESCALE;     // Clock on.

The last thing to mention is the selection of the prescaler value, and how to calculate the value of ticks. The HL1606 datasheet says that the maximum fade clock frequency is 200Hz. A little experimentation shows that we can overclock that as well, at least on short LED strips. The maximum rate is around 1KHz - beyond that you start to get glitches, dependent on the pattern being displayed - usually all the LEDs on the strip start flashing blue or white. We therefore need to come up with timer settings that allow us to generate a 1KHz or slower clock.

The timer is driven by the CPU clock with runs at 16MHz, or 62.5nsec per cycle. We need an up/down and down/up transition for each clock cycle, so that's two timer overflows per output clock cycle. The required calculation for a 1KHz fade clock is 1Khz / 2 / CPU clock rate / prescaler, where we get a choice of the prescaler value from 1, 8, 64, 256 or 1024. The best choice is a prescaler of 64 because that gives a nice whole number of timer ticks per KHz whilst giving us access to frequencies in the KHz range. 1KHz (1ms/tick) requires a OCR1A value of 125, and the maximum OCR1A value (65536) is approximately 2Hz (524msec). The HL1606 can fade between colours over either 63 or 127 ticks, which gives us a fastest fade speed of 1msec * 63 = 63msec and a slowest fade speed of 524 * 127 = 67 seconds which will be fine.

This isn't quite the end of the story. I added a second LED strip, using a /SS pin per strip to select the strip that I wanted to drive. That didn't work, with the second strip behaving in a most puzzling way. The next post in this series will describe how I diagnosed what was happening, and how I worked around the problem. Stay tuned :-)

Categories : Tech, AVR

How the HL1606 works

I've been asked by The Travelling Light Circus to make some radio-synchronized LED strips for them to use at the Big Chill Festival. I'm using 5V multicolour strips that I'm going to control with an Arduino. The strips are driven using the fairly commonly used HL1606 chips. However although these are commonly used, there's not much information about how they work, There's a project on google code that contains an Arduino library for driving the strips. That library was used to implement a flashing headband. However the library drives the strips using simple software delay loops and can only make the patterns ripple in one direction, from the end of the strip the controller is attached to. I need to drive at least four strips simultaneously, plus a radio, so anything that relies on delay loops is a non-starter. I also need to have patterns that go in any direction, including outwards from the centre of the strips.

The headband project contains the only english HL1606 datasheet I've been able to locate. The datasheet looks like it has been translated from chinese and is pretty unclear in some places, but it is enough to get going. One thing that immediately caught my attention was that it says the HL1601 is "SPI controlled". SPI is a serial bus protocol that is supported in hardware by the Atmel AVR CPU used on the Arduino boards, so it appeared I might be able to offload much of the work of driving the strips to the hardware support. Unfortunately, that claim is only partly correct, as I'll explain in a subsequent post.

What follows below is a combination of information from the datasheet with clarifications and corrections, because in some areas of detail it is wrong.

The HL1606 has two parts, two shift buffers (A & B) and two output drivers (A & B). Data on the input pin is shifted into the shift buffers, and then copied, under the control of the /SS line, into the output buffers to drive the two LEDs connected to the chip. In typical use such as a LED strip the HL1606s are daisy-chained together, so the output of one chip drives the input of the next. As data is shifted into each chip, it shifts the contents of the A buffer into the B buffer, and the contents of the B buffer are passed on to the next chip in the chain. Therefore if we wanted to set a 20-LED, 10-chip chain we'd shift 20 bytes into the end of the chain and they'd propagate down it. The pins we'll have to drive are as follows:

Software-accessible pins
Datasheet pin nameSPI signal namePurpose
D-IMOSIData input
CK-ISCLKData clock
L-I/SSSlave select (active low)
S-IFade clock

I'll cover the details of how to use the AVR's hardware SPI support in a later post, while was investigating how the HL1606 worked I just used simple digitalWrite() calls to drive the bus. The first three pins are the standard SPI ones - MISO is missing from the table because the HL1606 only consumes data and doesn't create any. Fade clock is the pin that's used to control the speed of the LED fades, more on that below.

LED control byte format
BitDefinition
0Blue LED control
1
2Red LED control bits
3
4Green LED control bits
5
6Fade rate bit, 0 = slow (127 steps), 1 = fast (63 steps)
7Buffer latch bit, 1 = latch, 0 = don't latch

Each HL1606 drives two LEDs, each of which requires one control byte. The particular strips I'm using have the LEDs wired up in (blue, red, green) order but other strips may have a different order, you'll have to experiment to find out.

To drive data to the strip you need to do the following, I'm using the SPI pin names rather than the ones on the datasheet:

  1. Set /SS low to select the chip.
  2. For each control byte to be sent, send the bits in MSB order as follows
    1. Transfer a bit to the chip by setting the MOSI pin high for 1, low for 0
    2. Send a clock pulse (high/low) on SCLK
  3. Set /SS high to deselect the chip.

It is important to pull /SS low at the start of the transfer and only pull it high after transferring all the bytes. For example, if you want to set just the fifth LED to red you'd pull /SS low, send a 'red' byte followed by four 'off' bytes, then pull /SS high. This is necessary because the state of /SS governs what is done with the data shifted in to the chip. If /SS is active the chip transfers the data along the shift buffer chain but doesn't copy it into the output drivers, so nothing is visible as the data is being shifted down the chain. When /SS is pulled high the current data is transferred from the A & B shift buffers in to the corresponding output drivers and the LEDs are lit appropriately. The library on google code doesn't do this, it drives /SS low/high for each byte that's transferred which causes an undesirable flickering effect.

Each LED uses two bits to specify its settings, given in the table below.

LED control bit format
Bit 0Bit 1Definition
00LED off
01LED on, no fade
10LED off, fade up on fade clock
11LED on, fade down on fade clock

The first two combinations are simple, the LEDs are either fully on or fully off. Although the HL1606 can fade between colours (yes, I'll get to that in a bit) it can't display a full RGB gamut as the fade clock is shared between the RGB LEDS and affects them all equally. That gives a total of eight possible colours (if you count 'off' as a colour). The available colour combinations are as follows.

Available colours
RedGreenBlueVisible colour
OffOffOffOff
OnOffOffRed
OffOnOffGreen
OffOffOnBlue
OffOnOnCyan
OnOffOnMagenta
OnOnOffYellow
OnOnOnWhite

Fading is possible in both the 'up' and 'down' directions by specifying one of the fade bit combinations above. Fading between any of the eight possible colours can be achieved by the appropriate combination of individual colour fades, for example to fade from red to cyan you'd send a control byte of (red fade down, green fade up, blue fade up) - see the tables above. The speed of the fade is controlled by a clock pulse supplied on the fade clock pin - the faster the clock, the faster the fade. As I've said, the fade clock pin is shared by all the RGB segments of all the LEDs in the strip. Two fade rates are possible, 127 steps or 63 steps, specified by the fade rate bit in each LED's control byte. Note that the datasheet says there are 128/64 steps but that's incorrect. Note also that LED segments that are set to fade up don't start out being off, they start at the first rung of the brightness ladder and fade up from that. Note also that the perceived brightness of the fade ramp is not linear, so although it is possible to use it to control overall brightness it's only at a fairly coarse level.

The last important thing to note is the purpose of the Buffer latch bit in each LED control byte. The google code library refers to it as the 'whitespace' bit, which isn't particularly accurate. For normal use, the bit should always be set, otherwise when starting with a fully 'off' strip the data shifted down the chain will have no effect and nothing will be visible. When the bit is unset, the rest of the bits in the control byte are ignored and the effect is to cause the chain to shift everything along by one LED, with the first LED retaining its current setting. For example, if the chain is currently displaying (R,G,B), sending two bytes with the latch bit unset followed by a blue byte with it set would result in (B,R,R,R,G,B) being displayed.

There are more details that I haven't covered in this post such as how to drive the strip with the AVR's hardware support, how to do patterns that go in both directions along the strip, how fast you can reliably drive the strip (not the same as the datasheet), how to drive multiple strips simultaneously whilst sharing pins between them, how the HL1606 actually isn't a SPI device at all and how to make it behave as one - but I'll cover those in later posts so check back for more. In the meantime, here are two videos of the strips in action, as a taster :-)

      

Categories : Tech, AVR

Simple parser for MovableType exports

As part of moving my blog over to I needed to be able to transfer the content from my old MovableType blog and my blogs.sun.com blog, which runs on Roller. Both MT and Roller can export in MovableType export format and Pebble has a MT importer, so it looked relatively straightforward. However when I looked at the content I was importing it was clear I'd need to munge it on its way into Pebble. The Pebble MT importer is one-pass and loads the entries into Pebble as it reads them, whereas I wanted to read them in, munge them and only then load them into Pebble, so I wrote a simple parser to read in the MT export. It's not a thing of great beauty but it got the job done. I thought it might be useful for other people who want to read MovableType exports from Java, so I've put a copy of it here.

Categories : Java, Web, Tech

Image thumbnailer for Pebble

This blog uses the Pebble package for delivering content. Pebble isn't a particularly common blogging package but it fits my purely personal and subjective requirements:

  • Not written in PHP (blegh)
  • Open source, and something in Java would be nice
  • Doesn't use a database and uses flat files that I can manage manually if I need to
  • Good RSS, search, tag and category management
  • Can be restyled easily

The old incarnation of this blog used MovableType but that doesn't really tick the Open Source box any more. blogs.sun.com uses Roller but that requires a database back-end. All these constraints combined to give a pretty short list of candidates, i.e. Pebble.

One thing that Pebble lacks is an image thumbnailer. I'm not bothered about glossy JavaScript solutions such as Lightbox, and I'm quite happy to type in HTML table definitions. All I wanted was something to save me the tedium of manually generating the thumbnails and typing in the HTML to display them and link to the full-size image in a popup window. MovableType has this feature but Pebble doesn't so I sat down one evening and knocked together an equivalent as a Pebble plugin, using the standard Java2D APIs to do the image manipulation. All the thumbnails on this site are done with it, and I've submitted this as a patch to Pebble so hopefully it will make it into a future release.

Update

The patch has been accepted and should be appearing in a future version of Pebble.

Categories : Java, Web

A busy day on the moors

I got a phone call from Fiona yesterday asking me if I'd help with some research work being done on Black Hill by the University of Manchester on behalf of Moors For The Future (MFTF). Beth is doing the research and she's using a spectrometer to measure the light reflected from different types of vegetation over the course of the year. She's doing this so that subsequent aerial surveys can be analysed using the information. Areas of different vegetation can be identified on the aerial survey by looking for areas with the same absorption characteristics as found on the ground survey. The spectrometer is a ASD FieldSpec Pro supplied by NERC, one of the UK's research bodies. It allegedly portable - well, perhaps if you have a donkey it is, because as well as the spectrometer there are four lead-acid batteries, a laptop and a number of other bits and pieces. to be carried, so myself and David went out to help Beth - and poor David got the biggest lump to lug across the moor :-)

ASD spectrometer        ASD spectrometer

The readings can only be taken when there's no cloud obscuring the sun, hence Beth's heavenward gaze. Each plot has to have four readings taken, one on a white reference tile and three of the vegetation, from different positions to get an average reading. You can see the reference tile and the sensing head in the pictures above. There's a bundle of fibre optics that takes the light from the sensing head into the spectroscope on David's back, where the light is analysed and the results fed into the laptop that Beth is carrying. I had the difficult job of carrying a clipboard and writing stuff down :-)

A couple of hundred meters away from us there was another group of people who were also working on the MFTF project. The moors in the Dark Peak are an internationally important habitat, Blanket Bog. The peat was formed originally by Sphagnum Moss, but over the last hundred or so years, environmental degradation caused in part by the Industrial Revolution has taken its toll and much of the Sphagnum has disappeared, and there has been widespread erosion of the peat. MFTF have been re-vegetating the moors with heather, but Sphagnum is one of the really important species to re-establish because it is responsible for generating the peat in the first place, and locking up CO2 as a result. MFTF have contracted Micropropagation Services to prepare Sphagnum pellets so that they can be spread across the moor to effectively "inoculate" the ground surface with new Sphagnum.

Sphagnum pellets        Sphagnum pellets

The pellets are going to be spread from helicopter using an adapted agricultural sprayer, they were testing out the system and working out the snags in preparation for spreading the pellets on a wide scale. It took three years to get to the current stage, so there's an immense amount of effort going into this environmental programme. There are more details of the project on the Moors For The Future website.

Sphagnum spreading by helicopter

After heading back from Heyden Head to Holme Moss summit, David noticed what appeared to be smoke drifting across the Bleaklow plateau. We are in a period of high fire risk at the moment due to the recent dry weather, and we've had catastrophic fires on Bleaklow in the past, so David and I had to bail out and leave Beth on her own so that we could go check out the smoke. We drove round the other side of the Bleaklow plateau and up onto Snake Summit expecting to see smoke, but there was nothing visible. We headed off rapidly down the Pennine Way to Alport Low where we could get a clear view of where the smoke had apparently being coming from, but there was nothing to be seen from there either - we passed Terry on the way with a group he was out with, and he also hadn't seen anything. I managed to get hold of Mike on the radio, he was on Kinder and had seen the smoke as well, but by the time we got to Alport Low there was nothing to be seen. Most puzzling - the three of us had quite clearly seen smoke from Holme Moss, all I can think if was that it was a small accidental burn that someone had put out quickly.

We then headed back to Snake Summit where we met up with Peter and Bob, then headed back round to the north side of the plateau again to put up "high fire risk" signs at Crowden and Arnfield - kinda ironic really - before heading back to the briefing centre and then home.

Stephen, I wonder if you recognise this?

I was reminiscing with Stephen about work yesterday, It's very faded after much use, but I wonder if he'll recognise the hat :-)

Categories : Friends, Solaris, Work

Green

Green oak tree

Went for a quick walk up quarry lane behind the house and came back down through the trees alongside Shittern Clough (yes, that really is its name). After the hard winter we've had, nature is on overdrive, the birds are all going mental and the trees are all that incredible eye-bursting green. I spotted the Oak tree above which was a particularly psychedelic shade.

I also saw a buzzard over Yellowslacks being mobbed by a pair of nesting Curlews. Spring is in top gear and summer is fast approaching.

Categories : Peak District