 Hey everybody. My name is TJ Vantol and along with me, as we'll be up here in a minute, is Zach Fields in the front row. We work for a company called Blues. We'll talk a little bit about what we do at Blues here throughout this talk, but this talk is about a journey and specifically a journey from Arduino to RTOS. Now to explain what we mean by this, I want to talk a little bit about my own personal journey. I am still relatively new to the world of embedded to the world of IoT and everybody here in this room either currently or before was in that role as well, where you're first getting into this world and you know that this world is complicated. You are inundated with different boards, different languages, different ecosystems, different frameworks. There are all this stuff out there that is all very confusing and you're wondering where do I get started? You're looking for really simple guidance, mantras, truisms, anything that you can trust. And one of them that you'll find over and over throughout this world is that for beginners or for people that really don't have any idea what they're doing, your happy path to getting started are platforms like Arduino and the Raspberry Pi. And then conversely, once you really are an expert, once you know absolutely what you're doing, then you're ready for the hardcore stuff, right? You can bust out an RTOS, you're ready for serious stuff, you're ready to actually build and deploy serious applications out into the field. Now you'll see this sort of advice repeated all sorts, basically online in a number of different places. If you just do a very naive Google search for getting started with the IoT, you'll find this Udemy course that very much lays out. All right, you're on the happy path. You're going to get started with Raspberry Pi and Arduino. Microsoft's IoT for Beginners Guide, which is really excellent, but it is, again, very focused about Arduino and Raspberry Pi. If you are a beginner that has the misfortune of Googling how to get started with an RTOS, I just checked a couple days ago. This is the first result. This is a Udemy course that will make you quit just about everything you're doing because it tells you about understanding the internals of an RTOS kernel. It talks about schedule or just talks about events management. It makes you think as a beginner, as someone knew that this is a scary world that is very overwhelming and something that you really probably don't want to get involved with at least at first. This talk is, oh, actually, I also, by the way, asked our future robot overlords because I was curious what they had to say about it. And they also concurred that, yeah, Arduino is definitely for beginners and RTOS is not. This talk, though, is about showing that throughout our experience, through my experience, through Zach's experience, we found that things aren't quite so simple and we want to dispel a couple of different myths. The first is that platforms like Arduino, like the Pi, aren't only for beginners. You actually can use them to build real and serious stuff in certain situations. And more importantly, that it is a myth that these RTOS platforms are really impossibly complex and only for the serious people building serious stuff. And really, the big thing that has helped change this is Zephyr, because Zephyr occupies an interesting middle ground where it is more approachable for people that are getting started and yet maintains the ability to build more complex and real things for people and for applications that need that behavior. What we hope you get out of this talk is, first of all, just a little more confidence that using something like Zephyr is possible and we're going to give you some guidance for what we feel is the best path forward. We'll talk about when an RTOS is a good fit and when we do think that it's overkill. And you'll hear of some of the pros and cons of Zephyr in action. We've done a lot of work with bootstrapping our own Zephyr projects and we'll share some of the knowledge we've gained through doing that. Now to give you a little bit of a background and why we care or why we're involved or why you should maybe listen to us at all, I've got to tell you a little bit about what we do. So we work for a company called Blues. And at Blues, we try to make development easy for all of you. We want to help, we pride ourselves on making all of the IoT, the embedded experience, as easy as possible. The primary way we do that is we make a product called the Notecard. This guy up here hopefully can get a sense of how big that is compared to my hand. The Notecard is a low power system on module. It's really a, it helps you with global cellular and also GPS. The Notecard's claim to fame is that it comes with 500 megs of cell data in 10 years of service, meaning you don't have to worry about signing up for a cell provider or have any sort of subscription fees. The Notecard has a JSON API, so again, we're trying to make things easier. Instead of having you work with a cellular modem directly, you instead send JSON to the Notecard over serial or I squared C. We work with a number of different cellular platforms. And importantly for this talk, we make a bunch of open source firmware libraries for working with the Notecard in environments like the Pi and Python or Arduino, C and Zephyr. If you want an easy way to think about the Notecard, you can think of it as a device to cloud data pump. So the Notecard knows how to talk to a secure cloud backend that we call Note Hub out of the box. And it just provides a really easy way for you to work with cellular data. If you want an even more reductive way of thinking about the Notecard, it's really a simple way that you can just bolt on a Notecard onto any project and start working with cellular data as easy as possible. Now the Notecard has an M2 edge connector, this guy on the bottom here. And you can either spin your own board around the Notecard or we make a series of development boards that we call No Carriers. The No Carriers are designed to be easy to plop in a Notecard and start using it alongside other developer conveniences. So you'll see some of these have JST connectors for things like battery and solar, quick connectors for working with quick peripherals, USB for power. We have integrations into the Spark Fund Microbot ecosystem or as well as the Raspberry Pi. But the sort of overarching thread is these are just development boards where we really want to, to our core mission of making things easy, want you to be able to get something from our store, plug it in, start working with data, start sending data over cellular as quickly as possible. Now over the last year, a big initiative of ours has been to take this one step further and make a series of accelerators. So if you're the multitasking type of person, you can even start to check these out. If you just Google blues, accelerators or go to blues.dev slash accelerators, you can check these out. These are a series of fully documented reference applications. So it really is designed to be a project that you can download, start using and get up and running within honestly a handful of minutes once you have the hardware. All the instructions are open source. We offer open source firmware and in some cases for some of these projects open source reference web applications as well. It really is kind of a starter kit to get you up and running fast. Now this is relevant to this whole discussion of Arduino and Zephyr because although we want to be like a multi-purpose, we want to work for everyone, right? We want everybody to be able to use the note card. We also can't create a sample for every development platform out there. We could lock Zephyr in the basement and tell them we need a Pi version of all these, a Zephyr version, a free RTOS version, but then we'd never see Zephyr again and that really wouldn't be fun, right? So at some point we have to make some decisions and that's where sort of our research that's played into this talk comes in because we've built some of these accelerators with Arduino, we've built some with Zephyr, we've built some with some other platforms as well and so some of the guidance that we're offering from this talk comes from this experimentation because again remember that our goal at the end of this is to produce something that's easy for all of you to use. We want you to be successful. We want you to like blues and have a happy experience from going through all of this. So for this demo we're going to focus on just one of these accelerators, a temperature and humidity monitor. The main reason we're focusing on this one is because this is one where we have firmware that we built for this project in both Arduino and Zephyr. So it's great because we could do a little bit of comparison and contrasting. The firmware for each does the exact same thing. It's a pretty simple project as its name implies it monitors temperature and humidity but it has some more advanced functionality where you can set thresholds in the cloud if you want to get say like alerts or alarms if the temperature exceeds or goes below a certain value same with the humidity. You can do things like manage fleet of devices and manage these values for these alarms across large fleets and you can also get alarms created related to voltage like low power USB power those things as well. The hardware for this project looks a little something like this. I have it on my desk up here monitoring the the temperature up here but it's a little bit easier up to see up here. This is what we offer and what we call our blue starter kit. So this is the note card. This is one of our note carriers that we call the note carrier F. The F is for feather because it has this is no carrier that has feather compatible header sockets and this is a microcontroller we make called the swan microcontroller that has an STM32 chip on board. The microcontroller can accept Arduino firmware, Zephyr firmware, Circuit Python so it gives us some options for what we want to build and for this option or for this project this is going to be the MCU that's going to hold the firmware that we're going to flash to and that's going to drive this application. And I want to show you a little bit of what this app looks like. So this is the Arduino firmware. This is something later on this is all open source on GitHub and whatnot but I'm just going to point out a couple of quick things. So the core of any Arduino app is loop and setup and I'm just going to quickly go into each. So if I go down to setup the core of setting up the note card is in here. When you set up a note card the main thing we need is just a unique identifier from our cloud service so the note card knows how to speak to note hub out of the box we just essentially need to know what project you set up to send that data into and then we also need you to configure different things about the note card like how often you want to sync data so there's two different modes the note card operates in one is continuous if you're not really concerned about battery power and you want data flowing as fast as possible you can put the note card in continuous mode but for something like a temperature in humidity monitor you probably don't need to be taking continuous readings more likely you were taking periodic readings and so the note card will idle in a low power state which we'll use about eight micro amps while idle and then at an interval you configure which is what this outbound flag is it'll fire up the cellular modem it'll sync and reconcile everything with the cloud. Now all of this is built using our Arduino SDK for our for Arduino so these J methods are just some conveniences for working with JSON because the note card speaks JSON under the hood this is just formatting up a JSON request through hub.set to do the configuration for this note card. If I go a little further down that's our setup the actual loop for this project is also pretty simple there's a little bit of a time gate to set an interval for how often you want to take sensor readings and once you've read that interval or passed that interval we're going to take a sensor reading from the bme280 sensor so there's a bme280 sensor connected through a quick cable which is going to take a reading and then there's a call here to publish the system status which is up here which is going to do one additional note card call in this case a note.add note.add takes an arbitrary JSON body oh this is the the sync one here's my body up here where it's going to take the temperature and humidity reading and send that request to the note card which then the note card is going to sync up to the cloud at the interval that you can figure. I think this is a little bit easier to see if you just look at the readings coming through in our cloud service so if I head back here and open our cloud app note hub and I go ahead and refresh so we can see the latest readings coming in so each of these sensor readings I have this configured to send data in like every two or three minutes because this is a demo in reality you'd probably have your monitor taking readings every hour but we want to see data flowing through fairly quickly and if I look in my data in my body we can see the temperature in this conference room which is actually kind of much colder than it was out over by the booth. Now the final piece of this equation with note hub just to give you the full picture of what an accelerator looks like from here you can take your data in note hub and route it to wherever you want it to go so we have a number of preconfigured routes for places like different big clouds like AWS Azure you can send it to your own server you can send alerts through Twilio you can send MQT there's a lot of different options you can take for this project we just have a quick dashboard set up through a platform we like using called data cake and the cool thing about data cake is it just lets you set up really simple dashboards so that the full data flow becomes your collecting data off the note card it's being synced at a regular interval up to note hub note hub then routes that data up to this dashboard so you have a really simple way of getting data flow in your project to build a really simple accelerator and really that's about it like I said if you look at GitHub you can see the full source code for this Arduino app and to bring this back around to the points we are making in this talk if I bring this back up this is really one example of a project that because it's relatively simple is totally yet totally manageable to do in Arduino we've seen our customers and our users use this sort of app completely fine because there's no real complexity going on here that's making this app particularly hard to use that doesn't mean though that Arduino is perfect there are definitely some limitations that we have hit in while building some of these and to talk about those limitations I'm going to bring up my co-worker and our local Zephyr expert Zach Fields so Zach sort of spearheaded the Zephyr development of our note card firmware and has also been involved in some of our accelerators so Zach I'm going to literally pass the baton over to you to take it from there all right thank you TJ hi I'm Zach I hope that I can fill the billing I was just given there so to give you I'm a developer of blues I've been working there for three years and I've worn a bunch of hats during that time recently I'm working on the developer experience and just like TJ said I've been working a lot with Zephyr and specifically trying to make it easy for the note card to talk to Zephyr with no real trouble beyond just a simple API calls that you would be used to doing in Arduino so the and so today I'm here basically to break down what the difference was to Zephyr to maybe demystify it a little bit and show you that it's not really a scary leap to go from Arduino on to Zephyr and it can be done really simply but then you get an enormous benefit as complexity comes into your application so before I get into that I'll give you a brief history about myself my my journey that starts all the way back about 10 years ago in Microsoft I was on the Windows embedded team that did Windows IoT and that was really kind of a code name for a group of us who were getting together to try to understand why Arduino was so popular and to skin Windows 32 with the Arduino API app to lure in people to kind of seize all the excitement around Arduino from there Windows 32 is sort of deprecated in favor of Windows 10 which everybody in my department hated and Windows 10 has its own unique .net style APIs and we were really committed to Arduino so we ported everything over to Windows remote IoT and then we even had Massimo Banzi himself come and lay hands on the code and give it its blessing or his blessing so that we were official in the maker world so I'm saying all that to tell you that like I am truly a believer in Arduino and I didn't come up here to bash on it or tell you why it's lame and you need to be on Zephyr it is a truly powerful system that has an insane amount of value all right so quickly just kind of recap what TJ just told you and and then we'll move into where that starts to run into the edges of its usefulness so first off Arduino as we know is fast and easy it has a completely intuitive API that is simple to use and it has a million libraries that you can just almost plug in anything and get it running in no time it's hard to compete with that it's powerful you can literally I feel like literally do anything with an Arduino and there's no real stopping you doing one specific task it's only when the task grows that things start to become a little harder to wrap your hands around it has broad support that's another thing that's a huge benefit to Arduino it runs on almost any silicon even windows 32 just like I told you and it has an enormous community this is this was the reason Microsoft even cared they were five million strong almost 10 years ago it's just an enormous group of people okay but the reality is Arduino has a dark side if you've ever tried debugging you have a really disjoint experience for the first I would say 10 years there was no debugging Arduino IDE did not support debugging at all out of the box and so you were left to print out statements which is useful but whenever you have a problem deep down in your app it is almost impossible to cipher it out and now we're at Arduino to point whatever and they they do have debugging now but it's for a selection of their boards not even all of them they have to be genuine Arduino for them to work at all and it and some of the old AVR boards just don't get debugging and certainly expressive does not get it to my knowledge nor does stm 32 or any of the things I've been working on lately there are ways around this the vs code extension for Arduino allows you to use the plumbing inside of vs code which you then can set up debugging but that is not a simple task and you really need to understand visual studio quite deeply to be able to set up this type of debugging and then finally there is platform IO that has somewhat come to the rescue and they put an abstraction over it and has made it reasonable but when it fails it's magical and it fails catastrophically another problem is a good benefit and a problem a double-edged sword if you will is the Arduino library system it's powerful but also really inconsistent so you have multiple authors that makes it the quality of the library is really the quality of the coder that wrote it and so when you have someone who might have been their first year of university and they just wrote up a quick library and stuck it out there it may not be something you want to go to production with but you know on the contrary you could have someone from Bosch writing a driver and it's completely perfect you don't really know also another problem whenever you're trying to get into production is each library has a unique license this is a sneaky one and you don't really think about it when you're writing up that app but you may be forced to open everything whenever you need to keep something closed so that you can make money and also there is no guarantee of portability people generally write a library for themselves for their hardware and so while it does tend to work across a lot of them it won't play with everything and then finally probably I would think the nail in the coffin for Arduino in a professional setting is that the complex code any complex code is not particularly portable or maintainable the Arduino API is rather small so the officially supported stuff fits on a single webpage that you can look at all in one screen and that's your digital read digital write analog read analog write pin mode etc those are the things that are portable across everything but whenever you start to get into radios or you start to talk about threading these are non-existent and people automatically drop down into the howl of whatever respective board that they're working on so let's say you started a project on an expressive but then you ran into difficulty and then you decided you need to go to st so that you have some facilities that maybe weren't there on the expressive chip well now you're going to be rewriting a large portion of your code because it's just simply not portable this is where zephyr comes in to save the day so what you've got is zephyr is an RTOS I think I've got it written right here yes they support and so you get all the great things about an RTOS you have native threading and timer support you're not relying on somebody's kernel that they effectively wrote as an Arduino library uh testing is a first class citizen in art sorry in zephyr so they have the twister framework and all of their libraries have testing and the testing is not not a second class system but it's right there and it's something that you'll need whenever you really want to move into production also support for debugging this is handled by their west build system you can debug and then you have I mean exactly what you need to do professional development and you have to be able to do step debugging also several of the sensor libraries are native so you don't have to rewrite them and I mean several of the Arduino ones that is so like for example the BME that we're using today has a native zephyr implementation so this isn't just something that somebody's thrown together like Adafruit or SparkFun or whomever this is a real driver that is supported by zephyr and has tests running to prove it out at all times so it's an incredible difference again when you're in a production environment that goes well beyond a prototype and so with all that awesomeness you're expecting you're waiting for the other shoe to drop and you want to know okay so then why would we all not be using that or why it has to be hard to get all of this benefit well I'm going to kind of walk you through that and then kind of show you that maybe that's not true at least not as much as you think it probably is so first off the basic looping we all know the empty Arduino sketch there setup and loop super simple obviously that can be immediately replicated in zephyr as a main and an infinite while loop so anything above the while is set up and inside the while is loop and I will show you that in an actual like well in a sketch soon okay so that's not scary that's actually I would call that identical really there's nothing different there okay so let's talk about blinky let's let's dial it up a notch so what we have here is on the Arduino side we have the standard pin mode we're going to set it to an output and we've got an alias for the led and that's just part of Arduino and then we go into the loop we turn it on we wait we turn it off we wait we turn it on we wait you get it all right and so now we hop over to zephyr ignore the first line it's ugly and so just kind of blank that out the screen right now hold your hand over it and then let's just look at the main loop really quick all right so I see something called GPIO pin configure that sounds a lot like pin mode and I see something called led so that's not scary and GPIO output active okay I can put all that together that that's almost exactly the pin mode instruction and then when I look down in the while I'm going to see pin toggle and that's kind of cool because the RTOS is taking care of remembering the state so that you don't need to keep that in your app and or you don't need to specifically say it's high or low you just want it the opposite of what it was so now we just have toggle and sleep for a little bit and then flip and flop okay this is great now let's get ugly and talk about that first line so what I see if there's a bunch of gross stuff I actually hate macros as soon as I see them I start vomiting in my mouth I need like a protector over my keyboard uh so the the let's go to the innermost part of the parentheses and I've got a dt alias led zero that's device tree is dt and so the device tree is magical and we're going to talk about that on the next slide uh but the alias is for led zero so okay that's led built in still not scary and then I see GPIO device tree spec get led and it's a GPIO spec so we're going to pick those up and then we just call that whole thing led and then now we're going to use it below as led so that wasn't too bad but we'll keep moving okay so the device tree in zephyr's own words they use device tree to describe the hardware available on its supported boards as well as the hard board sorry the hardware's initial configuration so what does that exactly mean for you well this is what the device tree looks like when it's printed out it's really gross and huge but you don't actually have to ever touch that and the really cool thing about it is they have device tree alias files so if you don't like the way the board is initialized then you can just alias over the handful of pins that you actually care about and give them a default position or a different mode of operation whether that's i squared c or GPIO your choice so really it's magical you don't write it and it's what abstracts every board away and allows the actual logic of the RTOS to run really deep unlike Arduino which is superficial and very thin so this is why it's so portable across so many different boards because the device tree abstracts the board by giving it a physical description and files that you do not have to maintain and then on top of that you have an entire runtime that is consistent across every single application okay so this is kind of the idea that you need to think about when you think about the complexity of writing a zephyr app versus an arduino app i'll give it to you that the original the early arduino apps when they're very simple or very much less complex than zephyr apps but that's going to flip flop so what you see here on this is you see a exponential curve for arduino so as it grows in functionality the complexity becomes untenable and then you see a logarithmic curve for zephyr and so as it grows in complexity uh or sorry as it grows in functionality it's actual complexity levels off rather quickly and then maintains about the same um difficulty throughout so in the very first example of just the basic setup and loop just the the most core functionality i'm putting those together down at the zero and then you saw blinky it had the one ugly line so zephyr is showing that it can be a little uglier than arduino and it probably is maximized at a single sensor sketch so whenever you're looking at maybe just reading a bme and logging out that data that is incredibly simple to do on a arduino and it requires a little bit more thinking on zephyr but normally you don't stop at just reading a single sensor unless you're testing that sensor you want to really build a full application so when you look at our demo where we're controlling a note card this is where it starts to reconverge and so to push this over the top we're going to add a little functionality to our demo remember it's reporting temperature and humidity so what we're going to do is we're going to add an actuator to that because normally when you get a temperature information maybe it was a greenhouse or a warehouse or something where it can't get too hot and so you want to turn on a fan typically so that's a normal thing that people normally do so uh so then let's move over to getting started uh so so let's let's jump back into the code but we're going to look at it as a zephyr app but before we get into the app part we'll talk about getting started with zephyr i don't know it's really not that hard but look at it i mean that doesn't i'm not feeling like that's super easy right now either so uh the first thing i did when i saw this was kind of another one that was like whoa and uh then i jumped over and decided that there's a way easier way to do this and we've made an open source container a dev container with vs code where we took all the toolchain and dependencies of zephyr kind of canned them up inside this container and then you can clone this down you don't need to use it for our stuff you could use it for anything i would highly recommend it because it everything is together and consistent and then you can use this from vs code you can use this from uh yeah pretty much you just use it from vs code and then you have the ability to compile debug deploy your application everything you need and like i said it's docker so it just pulls everything down it's incredibly simple but hit this url just to have a look because like i said this doesn't have to really do anything with blues this is super helpful for just you getting started it's just a blinky app where it sends a message so delete the message out if that's not what you like all right so let's go back to that demo so uh i'm going to spare i probably already bored everyone to death so i'm going to spare you me actually digging through vs code which is horrible and i pulled out like the good stuff so number one you see up in the high corner i emulated the arduino runtime like i told you before everything above the while loop is set up and inside the while loop is loop so i literally took tj's code pasted it over there and made this extra like main function it just runs the arduino like it wasn't tricky at all the only thing i had to change was the header file that you use for the library of arduino is switched over to the header file that comes in for zephyr and then the way we talk to the bme with zephyr is slightly different but as you can see here it's actually not very difficult at all you just ask if the device is ready and then uh and you and you print out that it is ready and then uh you come in and you read the sensor which is a fetch uh and you tell it that you're looking for temperature and humidity it comes back as doubles then you do what you will so it looks slightly different not difficult and even the bme is i think wrapped up in the device tree as well i think that's what we're seeing here i don't see the word dt in there but i'm almost positive it is so all right and then to add in this actuator this is what the reason they would actually be somewhat complicated in arduino is because um it's uh what would you say it's asynchronous and that doesn't work very good in arduino as if you're an arduino programmer you already know you can have an interrupt and then you can have it set a flag and then you can check the flag but you might be doing something else at the same time and so you actually have to wait until you finish that to get back around to check the flag uh normally that's not a huge problem but also it's not exactly what you want always because you can't set a priority you just have to let it ride uh so to set this up in zephyr is not really difficult at all so you're gonna at the yellow start at the yellow part um that is configuring the pen as an interrupt so that's not hard to do either so it looks a lot again like arduino and then down at the green part I know this is incredibly tiny but I just really wanted to fit all on one slide so just trust me about what's in the boxes and you can download the slides and look for yourself later but that's where we're gonna bond it's like two lines of code that's where you'll bond the interrupt and the callback and then uh up in the top that is the actual asynchronous callback itself it's really neat the way that it works in zephyr because instead of you trying to catch a real interrupt and do work inside of there they have an abstraction of a work queue so that you just say okay I'm in the interrupt queue this work and then it will set it on the batch and then it will run as soon as it gets uh processor all right so we're not ready for that yet all right so now let's see it in action so I didn't have a fan because that's boring and it actually it's really not hot in here either so maybe it'd be turn or we'll say that it was too cold we want to turn on a heater so all right so then what I did instead was I thought let's have a confetti cannon that we're gonna turn on instead of a fan and let's do something fun let's see here we go so I'm gonna here refresh this all right everything's live oh one second all right we're gonna tempt the demo gods and we're gonna let them shame me publicly in front of all of you but here we go so we're gonna fire the cannon instead of turn on the fan and see how it goes there's that and now it's going through the internet and I should get a shower any moment now any moment now this is I wouldn't have it any other way honestly this is let me see if I can go to note I haven't fired off manually really quick here so the way that it really looks if you want to do it from our cloud is you can actually interact with all these devices themselves so I can go to the actuator here I wonder if I've ruined my electronics I don't know so uh and then we will whoops I'm at one too far you can just highlight it and then we'll say note and I just set this to go off with any valid JSON and so hopefully now that one will come down and I get a shower well it's in a continuous connection so the it doesn't show up on that but I don't know it I've got I've got some blinking up here but not the kind I want and it should but all right so it's the demo that's how they go and it will surprise me and I'll follow over whenever it comes but thank you guys for coming and let's uh go on your Q&A can you go back to the last slide yeah here you pop that up yeah so again if you want to check out any of these accelerators you can head to blues.dev that's where all our resources is all of this is open source and whatnot as well we're also we have a booth here so if you want to see this fired up we're going to go to the booth like right after this and figure out what the hell just happened so if you wanted to be a part of that come hang out we'll figure this out we can talk a little bit more about how this how all this works but we do I think we do have a few minutes for Q&A I'm getting a thumbs up so does anybody have any questions and if you do there's there's mics on the side of the room too yeah yeah so the question and it's hitting the button I'm just just getting very nervous right here I don't know what he's connecting the question I'm gonna try to answer this with a straight face here but the question is can you go to like your cloud directly and the answer is no so the no card is programmed to basically connect directly to note hub that's partially for security reasons because we connect we communicate off the public internet so if we have like a VPN directly to note hub and note hub is really just then a proxy that you can send your data from there so yeah yeah so the question is can you have like a custom server and the easiest way to do that is within note hub if I go in to show the different route types the simplest way is you could just create the world's simplest route where essentially it's actually your computer not where's the general oh yeah there basically just a general HTTP so basically you could treat note hub as a pass through you get some cool things though too because you can filter different events so you might say only certain events I care about filtering to this server we have some demos at our booth too where we have somewhere it says okay this is this is my just data flows to send this to my AWS or whatever but this like I'm gonna look for conditionally if the temperature is above 80 oh that's bad I want to send it to Slack or Twilio because I need to to notify somebody because something's going on and needs to be looked into so you get those sort of granular controls you can also filter by like certain devices maybe certain fleets of devices to change where you want your data to go another question over there yeah so he was asking what mechanism is used so that we are certain that the message has gone from the Arduino onto our cloud so it doesn't happen inside of the Arduino itself what's happening is you're talking to the note card over i2c so the probability that you're talking to it correctly is extremely high and you do get a response back that it successfully accepted your message then the note card it has its own co-processor so there's a queue on it and then that queue is loaded and the message isn't queued and then what you have is it will it has logic that you can either configure yourself or is has its own default settings to retry if there is a failure and it will synchronize the queue on the note card with the queue on note hub and it will try over and over again until that's completed so it normally goes through first time obviously no problem but in case there were you were in a spotty connection or something like that then it handles that just well we're out of time okay so yeah any other questions we'll be out we have a booth down there and thank you so much