Hardware Meetup - now with biscuits

I had to tear myself away from a really good conversation to take this picture

We had another really good Hardware Meetup at c4di yesterday. Three new folks turned up and we’re going to start working with Arduino devices at the next session. We’re assembling some kits and some content to get folks playing with hardware. The idea is that you spend a princely five pounds on a starter kit containing an Arduino and some lights and switches. And then over the next sessions we’ll introduce other components to play with. If you fancy coming along, you’d be more than welcome.

The next meeting is on the 17th Mary at c4di as usual. Only now we have coffee, tea and biscuits. And hardware. It would be great to see you. 

Apple Homepod Review

One of the nice things about being a writer is that every now and then you get a note saying that a bunch of people have bought copies of your book and, as a result, you've got some money to spend. It doesn't happen to me as much as I would like, but it did happen last week. 

And so, of course, I used some of it to buy myself an Apple HomePod. What with there being one for sale second hand in a local shop, and me having come into a bit of cash, it seemed like fate was actually willing me to get one. 

I'm glad I did. I've got a couple of Amazon Echo devices and I thought that their sound quality was OK. But the HomePod blows them, and just about anything else I've got, away in terms of sound quality. It's far, far, better than the speaker and sub-woofer setup I have in my working room and has therefore completely replaced it. There is a lot more bass present than there has any right to be. It's actually quite startling.

Some reviewers have talked about the impressively wide sound stage that the speaker manages to create using its assortment of drivers and cunning calibration. I've not noticed this much to be honest. The output sounds like it is coming out of a speaker. But what output....

The setup was a breeze. I just held my phone close to the HomePod the first time I powered it on, tapped Yes to confirm access and away we went. It did such a good job of finding the best tracks in my music collection that I let it do that for around eight hours before I actually asked it to play anything specific. 

Voice control is not as great as it could be. It doesn't understand the artist name "Boz Scaggs" at all. I had to ask for the album by name from my library in the end. And saying "Hey Siri" is not how I like to start any kind of conversation. And when I do every single Apple device in the room pricks up its ears. The computer generated voice of the device is not a refined as Alexa from Amazon. I've gone for the Australian female voice as this sounds the least strange to me. Or perhaps I can't actually tell whether its strange or not. 

I've not used the HomePod for much more than playing music. I will tell me the weather and If I get some remotely controlled kit it should be able to control it. I've got an Apple Music subscription, which makes it a proper free-standing device. Otherwise I'd have to use my phone to get the audio source and play it over Airplay. I've not tried the HomePod as a speakerphone yet. It works in this role, but not in a way that you'll find particularly useful. 

From a software point of view it is a bit limited at the moment. There is a serious shortage of third party skill and, unlike the Amazon Echo, I can't use it to listen to the radio, which is a shame. 

However, it is what I thought it would be when I bought it. It is a super, super, speaker with some indifferent network features and a whole ton of room for improvement. I just hope enough people engage with the product to make Apple fulfil its true potential. Until then I'll be very happy listening to the amazing sounds it makes. 

Hull Pixelbots at Dot Net North in Manchester next Tuesday

Another Hull Pixelbot event coming up. On Tuesday next week I'm going across the Pennines to Dot Net North in Manchester. You can sign up here.  I'm going to try and crowd source some robot control. And apparently the pizza is really good. 

If you want me to bring my Hull Pixelbots to your neck of the woods (do woods have necks?) then let me know. 

Hull Pixelbot Robot Rumble at the Raspberry Pi Jam on Saturday

Don't forget the Hull Raspberry Pi Jam this coming Saturday at Central Library.  There are going to be lots of robots, including a bunch of my Hull Pixelbots.

I'm going to be testing a new "Hull Pixelbot Robot Rumble" in which two teams of robots face off against each other in a test of programming skills and strategy. Should be fun. You can sign up here

esp8266 wacky wifi

one way to get a screenshot....

This is rather weird. It all started when I got my old Nexus 7 tablet out of retirement. I'm doing some upgrades for the web server for the Raspberry Pi event coming up, and I wanted to use the Nexus to see if the web site would work on an Android powered browser. 

One of the applications on the Nexus is a WiFi analyser that I've used to pick and choose my WiFi channels. When I fired it up I noticed a few strange transmitters which were taking over the spectrum (as you can see above). 

I finally tracked this down to the esp8266 devices that I use in Hull Pixelbots. For some reason, when they wake up, they start doing things on WiFi channels. I've no idea of the precise meaning of this transmission, but I don't particularly like it. It turns out that if you turn off the WiFi before you do anything else (even turn it back on to connect to an access point) then you don't see this. 

I'd love comments from anyone else who've seen this, or has more knowledge of what is going on. In the meantime all my programs now start with:

