Tuesday, 30 December 2014

New year countdown with UnicornHat

Now Christmas is over, I'm missing my Unicorn Hat decoration. So how about a New Year countdown?

Using my Scrolling text library, I've knocked up some quick Python to display (in a random colour) the number of seconds remaining until 00:00:00 on Jan 1st 2015. Once that time is upon us it will display a suitable message.

from dateutil.relativedelta import relativedelta
from datetime import *
import calendar
from UHScroll import *
import random
import time

NY= datetime(2015,1,1,0,0)
cols = ['red','white','green','blue','cyan','yellow','orange']
while True:
NOW=datetime.now()
t = relativedelta(NOW,NY)
total = (24 * 60 * 60 * t.days) + (60 * 60 * t.hours) + ( 60 * t.minutes) + t.seconds
countdown = str(total)
if total < 0:
unicorn_scroll(countdown[1:],random.choice(cols),255,0.05)
time.sleep(0.2 * len(countdown[1:]))
else:
unicorn_scroll('happy new year!',random.choice(cols),255,0.1)
time.sleep(0.5)



Monday, 22 December 2014

Unicorn Hat text scroller

After I wrote my Xmas Tree code for the Unicorn Hat I felt like I needed to also be able to display a festive message. Although it is quite narrow, I reckoned a text scrolling app would work quite well on the Unicorn Hat if I kept the character size slightly smaller than full-screen(grid?).


I decided to fix most characters to 6x4 pixels (with the exception of those fatties M and W) which allows for portions of 2 characters on the screen simultaneously.

I've stuck the various Python files up on GitHub. In includes a test script which produces this output:



Anyway, my son liked it and wrote a program to create a random 5 letter word and display it in a random colour:

from UHScroll import*import random import string
bill=['red','white','pink','blue','green','cyan']
def wordpick():    qwerty = ''    for q in range(5):        bob=random.choice(string.letters)        qwerty = qwerty + bob    return qwerty
for w in range(5):    dad=wordpick()    print dad    unicorn_scroll(dad,random.choice(bill),254,0.5)
He likes doing stuff with the Python random module at the moment...

Thursday, 18 December 2014

Unicorn hat Xmas tree

The Unicorn Hat from Pimoroni is a great board for the raspberry Pi. It was just crying out for use as a Christmas decoration. So here's a quick bit of Python to generate an Xmas Tree.



A version (which may be updated) is also on github.  You'll obviously need the Pimoroni Unicorn Hat library for this to work!

import unicornhat as UH
import  sys, time
import random
UH.clear()

while True:
# create each row of the tree
for y in range(0,8):
for x in range(6,8):
UH.set_pixel(x,y, 0,255,0)
for y in range(1,7):
for x in range(4,6):
UH.set_pixel(x,y, 0,255,0)
for y in range(2,6):
for x in range(2,4):
UH.set_pixel(x,y, 0,255,0)
for y in range(3,5):
for x in range(0,2):
UH.set_pixel(x,y, 0,255,0)
UH.show()
#now generate the baubles at random
balbs = random.randint(1,5)
i = 1
while i <= balbs:
b1_y = random.randint(1,6)
b1_x = random.randint(4,5)
randr = random.randint(50,255)
randg = random.randint(50,255)
randb = random.randint(50,255)
i+=1
UH.set_pixel(b1_x,b1_y,randr, randg, randb)
balbs = random.randint(1,4)
i = 1
while i <= balbs:
b1_y = random.randint(0,7)
b1_x = random.randint(6,7)
randr = random.randint(50,255)
randg = random.randint(50,255)
randb = random.randint(50,255)
i+=1
UH.set_pixel(b1_x,b1_y,randr, randg, randb)
balbs = random.randint(1,3)
i = 1
while i <= balbs:
b1_y = random.randint(2,5)
b1_x = random.randint(2,3)
randr = random.randint(50,255)
randg = random.randint(50,255)
randb = random.randint(50,255)
i+=1
UH.set_pixel(b1_x,b1_y,randr, randg, randb)
UH.show()
time.sleep(0.4)

CodeClub: TechWillSaveUs DIY Gamer Final Thoughts

I thought I just knock out a few final thoughts regarding the TechnologyWillSaveUs DIY Gamer project I ran at my Codeclub this term. More to get my own thoughts together, but also as an overview for anyone thinking about something similar.

What was really good
  1. The whole hands-on soldering part of the project was brilliant. It was great to see everyone's confidence growing over the three weeks when we did the construction. In terms of learning about physical computing, this kind of activity is hard to beat. Even making mistakes - soldering the led in wrong way round - was a learning process.
  2. The DIY Gamers themselves are very well designed and engineered. They all worked reliably and had no problem coping with the odd drop or knock.
  3. The children became really familiar with attaching devices to their PCs and programming them through the Arduino interface. The first time we download something to the Gamer they found the various steps in the process quite daunting, but by the end of the term it had become second nature. 
  4. Exposure to basic electronic components was very useful and the children retained a lot of knowledge about what the various parts did and how they could be controlled or provide feedback to a computer. 
  5. The children loved designing their own arrows for the Simon Says game, and the repetitive nature of this task really helped them get to grips with how the led matrix was addressed through the code. 
  6. The project as a whole provide lots of opportunities to talk about and discuss areas of computing and computational thinking that don't crop up with the Scratch and Python syllabuses (e.g, robotics, sensors etc). 

What could be improved

  1. The soldering irons seemed to be quite low quality. Only one of the three I with which I was supplied still works, and I wouldn't personally like to use it on any serious soldering.  I understand the need to keep costs down but suspect these were a false economy. 
  2. The overall design of the course materials as a whole seemed disjointed in places. There were a few weeks where the activity seemed very isolated from the rest of the project. The children spent quite a lot of time getting to grips with the LDR but then never used it again. I think activities where each session builds on the last are much more effective.
  3. The quality of the worksheets was also variable in places. The last few session instructions felt quite rushed to me and I think a lot more thought needs to go into what the children will learn from each section. 
  4. There was a lot of functionality in the Gamer that was never used. Kids love noisy things, and it seemed a shame not to have the Simon says game make any use of the buzzer. 
  5. I think that not being able to keep the DIY Gamer at the end of the project is a real limiting factor. The children who attend Codeclubs are used to being able to work on their Scratch or Python projects at home and show their friends and parents what they've been up to. I realise there are pretty significant cost implications but some form of subsidy might be something worth exploring if you're thinking about this kind of project. 
  6. I think the Simon Says game is a little dull. When they were allowed free play with the Gamers, they always downloaded snake or flappy bird. Nobody wanted to play the Simon Says game. I don't think it was inspiring enough and this didn't help motivate the children through the tougher sections. 
  7. There wasn't a lot of opportunity to customise the game as they went along and some of the later session were easy to complete by following the instructions but without really learning anything or understanding what was going on. 

