WEBVTT 00:00.000 --> 00:24.480 All right. Hello. Hello, everybody. Welcome to the last talk before the 00:24.480 --> 00:30.640 last talk of today. My name is Heather Crespo. I'm from Spain. I work at a company called 00:30.640 --> 00:37.120 the Silver Botics. We designed monitoring devices, remote ones and devices, so low power 00:37.120 --> 00:45.120 usually solar panel and so on, and we designed like from the prototype in phase to mass manufacturing 00:45.120 --> 00:54.080 or at least series of 50-100-200 devices. Today I want to talk about the project in particular, 00:54.960 --> 01:01.440 in which a customer required us to build our new design for the meter, which is a device that 01:01.440 --> 01:08.800 tracks monitors like pollution, and for the first time we decided to use rust for the field work. 01:08.800 --> 01:15.120 So it was for us, it was a big decision because this has to work, this has to work, 01:15.120 --> 01:20.640 and it has to work not only for the prototypes, but for the devices that are deployed 01:20.640 --> 01:27.600 in the middle of nowhere, basically. So, yeah, first of all, a disclaimer, this doesn't intend to 01:27.600 --> 01:32.480 be a deep dive into into rust. There was a dev room for that, there were great talks about 01:32.480 --> 01:39.440 rust and embedded rust this morning, and this afternoon, but the talk is about looking back at the 01:39.440 --> 01:44.240 project and asking the questions, was it the right decision, should we do it again or not? 01:44.320 --> 01:50.960 So, yeah, well, first of all, a few words about like pollution, why is that important? 01:53.040 --> 01:57.200 Our customer was the European Space Agency and the Liberates Space Foundation, 01:58.160 --> 02:03.760 so obviously the may-re some was for astronomy, I don't think it needs any more explanation, 02:03.760 --> 02:10.080 why is that important? But like pollution is also important for, it has any impact in many other 02:10.080 --> 02:18.000 areas such as public health, it has an impact on ecology. There are great resources online trying 02:18.000 --> 02:27.600 to correlate the bird migration routes and the sources of artificial light. And in fact, 02:27.600 --> 02:34.640 our customers today, they are looking into using our device for doing that. It has an impact 02:35.280 --> 02:45.920 on cultural identity and so many other consequences. From the technical point of view to measure 02:45.920 --> 02:52.640 like pollution, pretty much all you need is a photo diode and there are several ways to interface 02:52.640 --> 02:58.560 that with your microcontroller. The one on the left is the one that most of the devices we're 02:58.560 --> 03:05.760 using when we started the project is a chip from AMS that converts the current the output of the photo 03:05.760 --> 03:11.600 diode to frequency-encoded pulses and then you just account edges for giving amount of time. 03:12.320 --> 03:18.560 And the one on the right is the version that we're using now. It's a new chip. 03:18.560 --> 03:23.280 We think, of course, the interface, it has a couple of channels, you can configure interrupts, 03:23.280 --> 03:30.640 you can configure the integration time. But in the end, it's the same. It's a photo diode, 03:30.640 --> 03:37.600 but a bit more powerful. And yeah, I want to, this is really important, the escrow is the interface, 03:37.600 --> 03:43.680 because the project from the system at the same point of view pretty much what you need is an 03:43.680 --> 03:48.640 escrow is the interface and then some kind of connectivity to send the data to the internet. 03:48.720 --> 03:54.320 In our case, that was Wi-Fi. So, for this project, we needed it was Wi-Fi and let's go see. 03:54.320 --> 04:01.520 So, yeah, choosing Rust was not like a big decision of this will never work. It was, yeah, 04:02.560 --> 04:10.640 yes. So, yeah, why Rust? Well, there are many, many language features that are 04:10.640 --> 04:16.240 interesting and relevant for embedded devices. I chose actually this three from the 04:16.320 --> 04:23.360 official website. I'm going to go quickly through them. The first one is the static analysis, 04:23.360 --> 04:32.400 the powerful static analysis, and what happens there, but yeah. So, what that means, 04:32.400 --> 04:40.640 since can define a GPIO, a GPIO is tracked and then depending on whether it's an input or it's 04:40.640 --> 04:48.640 configure an input or as an output, you have access to different functions. So, what does it mean? 04:50.800 --> 04:57.760 For instance, if you declare a GPIO at compilation time, if it is an input, you can only read it, 04:57.760 --> 05:04.800 if it is an output, you can only set it. And yeah, at compilation time, thanks to this is called 05:04.880 --> 05:11.840 the type state pattern. So, no runtime cost, and I think this is really, really powerful. 05:11.840 --> 05:17.120 The problem is when you are trying to understand, if you are new to the language limit, 05:17.120 --> 05:22.080 and you are trying to understand all those, that's really simple, but you can imagine that the 05:22.080 --> 05:28.800 hull of any other, any other crate is much more complex, but it's really powerful. 05:28.880 --> 05:36.960 Memory allocation also really flexible on Rust. You have core Rust, and then you have STD. 05:36.960 --> 05:42.000 So, if you don't want to use dynamic memory allocation, or you have to use to type this, 05:42.000 --> 05:48.800 no STD attribute on top of your main file for instance, and then instead of having access to 05:48.800 --> 05:56.320 defining a declaring a vector on the heap, you have to use some different allocator, 05:57.280 --> 06:03.680 for instance, the heapless allocator, that will have a similar functionality, a heapless vector, 06:05.280 --> 06:10.720 instead of using the heap it will use the stack, or any other custom allocator. 06:12.240 --> 06:18.080 And yeah, concurrency is also really safe in Rust, because of the ownership rules. 06:19.600 --> 06:26.160 To this piece of code from our project, we have to sum to stress one of them is 06:26.160 --> 06:31.840 for sampling the data, and the other one is for networking, because when we use cellular 06:31.840 --> 06:36.960 communications, we want to bring up the modem while we are sampling, so everything is ready 06:37.920 --> 06:43.760 when the data comes out, and of course we share some data between those threads, 06:43.760 --> 06:50.720 and with Rust with the ownership rules, you cannot mess it up. You will not incur into 06:50.720 --> 07:01.600 the data risk conditions. For embedded devices, what you would probably benefit from is in case 07:01.600 --> 07:07.040 of handling interrupts, so it is the same, it is a context switch, and thanks to the same rules, 07:07.600 --> 07:14.720 you cannot incur into the data risk conditions. But for me, so for me the killer feature is not 07:14.800 --> 07:23.920 the language, which it is great, but for me the killer feature is the tooling. Rust includes 07:24.640 --> 07:31.440 cargo, which is a package manager, and it pretty much handles all the project life cycle. 07:31.440 --> 07:38.320 So if you want to build the project, you just do cargo build, no more make files or see make files 07:38.400 --> 07:46.480 all around the project nested, and it is a device placed on the source file, and for most of the 07:46.480 --> 07:53.280 cases of course, and it will compile and build everything together, cargo run, if you want to run 07:53.280 --> 07:59.920 the binary or if you want to flash it to your board, it has support for testing, so if you do the 07:59.920 --> 08:06.400 cargo test, and there are tests into your code, you don't have to, you don't need any other 08:06.400 --> 08:14.000 tool that includes any testing integration testing examples, testing everything, and the most 08:14.000 --> 08:19.920 one of the, well for me, the best feature is the package manager, so this is similar to PIPI, 08:20.480 --> 08:27.440 you can type in your console, cargo are the name of a library or a upgrade, that's called the 08:28.320 --> 08:36.240 code, and you have access to see the realization of data, parsing, logs in a more efficient way, 08:36.960 --> 08:47.120 parsing a bit fields, everything. For embedded systems, that's really important, 08:47.680 --> 08:53.920 because you can do stuff like cargo art and the name of a driver, and this is because the 08:53.920 --> 08:59.840 there is some official working group for embedded devices, and they have been working for, 08:59.840 --> 09:06.080 I don't know how many years, in trying to standardize the interfaces, so everyone pretty 09:06.080 --> 09:12.080 much of the community has agreed with them and is following their advice, and most of the 09:12.080 --> 09:19.040 drivers are compatible with this embedded hull, so that means that if you add a VME, and you have 09:19.120 --> 09:28.640 a compatible hull, which I think it's all of them, do you just have access to a lot of drivers 09:28.640 --> 09:36.640 for free? It would work something like this, you instantiate the S4C bus, you configure it, 09:37.360 --> 09:43.920 and then you type into your terminal cargo, a VME to 80, and then you have access to a 09:43.920 --> 09:50.640 japan instantiate VME to 80 driver, and you pass it the S4C bus, and then you all have to do 09:50.640 --> 09:58.480 this fetch the data. If now you want to another sensor, that's an accelerometer, cargo art the 09:58.480 --> 10:06.080 name of this driver, and yeah, then it's the same, you declare the driver with the S4C bus, and you fetch 10:06.080 --> 10:12.080 the data. So that's all the code, instead of having to, what I would do before is go to get 10:12.080 --> 10:19.680 have at a fruit, find the driver, clone the project, try to compile everything together, here is 10:19.680 --> 10:26.160 just, this is all the work we have to do. This is great, but I mean we all know this comic, so 10:27.360 --> 10:32.960 I guess for embedded developers, modern tools, main modern problems, but we have to live with that, 10:32.960 --> 10:44.960 it's the price to pay, yes. So yeah, the conclusion about this entire rest thing is that the 10:44.960 --> 10:51.680 community is really strong, it's really active, it's really cohesive, so that's really, really good. 10:52.880 --> 10:58.320 The tooling is great, compared to what we had before, as embedded developers, 10:58.960 --> 11:07.920 well, there are some other good tools out there. The documentation is, I mean, I don't like to 11:07.920 --> 11:14.720 write documentation myself, so I'm going to complain about it. And for me, the biggest problem 11:15.920 --> 11:23.760 is the lack of official vendor support. Maybe not for me as a developer, but for the adoption 11:23.760 --> 11:29.760 of a white part of the industry, there are only a few players, so they're expressive and I think 11:29.760 --> 11:34.880 if you know something that really, that are really supporting rest. 11:39.040 --> 11:45.920 Yeah, so about the device itself, the device that we have designed, it has three, well, 11:45.920 --> 11:50.000 it's this is small, this is the device, it has three sensors, 11:50.720 --> 11:55.440 while the BME for a temperature pressure and humidity inside the box, 11:56.640 --> 12:01.440 obviously the delay sensor, which is the one I showed in the first slide, 12:02.960 --> 12:06.320 and then we have an accelerometer to measure to measure pointing. 12:08.800 --> 12:17.520 The main MCU is on USB 32C3, from expressive, they have official support for rest, they have 12:18.480 --> 12:29.120 four, five, six people working full-time on these tools. In fact, they have two different versions, 12:29.120 --> 12:34.720 one with STD and another one with STD. We use STD because it's pretty much a 12:34.720 --> 12:41.120 proper of the USB IDF, and that's really stable, it's really, I mean, everyone uses that and it works. 12:41.760 --> 12:47.520 If you want to use no STD, which you might, that might be the future, and that's what they 12:47.520 --> 12:55.040 are working on, but at this moment, we're using STD. Then we designed two expansion boards, 12:55.920 --> 13:01.680 so the main board with the sensor on the USB 32 communicates through UART and 80 commands to 13:02.720 --> 13:09.520 send you our modem with 2G WiFi and even an GUT, and another expansion board with 13:10.240 --> 13:20.480 support for LERA1. Again, UART and 80 commands. Then we have some extra features for 13:22.160 --> 13:30.720 backtones and so on, but many things. This is the flow diagram, so when the device wakes up, 13:30.720 --> 13:36.720 the first thing it does is take a sample, sampling takes roughly one minute, because you have to 13:36.800 --> 13:40.400 especially for the light, you have to take a lot of measurements, and then you want to 13:40.400 --> 13:45.840 obtain the mean and you have the standard deviation, the same with the temperature, but not so 13:45.840 --> 13:50.480 often, so you want to meet it, and that's why we have two threads, one for sampling and another 13:50.480 --> 13:55.360 one for networking. Then we put the data into a buffer, if the buffer is full, 13:57.440 --> 14:04.080 if there's enough battery we connect to a network and send the data, and finally, depending on 14:04.080 --> 14:12.960 whether it's day or night, and something that you can note because of the GPS location, 14:12.960 --> 14:20.000 and the timestamp, you go to sleep either for five minutes or for the entire day. 14:21.440 --> 14:28.160 But from this slide, what I want you to observe is the all the steps that I put into into the 14:28.160 --> 14:34.880 red boxes, those are external grades, so all the job that we have to do is cargo out, 14:35.680 --> 14:43.440 for instance, they are night, it's just a bunch of equations that you you enter Wikipedia and 14:43.440 --> 14:49.120 do it, but in this case, there's a grade for that, so you just do cargo, cargo out, 14:49.120 --> 14:54.720 sun rays, and that's it, but you have to do it since we integrate that into your code. 14:55.600 --> 15:04.640 The same for the mode and drivers, for the sensors, I mean, well, all we have to do, 15:05.600 --> 15:12.320 some of them, we build the drivers and publish them openly as a different grade, but you know what I mean? 15:14.560 --> 15:23.760 Well, our power consumption, it is a tricky, this is one for cycle at night, 15:25.680 --> 15:34.080 you have to take into account that the device is power on 20% to 25% of the time, so every five minutes, 15:34.080 --> 15:39.760 we take a sample and sampling takes one minute, one point, something minutes, 15:42.240 --> 15:48.720 and then we depending also on how often we want to send the data, we have a buffer, we send the data 15:48.720 --> 15:58.640 every thing or samples, this would be the power consumption, and now we focus on that's one of 15:58.640 --> 16:08.080 the sampling, but no networking steps, this is the power consumption of the sampling thread, 16:08.080 --> 16:20.080 so if you check down here, it's 10, 9.3, and finally, well, sampling and sending the data, 16:20.080 --> 16:28.400 as you can imagine, when you turn on the modem, it's like, this is for cellular, I think, 16:28.400 --> 16:33.920 so once you turn on the modem, it's really, I really high power consumption, 16:34.880 --> 16:45.920 and some of the results, on the top, you can see the battery graph, the battery, 16:45.920 --> 16:56.000 dear in the night, it drains 10%, so if you don't have access to the sound or if the solar panel 16:56.080 --> 17:06.880 is not connected, the battery would last around 10 to 12 days, in the middle you have the temperature 17:06.880 --> 17:14.240 graph of this particular device, this was dear in winter, so it goes from positive 28 to negative 8, 17:14.560 --> 17:25.920 dear in the summer, it goes up to positive 50, 60 degrees, and well, I mean, the light, 17:26.640 --> 17:31.680 you can really analyze the data with the computer and do something much more interesting, 17:31.680 --> 17:40.480 but with just by having a look, you can see that the sensor overflows, you can detect 17:40.480 --> 17:46.000 for instance at the bottom right corner, and that's the move starting to come out. 17:50.000 --> 17:55.120 Actually, well, here I, this is taking from Mr. Laryon, that's the position of the move, 17:56.560 --> 18:01.280 and I don't know if you can see it in the top right corner, just by having a look at the data, 18:01.280 --> 18:08.400 as you can detect how the, how there is a peak of light moving from the beginning of the night 18:08.480 --> 18:14.640 to the end of the night. Yes, so I mean, in the end, it was a really successful project, 18:14.640 --> 18:22.160 the devices are deployed, the Canary Islands, in Madaya, in Greece, there are some devices, 18:24.000 --> 18:32.480 there are some, they are fetching data like every day, there are, we, every night, there are, 18:32.560 --> 18:39.520 I don't know, but we have probably hundreds of megabytes of data of all these devices, 18:40.080 --> 18:46.080 and so far, rest has been a nice adventure. So yeah, that was it. Thank you very much, 18:46.080 --> 18:52.800 thanks to our partners, thanks to the President for organizing that, and yeah, that's it, thanks. 18:52.800 --> 19:05.200 Hi, when you say that the Expressive Support Rust, you mean that it's a binding, or they are 19:05.200 --> 19:14.640 literally held in a real time, when you said that the Expressive Support Rust, you mean a binding, 19:14.640 --> 19:20.240 or is there a real time operating system within a Rust? Yes, so they have two options, they 19:20.240 --> 19:28.080 one with, with, with support for SD, that sub-rupper of the USB IDF, so under it could see, 19:28.080 --> 19:35.200 it is three articles, and they have implemented the post-excompliance, so that's why you, 19:35.200 --> 19:47.200 here you can see, this SDD thread is found something that's actually a free artist task, 19:47.280 --> 19:52.400 okay, so you're actually binding to the C++, right? In that case, yeah, but then they have the 19:52.400 --> 19:58.320 Windows 3 version, which doesn't have any, any articles, and it is I think, so you would have to 19:58.320 --> 20:06.240 use an Icing executor, such as Embesley or any other executor. Okay, but, but it doesn't have a 20:06.240 --> 20:12.720 scheduler from the Ertos, no, the, the bear one, the bear knows the version doesn't have any 20:12.800 --> 20:32.880 any escalator. Thank you. Okay, so I, just a sort of, coming, I saw you monitoring the 20:32.880 --> 20:40.160 battery voltage, and I've also done some work with Rust, with a battery-pad device, and I see 20:40.160 --> 20:46.400 it, like, you're, you're getting up to, you have, sort of, charging Icing, and you have, like, 4.2 volts, 20:46.400 --> 20:53.440 depending on the day. I, you, you worried about that sort of killing the batteries quite quickly, 20:53.440 --> 21:00.080 if you had any issues with that, that we chose to limit the battery voltage to 4 volts, 21:00.800 --> 21:05.120 particularly when it is really hot during the day, we had read very fast degradation on 21:05.120 --> 21:10.320 battery cells, and the voltage was right up to 4.2, but I don't know if you'd seen any issues 21:10.320 --> 21:17.280 with that. Well, I mean, we didn't have that issue, so far, and we have not of this particular 21:17.280 --> 21:24.880 device, but for the devices, we have, I guess, 1,000 devices charging up to 100%. And I guess, 21:24.880 --> 21:30.160 because they are, they are always in the same pretty much full, full region. We don't have any, 21:31.120 --> 21:36.080 we have degradation issues, but not something that we can, we have to change the batteries every 21:36.080 --> 21:46.720 few months, it's, it's, it's okay. Think of presentation, how one question do you use any 21:46.720 --> 21:52.800 interrupts in your Rust code? No. Because one of the pain points is just borrow checker getting into 21:52.880 --> 21:59.440 middle of sharing anything. Yeah, yeah, yeah, I mean, it's the same as using threads, 21:59.440 --> 22:05.520 but yeah, it's, it's one of the things that is difficult to understand if you're new to Rust, 22:06.080 --> 22:13.280 and the compiler is really, really hard on getting it right, but you have to trust the compiler, 22:13.280 --> 22:17.840 it will work. I mean, all you have to do, I don't know much about Rust, but all I have to 22:17.840 --> 22:24.320 default the compiler instructions and I end up to something which compiles and it works, I don't know. 22:27.200 --> 22:31.280 Oh, yes, I have a question about testing. Yeah, like you mentioned, 22:31.280 --> 22:38.240 I've got a test, which is like, unit testing is pretty good and like Rust on, on desktop 22:38.240 --> 22:44.480 devices, but how is it on embedded, like, do you have any idea of how you run tests? 22:44.880 --> 22:50.560 Yeah, that's a good question. I was actually trying to find it out the day before, the day before 22:50.560 --> 22:59.120 yesterday, because apparently there is no, if you find it, so if you go to, to get lab, you call 22:59.120 --> 23:05.280 the project and you do a cargo test, it will try to compile everything and flush it to your board 23:05.280 --> 23:11.120 and run it into your board, so you would need to specify a different target in your cargo 23:11.440 --> 23:18.880 tunnel, but because that's not possible, but what people is doing is creating another work space, 23:18.880 --> 23:29.440 which doesn't have dependencies on the hardware itself, so let's say you have a hull and the hardware 23:29.440 --> 23:39.600 code and only the main logic has access to a target which is not the main MCU. So that's something 23:39.600 --> 23:45.840 that is not easy to, to be done in the, in this kind of, of applications, at least at the moment. 23:48.400 --> 23:52.800 Thanks for the talk. Quick question about the development time. Can you share a little bit 23:52.800 --> 23:59.920 on about how much changing to Rust impacted the project? Can you say something with comparison 23:59.920 --> 24:07.760 of previous projects? I don't think this is a fair comparison in this project, because I mean, 24:08.320 --> 24:12.560 the project is, this one is really simple, it's, as I said, it's Wi-Fi and as 24:12.560 --> 24:18.720 course we could do this with micro Python, with Arduino, with whatever, so this is not a fair comparison. 24:19.600 --> 24:26.160 In Arduino, this would be, I don't know, a few weeks, if we want to do something safe and reliable, 24:27.200 --> 24:35.280 I, in Rust, it took, in two weeks, we didn't have the, we didn't understand the language itself, 24:35.280 --> 24:41.840 so we started from zero, we started from zero, so it took probably two months or something, 24:41.840 --> 24:47.040 but yeah, the customer was, was okay in the Rust Foundation, so thanks to the Rust Foundation. 24:49.840 --> 24:55.760 Yeah, hi, thank you for the talk. Our question is about hardware abstract abstraction, sorry, 24:55.760 --> 25:02.400 yep, in the hypothesis of a new hardware version, what would,