WiFi.mode(WIFI_OFF);

..and we're back

I've discovered that trying to produce a blog post every day is getting in the way of proper blogging. I'd have a great idea for a blog post and then remember that I'm a few days behind and I'd have to "catch up" before I could post the new one. 

I know, stupid really.

So, from now on the Rob Miles blog will be much more free form. I'll post when I find something interesting and not worry about keeping a continuous flow of posts. That way, you might even hear more from me than with my previous policy.

BMW i3 Factory Tour

Click through the image for the full 360 degree experience

Monday, tour day, we were up bright and early and, after a quick trip to a local Aldi for cereals, we headed over to the hotel to meet up with the rest of the tour group and go on our way to the factory via tram and bus. Everyone was very excited.

I'm a member of the BMW i3 UK Facebook group. I've even posted on there once or twice. I joined the group when I got my BMW i3 and it is a fantastic resource for owners and anyone thinking of getting an electric car. The folks there are all lovely too. And they'd organised a trip to see the car being made.

When left the university I was determined not to do anything silly like buy a large expensive car. So, I bought a small expensive car instead. It's the nicest car I've ever owned. It's powered by a battery, and a tiny petrol generator that kicks in when the battery runs down. You can use it to go a lot further than your average electric vehicle. It has a carbon fibre passenger compartment and a metal chassis. Like a supercar.

There is only one company in the world who is mass-producing cars like this. And there is only one factory in the world where they're doing it. And at 11:30 today they are going to show us around it. Very excited. After a tram and bus ride (they do trams really well in Leipzig) we arrived at around 11:00 and pottered around the vast visitor's foyer waiting for our tour to start.

And then we were off. They showed us pretty much everything. From robots making the carbon fibre safety cell to the moment where they screwed the wheels on and drove the car off the production line. I can't show you any pictures, but BMW rather helpfully made a video that you can watch if you like.

The tour lasted around three hours, but I didn't actually notice this. I was too busy being impressed. Having seen how they make it, I now like my car even more. Very, very impressive. Some fun facts that I think I remembered correctly.

  • Each stage of the production of the i3 lasts around 7 minutes. The cars are on little robot vehicles that move along the production line. They also build the i8 (the proper supercar) here too. Production stages for this car are 30 minutes long. The folks who make the i8 must be very, very skilled. It takes a few hours to make each car.
  • The pace of production is set by the time it takes the glue to dry when they are assembling the structural elements. They do use bolts to hold things together, but these are used for alignment, not strength.  
  • Each car is built to a particular configuration for a specific customer. This extends to the wiring looms which are fitted to the car. Basically, if it isn't on the spec, there won't be a wire for it. 
  • They save a lot of paint because they only have to paint the outsides of the panels on the i3 because there is no need to protect the chassis or the body panels against rust.
  • All the carbon fibre that they cut away during manufacture is recycled to make other components in the car. 
  • The carbon fibre body shell is around a third of the weight of a metal one. 
  • They can't paint carbon fibre. Paint wont stick to it. The roof of the i3 is a carbon fibre panel and if you look closely you can see that it is covered with a form of varnish, you can see the fibres in the surface.
  • The point where they connect the car body to the metal chassis is called "the marriage". They have around five minutes to get the two elements aligned before the glue sets. Normally robots do this, but if the robots hit a snag they have a few minutes for humans to rush in and sort it out. 
  • They have some robots (they are coloured white) which can work alongside workers on the line, with no safety cage required. 

After the tour we got our bus and tram back to Leipzig, had a quick break at the flat and then headed out for a celebration dinner at Ratskeller, a place in the basement of Leipzig City Hall. 

It was great. Good food, great company, talk about cars and lots of other things. Thanks to the group for organising everything. We've got a few more days in Leipzig. Looking forward to seeing what the rest of the city has to offer. 

Breakfast at the Zoo

Breakfast view

Sunday dawned, and with it the realization that we needed to go and get some food for breakfast. Unlike virtually everyone else on the trip, we'd gone for an Airbnb flat for our accommodation. Not for us the overpriced continental breakfasts they serve up in hotels, no need for us to stand in the queue for cereals wondering where on earth you get the spoons from. No sir. We were going to live like locals, eating what they eat, shopping where they shop. Except that all the locals had bought their food yesterday when the shops were open, and all the food shops were now shut. Sunday opening is not a thing in Germany.

We messaged our Airbnb hosts for help on where to get a bite to eat. The reply came back. 'Go to the zoo'. It was a lovely day, so we did. Leipzig Zoo has apparently been judged "The second-best zoo in Europe". Having been there, I'd now quite like to got to the best one, although I'm not sure how it can better Leipzig. The zoo is vast, and a stone's throw from the city centre. It is peppered with great places to eat, our hosts had suggested three, and we selected the one that lets you eat your breakfast and watch the giraffes go past.