Questions

  1. What should schools/clubs do with the Gamers at the end of the projects? As the children have been working in pairs, letting them keep the units could be tricky. Options for re-use seem fairly limited though. De-soldering the components and starting the whole project from scratch just really isn't viable in my opinion. You could re-run the sessions  starting with a completed Gamer but without that initial hands-on element, I think the overall impact would be greatly diminished. If there were some more follow-on projects for the Gamer, then that would be great.  Alternatively I might use these Arduino's for other activities that I've been thinking about, although I'm aware that not everyone will have the knowledge or time to do this.
In summary, would I recommend the DIY Gamer project to another club/school?

Absolutely. It was a great experience for both me and the children, and everyone learned a lot.

If I had to give one piece of advice to anyone running a similar project it would be to not worry about the children understanding every single aspect of the code they encounter. This is real programming!

Friday, 12 December 2014

CodeClub: TWSU DIY Gamer The end!

Final week of the DIY Gamer project!

I'm fairly sure that when the kits were first released, it was intended to be a 12 week project.  The final worksheet certainly seems to have crammed a lot in, with 20 pages of stuff to do.

To add the final features to the game (start screen, scoring etc), the idea is to use a code library which contains the various functions needed. I like this as a concept as it reflects real-world coding practice, although the worksheet doesn't really explain this apart from a brief mention on the front page. Obviously I try to talk things through as we're going along, but this is not always easy when you're spending a lot of time trying to find the missing (or extra) semi-colon(s) in the clubbers' sketch programs!

My observation has been that the children generally skip over the 'code comprehension' pages which is a shame as they are normally very useful. However I have to say that the examples in Lesson 10 were quite skinny. The explanation for the code block:

for(byte b=0; b<sequenceLength;b++) sequence[b]=0;

was:

"Clear the sequence. A 1-line for loop doesn't need parenthesis, but we have added them for consistency."

I know the children at my CodeClub are very bright but unsurprisingly, none of them could make head nor tail of this particular gem.

Only a couple of groups managed to get to the very end having completed everything (and one of those only because they came to my afterschool codeclub to finish it off - there's dedication for you). I suggested to the whole group that we could have an extra session at the start of next term so that everyone could complete the whole project, but the general consensus was that we should start something new. They've definitely got the hardware bug though, so I'll have to dream up some suitable projects to keep them satisfied.

Things to do differently next time?


I think it would be worth really taking more time to explain what's going on with the 'Advanced tab' and the code library. 

When you are dealing with this much code, debugging problems can be quite tricky. The compilation error message generated by the Arduino Sketch editor are not always the most helpful and the line referenced is often not the origin of the problem - typically it is a missing } further up. Sometimes the code has become such a kludgy mess that the easiest fix is to start from a known-good state. I think more liberal use of 'save as' as the children progress - essentially saving a new version at every stage - would make it easier to revert in the event of problems.  Although I had the various 'working' examples to hand, the kids were reluctant to use these as they didn't contain their unique arrow designs and copy-n-pasting them from one file to another often generated more problems. 

So this is the end of the DIY Gamer project. I will try to post some general comments over the next few days but I'd be really interested to hear about other CodeClub's experiences. Drop me an email, tweet or leave a comment below. 

Thursday, 4 December 2014

CodeClub: TWSU DIY Gamer Week 11

The advantage of having one pupil who is slightly ahead of the others is that they provide an early warning of potential problems in the next part of the project. So I knew that there were a couple of 'gotchas' in the instructions for Lesson 8 - Button Press.

The first one is that one particular section asks you delete a big swathe of code from the existing project. The worksheet says to delete the code highlighted in red. Unfortunately it isn't actually highlighted, its just in a red font, as is a lot of the other Arduino sketch code shown in the examples. This includes the void loop() line immediately above the block of code to be deleted. Very confusing!

It also raises a good point about the worksheets. Not every one will be able to print/photocopy multiple copies in colour. Certainly the main copier at my school is B&W.

The actual code that is used in the session is fairly minimal and most of the groups got through it in plenty of time. It certainly feels a lot skinnier that the previous sessions and is really just coding by numbers. The challenge at the end didn't make much sense either, it asked "can you think of a way to use another for loop?' But the code used for this part of the project doesn't include a for loop - that was the bit that was deleted. I'm not really sure what the children were supposed to do here.

As we're approaching the end of this project and the end of term, I was asking the children what they'd like to do next year in CodeClub. The unanimous answer: MORE SOLDERING!

Things to do differently next time?


As usual there was quite a lot of debugging needed. The children are certainly learning how unforgiving the Arduino sketch language is! Finding the error can be quite hard even for me. To be honest, the children really don't have enough experience to have much of a chance of correctly the interpreting the error messages. This means their efforts largely centre around spotting the difference between their code and the sample at the back of the worksheet. I think this discourages them from ever attempting to try their own modifications so I might omit the cheat-sheets from the handouts next time.

Thursday, 27 November 2014

CodeClub: TWSU DIY Gamer Week 10

Nearly everyone was starting the lesson 8 worksheet this week (one superstar is already on lesson 9).  This is really the first session of the final project - building the Simon Says game - and this seemed to be good news for the clubbers as the last couple of weeks have felt a little unconnected and disjointed, There were a few questions about why we'd bothered with the spaceship animation last week and whether this fitted into the final game, but I explained that the idea was that they could use moving images to customise the opening sequence of their game.

The basic premise of this session is to design variations for the various screen images used in the game: left, right, up and down arrows, a tick, a cross and the word go. I must admit I was slightly dubious about this session. Although one thing that I think has been missing from this whole project is the flexibility for the children to customise what they're doing, this seemed like a another distraction with the originality being more about design than coding. I was also sceptical because it seemed to me that there only a few ways to make an arrow on an 8x8 grid different.

As usual, the children demonstrated the power of their imaginations and creativity (and, I guess, the feebleness of my own).

Minecraft axes, smilie faces, stick figures.... just brilliant!





Things to do differently next time?


