 Hi, everyone. I'm Ben. I work for the Raspberry Pi Foundation. This talk is kind of an idealism based on an existing library for the Raspberry Pi, and I want to see the idea of it being taken further and moving forward into other areas. So, the Raspberry Pi is a single-board computer that provides you a set of GPIO pins. These pins allow you to connect up to electronics and real-world applications and devices, and they're a simple interface to programming devices and reading values and sensors and controlling things in the real world. Prior to the library that I created, there were several low-level libraries which you just talked to the pins. If you've ever used an Arduino or something like that, you do a lot of turning pins on and off reading the state of pins. The way my library GPIO 0 works is implementations within device classes. So, you create an instance of an LED, for instance, and it provides you all the things that you want in human terms to an LED to be able to do. So, an LED is just a light, so you have on, off, toggle, blink. You can read its value as well and things like that. So, that's just a really simple example. This all kind of stemmed around. Myself and my friend Dave Jones created this library together. It was inspired by Dan Pope's Pi Game Zero, which is a zero boilerplate version of Pi Game for making games with Python. We took the same kind of idea, so we wanted to minimise the amount of code you have to write to make something happen. So, in Pi Game Zero, in just a few lines of code, you can get something on the screen that you can control with a keyboard and move around. And your implementation of your game becomes very centred around the actions of what is going on in the game, the actors in the game, not about implementation of how these things should work in the underlying sense. And the same applies here with GPIO. So, rather than writing out your implementation or copying, pasting an implementation of how to read something complicated, like an ultrasonic distance sensor, you send off a signal and wait to have a signal back on a different pin and you're reading pin values and doing calculations, you actually just create an instance of a distance sensor device and you read its value or read its distance. And they all have, so that it was intended for use in education because we used to teach with a low level library teaching teachers how to do physical computing. And there's an awful lot of code that you had to write to be able to just do the basics. And it was very difficult for them to have the confidence to actually move forward and do more complex projects. But if you can write in a pythonic way with simple, guessable API, commonly used names and sensible default values, it's a simple introduction that allows you to progress along a smooth learning curve. And we went for a kind of a multi-paradigm approach, which is what one of the things I'm going to be focusing on in the talk. So there isn't just one way to do something like a procedural way. There's various different methods you can use. The same way in Python, you can start doing while loops and if statements and move on to writing your own classes or writing your own functions or using functional tools and things like that. And it's very extendable. So if there's a device that you've got that we haven't got an implementation for, it's very simple to build on existing classes and write your own or even write other devices that perhaps aren't tied to GPIO pins, but have them be controlled in the same way or control other things in the same way. So GPIOs are supports all the kind of basic electronic components and a few sort of add-on boards and more specialized components. There's a huge device hierarchy so everything kind of builds on other things. So looking at the sort of what I consider the four main different paradigms. So in the most basic sense, if you want to have an LED light up when you press a button, this is one way of a really great way to introduce a teacher who's new to this or a child who's new to this or any beginner to write a while loop that has an if statement. So if the button is pressed, turn the LED on, else turn it off in a while loop. And if that's all your script is doing, it doesn't matter that you'll stick there in a while loop. A slight variation on that is to use procedural book with a blocking. So rather than continuously asking if and going one way or the other, you wait for the button to be pressed and it will just sit and block at that point until the button is pressed, then turn the LED on, wait for it to be released and turn it off. Which has its benefits as well. You can have a control flow rather than continually asking. And then you have an event driven approach. So you assign an action to the button being pressed and the button being released. Now this is exactly the same thing, but using callbacks. So a threaded callback would be fired to fire the LED on function. You can provide any function. It doesn't have to be a GPS error. So it's just something that's callable so you can write your own custom function, have it fire that when you press a button or something as well. And the final example, so you'll see each of these has reduced the number of lines needed. But this one kind of takes a bit of explanation. In a way it's much simpler in that there's just one line defining the behaviour. So you're setting the source of the LED. So it's saying from the LED's point of view, where do I get my values from? And the button dot values is an iterator yielding its current value continuously in the background. So the way that values work, so we have every device has a dot value property. You can read whether it's an input or an output device. So here I'm creating not an LED but a PWM LED, which is just an LED component that you want to be able to control the brightness, bringing it up and down from zero to one, not just on off. So an LED's value would be true or false, but a PWM LED value is a float zero to one. And now, in fact, I can run LED dot on and then read the value again and I've got 1.0. I can also just set it to zero and that's the same as running LED dot off. So you can't set a, say, a button's value. It has to be pressed for the value to be changed, but an output device, you can have its value set. But you could always read the value of an input device. So if you create a PWM LED, for instance, and a potentiometer, so a rotary dial, which also has a value of zero to one as you slide the dial around, you could read the LED value and see that it's zero. Read the potentiometer value and it's that sort of roughly around halfway. And what you could do is you could say LED value equals the pot value. So you set that once. The LED brightness is now set to that sort of roughly half brightness, but whatever the potentiometers at that particular time. And then what you find yourself doing is putting that in a loop to say, well, I want you to continuously update. And that's where the idea of having source and values came from. So output devices have a dot value, a dot values, which is an iterator constantly yielding the current value. And then any device that can have its value set also has a source. And you can just pipe that straight into there just by setting the source property to equal any iterator to be honest. You give it a list of values and a delay and it will iterate over them. But if you give it another devices dot values, it will constantly iterate over those, keeping those two devices paired, essentially. And so you end up with this. So an LED in a button paired up in that way. You can also process the value in between. So you could take the set of values and apply a function to each value before you pass it into the source. So if you wanted to say, do the opposite of the LED is lit up by the button press, you could have the LED is on until I press the button and then it goes off. You could negate that with a function in between. We actually provide a set of common tools for things like that that you would want to do. You can write your own custom functions which do this. It's all bog standard, just passing values around with iterators. But we provide a bunch of source tools within GPIO0.tools, such as negated and various others. So if you've got a value that says zero to one, but you need to turn it into a boolean, then you just pass it through the booleanized function. You can clamp, invert, negate, delay them, quantize them, smooth them, scale them. You can do all sorts. And you can combine these as well. You can even have some source tools which combine multiple sets of values. So you could have two input devices, which some function takes those two values, does something to them and passes it into an output device. So there's things like other combining tools are things like all, any, averaged, multiplied, and summed. So you could have, for instance, an LED that's only lit when two buttons are both pressed. You could have the all values, the and of those two buttons. And you can also provide artificial sources. So have a function which gets passed into the source, but it's not coming from a GPIO device. It's just coming from some function that isn't connected to a device. So things like if you want to pass in cos values or sine values or random values or define your own function that just provides a set of values from some artificial source. We also provide a few other classes which are we call internal devices which have all the same properties that the other GPIO devices have, the other device classes. But these are not after artificial, but they're just not related to GPIO things. So time of day, for instance, here's an example, so I've got a pet tortoise at home. We've got a lamp, a heat lamp that needs to be on for a certain amount of time during the day. And the lamp is connected to something called an energini socket which is a remote control socket that you can send a radio signal to and it will turn on and off the actual wall socket from the Raspberry Pi. And that's just controlled by a few GPIO pins. So here I create an instance of a connection to an energini socket which I call lamp. That's the representation of what it's controlling. It's controlling the lamp. I've got a daytime object, an object I'm calling daytime which represents the hours between 9am and 6pm. And I set the source to the... So it's a bit the time of day object is a bit like a button and it's either active or it's not active. The same way a button is either pressed or not. It's the same kind of idea. But it's just like a button that is pressed for those hours of the day and then released. So this is one example of how you could use that to control a lamp using daytime. Another one, so we have CPU temperature. So you can read the CPU temperature of the device, of the direct like the temperature of the Raspberry Pi. And we have something called LED bar graph. So that's when you've got a series of LEDs in a row. And rather than be... You can have them controlled arbitrarily. So you have an LED board and you just say you could turn them on in any interval. But if you want them to act like a bar graph so they can only go from one end up to the other and being lit up then use the LED bar graph which is a really effective way. If you've got say 10 LEDs in a row and you pass in the value 0.5 it will light the bar graph up to half of the LEDs. So here I'm using... The LEDs will always be representative of the current CPU temperature of the Pi. So you could see visualize like the temperature rising as you do stuff with applications on the device. Another one, so ping server. It's just again it's either active if it can do a successful ping or inactive if it can't. So here I'm using source delay which delays how often it should be reading that. So I only want it to ping Google every 60 seconds. And I'm also setting... So I've set the green to match the Google values but it's only looking every minute. And then the red is... Rather than coming from another input device it's just negating whatever the green is. So either the green LED is on or the red LED is on according to whether it can access Google. And you can define your own. So this is one way of doing it is actually providing a class that subclasses the internal device class and just implements how it reads its value. So I'm just going to read... Here's just reading from a file and that just contains an integer. So you could have some sort of interface that writes to a file either writes a 0 or a 1 and sets some LED to match whatever there is in that file, for instance. You could also implement this as a function that just yields that value as well but it's just an alternative. So there's a separate library written by Martin O'Hanlon called Blue Dot. So this is... It comes with an Android app for your phone that you can... You get a big blue dot on the screen and you can either use it like a push button. So when you press the button on the app it's Bluetooth connected to your Pi and you can read whether the button is pressed or not in real time. But it also acts like a joystick as well so you can rotate your finger around the D-pad and retrieve the X and Y and the angle and things. So you can use it to do simple things like you could control an LED just by pressing the Android app or you could use it as a D-pad to control, say, a robot. It's really simple to do that because Martin uses the same... Same kind of style of API as GPI-0 does so it plugs in really well together. So you create an instance of your blue dot connection. Here's the exact same examples of the LED and button I did before but the button has been replaced with this blue dot controller. Exactly the same API. So you've got... If the blue dot is pressed, turn the LED on, wait for press, when pressed and then source and values. It's even implemented the source values thing. So GPI-0 is a cross-platform library. So it's distributed via app in Raspbian and Ubuntu PPA and obviously through PIP. So you can run it on Raspberry Pi operating systems and access the GPIs directly. You can also run it on PC and Mac and there's various reasons you would do that. So one thing we did was initially we built the library on top of the low-level library I mentioned that we used to use to teach kids and teachers how to do stuff which is RPI GPI-0. The guy who wrote that library, Ben Crosston, he wrote it as a way to control his beer brewing process and he runs a beer brewing business and he sponsors Pipe on UK often because he used Python to do that and he wrote the library which is what we ended up using as a teaching tool which is really cool where something like that coming out of the community. But we built on top of that initially and it was just directly tied to RPI GPI-0. GPI-0 was just an abstraction on top but then later on we made a way of providing multiple swappable backends so you can say well actually I want to use this I want to use the GPI-0 API but this particular library underneath because it has this feature or this other thing that I like. So there's a couple of other libraries one in particular is Pipe GPI-0 I'm going to go into next which allows remote connections which is a really useful way of being able to control things from your PC over the network onto another pie. We provide a native pin implementation just bundled with GPI-0 that's quite limited but an experimental but it's just a way if you don't have one of those other pin libraries you can just use that and Mock as well. So we have a test suite in the library that just mocks there's no actual pin interactions going on just purely mocks it purely in Python which is really useful for both in our test suite and for personal testing as well you can validate that your code runs without having access to a Raspberry Pi. So here's an example of how Mock works so you just set the pin factory as we call it to Mock in an environment variable run your Python shell or your Python file and you write exactly the same code that you would on a real Raspberry Pi there's no warnings or errors or anything it just the underlying pin object that's connected to the device is just a Mock pin which just stores the pin state in memory. So it's just flashing an LED and reading its value not very interesting. The next one just demonstrates that you can connect Mock devices together so you can verify that if you have a Mock button and a Mock LED your LED's value should change according to the button value which you can tell to drive high and low to simulate the button being pressed which is quite useful. So the PyGPIO library is a really good library written in C the author's name is Joan and she does a really good job of implementing all sorts of different GPIO and other communication protocols for Raspberry Pi in this library really well documented library as well and the way that it works is it runs on the Raspberry Pi as a demon that can accept socket connections so you can give it remote commands if you open up give it permission to then you can have it receive commands from another device. So if you run with these environment variables setting the pin factory and the IP address then you can actually have the exact same code you would run on a Pi but running remotely so give it an IP address and it will run if that Pi is running PyGPIO and actually accepting connections then you can just write the same code and it will do that over the network. Another way you can do it instead of using the environment variables is create your factory objects inline in your code which also means you can have multiple ones so you can control multiple devices over the same sets of pins but on different PIs within the same script so you can have a sensor on one Pi in one room controlling a device in another room. So it's an example of blinking an LED on a remote Pi and this is one where so the default pin factory unless you've set it in the environment variables is on the Pi itself so this script is being run on a Pi and so the LED here on pin 22 is the Pi's own pin 22 but the button is on another Pi's pin 22 so the LED and the button are on different devices there but one is explicitly set to another pin factory which is a remote Pi one is just the local pin. And another use for this is we provide an x86 distribution of our Linux distribution Raspbian so we call the Raspberry Pi desktop for x86 so you can run this on your PC and Mac either live boot it from a disk or stick or actually install it on your machine and the good thing about this is it's a bit like an educational distribution so you've got but for programming so you've got all the programming tools and things that come with Raspbian the stuff that we want Raspberry Pi users to have access to you have all that installed and ready to use this also means you get the GPIO libraries and things like that now obviously if I hadn't told you what I've just gone through about the remote pins and things you would think well there's no point having access to those because you're on a PC you don't have access to the pins but a new addition allows you to plug in a Pi Zero which is the smaller form factor cheaper version of the Raspberry Pi and you can just plug it in with a USB cable and no SD card so you don't actually have to install Raspbian on the SD card you can just boot it over USB using OTG and you can tell it that you want to access the GPIO pins so when you plug it in this dialogue pops up oh you've plugged in a Raspberry Pi what do you want to do with it? if you say you want to use it as a GPIO board it will boot a copy of Raspbian into the RAM on the Pi Zero from your PC boot it, run the Pi GPIO demon and then it's provided as an IPv6 gateway to the device so you can create a pin factory on the reference to the IP address the same way you would a remote Pi but it's actually just going down the USB cable so it's a nice way of doing plug and play Raspberry Pi GPIO stuff just from your PC this is also provided in a PPA for Ubuntu so you can install that and run it on Ubuntu and we're looking into getting this ported to Windows and Mac as well at some point so that you'd be able to do GPIO things directly from your PC and Mac without installing or live-booting the Raspberry Pi desktop which you can do now this is a really cool way of doing it it means things like code clubs and coded dojos and Raspberry Jams and things have an easier way of getting access to being able to run workshops and doing this kind of thing the physical competing GPIO stuff and so one of the ones to go on to was the idea that you could use this kind of interface this simple interface this Pythonic API and these different programming paradigms that have been provided for the different ways of accessing and describing what is going on in your system that could be used elsewhere regardless of how it's implemented you could provide something like a garden light class which control the actual physical light in your garden attached to say a motion sensor and a light sensor so here's an example where we use the combining source tool all values to say we'll take the negated light values so it means if we read it whether that is dark and so when there's darkness and motion both darkness and motion then the garden light should be on and that's just a one line thing describing the behaviour of that system but you could write it using one of the other paradigms as well the idea that it doesn't matter how you talk to your garden light or your light sensor or motion sensor but that implementation could just be within the class and you provide these as long as you provide like blue dot as long as you provide the means to to provide the sorry as long as you provide the the API that GPIO zero devices have so the value the value is the source the is is pressed and when pressed and all that kind of thing then you have the ability to write code like this so there's a a series of devices you can get with Z-Wave controllers they're called that a lot of people have in increasingly in the home for controlling various things around around their house so things like their alarm system or their irrigation system and scenes in different rooms you know the kind of things you get with hue light bulbs and that kind of thing smart devices around the home that are on the same protocol called Z-Wave so you have a you have a server that's on your network and talks to all these devices so a friend of mine has has taken the idea of GPIO zero and this kind of interface and written an asyncio implementation of the source values kind of protocol which means that you can declare in simple python terms how you want the things around your house to behave so he has rules set up for things like I want the bathroom lights to come on when you know he's got things like humidity sensors and light sensors and timings and and various other things that he just decides how he wants them all to behave in his house the good thing about the asyncio implementation is that it's a sort of push based rather than continuous polling so whereas in GPIO zero the devices are every every source every time a source is set it's actually running a background thread so there's lots of threading and message so they're very simple threads just passing passing data values around but it just means that they're constantly being sent regardless of whether they've been updated or not so if you're polling let's say we had a light switch implementation it's constantly sending off off off off off to the to the to the the lights whereas if you if you do it push based then and not until you you press the button and change change the setting of the light that that it sends over the new value it would be interesting to investigate implementing this kind of this kind of implementation into GPIO zero we currently still support we have Python 2 and Python 3 support for for GPIO zero which will probably probably die out soon so we wouldn't be able to use asyncio without deprecating that and also that as asyncio has has developed and matured over the last few python releases once we get a stable asyncio that will work on on on Raspian on the version of Python that ships with the current version of Raspian we'll be in a position we'll be able to do that so it'll be something to look forward to in the future so you can find more about GPIO zero on our GitHub it's on the RPY distro organisation and and on readthedoc so GPIO zero dot readthedocs dot io and just another thing I want to talk about this could be a talk of its own but I've just limited it to just the one slide PyWheels is another project I've worked on with Dave it's a Python package repository that built automates builds of all the PyPy releases so every package of every every version of every package on PyPy we build an arm platform wheel so that they work on the Raspberry Pi and they're built on Raspberry Pi hardware in the Mythic Beast Pi Cloud a server hosting company has an actual Raspberry Pi's we automate all the builds of all the packages as they come out and we have a few manual builds like we build OpenCV ourselves offline and import those and the TensorFlow team at Google are actually providing us with their own custom builds of TensorFlow so you can pip install TensorFlow on a Pi and you get it as quick as that so the problem this solves was that it used to take a very long time to install packages on Raspberry Pi because you had to build everything from source because the wheels that are provided are for other architectures so we natively compile all of these on Raspberry Pi hardware and provide the repository so there's multiple pies in the rack that are doing the building and they just kind of there's a Postgres database that just keeps up with what has been built and what has been attempted and then provides them all in the repository index and then there's just one single Raspberry Pi that receives all the requests and just dishes out files as they're requested it's pre-configured in Raspbian to use this as an additional index to Pi Pi so obviously when it has a choice between a source distribution from Pi Pi and a wheel from a matching platform wheel from Pi Wheels it goes for Pi Wheels so reduces your install time right down which is really useful for Raspberry Pi users but that single Raspberry Pi hosting the packages is currently serving around three to four hundred thousand wheels a month and it's holding up really well and just to finish off I just wanted to talk about a few of the programs that we run at the Raspberry Pi Foundation so Raspberry Jams is the name for independently organised community events that are held around the world they're kind of family friendly events so they're not just workshops for kids like the kind of things that people in this room could go along and work on projects or even take your kids along and meet other kind of makers, electronics enthusiasts, hackers and engineers and other programmers and all sorts of beginners as well they're really great fun events they're a mix of kind of some of them are like meetups some of them are kind of more like a conference where they have speakers and talks and presentations some of them are kind of allow you to drop in and do workshops or work on your own projects so yeah, if you head to raspberrypi.org the jam page has a map and calendar of upcoming events and also Codidojo is another program we run which is for under 18 kids so that's the way that you could you could join in by volunteering as a mentor and actually help teaching kids in a kind of a youth club to learn programming skills across any technology on raspberrypi's or on laptops using micro bits or anything and if there's no existing dojo in the area you live they're really easy to set up and just a few people volunteering some time a couple of hours once a month something like that would be a great way to provide the kids in your area a way to learn some programming skills and get interested in using and learning technology and finally I'm presenting a poster just through in the main room there today so if you want to come and read more about the raspberrypi foundation and the raspberrypi and python world and come and talk to me and I'll answer any questions you've got or discuss anything with you and that's all, thank you so we have some time for QA hello, thanks for the talk you showed these four alternatives for interacting with the IO pins is there any relevant concern about power consumption or any relevant difference among them there will be I wouldn't say there won't there isn't any but it's in my experience it's not really caused any problems so I think one time I noticed there was something running where there was something like 25 LEDs on a Christmas tree and each of them had had their source set to the random values so they all sort of sparkled but because each one of them was generating random numbers in a background thread and there were 25 of them and it was actually running on a pi zero so it was 700 megahertz the chip that was in the pi one so a very weak processor compared to what we have with the pi three and three plus today it started to sort of well it worked fine but if you try to open a web browser on the pi at the same time you'd have really struggled it would have been eating a lot of RAM but you have to do quite a lot to make that work and it's very simple to refact to that the code in that example to run more efficiently just by setting the source to say a 26 tuple of random values rather than each of them doing it in their own background thread for instance but yeah it's not really been a problem I mean blocking is quite a good way of you know when you've got those while loops I mean people do that all the time in projects because it's the easiest way that they think of to have something continuously update so they'll constantly checking something not even putting a sleep in it it's fine I think I prefer the blocking way just because it feels like you're you're just restricting the amount of stuff that needs to happen but yeah I think it's a good question yeah but not a horrendous concern some people probably not like the idea of that many threads going on but it's they're very very simple threads they're not doing loads of stuff in the global namespace or anything like that they're they're just doing having one very small job just to pass messages around so hi so thanks for like selling us this GPIO0 I see that provides a lot of like great structure for the for the applications for the software on Raspberry Pi but my question is as you actually mentioned yourself Raspberry Pi is quite powerful and maybe for some users it's too powerful actually and using too much power do you think that you could possibly run the same library or like maybe stripped down on for example MicroPython devices because this was this is actually my use case which I would very like to go with yeah so I'm going to call and call us in a minute so the API to the on the MicroPython API for the micro bit we kind of there's a group of people that worked on that and I I remember in the early days actually conversations with Damian George around that API was kind of what led me to towards devising something nicer API like this and that API is quite nice it's not got some of the features that that this has because you you don't have you know the resource resources available to do the background threading thing I don't know MicroPython supports threading does it? No so you couldn't do some of those callbacks and things so you will see kids writing MicroPython scripts on the micro bit that that are just doing the while loops all the time and things like the way that we use properties quite heavily so setting properties is quite usually you see getters and setters and things like that even in Python I really really like being able to use that that style to just declare something so the same way you would set a A equals 1 I want to be able to say the LED value should be true or should be something like that so I really like being able to do that as well as and as well as use the use the methods and things but I don't think you can really get away with doing that with properties and in MicroPython as well but I think you can get you can get quite close and you you just don't have the luxury of being able to do a lot of that stuff but yeah you can make some nice APIs that use some of the the beginner stuff in that I showed you Okay Thanks a lot, Ben you showed a function in the middle between the the inputs and the outputs in effect and you showed quite simple ones but presumably you could have really complex ones where you're doing machine learning processing or I don't know something quite complex to exactly and that would how how complex can you get and still have this stuff working in in real time I mean some of them are more complex in that like the the energini lamp is kind of controlling mains power see actually it's still very simple and you're just turning a few power pins on it sends a signal to the to the socket and actually turn but you could have that could doesn't have to be a lamp that's a glorified LED you know in a way in that you're just still turning a light on it just happens to be more powerful a light and it's a heat lamp but that could be controlling something more critical like some sort of machinery or something but I mean there are there are some really interesting GPO components that you can use things like ultrasonic distance sensors so you could have if this was the sensor I could be wave my hand in front of it and you can graph the value of the the distance because it's constantly reading how far away the object is by sending a sonar pulse and reading the value back and it just means you can you can do some interesting things like that like how many LEDs you light up according to how close you get or tell the motors of a robot to stop when they get to a when they get to a wall or to like the there's an example I wrote for for blue dot controlling a robot so actually having a little robot sensors attached to a Raspberry Pi on on wheels on a little chassis but using the blue dots so you pack you pass in the the coordinates of where your thumb is on the on the dot pass those in and sort of clamp them and and you know do apply a couple of functions I figure what they were now clamp them and scale them I think it's so that they're in the same thing that your your motors and your you're not just passing and go forward and go backwards you're passing in is still very simple but it's sort of a progression towards a showing you what what you can do um yeah there's there's all sorts of different electronic components that you know you can control things like LCD screens or um and all sorts of different sensors but that yeah a lot of the examples are just LEDs and buttons which is it's the most simple thing to explain it with but yeah you can do some really interesting stuff with with other components classes for instance that control something else entirely so and use the same kind of kind of API Thank you Yeah coming back to the question of polling versus blocking um I was wondering if the Pi's GPIO pins support hardware interrupts and whether you guys um have used them or are planning to integrate them uh yeah I I believe so I think there's a certain amount of um because it's happening in Linux right? It's not like a you're not talking to a micro controller um so it's yeah there are system level interrupts um I think that's how they're implemented in the I don't touch the underlying libraries really so but I believe so yeah um you can certainly do um you there's certainly are are ways of of doing the complete system interrupts at that level yeah I think we have time for one last question or okay I think we'll find thanks so much thanks