After some discussion at the till about the sensibleness of selecting an "all you an eat" buffet ten minutes before it closes (we didn't in the end) we settled down with our croissant and coffee and did indeed watch the giraffes go past. Today was flagged as the hottest day of the trip and it didn't disappoint. We actually went into the tropical rainforest area to cool off a bit.  If you go to Leipzig, go to the zoo. If you're not going to Leipzig, go to Leipzig and then go to the zoo. You'll thank me. Oh, and eat lunch at the Hacienda. Have the chilli. Then you can thank me again.

We staggered back from the zoo to the flat through the city, noting all the closed food shops as we went past them. We finally found a tiny place that was open which sold about a hundred different kinds of beer. It also sold milk and chocolate biscuits. So, we bought some milk, some biscuits and, of course, some beer, staggered back to the flat and settled down for the night.

Pro-tip that we realised later: shops close on Sunday in Germany. But filling stations do not. Pretty much every petrol station has a mini-supermarket attached and sometimes even a tiny café. We could have nipped to the nearest BP station – our hosts had even noted its location on the map – and stocked up there.

Arriving in Leipzig

The girl at the information desk looked at her colleague, then at us, and finally shrugged her shoulders, holding her palms outwards in the international gesture signifying "Sure. Why not?". We'd just asked her in halting English if it was possible for us to catch the 22:24 train out of Leipzig airport to the city centre. Except that we didn't know where the train was or where to buy tickets. And it was 22:14. Well, if she sort-of thought we could do it, we could sort-of do it. So off we went.

It turns out that ten minutes is just enough time to buy tickets, find the wrong platform, and then stand on it watching the 22:24 train leave from the right platform. The only positive was that the next train arriving at the wrong platform was running late. And going to Leipzig. Worrying that we'd used up all our good luck for the entire trip, we hurried aboard and begin to ponder the next hoop we had to jump through; getting the keys for the apartment.

Because of our late arrival; our hosts would be leaving the apartment keys in a locker in Leipzig station. We'd been sent the locker number and code, along with a picture of the locker itself. I was sure I'd played this video game before and, since Leipzig station is one of the biggest in Europe, I was now playing it on level 10.

After a number of false starts and discovering that I didn't know the German word for "locker", and everyone we met didn’t know the English word for "locker", we finally got the key and made it to the taxi rank, clutching the piece of paper with the address and map that I'd prepared earlier.

The taxi driver took one look at the map, nodded, ushered us into her vehicle and then sped off in what I considered to be completely the wrong direction. Which shows how much I know about Leipzig. We arrived at the door to the flat in record time, stood for a while in the doorway while I played with the key in the lock, and finally we were inside what would be our home for the next five days.

We'd come to Leipzig to watch a car being made. It turns out that there are also lots of other good reasons to visit the city, including parks, restaurants and an amazing zoo, but for now the BMW factory tour on Monday was the thing we were most looking forward to. Or at least, I was looking forward to. The flat was comfy, everything was in place for a nice few days.

Another awesome Hardware Group Meetup

Why I like c4di. 2.4 Gigabytes to download. In a couple of minutes. 

I keep taking my camera to our Hardware Meetups with the intention of getting some pictures of what goes on, and then getting into so many chats about different things that I completely forget to get any pictures. 

It happened again tonight. We had some new members with awesome ideas about projects they want to build. And folks I've seen many times were rocking up with some splendid new stuff that they had made, or were working on. With the LoRa project just around the corner, you really should come along if you've any interest in making interesting stuff. 

The next meeting is on 3rd of May. Sign up here

Midsummer Night's Dream at Hull Truck

There are a few nights left of this performance of Shakespeare's classic play at Hull Truck. You can probably still get tickets. 

And you should. Go here. Buy them. Go see. You'll thank me. 

We went tonight and it was very, very, funny. Some lovely twists on the original, and a bun fight at the end. And that's the most I can say without giving away any spoilers (which is not something you can usually say about a Shakespeare production).

Talking Hull Pixelbots at the new Hull Makerspace

I stole this picture from Hull Makerspace. Thanks for that. 

Today I got my first look at the new Hull Makerspace. 

It's splendid. It's a huge room full of potential; connected to a bunch of other rooms also full of potential. The stuff they are installing is fantastic, including pottery kilns, a CNC machine shop, a paint booth, wood working, sewing and of course frickin' lasers (not mounted on sharks, that would be silly, but for cutting things with). 

I'd been invited to give a presentation at a Code Club meetup. Code Club is an an organisation that does just what it says on the tin. It sets up code clubs, usually as an after school activity, where kids learn the basics of coding. They're getting going in Hull, but they could always use more help - contact them here for more

We also had a talk from Matthew about his efforts putting a Raspberry Pi in the sky, Becky on why we should all be taking part in Code Club and Jon, giving details of the next Raspberry Pi Jam in Hull. 

When it was my turn I showed off the new Hull Pixelbot in perspex,talked a bit about HullOS and we had some fun making robots move via Azure IoT Hub and MQTT. Such fun.

Thanks for the invite folks, I look forward to seeing a lot more of the makerspace in Hull. 

C# Quick Question 2 resolution

Ha. Nobody seemed to know this. Or nobody cared....

Anyhoo, the question was:

"When would a value type be stored on the heap?" And no, the answer doesn't involve boxing.

A value type just holds a value. Not a reference to something. If I have an object managed by reference I have to be careful about removing it from memory, because I need to be sure that nothing in the program is referring to the object. This means that objects managed by reference are stored in a "heap" of objects. It is the job of the "garbage collector" to find objects that are not referred to by anything, and remove these. 

However, value types are easy to get rid of. There can't be any references to them. 

Think of a value type as a book in a library. We can take the book away and nobody can use it any more. That's sad. But we can be sure that nobody is using the book when we take it away. Think of a reference type as a web site. We can't just delete a web site because we don't know how many people out there have made references to the site. 

So, when do we need to put a value type on the heap, and treat it a bit like a reference type? One answer is when we "box" a value type to convert a value type into a into a reference type, but this this is not what I'm after. 

The answer is when a value type is used in a "closure". We see closures when we use lambda expressions. OK, so what's a lambda expression? Lambda expressions are a pure way of expressing the "something goes in, something happens and something comes out" part of behaviours.

The types of the elements and the result to be returned are inferred from the context in which the lambda expression is used. Instead of writing a method and creating a reference to the method, you can just create a lambda expression.

We get into lambda expressions shortly after we start trying to treat lumps of functional code as we would data. Consider the following method:

static int add(int a, int b)
{
    return a + b;
}

This method is called add, it takes two integers and returns their sum. Maybe, for some reason, I want to my program to select between adding, subtracting and some other mathematical operations that take in two integers and return an integer result. C# lets me create pointers to methods. They are called delegates and we would make such a delegate like this:

delegate int IntOperation(int a, int b);

A delegate is another type I can use in my program. So I can create a variable of type IntOperation. And I can make my delegate refer to a method. Watch carefully:

IntOperation thingToDo;

This statement has made a delegate called thingToDo that can refer to methods that accept two integers and return a single integer result. Now I can make this delegate refer to a method:

thingToDo = add;

Now, if I call thingToDo, the add method will run:

int result = thingToDo(1,10);

This would set the value result to 11, because thingToDo presently refers to the add method. With me so far? Good. We can create our methods "the hard way", or we can use a lambda function instead. Look at this statement:

thingTodo = (a, b) => { return a - b; };

Don't panic. It wants to be your friend. Let's take a careful look at what I've done. I've made thingToDo refer to a lump of code that will perform a subtract operation. The code that does the subtraction doesn't live anywhere and has no name.  It is a lambda expression .Sometimes called an "anonymous function". The sequence => is the lambda operator and it separates the "stuff goes in" from the "stuff comes out" parts of the expression. In this case the parameters a and b to in, and the result of a-b comes out. Because thingToDo accepts integers and returns integers, inside the lambda expression the types of a and b are integers. 

OK. We can put these anonymous lumps of code in our program and pass them around on the end of references, just like any other object. What about closures? Take a look at this strange code:

{
    int localValue = 99;
    thingTodo = (a, b) => { return a + b + localValue; };
}

This is stupid, useless code. The statement inside the lambda function is using the local variable localValue for some silly reason. This is quite legal, compiles fine, and gives the compiler a problem to solve. The problem is that the lifetime of localValue exceeds the block in which it is declared. Remember that local variables are usually stored on the stack and deleted when the program leaves the block of code in which the local variable is declared. However, thingToDo is still referring to a lambda expression that uses the value of localValue. So localValue can't die. It must live on outside the block in which it is declared.

The compiler solves this problem by putting the localValue variable on the heap, rather than the stack. The heap is where we keep stuff that has to stick around for a while. This extension of the life of a local variable is called a "closure". 

Short question. Long answer. Phew. 

C# Quick Question 1 resolution

This was the question:

Can I make some C# that compiles and contains these two statements? What type are d and x?

d = null;
d += x;

I wrote the question as a result of my surprise that you could do this with delegate types. In other words, you could add things to a null delegate.

However, it turns out that it works with other things too, including strings. It seems that a += overload (which is how we get the behaviour that allows us to use += to append strings and add handlers to delegates) is also smart enough to make a new object if it turns out that the original is null. Which makes very good sense I suppose.