If I'm honest, I'd completely chuck away the worksheets and either write my own or just try to introduce what they have to do through a demonstration.  It took me a couple of read-throughs to work out exactly what you were being asked to do, so I expected the children to struggle.  The over-achiever who completed this part of the project last week had run into problems so I knew what to expect.   There are a number of areas where I think this session's worksheet could really be improved.

A big problem is that the first 4 pages are basically just information for the children to read.  A couple of the children were asking what they were supposed to do and my only answer was basically  "just read it". That's not so bad, but then the actual practical instructions that follow are quite confusing. 

First of all, there are two many small but important steps that are easily missed out.  Part of this problem is that the children just don't take the time to read them carefully. So crucial steps - like closing the file you've just opened and then opening another one (with a similar name) need to really stand out and be made clear.

Secondly, the description of how to modify the code shows two array blocks side-by-side in a sketch window. So naturally,  a couple of the children tried to type up their sketch to make it look just like that, not really comprehending what the red arrow meant. 

Thirdly, the children wanted to use the DIY Gamer Image Painter software to design their arrows. This is completely sensible, and the worksheet even has a screenshot of the application (even though it says to use the design worksheets).  I don't know why you'd edit the ones and zeroes of the code directly when you have a neat tool that makes the task much easier. However, doing it this way leads to some additional complications. 

The problem is, if you open a sketch window with the code to be modified (i.e. your version of the Simon game) then open the Image Painter app, every time you try to copy the code version of your design (using the insert code button), it will overwrite your entire existing sketch. 

There is a simple work around - open a new (empty) second sketch window and then launch the Image Painter app from that window. That way, the code for the image you create will be inserted into the empty sketch so it is easy to copy-n-paste into your game sketch. 



This still isn't fool-proof. If you close the sketch editor window from which you launched the Image painter app,  it has nowhere to insert the code but doesn't raise any kind of error message - it just does nothing. 

A final problem is that the code generated by the Image Painter is not formatted in the easiest way for easy copy-n-pasting. Several times the children accidentally included the  curly bracket and semi-colon (or missed out the last one or zero) which meant their code would not compile.  By the end of the session they certainly all agreed with the opening sentence of the worksheet: the basic C programming language used by Arduino is very picky!

Suffice to say I was kept busy this week!

Mirobot madness

Following the success of the DIY gamer I've been thinking about what projects might be possible at future CodeClubs.

Earlier this year I funded Mirobot - a wifi robot based around Arduino - and last week it arrived. A wet Sunday afternoon seemed the perfect time for may son and I to have a crack at it.

The main PCB is beautifully manufactured and perfect for young solderers. The instructions are very clear and easy to follow. The issue we encountered is that they never tell you to install the stepper controller IC (although it is shown in some of the pictures).  Working together it took about 45 minutes to get the main PCB and battery pack assembled. I liked that you could perform a useful confidence test by checking the Arduino leds prior to soldering the pack.

With the electronics bit complete, it is time to put together the chassis. All the parts come on 6 laser-cut boards. The componets should easily pop out but I found that some of the smaller parts were quite difficult to extract. Some of them are quite narrow and I needed to go over some of the cuts with a stanley knife to allow them to come away cleanly. My son was struggling and was worried that he would damage some of the delicate pieces. Although the material looks like wood it is really MDF and handles and behaves like thick cardboard: it can easily be torn and split.

I think if I was going to have a larger group of children assemble Mirobot kits I'd be tempted to extract all the pieces from the boards in advance.

The instructions note that the wifi antenna mount is fragile and I found it quite tricky to insert the rigid plastic aerial through the small piece of MDF. The sides are only a couple of mm thick in places and could be easily ruptured. Even with my (relatively) steady hands, some of the pieces came free leaving a layer of MDF behind. I fear that young impatient hands might struggle to complete this step without incident.



As you'd expect, until you get three sides on the chassis it is all a bit wobbly and I wondered whether the finished would need some wood glue to help its structural integrity. However the Mirobot uses an ingenious system of wedges to lock everything into place and the completed unit feels surprisingly sturdy (although I do wonder how long before the transparent wedges come loose and disappear up the hoover). My son is master Lego builder but even he needed an extra pair of hands to hold everything together for some steps.

Once everything is assembled, getting started is super fast. The built-in wifi makes its easy to use a tablet or phone to quickly confirm that everything is working in a few seconds.

However I did find that the connection to the Mirobot sometimes dropped out and the red 'reconnecting message' became a constant presence. I tried configuring the Mirobot to join my home wifi network but although that was successful, it didn't stop the dropped connection problem.

Eventually I seemed to find a workaround which was to keep a ping running from my laptop to the Mirobot. This is a trick I used to overcome issues with wifi dongles on Raspberry Pis suffering from power management issues.

This is a minor niggle and the Mirobot is a great little robot project. As part of the Kickstarter stretch goals I received the add-on kit too which includes a collision sensor which, if our initial tests are anything to go by, will be a useful upgrade. Hopefully we'll be able to get that up and running this weekend.



Thursday, 20 November 2014

CodeClub: TWSU DIY Gamer Week 9

Actually, if you follow the official worksheet numbering, we're still on week 6!

By the end of this session each group had successfully got their spaceship to fly across the screen. They had all worked out how to change the speed of the animation and we talked about how we could use a variable to store the time for the delay so that if we wanted to make changes in future we only needed to change the variable and not each individual value. They were all familiar with using variable in this way and seemed pleased at this additional efficiency.

I was also a little dissatisfied with this end of  particular module of the project. The only thing that changes between the different arrays that represent each frame of the animation is the x,y coordinates of the pixels, and they just increment by one each time It seemed to me to be a great opportunity to use a loop!

So I'd prepared a simple challenge sheet to show how to use loops in Arduino and relate it back to some of the loops the children were familiar with in Scratch.


This is quite tricky to implement and even the most accomplished coders were struggling to work out exactly how to do it. It was a shame that the session ended because I think a couple were close to figuring it out. I'll take them through one way of doing it next time.

Thursday, 13 November 2014

CodeClub: TWSU DIY Gamer Week 8

We started off today with a short chat about the amazing Philae comet landing. I'd changed the background wallpaper on my laptop to the latest picture taken by the CIVA . We talked about the similarities between what they were doing in CodeClub - programming hardware - to the kind of robotics control needed by something like Roesetta.  I was pleased by how much they knew about the mission and wasn’t surprised to find this group really enthusiastic and excited by the technology involved. 

