Okay, the setup is done. We are ready for our next talk. Next talk is by Ikea. Ikea doesn't like things easily. Why Ikea is using a MacBook, ARM-based laptop, running a complete Linux kernel? I'm miracle that this works. If anything goes wrong, we just blame Apple. Remember, if it goes wrong, we just blame Apple. Ikea doesn't like things easily because I like smartwatches. This one runs Linux, this one runs JavaScript, and these ones are proprietary ones, which I won't talk about. But I have non-running Go, and you have one. And that's what we're going to talk about. Go on our smartwatches! Well, hello everyone. So, yeah, I'm Ikea. I'm about six years ago, I was programming using MicroPython. I was programming some LED strips, of course, but I found that they were a little bit too slow, because Python is kind of slow. So, of course, I did sensible thing, and started writing a Go compiler for my controllers. Nowadays, LED strips work really well in TinyGo, because that's a project, of course. So I needed a little bit more advanced project, and that's programming this watch. As you've heard, it's a little bit more advanced, as you've heard, it's... oh, wait, where did my camera go? Well, here you can see it. It's the pine time. It's from pine 64. We also have a stand here and another building. So you can see it live, maybe. No, it can't. Oh, it does have color. Cool. Let's see. Zoom in, maybe. So, yeah, it's a watch. It shows the time. It was in digital. It has very sensors. Step-bunt is wrong, because it doesn't reset at midnight, but whatever. So, yeah, that's what I'm working on. Why this watch? Because there are basically very few other open smartwatches. I know of two or three others, so they're very rare. And this is a relatively cheap one. The hardware is pretty standard, really. A Nordic semiconductor Bluetooth chip with some flash memory in external storage. It has actually a really nice display, but I'll talk about it more in a minute. And it has a hard-wired sensor and a step counter, like normal stuff you'd expect in a smartwatch. So when I started working on it, I decided, oh, wait, you can see it. Let's see. This is supposed to be... There you go. So when I started working on it, I realized I could actually use the smartwatch as a way to improve time ago itself. Because we have a lot of projects that are basically like demos or prototypes, but not a lot of actual professional projects. So my goal was to make this like a actual watch could be like you'd buy, which means I'd have to implement a lot of features you wouldn't implement in just a talk project, such as it has to be fast, it has to be efficient, user-friendly, there have to be translations, but also things like security. So the way I started is by working on a Borg package, which is basically a hardware abstraction layer. It abstracts a lot of different... It works on a lot of different kinds of hardware, like the point time, of course, but also this batch, which is the same hardware, and a few other batches, but might have more in the future. But because it's hardware abstraction layer, it can just as well work on a desktop computer in a simulation. And on all these different kinds of hardware, it exposes the exact same API, which is actually tested in CI because it's easy to introduce differences. This makes it possible to just write for one platform and then have it work more or less for hours without too much effort. As an example, I can actually... Here's the camera again. This is the Adafruit PyPortal. Let's turn this around. It has the same... It can be a little bit tricky to get working, but it runs the same software. So for example, the touchscreen is a little bit finicky. Here you have the same clock running. So the code I wrote for the smartwatch is entirely... Well, it's written for the point time, but it's independent of the point time. There's no point time specific code in the watch code. So I think that's great. So the simulator... Let's move to the next slide somehow. Yeah, this is the simulator. It's running like in any other Go program, so you can just go run dot and you run the program. Let's see what I can quickly get this to work. So for example, here's the same watch. You can debug it here. There's sensors all emulated. There's a step counter here. It disables the screen, of course, but you can change it. So there you go. But there's another feature. Can I show this? I'll try to show this. Help. There you go. Basically, this even emulates the... Well, it uses the Bluetooth package, which works both on like the point time and on the desktop operating system. So what I can do now is I can connect the def kit. Should be connected now. But it's mostly invisible. And if I have... Sorry about this. Where's my cursor? There you go. I can increase the steps. And it should also increase the steps on the simulator. But it's apparently takes a while. Well, this is not going to work right now. But it does work. It's not right now. It most definitely works. So this is a way to be really productive because you can actually test the whole system, including things like Bluetooth, which are normally specific to the hardware. And also the accelerometer, it's not implemented, but you could just easily add settings to change it. And you can debug the same thing using like Delve or something. So that should just work. Here's the Go-Batch in simulation and a game I made. The only thing I really add... Wait, I don't have much time left. The only thing I really add added to each project is like a small configuration part, which isn't actually built on actual hyperpossess in a statement. And just set some parameters. So the simulator knows what screen size to use and even the draw speed. But you could just as well leave it out and then it uses its standard size, which happens to be the same as this batch. Oh, wait, I didn't actually show this. There you go. Sorry about that. Maybe I should have used screen memory. Anyway, so that's the developer side. And I think that's really important because debugging hardware can be quite finicky. And for example, the pintime, either you flash it over the air, or you can't really debug it in any way. Or you have like these small thin wires that are really easy to mess up. So running it on a normal computer is really helpful. So that's the developer side, which I tried to improve. Next up is the battery life. I think I'm going to skip explaining most of these, but basically there are a lot of really small things that need to be implemented to make it really efficient. For example, one is that the chip itself actually runs at a lower voltage. So it has a linear regulator inside to lower the voltage. But that's really inefficient. There's also a DC-DC converter, but it needs some external hardware. But because it needs external hardware, it's disabled by default. But it's like one line of code to enable it. So it's things like this. Most things are more complicated than this. All of these things are implemented in the board package that I mentioned before. So if any of you like to write your own firmware for this watch, you can just import the board package and it'll basically do almost everything you want without. Yeah. So that's battery life. Then the display. This was actually a lot of work. So as I said, the display is like a really nice display, a very high resolution. By default, it uses 16 bits per pixel. The only downside is that the connection to the main market controller is like 8 megabits, which is like 8.5 frames per second. So quite slow. I used a few tracks to speed this up. Yeah, maybe you've seen it before. It was part of the responsive. The first one is that I configured the display to use 12 bits per pixel instead of 16. This low is the image quality, but not really that much, especially for smartwatch, which doesn't need that high resolution. The second one is you can just update a part of the display. You don't need to update the whole display at once, because the display itself has a frame buffer in it. The frame buffer in the display is more memory than in the main market controller. That's how embedded works. Sometimes we get like that. The third one is fast scrolling. Maybe I can show you quickly. So it may not be very visible, but this scrolls with very little delay, except when the touchscreen locks up. And... No? There you go. This is actually a hardware feature. Basically you can say from this line to this line, I'd like to rotate the display by this many pixels. It works, but it's a pain to implement. Oh man, I've had so many headaches. But it worked. Anyway, so that's one of these really specific things for this place. And the fourth one is DMA. DMA, if you don't know, you can think of it as like a co-processor that does one thing, one thing well, which is copying data from one place to one other. And that's basically the only thing it does. So you can basically copy... So what you can do is prepare an area of pixels and then say to the DMA, like, hey, copy this now to the SPI bus, which is how the display is connected. And then it will start copying in the background and you can just continue rendering the next block of pixels. And this can actually really improve performance quite a lot because the CPU is fast for a market controller, but not actually that fast. That's 64 megahertz. I've implemented all four except for the last one because basically... Basically, DMA is a little bit harder to implement in a portable way. That's also Go-style. The hardware works a lot like the async await button in many other languages. You can just say, start this project and later say, just wait until it's finished. But that's not really how things are usually done in Go. So we will need to figure out a nice API for this. But it will get there. Of course, this display is quite complicated and you really don't want to write for this one display. So we have a display API, which is an interface. Many displays in the TinyGo driver's package use an interface like this. Of these, the draw bitmap method is the most important. And as you can see, it has a pixel-built image type, which is actually a generic type. This works a lot like a Go slice, except it's for pixels and in two dimensions. The main reason I did this is because the display is 12 bits per pixel, so they don't fit well on the byte binary. So a Go slice only works for, when each element falls on the byte boundary. So basically, we implemented a slice-like type for pixel buffers. I think this is actually going to be really useful in the future because there are many really weird pixel layouts in some displays. I have seen a display with nine bits per pixel that doesn't fit in the bytes or two bytes. There are all the displays with one bit pixel, like many E-Ink screens or some OLED screens. I'm not exactly sure whether this pixel-built image type is how generic they are supposed to be used, but they are very useful and they are very efficient as well. So that's the main set of methods that most displays implement. But some displays also have special support for the scrolling, which I mentioned before. Actually, the way you use it is by simply doing a type assert on the display drive and seeing whether it supports scrolling or not. That's just a regular old Go type assert. So that's display API, one level higher. Then another level higher is tinyGL, which is something I have been working on lately. It's basically a graphics library for drawing widgets and stuff. There are many existing libraries which do the same thing, like what's happening right now? Lvgl, maybe people have heard of it. It's a C library and it's very often used for embedded devices to draw widgets and stuff. It's also used by Infinitime, which is the default firmware on the pintime. Downsides are that it's written in C, which is difficult to wrap in Go, and it has a lot of macros and compiles to ARM constants, which Go really doesn't like. The only thing we have are build tags, but really you want to avoid them as possible. Another library that's often used, especially in toy projects, are some libraries from Iterfruits. They are kind of slow, though, because they draw each pixel individually, which means you have to send the x-coordinate, i-coordinate, the width and the height of the area in your corner paint, and then one pixel. That's going to be slow. It doesn't support 12 bits per pixel like I'm actually using. It doesn't really work for me either. Then there's TinyDraw and TinyFont, which are libraries used in TinyCo, that are part of TinyCo. But they work sort of similar to the one in Iterfruits. They're great libraries, but they're not super fast, so that's why I wanted to make something different. So that's why I made TinyGL. It works really well together with the board package that I made. They are independent. One of them doesn't import the other, so they're separate, but because they're an interface match, you can just really easily use one with the other. Some of the features include that everything it draws is anti-aliased, including the text circles. Actually, I do have a circle in the middle of the screen. There's my cursor. There's a circle in the middle, which is anti-aliased, and these lines are anti-aliased, which actually took me a week to implement or something. It's kind of difficult. I actually based the algorithm for the anti-aliasing in these lines on an algorithm that was originally used in, I think, the second Star Trek movie, from the 80s, for the Genesis device. It was really nice reading the paper and seeing the mention of Star Trek. But computers from back then are somewhat comparable to my controllers today, so it makes sense. I am going to write a blog post in the future about how I implemented these lines because it's way more complicated than it looks. It basically is polygon rendering because it's like a rectangle instead of just a line. Yeah, I think that's it. Some things I want to work on in the future include, I mentioned before that I think security is important. Well, I haven't actually implemented any security features yet, so that's some work in progress. For example, in Bluetooth you can change the MAC address every 15 minutes, I believe, and you can bind the devices so they can connect security the next time. But that needs some work and probably some flash storage, which is another thing I need to do. And of course translations. I plan on looking what's available for our go and seeing whether any of the existing packages would work for a tiny go. And maybe write my own, but maybe not because I'm not a dialogue experience, but languages. So that's it. Any questions? Thank you. My takeaway is hardware is very hard. Tiny go, lots of effort. Any quick questions because I think Ron needs setup. Hardware is enjoyable, though. Was there a question? Please raise your hand again because I lost you. Sorry. Keep holding your hand up. Thank you. Hello. How do you power your earrings? Sorry. Oh! Sorry, I totally forgot about them. There's a small lidsim on the back side. It's a CR1225. How long does it last? About 30 hours, I think. The most crazy thing is that I actually wrote part of it in go. And assembly. Second question is how can we get a kit, like a development kit for the watch? Sorry? Is there like a development kit that we can buy? I believe so, but you'd have to look for the Pine 64 store. There should be a development kit, so you don't end up breaking the device if you make a mistake. The Pine 64 people have a stand in the stands building. Go ask there and they will point you to the right place. Pine 64. Any other questions? Really quick. I see none. Applaus!