I don’t want CodeClub to be a ‘sit and listen to teacher’ lesson but after my experience last week I felt I needed to try to get everyone at roughly the same stage. Part of the problem is that there is quite a wide range of ability across the group. A couple of the boys who do a lot of programming at home have been whizzing ahead whereas one pair who haven’t really done much coding outside of CodeClub are struggling a little. It is interesting to see that the age of the children has no relationship to ability (the two high flyers are from years 4 & 5).

So this week I got everyone to follow along with me as I went through the worksheet.  It worked reasonably well. It definitely helped that I could point out to the group that they didn’t really need to do much typing. Once you’ve typed the block of code to display the spaceship once, you can simply copy and paste it and just edit the coordinates. As a lazy programmer that is an obvious approach to me but a lot of the children don’t always think of that and set themselves up for some unnecessary typing. 

Having been shown the shortcut they were able to make much quicker progress  through the worksheet. I was also able to save them having to do a lot of reading by explaining what was happening as we went along. 

Although the session perhaps felt a little more stilted than usual, on reflection I think it was the right approach and I think everyone got a better grip on the concepts as a result. 

I let all the children work individually unless they really wanted to share the typing. Swapping the Gamer devices between PCs doesn’t cause too many problems but it does slow things down a little.  Every now and then the Arduino sketch editor throws and error when trying to upload the new code and needs to be unplugged and then reconnected. 


Thursday, 6 November 2014

CodeClub: TWSU DIY Gamer Week 7

With everyone having finished constructing their gamer, I wanted  to get started with the 5th lesson, using the Light Dependent Resistor to control the progress of an animation.

A couple of the groups had started this worksheet in the last session but hadn't seemed to get very far.  In order to make sure everyone was starting from the same place, I demonstrated the key parts of the session to the whole club. There were still a few blank faces and a few questions about why were doing this activity. Quite a few wanted to know how it related to the game we were going to write for the gamer. I'm not sure that my answers - that you could use the LDR as an extra button or that it could used to build some sort of alarm - were very convincing. To be honest, I've never been able to come up with a great use for the LDR in the context of creating games. The fact that it will always need some sort of calibration based on the actual light levels at the time of use makes it seem a bit difficult to reliably use in a working game.

The clubbers started to tackle the worksheet and I got the impression that they found it quite confusing. All of the groups made the same mistake in the first few pages: they created two void loops functions. Looking at the instructions I can see why. First of all it asks them to create two empty functions (the setup and loop). Then a few pages later it asks them to edit the void loop function to add the code to print the light value to the serial console. I think it needs to say "modify the loop you created in step 6" or at least make it more explicit that you're not adding another loop function. 


Every group also struggled with the next section. Opening and closing the different scripts and copying bits from one to the other really had them in a muddle.  It does all seem a little futile.  They may as well just insert their LDR max/min values into the example animationLDR script and run that. I don't think they learnt anything from typing in a couple of quite baffling lines of code. Although there is an explanation of what the code does in the worksheets, they do require a lot of reading and don't really explain how you might use similar code to control something else (e.g. the IR receiver).   

To try to liven it up I suggested they use their own animations from the previous week but I think that just added more confusion.

Certainly compared to the normal CodeClub Scratch or Python projects this all seems quite a slog with very little payout (although perhaps it just feels like that after the excitement of the soldering and assembly). 

I'm also concerned that lesson 6 may have similar problems. Although controlling and moving an on-screen object with the buttons is clearly a key learning point, it isn't really used by the Simon Says Game so it feels a bit superfluous again. 

Things to do differently next time?


I'm not sure I would bother this week's activity at all, unless the use of the LDR can be more integrated within the overall project objective.  An exercise to demonstrate the potential for some of the other gamer components is a good idea but I wonder if a simple program to exchange messages via the IR capability might be more interesting.  

One of the gamer's LDRs was only showing a very slight change in the value it reported through the serial console for different light levels. On closer inspection I think the soldering is a bit ropey and the LDR actually wobbles a little. Hopefully re-soldering it will correct the problem. Next time I'd try to check that all LDRs work correctly before the session. 

Thursday, 23 October 2014

CodeClub: TWSU DIY Gamer Week 6

This week everyone finished off their Gamers! The last components were soldered in place and the led matrices and chips were installed

I'd only managed to get one soldering iron working anywhere near decently. One has completely died and does not heat up at all. The other one refuses to tin despite having the tip well cleaned. I brought one of my soldering irons from home in so that there would be at least two working irons for the session.

Neither of the two Gamers completed today worked completely correctly first time. The red led would blink when the Arduino was loaded with the program from lesson 3 but when a game or animation was loaded - nothing.

On inspection one Gamer had a couple of wobbly solder joints which when re-made fixed the problem. The second took a bit longer to diagnose... until I noticed that the two chips had been inserted in the wrong sockets. We swapped them over and the full set of Gamers was now in operation!


Meanwhile the other pairs were either finishing off their animations (lesson 4) or starting work on controlling an animation using the light dependent resister (LDR) (lesson 5). I'd set my own gamer up running the code and it was good to demonstrate what they were trying to achieve before they started.

I particularly liked the Minecraft Creeper head in this animation:



There were plenty of issues with syntax errors in the code. The kids were often not reading the worksheets carefully and just skimming between the code snippets. Consequently they put lines of code in the wrong place or were getting things the wrong side of brackets.  This is all part of the fun/learning process and by the end a couple of the more intuitive programmers were started to get a feel for the Arduino code.

Things to do differently next time?


I should have demonstrated the whole process of monitoring the serial line to discover the range of values from the LDR. The instructions don't make it clear what you're trying to achieve at the start and a couple of pairs got confused about what the code they were writing was trying to achieve.

Check for swapped chips earlier!

Thursday, 16 October 2014

CodeClub: TWSU DIY Gamer Week 5

It was another hectic session today, with different groups working on the activities from the worksheets for lessons 2 (soldering/assembly), 3 (first Arduino programming) and 4 (animation).

Only two groups have yet to finish their assembly.  I noticed today that the soldering seemed to be going slowly and there were complaints that the irons weren't working. On investigation I noticed that the tips on all three had a significant build up of black crud and were not tinning properly.  This is quite disappointing given that they were brand new and have only been used for less than 3 hours each.

I've taken the irons home to clean off the crud - I've done one so far and it is now tinning OK.

We also had the first major soldering hiccup today - one pair soldered their resisters in the wrong way round and then managed to break the leg off one while trying to desolder. That Gamer has come home too so that I can remove the debris. The whole area around that hole is now quite messy so I'll probably solder in a replacement resistor myself.

Meanwhile the other groups were whizzing through the animation steps and enjoying coming up with some funky designs. I decided to let everyone work on their own but this did make it difficult when both partners wanted to test their work on the Gamer and had to swap the unit between their computers.

One thing I'd noticed with my own Gamer was that the code generated by the Image Painter software tool typically resulted in a noisy, flickering image as the refresh rate of the Arduino is just too fast for the led matrix.


Simply adding delay(1) after the gamer.printImage(image) in the loop is enough to keep the output stable and this was actually a good way to get the kids to focus on the code when showing them this fix.



My most capable pair who have been steadily pulling ahead on the others came up with a great little animation that flashed their initials on the screen. They're ready to start on the LDR section nest week.


The Image Painter and Animation Generator are nice little apps and the kids got to grips with them without any real explanation or demonstration from me. I think the functionality of the Animation generator is a bit strange: the "add blank frame" and "duplicate frame" controls only insert a new frame at the end of the whole sequence so you can never go back and add a missing frame part way through (at least I can't see a way of doing that). I also don't really understand what the 'save animation' control does. On OS X it brings up the same dialogue as the 'load animation' control, which means it doesn't allow you to actually type a filename. Obviously you can save the raw code but I'd suggest this is a bug rather than a feature.

I also remembered to give out the certificates I made last week. Everyone seemed pleased and immediately asked when they'd get the Level 2 one.

Things to do differently next time?


Check the soldering irons before each session and make sure I've got some sandpaper handy at school to clean up any manky tips. 

Remember to hand out the animation planner sheets. I forgot today and even though it didn't seem to matter too much I think it would help to get the kids more focussed on the process itself. 

Thursday, 9 October 2014

CodeClub: TWSU DIY Gamer Week 4

It works! Shouts of glee this week from a couple of the pairs as they connected up their soldered circuit board to the Arduino, uploaded a game and got to play it!


Everyone got to work straight away, eager to get stuck in to the soldering. It is great to see just how much their confidence and competence with the soldering iron has grown over the last few weeks.

I also explained that anyone waiting for a soldering iron should get out their Arduino and start on Lesson 3. Although a few seemed a little daunted by the wordiness of the first couple of pages, most quickly worked out what they needed to be doing (especially those who'd had a taster of Python last term). This was also where working in pairs helped as they were able to figure it out together.

I'd wondered if making a green led flash would be a bit underwhelming but when it worked they were really pleased and everyone else crowded around to marvel at the first pair's success.

Three groups finished all their soldering today. I think everyone struggled with fitting the ICs into the sockets - primarily because they were nervous about breaking the legs - and I had to do it for them. Fair enough - I'd rather that than have to try to get replacements.

Two groups got everyone done and then were able to connect their circuit board to the Arduino, Because it was now loaded with the "led flash" program, the chunky red led on the top of the Gamer immediately began to blink when powered up.  A nice first test.

Once I'd shown them where the Gamer library was to be found on the PCs, they were quickly able to select a game and try it out too. Although we didn't have time for exhaustive testing both groups' Gamers seemed to operate perfectly.

This was a real cause for celebration and there were plenty of high-fives.


Knowing that the children always liked the CodeClub certificates from the Scratch projects I knocked up a similar one which I'll hand out next week in recognition of their great work.  

I expect all the other groups will have finished their Gamer next week. 

Things to do differently next time?


Having children working on several different parts of the project simultaneously (soldering, assembly and 1st Arduino coding) was quite chaotic for a while. Fortunately once I'd helped sort out a couple of issues once they were all able to help debug each others' work. It also meant they those who finished assembly were able to reach a really satisfying point. So on reflection I'd probably do it this way again given the choice. 

There were a couple of very minor burns this week. Nobody seemed to mind though and claimed it wasn't hurting enough to warrant a trip to the bathroom to run it under the tap.  

As is usually the case when children become more confident at something, the potential for silliness increases. A couple of the girls discovered that melting the foam pieces used to protect the board  pins produced a nasty (and probably toxic) smell.  I had to quickly make it clear that further investigation of what other materials could produce interesting effects when put in contact with the soldering iron was not part of the project even if it possibly could be considered a valid scientific experiment. 

The DIY Gamer is much more involved than the normal CodeClub projects.  Simply the amount of physical preparation of the classroom and subsequent tidying up afterwards means there is a lot more work for me than just turning up with a bunch of photocopied worksheets. There's not much that can be done about that as it is the nature of the activity, but it definitely requires a lot more work on behalf of the volunteer. I also think I wouldn't want to run this as a first project with a group that I didn't already know. 

Thursday, 2 October 2014

CodeClub: TWSU DIY Gamer Week 3

So this week the children who didn't finished their small led board last time did so at the start of the session. It was quite nice not to have a movie to watch or any group instructions to give first thing: the kids often arrive in dribs and drabs so it was good that they all had something to be getting on with straight away without waiting for everyone to arrive.

Those who had finished the little practice project got stuck into the DIY gamer board itself, assembling the components ready for soldering.


I'm pleased that I took the time to do the practice exercise, as everyone seemed really confident this week and on the whole, the quality of work was pretty high. Inspecting the joints it looks like most will be good enough to let the Gamer work when complete. There are a few larger than ideal blobs in places but nothing too dramatic. In fact some of the more competent children were able to spot when they'd used too much solder and use the solder sucker to make things better.  The best work was actually done by the only Year 4 attendee. To be fair he is also the only one to have ever done any soldering before, but nevertheless I'd be more than happy with the joints he made today if I'd done them myself.

By the end of the session most pairs had completed all the buttons and the LDR. Some had added the buzzer and started on the resisters. The main bottleneck is waiting for the soldering irons to be free. One pair in particular were quite slow - but their work was excellent - which meant that there were always more than half the group waiting.

No burns today, pretend or otherwise. The only minor mishap was that one clubber managed to slightly melt the cable of the soldering iron. The smell of singed plastic was actually a pleasant change from the pong of burning hair (one of the girls, despite having her hair tied back, managed to shed plenty of strands onto the hot soldering iron).

Everyone was keen and enthusiastic again today. It is clear that this sort of activity is unlike anything else they normally do at school and they are really enjoying it. There have been no problems working in pairs and sharing the soldering duties. They are all very sensible with the soldering irons and don't complain about wearing their goggles. In fact two of them had to return after the end of the session because they'd walked out with them still on their heads!

News of what is going on in CodeClub this term seems to have circulated nicely around the school. I've received and overheard several admiring comments from children and teachers alike.

Things to do differently next time

I did consider having everyone also start on lesson 3 (writing the first Arduino sketch) this week so that they could work on that while they're waiting for a free soldering iron.  However I'd then have to reload the games back on to each unit ready for testing when the soldering was complete so decided against that idea. I think I'll maybe do it next week though.

Open more windows to increase ventilation!

Thursday, 25 September 2014

CodeClub: TWSU DIY Gamer Week 2


After last weeks introductory session I was keen to get everyone doing something. I was also slightly anxious about having everyone going straight into soldering up their DIY Gamers having never done any soldering before. Rummaging through my tub where I dump carefully store all my spare components and bits of stripboard, I managed to come up with enough parts for everyone to make a simple flashing led circuit each.  I'd had a quick look online but the cheapest equivalent kit I could find to buy was at least a fiver each. I reckoned mine would have cost about £1.30 each if I'd had to buy everything new, possibly half that if I was patient enough to wait from shipping from China. 


 I chopped the board into 10 pieces and colour coded the holes where each component needs to go whilst watching my oldest son strut his stuff at Rugby practice last night.  I then knocked up a quick handout to show the position of each components.


Remembering the lesson from last week, I'd set out the soldering irons with plenty of clear desk space around them.

In my experience, kids rarely listen when you tell them about some minor hazard, particularly when it's about hot things. A good example being my son burning his hand on the steaming pyrex dish which he'd just seen me remove form the oven, and which I'd specifically warned him 10 seconds earlier not to touch because it was hot.  Having said that, I've also found that having made the mistake once and experienced the pain, they are not likely to do it again in a hurry. My son certainly acquired a newfound sense of caution regarding hot things following the now infamous (in our family) "burnt by the sausage casserole incident".

Nevertheless, I wanted to do everything I could to prevent the clubbers under my supervision from using 'I've burnt my finger" as an excuse for untidy literacy work that afternoon. 

I really like the soldering irons that TWSU have provided. Having a visible temperature control helps emphasise how hot they get and it is also easy to see when they're on. But just to try an reinforce good safety practices, after they'd watched the amusing TWSU intro to soldering movie, I showed them a slide of soldering irons pictures I'd put together.  I asked them which one was hot: 


My clubbers are a smart bunch and they quickly realised that you can't tell just be looking at it. Point made!

They all seemed really pleased to able to have some practice and got stuck in to the job with their usual enthusiasm. Overall I was very impressed with their first efforts at soldering. We managed to get all but two boards completed, with 4 of them working first time. Two more needed only a single joint re-soldering before they worked and one just had the battery the wrong way round. There was only one which was a bit of a mess, but it was still really good for a first effort.


A couple of children claimed to have burned themselves as they went along but I'm not convinced they weren't just saying it for effect. I couldn't really see any marks and their reaction (or lack of one) suggested that it must have been very minor. Either that or they have asbestos hands. They were very sensible and enjoyed wearing their goggles, saying they felt like proper 'mad scientists'. There were also lots of questions about what would happen if we were using solder that contained lead. Just goes to show they were paying attention to the movie.

I realise that I deviated from the published lesson schedule this week but I think it worked. The children were really pleased to have something that they'd made to take away with them.

Next week those who didn't finish their little led board can do so while the others get started on getting their DIY Gamer components in place ready for soldering.

I was really pleased with how this session went. It was clear when we started that most of them didn't really understand what soldering was all about or how it worked. At the end of the session they were proudly demonstrating their understanding by explaining it to me! Although I'll give myself some credit for the descriptions I gave during the session, it was clear that it was the act of physically doing it that helped the concepts coalesce in their brains. Learning by doing: it works.

Things to do differently next time

  • I think I'd have the worksheets for lesson 3 available too so that those who finish or are waiting for a free soldering iron can start using the Arduino. I'll definitely do that next week. 
  • More fresh blu-tac! The stuff I was using today was a bit fusty. There were a few issues with stripboard slipping out of the blu-tac under pressure from the soldering iron.

Thursday, 18 September 2014

CodeClub: TWSU DIY Gamer Week 1

A new term means new faces at CodeClub. I've got some returning children from last year (now Y6) and some (now) Y5s who came to the club I ran for Y3-4 last term. They were all really keen to get started again and had remembered the DIY gamer which I showed them in July when we got the kits.

The children arrived in dribs and drabs as usual so I got them started on the pre-course survey straight away. It only took them a couple of minutes and they seemed to appreciate that it would be help improve the project for future participants. I explained that unlike the Scratch projects we'd done last year, this was all new stuff and very few children had tackled these projects. They liked the idea of being pioneering beta testers!

I wanted to be able to show the children the finished version of the DIY Gamer that they'd be building. I think it's really important to demonstrate what you're aiming for. I remember not doing that in my very first CodeClub session when we were working on Felix & Herbert, and noticing that quite a few seemed a bit confused. At the end when she'd finished, one clubber said 'Oh, now I see what we were trying to do...” (this is what I love about running CodeClubs – I learn so much too).

So I'd gone through all the DIY Gamer worksheets, finished the Simon Says Game and had it loaded on my Gamer so that I could pass it round and let them all have a go. I'd also added a few extra bits to the code so that there is an animation running on the screen until you press 'start' and the game begins. I also added a 'beep' to each arrow when the target sequence is running. I don't see the point of having a buzzer if it doesn't make any noise! HopefullyI can add these extra features as challenges at the end of the project.

In testing I'd also noticed that the same sequence was being used for successive games. The PRNG is Arduino is not that great and it actually produces a long but predictable sequence. However you can get the random() function to start at a random place in its sequence by calling randomseed() first, so I added that and now the Simon Says game offers a different challenge each time. My modified version of the game is here.

I'd actually been a bit dense. Because I already had a DIY gamer myself, I did not build another one from the batch supplied for CodeClub – that way another 2 children can attend. So I didn't realise that a lot of the soldering that you need to do for the regular consumer gamer kit has already been done (yes, I know that it does mention it in the introduction presentation but I hadn't read that carefully enough either). That explains why the worksheet doesn't cover soldering the switch, IR components etc.... Duh. 

Overall I think the session went well. There was certainly plenty of energy and enthusiasm.

They liked watching the intro movie and enjoyed unpacking the kits. Identifying all the components was fun and they liked my demonstration of how to 'see' the infrared light from a remote control using the camera on my phone. They didn't find the component strips game that stimulating though. Partly I think it was because they were keen to get started, but also because it was essentially a thinly disguised “have you been paying attention” test. A couple of the more restless kids were certainly getting a bit fidgety by the end. This first week is definitely a bit more chalk-n-talk that they're used to from the Scratch sessions.  As usual they were full of ideas for games they could make themselves. Hopefully they won't be too disappointed with the fairly basic nature of the Simon Says game. 

Connecting the Arduino to the perspex back went well and it was interesting to see the range of dexterity across the group. They all seemed to struggle a bit with the initial orientation of the two parts using the handout. Fortunately being able to compare with the finished gamer really helped them work it out.

They left excited and keen for next week and the soldering! One boy's description of his dad's soldering iron was a bit worrying - “it shoots out red fire” - before I realised he was getting confused with a blow-torch.

Things to do differently next time.


  • Skip the component strips game?
  • Make more room on the desks for the unpacking. We'd been in the ICT suite to watch the movie and complete the questionnaires. I then got them to unpack and check the components sat at the desk with the PCs on. This did not leave them enough room when it came to actually start assembling things, and quite a few components got dropped on the floor. This was compounded because they are sharing one between two and trying to do things together (e.g. one person holding the perspex plate while the other pushed the bolts through). The person working by themselves (because their partner was absent) finished first and with the least help primarily because they only had to coordinate 1 pair of hands.
  • Check that all components are present in each kit beforehand. I know that kids love opening things so I left the unboxing until today. Unfortunately one set has a missing start button (I'm sure it is missing from the kit rather than lost today, as the children pointed it out without opening the jiffy bag and I checked around pretty carefully afterwards to check that it hadn't just been dropped).
  • Get the children to open the box by slitting the seal along the bottom. Most of them unfolded the cardboard at the ends to gain access. This worked fine but putting everything back in at the end was tricky...
  • I should have provided a greater range of stickers for decoration. The perspex is pretty resistant to any pens other than sharpies. If we do end up using these kits again then I'll be having fun with the white spirit in any event.  

Thursday, 14 August 2014

Timelapse Pi camera rig

My Timelapse Pi rig

I wanted a quick way of setting up the unit, framing the shot and then starting the timelapse capture process, so I used a FTF touchscreen with tactile buttons.


Here are a couple of test movies I made while in Cornwall for my hols.

Sunset at Godrevy Lighthouse 



Carbis Bay for a day

Here's a brief description of how I've set it all up.

The tactile buttons perform the following tasks:

Button 1 (left) [pin 23]: Power off/On
Button 2  [pin 22]: Blank the screen
Button 3  [pin 27]: Start the timelapse shoot
Button 1  [pin 18]: Activate the camera

Putting this all together was fairly simple, following the excellent Adafruit instructions for getting the PiTFT working and building a Pi touchscreen camera.

I then used some simple Python to add functions to the buttons. These 3 scripts are all run from /etc/rc.local

Button 1

import RPi.GPIO as GPIO
import time
import os
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
prev_input = 1
while True:
input_state = GPIO.input(18)
if (input_state == False) and (prev_input):
print 'button pressed ' + str(input_state)
os.system("python /home/pi/adafruit-pi-cam-master/cam.py")
prev_input = input_state
time.sleep(0.05)

Button 2

import RPi.GPIO as GPIO
import time
import os
GPIO.setmode(GPIO.BCM)
GPIO.setup(22, GPIO.IN, pull_up_down=GPIO.PUD_UP)
prev_input = 1
while True:
input_state = GPIO.input(22)
if (input_state == False) and (prev_input):
if os.path.isfile("/sys/class/gpio/gpio252/value"):
file = open("/sys/class/gpio/gpio252/value",'r')
gpio252 = file.read()
if gpio252.rstrip('\n') == '0':
os.system("/home/pi/Python/backlightOn.sh")
else:
os.system("/home/pi/Python/backlightOff.sh")
else:
os.system("/home/pi/Python/backlightOut.sh")
os.system("/home/pi/Python/backlightOff.sh")
prev_input = input_state
time.sleep(0.05)

Button 3

import RPi.GPIO as GPIO
import time
import os
GPIO.setmode(GPIO.BCM)
GPIO.setup(27, GPIO.IN, pull_up_down=GPIO.PUD_UP)
prev_input = 1
while True:
input_state = GPIO.input(27)
if (input_state == False) and (prev_input):
print 'button pressed ' + str(input_state)
os.system("/home/pi/Python/LapseLaunch.py")
prev_input = input_state
time.sleep(0.05)
This calls another Python script that checks to see if a photo shoot is already in progress and, if not, starts the Timelapse bit.

LapseLaunch.py

#!/usr/bin/python
import commands
import time
from subprocess import call
pros = commands.getoutput('ps -A')
if 'timelapse' in pros:
print 'not running another'
else:
call("/home/pi/Timelapse/timelapse.py")
 And finally, the actual Timelapse Python:

timelapse.py

#!/usr/bin/python
import serial, time, sys
import picamera
from datetime import datetime, timedelta
with picamera.PiCamera() as camera:
    camera.resolution = (1280,720)
    camera.start_preview()
    time.sleep(2)
    #for filename in camera.capture_continuous('img{counter:03d}.jpg'):
    for filename in camera.capture_continuous('/home/pi/Timelapse/img{timestamp:
%Y-%m-%d-%H-%M}.jpg'):
        print('Captured %s' % filename)
        time.sleep(28) 
For outdoors power I use an RS Power Bank which gives around 2.5 hours of operation on a full charge.

If I need to reconfigure anything (for example, alter the frequency with which photos are taken) I connect my Android mobile via USB tethering. I've found that using ConnectBot as the ssh client (with the invaluable Hackers keyboard also installed) provides a great way to gain access without having to lug a keyboard around. 

Finally, I also have a tin with an appropriate hole for the lens,  in which I can put the whole kit and caboodle if it looks like its going to rain!

Tuesday, 8 July 2014

Beta testing my Scratch/Minecraft worksheets

I'd been wanting to do let some of my younger CodeClub posse loose on a Pi activity for  a while but hadn't been able to find a project that they I thought they'd be able to work through without a huge amount of attention from me - some of my Yr 3s are still really new to coding and Scratch and need a lot of help and encouragement.

So I thought I'd write one myself, based on the simple yet powerful format used in the regular CodeClub materials.  The plan was to lead them quickly through setting up the Pi and then launch them into Minecraft and doing cool stuff with Scratch.

I used the latest version of Raspbian with Scratch2mcpi installed. I swapped out the standard Cat for a Minecraft-inspired sprite (it also makes it easier to quickly make sure they're using the right version of Scratch).


The worksheet then leads them through retrieving the co-ordinates of the player to placing blocks. they start off with a single block, move on to rows and columns then whole walls, finally building a simple castle. Here's a sample page:



The first session worked well with my three beta testers progressing quickly through the first few steps (ably assisted and helped by my young apprentice who'd already done much of the alpha testing).  Meanwhile my younger apprentice and I were able to help out the rest of the group as normal. If nothing else I was pleased that my beta testers managed to resist the urge to just sit and play Minecraft!


I'll see how they get on next week when there'll be more think and less copying involved...

Lesson learned so far:

  1. I think I'll add troubleshooting section to the worksheet. As usual there seems to be a couple of common issues (e.g. having 2 copies of Minecraft running) that cause problems. 
  2. Even though I let the kids set up the Pis, there's still quite a lot of preparation immediately needed before the session to make sure all the cables are available.  Then there's the tidying up at the end.



Thursday, 22 May 2014

CodeClub for years 3-4 Week Two

So after the success of week One I was fairly confident that this next session would go well.  It did, but there were a few obstacles to overcome first.

Problem one: the projector for the smart board was out of action. I had planned to show few things on the screen. Luckily I discovered this during my regular lunchtime CodeClub so I was able to plan around this in between clubs.

Problem two: I'd planned to get everyone started on LightBot this week. Unfortunately when I setting up the machines in the few minutes before the club started the site was down! Once again, good planning got me out of trouble as I quickly switched to the Angry Birds/ blockly tutorial instead. Phew.

It was interesting to see the difference in ability across the attendees. A couple of them had already down the exercises as part of the hour of code so they whizzed through it. Another two (who claimed not to have done it before) were just as quick.  Age did not seem to be a factor here as the high-flyers were split across YR3 and YR4.

Everyone worked hard and noisily for about 40 minutes then I called a halt and introduced the 'unplugged' session.  Following on from last week's jam sandwich extravaganza I wanted to focus on something that robots and computers are good at - sorting numbers. Borrowing from the Sorting Networks activity I took everyone outside to the playground armed with small whiteboards and markers to where my young apprentice helpers had been marking out the sorting matrix with sports cones and chalk. I explained the steps involved, stressing that really there is just one 'operation' - the comparison of two numbers - that is performed several times to build the algorithm (I was ignoring the multi-threaded aspect for this discussion.


First we worked through it in groups 2 groups of six, with each clubber picking their own number between 1 and 1000. Of course the smarty pants maths geeks all tried to pick 999.99999999...

Then I asked them to run it so that the numbers were sorted in descending order and they quickly worked out how to modify their program.

By the time we'd done this we were all very hot (it was the hottest day of 2014 so far!) so we went back inside to carry on with Angry Birds/Zombies. By that time, LightBot had got its act together so I was able to direct those who'd finished the previous exercises to start on that.

So it was a shame that I couldn't really show my Scratch sorter - this would have been a nice introduction to those who've never seen Scratch before. Hopefully it'll be fixed after half term.



Lessons Learned from this weeks session: always have a backup plan for everything you're planning to do!

Tuesday, 20 May 2014

1st attempt at Cress Heads

I want to get my CodeClub to setup some timelapse photography using their Raspberry Pis and the PiCameras. Fortunately there is a great resource for with instructions and ideas for doing just that using quick-growing cress as the subject matter.

Lighting can be crucial to getting decent results when doing timelapse photography. While changes in brightness can be dramatic for landscape scenes, they can spoil the illusion for close-up objects. So I wanted to experiment with a few ideas.

Because this is for CodeClub, I also thought I'd emix the original instructions  thought I'd use the excellent picamera Python module to control the camera. This also has the advantage of making it easier to integrate other peripheral devices into the system... like a PiLite (to provide illumination) for example.

Obviously you need somewhere where the whole operation won't be disturbed. I plumped for the windowsill in my office. It gets plenty of light in the day, and hopefully the PiLite would provide enough balance illumination during the night (obviously you don't have to use a PiLite, just a bunch of leds in a breadboard would do).

Here's my setup. There's nothing significant about the Camus book - it just happened to be the right thickness to keep the Pi level on its side!


I only need to activate the PiLite while a picture is being taken, and this is pretty easy to program.

#!/usr/bin/env python 
import serial, time, sys
import picamera 
from datetime import datetime, timedelta 
s = serial.Serial()
s.baudrate = 9600
s.timeout = 0
s.port = "/dev/ttyAMA0" 
try:
    s.open()
except serial.SerialException, e:
    sys.stderr.write("could not open port %r: %s\n" % (s.port, e))
    sys.exit(1)
with picamera.PiCamera() as camera:
    camera.start_preview()
    time.sleep(2)
    s.write("$$$ALL,ON\r")
    for filename in camera.capture_continuous('img{timestamp:%Y-%m-%d-%H-%M}.jpg'):
        time.sleep(10) #
s.write("$$$ALL,OFF\r")
        print('Captured %s' % filename)
        time.sleep(3600) #
s.write("$$$ALL,ON\r"
)
(I'll need to make this a bit simpler/clearer for the CodeClub posse but it's good enough for government work here).

Here's the end result after 7 days:


As you can see, the difference in light from day to night time remains quite noticeable despite the PiLite's bright leds.  I wanted to make sure the cress got plenty of light during the day, but perhaps it didn't need such direct sunlight.  Next time I think I'll make a 'studio' that surrounds the cress more completely from the sides.

Or you can have some motorised blinds that were also controlled by the Pi and closed just before the images was taken. Hmm that might be a little complicated for this project.

I also need to make the walls of the studio less shiny to reduce reflections of the PiLite at night (ok, perhaps Lego wasn't the nest choice but is was very quick and convenient).

You can also see that the gooseneck mount does seem to flex slightly during the day (possibly due to thermal expansion). Perhaps a more rigid mount will be better (more Lego!).

Finally, the cress grows really high! I'll need to have the camera framed higher next time.