So, this is going to be a talk about writing the upstream wave of Zephyr and developing an out-of-tree application and how to keep it in sync with upstream. So, I just want to do a quick introduction. So, Lunaro is the company that we all work for. It's a collaborative engineering organization that's kind of focusing on ARM solutions. The group that the presenters are working in is Lunaro Technologies. They're a small team inside Lunaro. We focus on taking open-source software, making it better than applying it to a real world solution. So that's kind of what we're all about. So I'm Tyler Baker. This is Ricardo and Michael. They're going to be presenting kind of a co-presentation today because we've all got kind of different parts and different perspectives. So if you're interested afterwards getting in touch with us about anything, we've got links here. These slides have been uploaded so you can grab them off the web and follow us or send us messages. So what are we building with Zephyr? It's pretty simple. So we're building an application that delivers firmware over the air to real hardware and multiple MCUs when we talk about hardware. So we want to use the latest from the Zephyr project and it's been successful but it's also been difficult and that's what we're going to talk about today. So what hardware did we work on? So these three platforms are the ones that we've mainly been focused on. They're all ARM CPUs because that's what kind of Lenaro focus is on. So two of them are 96 boards which is part of our 96 board program. The other ones at NXP chip. All of these are supported to some extent upstream in Zephyr. So we had a hand in some of that and the K64F was pretty well supported when we started. So how does this firmware over the air app work? So really what we're going to talk about is this part of the equation but there's a lot more pieces than just the Zephyr part. So we're talking Zephyr, our Zephyr application talks six low pan to the gateway. Our gateway joins devices with a service that we wrote so it can search out beacons or search out MAC addresses and add them and then we can start to communicate over IPv6 to the gateway which then turns it from IPv6 to IPv4 to talk with web services. As we were going along with this demo, we've been working on this for about six months now, we realized none of the cloud services natively support IPv6. So the IoT devices endpoints can't talk directly to these services. So we have to kind of do a little bit of six to four tunneling to get things to work. So that's kind of the architecture of what we built and we're really just going to focus on the far left piece today. But if you have any questions during this presentation and we have a small enough group, just go ahead and stop me and throw your hand up and we can talk about it. So the question is, is this implementation that we're going to talk about open or closed source, it's all open at the moment. And I intend it to be that way for the foreseeable future. So let's get started. Okay, so let's talk about what our project goals are here. So we want to support delivering firmware over the air. What does that mean? Well, we have to have an AV partitioning scheme. There's been lots of presentations at ELC this year about AV partitioning. So it's really not much different than that but it's doing it with Zephyr. So we basically download firmware to a scratch partition and then we have a bootloader that will go back, cryptographically validate the images and if they succeed, we'll boot into them. If they don't, it rolls back. So we have all that working hardware. We wanted to support all the MCUs that we listed before. Technical debt. Zephyr's moving very quickly. We want to keep our patch set low and rebase on upstream master as much as we can. So that means upstreaming all our platform code and keeping application changes in sync with upstream, which sounds easy to write on a slide, very difficult to do in practice. And then quality. We want a testable design when we're building this because we want this end to end solution to continue to work. And it's something that we can use to help fix any issues that we may find in Zephyr so that we have something that's open source that works. And it's a real world use case that we can test with. So we want to also automate all the things. We want to leverage as much automation as possible to keep the work, the manual labor of keeping everything in sync kind of make that easier. So I'm gonna have Ricardo come up and talk about things that we're missing when we started. All right, good morning, everyone. So I'm just gonna talk quickly a little bit of the challenges and the work that we did when we started this. Tyler showed the tree boards that we wanted to support at that time. But we're kind of designing the boards as well, especially the 96 boards kind of in parallel when we're trying to decide what we're going to do in the software side and the project itself. So the first thing that we had in our mind is to try to get it supported by Zephyr. We were targeting Zephyr, so we like to get back and see like the MCUs were supported or not and get that in place and see kind of everything else that was missing in there. So we can actually try to focus a little bit more on the application side. So some of the things that we found out is the usual lack of harder because the project was quite new and recent at that time. At least in particular with ARM, there was not many MCUs supported by the project. So we had, especially on the carbon here, we were using two different MCUs, one just the main application based on MCUs like the STM32 and the one NR51, just simply providing the Bluetooth part of it because the main MCUs doesn't provide Bluetooth by default. So we kind of had to think and know how we're going to get that supported and how we're going to get that to work with Zephyr at that time. So there were several complications. We had to contribute a lot as well, especially kind of nearly they should get all of this going. And there's no, for example, there was no specific boot loader supporting Zephyr at that time, besides simply the realm that was available in some of the hardwares. And as Tyler showed up, we wanted a boot loader that could validate the images, swap the images and so on and also be generic across multiple harder. So we didn't have anything in Zephyr at that time. We were looking around and not our tosses. We did find a project that had that already kind of in place, which is what the runtime guys, like talking about like yesterday, we now kind of have sorted that out as a common boot loader. And also some of the things that we found at that time, like even though, like for example, Nitrogen, which was an RF-52 base at MCU, was supported the readiness effort. There were several things lacking in me saying like, for example, the flash driver wasn't in place, even GPIO wasn't kind of well supported. So I had like to do several fixes across the boards that we wanted to use and besides just simply including hardware support in that case. So and then after, I think like two or three months, we were working and trying to get to kind of was our first milestone like in connect last year and like in September, tried to demonstrate. They know like go through like those project goals and try to show up something like showing the update over the air basically with those boards that we wanted. So we simply focused on carbon and Nitrogen at that time, simply because we were like also demonstrating the gateway and having the conversation over Bluetooth 6 low pan. And what we were able to demo in there was at that time was based on Zephyr 1.5, like I think 1.6 was released a few, like far from that date that we had the demo. We were able to demonstrate the entire Bluetooth support over 6 low pan and getting the device and talking through the gateway to an open source cloud-based service. Another service, but like the server based on Hockbit, using one of the 96 boards, Community Edition boards as gateway. In that case, we're using Dragon board, we're using High Key now. And we at that time because of the bootloader problem that we had, we simply decided there was like no time to get that properly done in Zephyr. So the demo that we had, we're simply using the bootloader from different RTOS that was actually booting Zephyr. So it was one of the things that we wanted to fix moving forward. But and one of the other things that was nice as well is that by the time we were looking at in carbon in particular, because of the the difference here that you have a different MCU providing Bluetooth support. The only firmware that was available at the time for this MCU was like a proprietary firmware, which is called its soft device, which is also like containing a proprietary protocol. So we wanted to avoid having to add a proprietary protocol in Zephyr. And see if you could have something that's more generic, like a pure HCI protocol, for example. And one of the nice things is that by the time we were looking at that problem, like the thing this slide went off, right, there we go. Is that Nordic showed up and contributed the whole controller stack, which was great for us. We just had to get that to work with the NR51. And then one of the challenges of course like in there is that there was no Cortex-M0 support at the time and that is Cortex-M0. So we had to first work with Zephyr to get the M0 support in place, get support for all of those MCUs, get support for the boards. And then we could actually get the carbon to be online and use the Bluetooth connectivity and so on. And by the time that we had the demo, we had still several technical dabs and several things that we wanted to fix. The first thing is of course we didn't want to use two RTOS to demonstrate our project, we simply wanted to focus on Zephyr. So the first thing is sorting out the bootloader, right? How can we get like a bootloader Zephyr compatible? Booting and other Zephyr application. The other things that we had in mind as well is that the project is moving like really fast, especially like over the last couple of months. Like a lot more contributors are joining up the project and so on. And we wanted to at that point, you know, like continue working on the application of the demo, but making sure that everything that we're doing, we're in sync with upstream and continue, you know, like contributing and testing and make sure that we simply didn't like fork the project at that time. And we still had like several changes that we're carrying our branch in particular here is I'm saying the Zephyr support, the slave support as well. So there's like some discussion that we had like on this over the past few days and we hope like to get disordered soon, to get this merged up stream as well. There you go, the slide went off again, all right. So and also like we wanted to be prepared with the core changes that are going to happen with Zephyr 1.6 and 1.7. One of the things that we're kind of scared about at that time is like the IP stack that we were planning on replacing the entire IPC stack. And at the point that we had this demo, we kind of had it working with the old stack. So there's several things that are gonna be replaced over the following releases. So we wanted to try to make sure like to be aligned and getting that out to work as we continue working on the project. So I'll hand it over now to Mike. Mike was gonna talk a little bit of the challenges of keeping in sync with upstream and kind of the issues that we had after the presentation and since until we actually earned it. Yeah, it's gonna talk a little bit about the fund that we had over then, it's better now. Good morning. Yeah, it was so obviously at the end of Connect, we were in a fairly good place. The demo was mostly working, it had its complexity, and we knew what we wanted to solve. But then we had upgrades we had to deal with. And I think there was an initial sort of, hey, we gotta get everything working, Zephyr's just go, go, go. Let's get the code in, let's move faster. And then with the change to 1.6, Zephyr kind of started establishing itself and we kind of started feeling like, wow, we're really going places. Everybody kind of started joining in thinking that maybe it was a little more stable than it was, but it's still moving super fast. And so I think we're kind of entering the gold rush phase of Zephyr right now where everybody's kind of like, let's get aboard, let's go. And here's where we had problems. So obviously the biggest change that we introduced in, or at least Zephyr introduced in 1.6 was we unified the kernels. But prior to 1.6, we had the two different models. You had the nano model and you had the micro kernel model. And we obviously had code that was out of tree. We were using fibers and we were using all of the previous APIs. So immediately we had to start adjusting our code, which wasn't in the source trees so it took quite a while to bring that back up and then came the IP stack. So what could possibly go wrong? It's a new IP stack, we kind of have an IP based app. When we jumped in, I think we had a higher expectation of where the stack was going to be at and I don't know whether we jumped in maybe just ahead of sort of the maintainers and where they were at. I'm sure they had use cases that they were testing. But to be honest, when we jumped in it just wasn't working. I mean it wouldn't connect, the states were wrong. There was quite a bit of debugging that went into this. I mean I think we spent three to four weeks of literally looking at TCP dumps, figuring out why things weren't connecting, adding our own tooling to figure out where the debugging was going. And so I think if it was one thing I'm pretty proud of is that we made some really good contributions to the IP stack. And I think as open source citizens, that's kind of the responsibility. If you're going to try to develop an app, you're going to stay upstream. We can all make really good contributions and get things working together. So now everybody benefits, right? And at the end of this, I think we're on a Zephyr 1.7 now. It is working and TCP is functional and it's actually in pretty good shape. It's a lot better than it was. The 1.6 was completely broken when we jumped to it. Now 1.5 was, you mean 1.5 was working okay. It definitely had issues and I can see why we wanted to migrate away from that and get to a more stable stack where we had a little more control. This was definitely built from the ground up. I mean the code was there. They had done a good job of kind of getting the base sort of structures in place. I just think that like I said we kind of jumped in a little early. They were testing UDP at the time. I think we were kind of early into the TCP phase and but it worked out. And to be honest, the maintainers were great as we were submitting patches. They were very responsive. Yeah, yeah. No, that's a good point. We were literally daily or every other day rebasing on master to try to bring in changes and make sure that everything was going to work. It was kind of an incredible, you know, it was a big switch for us. I know obviously this was our biggest challenge really to get and it was timing. When it was timing, you know, we happened to have a purely TCP based app that needed some sort of core functionality. It just wasn't ready yet. But I think it worked out really well. And I'm going to talk about problems but I do want to focus on, you know, this is sort of our commitment that when you pick up an RTOS or you pick up something that does have problems and you fix them, you need to get them upstream. You need to get things fixed so that everybody benefits. And that's so I don't want to be totally negative about the problems. I think it all worked out towards the end. Some of the other issues is obviously, you know, the documentation is changing. Things are changing so fast in the system. Sometimes you don't necessarily, it's not clear like if you're going to implement like a flash drive or if the erase needs the right protection set or things like that. And these things cause little delays along the way. So, you know, as we moved along, we sort of just little by little, you know, the whole project sort of kind of got rebuilt on Zephyr 1.6 and 1.7.  I mean, there's so many settings in Zephyr to control the memory usage for the stack and for the, you have data buffers and you have transmit buffers and receive buffers. You've got Bluetooth buffers. I mean, it's an end-to-end. I would say I really felt like the knobs doubled between Zephyr 1.5 and maybe 1.6. And so we spent quite a time debugging what were the right settings for our app, you know, versus the defaults. A lot of the defaults are still old settings versus new settings. And luckily these are getting better. These are things where as we bring up issues and use cases, you can make real changes so that maybe the next guy doesn't have to configure his app from scratch. If you have a TCP app, the defaults are better for, you know, where the TX and the RX buffers are and things like that. But these definitely cause problems. I mean, there was just kind of one thing after the other. And a lot of these issues, you know, being new to, it was, I jumped on board right after the switch. So there's a fundamental understanding of what you need to turn on to really debug your app. A lot of the errors don't print without turning on a config. So it's not maybe natural thinking, but you have to enable the debugging. I mean, you would think maybe some of the errors would print automatically, but they really, they don't. And then some of the debugging is so heavy, you can only turn it on for a little while because it actually causes race conditions and other things to kind of creep up in your code. So debugging is kind of a lesson all by itself. And then we hit other issues. So obviously our app is dependent on Six Low Pan. Six Low Pan has been around a while in the Linux kernel. But it'll come back, but we actually were hitting Linux kernel problems as well. And so there again, we have a couple patches we're looking at now. We have one already, I think that's going to get submitted. But the interface is debugFS currently. And it's almost like it's still a very work in progress type protocol. So if you hammer that debugFS a little too quickly, you can cause the kernel to crash. And there are other issues where there was a ref counting issue that got figured out. And these all kind of added to the complexity right around this time period of going from this what was seeming to work to our newer app, which is now a lot more stable. And so here we are today. We're based on Zephyr 1.7, RC1, although I believe maybe RC2 just came out. We have a unified bootloader, which is maintained outside of the Zephyr and the minute code base, but it works with both. And you have kind of a real good community of contributions there, where it's validating images. We're using real technology, real security, we've got an IP to work. There's still some probably fixes in place. I know that we actually still are dealing with like a Six Low Pan issue, where the headers are still getting modified, but that's coming. So once again, we have more Zephyr changes coming. And I think the focus is that we need to focus on master and keep as close as possible to the upstream so that you can still get the benefits of where Zephyr is going, because it is moving so fast. So down at the bottom here, this is kind of a summary of what our versus master branch is, things we're gonna try to get upstream. We have a couple of the speed drivers. And I'm gonna hand it back off to Tyler. Tell you how we're doing it. Thanks, Michael. So now I'm gonna talk about continuous integration and automation. So we just kind of saw where we started from and then where the current state of the demo is and the problems we hit along the way. So now I wanna talk about how we're trying to keep this app functional and still rebasing on master. So first thing we gotta do is we gotta keep track of the sources. So all of our code is in GitHub. So funny enough, we just decided that we were gonna integrate with GitHub because that's how our workflow works. So I hear there's talk about having the Zephyr project moved to GitHub, away from Garrett. So that seems to work well with our workflow. So we endorse it. So the Zephyr tree itself, there's three branches we're monitoring.  And then 1.7 dev, which is like our stable type branch. That's fun. Is it the projector doing that? Okay, oops. Okay, so then we have MCU boot, two branches there. MCU boots is a Zephyr application, right? So we have to validate against all the Zephyr trees up there. So the growing permutation list that we have to validate against. And then our photo application also builds against the Zephyr tree. So now we have to build it against all these branches. So yeah, I mean this is a complex matrix of just build testing this stuff. So we wanted to integrate with GitHub and have our CI there, because I don't want to force people to go to some other website to look at the results of some of the CI. So let's take a look at what this looks like. So if you go to our GitHub page for the photo app, you'll see this. This is updated live. These badges come right off of our CI server. So like our 96 board carbon on Zephyr master is failing to build. There's a flash driver patch that is in progress that Kumar is going to graciously merge here very soon. So we can fix our build issues. I already merged. Good to hear. It's like, yeah, this is a snapshot. This is an image. It's not live. So yeah, this is just, you know, okay, this is how our apps building for our different platforms that we care about across our branches. So we can see when something breaks in master and our app is failing to build, we know about it instantly. And we get, you know, when that build fails, we get an email as developers. So that's really nice. But we can also kind of see, okay, there's something upstream that's coming that we need to investigate and either it's a regression or it's something's changed that we need to know about it up front so we can get patches together in our master upstream and figure out if we need upstream or something we're going to have to hold. So let's look at the next one. So this app's got lots of dependencies. So that's on the first page. If you click the dependencies link, you'll see we have to track all of the MCU boot changes, right? So you've got two branches of MCU boot versus the three branches of Zephyr. And we've got this build matrix too. Down here is actual sanity check across all three branches. So that's just checking Zephyr. So we have this kind of at a glance for developers to look at since they're going to go to GitHub anyways and look at pull requests. So that seemed to work out okay. So what's the strategies that we use? So we need to answer some questions. How do we stay close to upstream? You know, how do we reduce our technical debt, keep our patch set small? But how do we do all of this and make something that works? Because that's the challenge. It's always a challenge doing that. So basically we have our solution is we're going to build and use automation as much as we can to kind of do the heavy lifting. So we build all the tests. We run the unit tests for applications on supported hardware.  So we actually like flash it onto devices, check that it comes up, and then test the end to end story, which I'll show you in a second. So how does this keep us sane? Well, it's changing all the time. So it's just better to detect problems because they're just going to be there so that you can deal with them and it's not a surprise. So we were actually looking to rebase on RC2 and we did some testing and there's a regression. So five times out of six, our device is update. And when it jumps to the next slot where the application loads it's just hanging. So there's an issue that's popped up just between RC1 and RC2 that we need to look at now. But we were able to kind of identify that with some of the CI and automation practices. So what do we do for pre-merge testing? So we've got it all hooked up to GitHub. So if anybody does a pull request, they're going to get this little five checks. So what are the five checks? We build the photo application. So this is the tip of master plus the pull request. So all the patches applied. Then our bootloader, we just sanity check it that we can still build it. That doesn't really, probably don't even need to have the bootloader here but we do it anyways. Then we run check pass just like you guys do on upstream Zephyr projects in Garrett. And then we actually deploy the devices. So we, these basically wait for these to finish and we deploy a bootloader and the application that the pull request represents to a device and just check that it actually comes up. And we use the test case utils library within Zephyr to create parsable output. And I'll talk about that in a second.  We're advertising the right profile. You know, it's all ready to go. It's not necessarily hooked up to a gateway and talking, you know, IPv6. But the app comes up. The Bluetooth radio comes up. That's good enough for us to just say, yeah, that's probably okay. So this is what it looks like. It's a little verbose.  And I know that's a problem in Garrett, but at least we can turn that stuff off with GitHub. So that's kind of how that looks. So how do we do the hardware testing? I used to be a maintainer for Lava. So we kind of naturally decided that, well, let's try to use it, right? So I developed an upstream to bare metal testing interface. So it's like a monitoring testing interface. So it basically just grabs the console or it flashes a device. And there's a way to basically detect start and end of test cases. You can parse the console output with a regular expression. And then there's also a new feature we added that allows you to send commands and then parse the output of that command. So if you have a shell, we have a shell application kind of built into our application. So we can poke different things and do functional testing that way, rather than just relying on the app to do all of its own testing. So we added some firmware tool support. So like PyOCD supported, DFU utils, the mass storage. I'm not really sure what to call that. It's basically where there's a mass storage device and you drag and drop an application. Well, we just mount it and copy the application over and then unmount. So these are all the devices that we support now. So fair range of actually x86 CPUs and QEMU. And then we have some whole bunch of ARM platforms as well that we can test on. So what is the job definition? I guess you probably can't read that at all. But it's broken down into three things. So deploy, what images we want to deploy. I mean, these image arcs, you probably can't read it. They're basically wrappers around those firmware tools. So it allows you, if you're gonna have to do something special with the firmware tool, add different flags, you can just define it there. And then that bracket bootloader matches this name here.  So we have ability to flash multiple partitions with this schema. So we can put a bootloader down first that does a full chip aeration and then lay the application down. And then the last step there is, okay, what does my start of the test look like? What's the end of it look like? And what's the regular expression to parse everything in between it? So that's kind of how the hardware testing looks. What's the rollout testing look like? So our CI builds are pushed into Hockbit that are rolled out to once. Hockbit's actually a deployment server, more or less, right, that manages devices. I think, who makes it? Is it part of the Clip Foundation, I believe, yeah. And I know Bosch is using it. So we decided that it's okay, it does its job, it's nothing fancy. But yeah, it uses HTTP. We didn't have to worry about other protocols like MQTT or lightweight machine to machine. So a little bit easier to go. But you can kind of see here, on the left side here is our devices. On the middle column here is all the builds. And then on this side is all the activity. So you can kind of see when firmware updates fail. It rolls back to the images, comes back online, and ready to accept another image. So we can actually show you guys if there's time left over. I'm not sure where we are on time. But we can do a firmware rollout to like six devices in my house in Seattle from here remotely. I mean, that's basically, I think, kind of the progress we've made. Our demo in Las Vegas last year was like two devices on stage. And we got one update. But now we're to a point where we can roll out to a lot of devices now and have pretty good confidence about how things are going to work. So when that comes back up, we'll talk about developer testing. So, if it actually does, there we go. So another kind of aspect of this is when you're developing something like this, you don't necessarily want to just do pull requests and not really know if it's going to pass the CI test because it can be embarrassing or it's just like I'd like to be more diligent than that. So we have a way that you basically say, here's my get URL to my Zephyr tree. Here's the branch I want you to check out, and then that'll run sanity check. So before our merges, when we go from RC1 to RC2, we push it into this thing and just see how the sanity check turns out. And if there's issues, we figure out, okay, well, we need to patch that. So we always have a good Zephyr branch that builds. We can also do it with our photo application. Since our photo application depends on a Zephyr tree, we can say, here's our photo app, here's our branch, could be any developer's branch with their tree, and against any Zephyr branch and any Zephyr tree. So then it kind of puts together, we can take RC2, build our photo application with it, and then actually test it before we run any CI tests on it. So what are our future plans? We want to have developers be able to trigger hardware tests so they can just kind of do that out of band, don't have to deal with the CI system, but there's an easy maybe command line way of triggering that. Automated rollouts for common pool devices distributed around the world. That's kind of my idea is that we get to a place where this is working good. We can really test the Canary device as well, that all of the developers that are working on this project have a gateway, 9, 10 devices sitting at their desk and a subset of those can just be automatically updated as new builds come out of the CI machine and everything continues to work. So that's kind of like the goal for this is to be able to have a centralized Hockpit server pushing updates continuously to devices. Because I think that's where you want to be for a product at some point, is to show that you can continually deliver software that's going to be stable and never really have much downtime. The other thing we're not solving right now that we've kind of neglected is that we're not delivering a boot loader over the air. So that's something that we want to do eventually. That's kind of the pain point right now is if we change something that's dependent on the boot loader, we have to go reflash all the devices. Whether or not they're in Hockpit or not because Hockpit can't deliver the boot loader. So is there any questions about this? I know there's a lot of information and if there isn't, we can do some demos that might be kind of fun. That's a manual process now. We kind of look and say, oh, the net changes were merged or the Bluetooth changes are merged. Okay, let's pick it up and take a look at it. When there's interesting stuff, typically we don't like to go more than like two weeks because then the delta is massive and the quicker the better. But it does, like we found this regression. So we know now we have to do some work to figure out what's going on. Go ahead. One thing that we're not doing yet is and we're kind of why we're doing manually is that most of the core changes are kind of, we're getting them in like a big box of changes. Like for example, the net branch related changes or the Bluetooth related changes. So we're just basically tracking master now. We still need to track like those individual branches because they change quite often and the merge when you have is like a huge merge actually. So we can kind of ping point and track what is going on in the master. But it's still kind of a little bit complicated to go back and tack because those mergers are pretty big at this point. So this is something that we're not yet covering. Okay, let's see how well our system works. So I guess we'll do a live demo because I think that's fun. So again, what do we have here? So we've got nine boards online right now, three of nitrogen's, six are carbons. We'll just update six carbons to keep it simple today. And so we're going to roll out six updates right now to devices in the field. So, and then these are our CI build numbers. So we'll just go to the bottom here and grab the latest. And so what's interesting is that the latest Zephyr build against for our platforms actually here since we track all of that stuff, it's all being pushed into HocMats. We have all these builds available. Eventually we want to be able to just roll out master Zephyr, our app built against master Zephyr. That's the idea is that we have zero deltas at all. It's all upstream and we can just take that stuff and it's very usable. So here's our 1.7 dev branch. It's lovely. I wonder why it's doing that. So I'm just going to drag them here. There's a rollout way. There's an API. You don't ever have to do this manually, but just for the sake of making it look cool. Okay, so let's just check and see what it's actually going to assign. Okay, so here's six different carbons, same build. We're going to roll them out. Before we do that, let's just take a look at the timestamps of when they've talked and what build number they're running. Just see it's not vaporware. So 934, so that thing talked to Hocbit. You can see down here, it talked to Hocbit. Yeah, well, I'm just going to show what build number's on here. Yeah, so we got build 171 on this device and all of the other ones, right? And we're going to update them to 176, just so. We're going to go up a few versions. So we'll assign them and now they go into the yellow state. Unfortunately, you can't really see the console logs and actually we can probably look at one as it's going here. Hold on, I think that's a, we shall see. Let's see, there it goes. Okay, so this is the console output on one of the devices that we just asked to go and update. So it looks like it's going to start downloading and flashing now. So all six are doing this. They're just cranking away, getting their update from the CI server. This is a UART on the, on the carbon. That's a good question. How big, do you know how big the photo app is? You're doing on time. Okay, so we can also validate, I think the experience is quite a bit smaller than that, it's like ethernet. Well, initially when we were having problems with it after the demo in Las Vegas, you switched to just using pure ethernet because it was like one less thing to deal with, right? Yeah, I mean, so all of this traffic's going over, IPv6 silver Bluetooth right now from a gateway. So we have an ARM64 gateway to ARM devices and talking to the cloud and it's being fetched and proxied through tiny proxy. So I mean, it's exercising quite a lot of software to get an update. It doesn't seem like a lot, but it really is. I mean, it's like, there's multiple players involved here and I think this is kind of exciting because we're at the point now where I almost don't reflash my devices. I'd rather just roll an update out and it's just that stable. So we want to keep it that way. And we also want to provide this reference to the community. Like, if you guys want to do over there updates for your product, we've got a good framework here and go ahead and use it and help us build on this. I mean, so we're kind of thinking about some longer term issues here. Like, this thing's an app that does updates, but that doesn't really make sense, right? If you want to develop your app that does functionality and then you just want to call a library to update, right? A service, exactly. There's like a daemon like DHCP, right? It just needs to be looking for it and then when it decides there's an update, maybe it does a callback to the app saying, are you ready, save your state? And then it says, yeah, I'm ready, here's my app. And then it starts to pull the update and flash it and lock everything else out, right? So what just happened there was our MCU boot validated that image because all of these are signed with our key. So if we set an image down that was unsigned, it would have just reverted back to the other slot and came back up. So all of this outputs what we process, right? So project execution successful. We blink the light. We can advertise the profile. All of that's using the test case library inside of Zephyr. So you see we connected to Bluetooth again. So the app's gonna delay a little bit and then start trying to talk to Hockbit and say, hey, I'm all done with my update. So now it's talking to Hockbit. Let's see if any of the other ones are done here. Whoops. And we're complete. So you see here, we've got three that have updated. The other three are chucking along, probably doing something similar. They'll be along here shortly. So we'll go back. This is all talking to the server, right? So these, yeah, it's like a RESTful API, right? And so we're just, we call every 30 seconds because the server actually tells you how long it wants you to pull, right? So we have it set at 30 seconds just to keep the devices active. It's being passed through the gateway to the service. So we're actually, the devices are making HTTP calls to the service directly. It's just being proxied from IPv6 to IPv4 via the gateway and then to the service. Polling. Yeah, so this right here, it's sitting there and like, okay, do I have any more things to do? Do I have any more things to do? And then eventually when I drag those things and say assign them, the next poll, it's like, no, I want you to download this image. And I think if you actually go up a little bit here, you can see, this is the JSON response or part of it, right? It's like, go get these artifacts. Here's the MD5 for all of the bits.  And then our app takes them and we'll chunk them and then write them in the flash kind of as it. Yeah, it's on a carbon, yeah. So we're five of the six devices, the other one. I mean, that's the other problem that we've got is it seems like when we roll out a lot of devices, some devices connected the gateway fast and download and someone, they go a little slower. So we still have to kind of look at those things, but we're able to roll out new software to a large set of devices. And really, we're actually hitting, running up against gateway, like, Wi-Fi chip kind of requirements that they can't have more than nine nodes, endpoints connected over Bluetooth at a time. So to really scale this out, we just need to start adding more gateways and more devices. Actually, we have a good deal. That's what we're finding too. And I talk to you. You can kind of get more devices online. Huh, we gotta try that because of the use of these apps. And we'll have a few of them. The other problem that we have is that not many like Bluetooth tips actually supporting like this. Like this one that's from TI, say it's supported like 10, but reliably we can only connect eight.  And you mentioned about the debug app that says API that they will say to you. And they promised to fix it.  That would be way better. Yeah, echoing stuff into debug FS is fun, but you know, like not really a production thing. If anybody saw that code today, you know. And just to see now the devices that have finished already are reporting the new version of 176. So that's the software that's running. Yeah, it'd be interesting to have more conversations around how we could, you know, take this app. The problem we're facing is now we wanna put like a different protocol with a different device management service other than the Hockbit in place. Now we do stuff to fork our own app and make those changes. So we'd rather have something more modularized to, you know, deal with the update side of things and then, you know, your application can talk to device management back ends. So are you sure that they are doing a 101 beta? Yeah, yeah, you'll have to flash drivers and partition layout and yeah, should work. Yeah, should work trademark. So you can see the boat loader here. So yeah, one of the regressions that we had is the big block fixes. It calls for a chain loading to see what happens. So that's something that I need to talk about here. So how big is the set group loader? I can look here. Most of it is like, nowadays, like the board, for example, depending on the board that you have, it's already automatically made with a bunch of things. Yes, yes, you need to talk to my app. Especially for the boat loader, you really have to remove a lot of the serial, a lot of the heavy to debug, a lot of the data. Well, then when you want to update it, you have to have another partition, scratch partition for that boat loader and things get complicated. All right, any other questions? I think we can kind of wrap this up. Thanks for getting up early, guys. I appreciate it.


I'm not sure. What's up, money geeks, Mr. V here. Welcome to another video, guys. So, in today's video, we are going to talk about Lucid Modo's ticket symbol, L-C-I-D. This is a stock that we talk about here a lot on the channel. I cover it when there's any major news. You guys know I'm a big fan, heavily invested in the stock. So, when there's news, I want to make sure that some of you guys that are investors in this particular company are aware of so there's some news that is potentially going to be coming out here pretty soon. I want to give you guys a heads up. But before we get started, guys, if you're new to the channel, we talk about how to earn money, how to save money, how to invest and build wealth. So if you have something that interests you, go ahead and hit that subscribe button and the notification bell so you don't miss out on new content. So when it comes to Lucid Modo, guys, this is a long-term play for me. I've been buying the stock ever since they started or announced they're going to go public. I keep adding. This skyrocketed, came back, I'm still loading up and keep buying the stock as I see. This is going to be a big winner for me down the road. But again, along the way, there's ups and downs and for people that can ask stomach, that movement, that up and down, some people might sell and leave. For me, when I see bottoms, it's an opportunity. I'm a scavenger. I eat from the bottom. So when I see that opportunity, right there, I just go out and try to give, if I have cash, try to buy as much as I want. But what I wanted to talk about here is not to show you guys this fancy car driving on some street in LA, but some important information because this is going to impact the stock price. Because right now, if we look at Lucid Modo that's currently trading somewhere sitting about $21. Again, this thing is just going through a much swing seat. It's gone to a high of $24. Just in the last month, we go last six months, you can see here tested 30 somewhere up there and then pulled back. And then we can see here, it went down to as low as $17. So it's been up and down. You can see it's been just like crazy. But again, this is a long-term play. So don't be short-sighted by these movements that we see. So if we just go back again today, look at the stock is down to just a little bit above 2%. But the news that I wanted to tell you guys here is something here. So September 1, I want you to mark this day on your calendar. If you are an investor in Lucid Modos, because on September 1, pipe investors can sell their shares of Lucid Modos. And again, when I say pipe investors, this is a private investment and public entity. So these are people that are invested even before this company went public. So they can sell their shares as of September 1. This doesn't apply to other insiders. So if you are an insider, they have to wait six months and 18 months after they receive their shares before they can sell it. So the only stocks that are going to be hitting the market potentially as of September 1, it's going to be pipe investors. I'm assuming that some of them might want to take some money and go invest somewhere. So you're probably going to see Lucid pull back during this period. And again, guys, if you are long-term, don't panic. This is not a situation that calls for panic. As a matter of fact, when they pull back like this, become a scavenger. Go out there, buy those bottoms so you can ride it back to the top. That's my personal take. So that is something that I wanted to just make sure that you guys are aware of. Again, if you can see the stock has been trending in the wrong direction. Again, giving opportunities for people to get in. People that are not in the stock are giving them opportunities to get in. So I'm not too worried about it. I'm going to keep my eye potentially for day trading. If I see a shorting opportunity, I might short it just for day trading. Again, my long-term position, if I make some profit shorting a day trading, I might take that money and turn it around and buy it and hold it long-term. So that's my strategy. Again, you figure out what works for you. There's been other little things in the news about the stock. There's some news that I'm going to cover here because I think it's important when they're looking potentially to start doing delivery of the Lucid A. Again, this is a luxury brand EV car that most people are not even aware of. So this is going to be the Lexus of Tesla. So again, that's just my personal take and the reviews of the cars are just insane. So I'm excited. So again, that's me because I'm heavily invested. So I might be coming from a position of bias because I'm invested in the stock. But anyways, guys, I just want to let you know that come September 1, you might see Lucid model pullback because if those pipe investors start selling those shares, you're going to see a massive pullback in the stock. But again, just like we've seen in the past, it's going to rebound. So when you pull back, if you have money, buy those dips. So this again applies only to pipe investors, insiders are not allowed to sell until six months or 18 months after merger and after they receive their shares. So that's still quite a waste. And who who want to sell their shares? Anyways, if you are on the inside or you want to sell your shares, means you don't know what you're doing. People can sell their shares with Nikola, but not with Lucid, because I think the company is headed in the right direction. Again, let me know what you think about this news in the comments section. If you're new to the channel, we talk about how to earn money, how to save money, how to invest and build wealth. So that's something that interests you. Go ahead and hit that subscribe button and the notification bell so you don't miss out on new content. Also, if you're looking to get started with investing, we both have their promotion where if you sign up and deposit five dollars, you get free stocks, links in the description. And as always, guys, do your due diligence. Don't be a great savage. Stay motivated.


Full information maximum likelihood estimation, or FIML, is a common modern technique for dealing with missing data. This is something that is available in pretty much every modern SEM software, and it produces you consistent and asymptotically unbiased estimates under missing at random. So as long as the cause of missingness is observed, this technique will deal with the problem. If your data are missing not at random, then the estimates might be inconsistent and biased. Let's take a look at what FIML does. So normally when you estimate a maximum likelihood estimates of a latent variable model or any other structural equation model, what you do is that you have the model implied correlation matrix that you construct based on the model, and then you have the observed covariances and you find the values of the model parameters. In this case we have the lambdas and the correlation of this factor analysis model, and you try to make this observed correlation matrix and this implied correlation matrix as similar to one another as possible, and those are the maximum likelihood estimates. The traditional way of dealing with missing data in this kind of estimation is that we simply calculate this observed correlation or covariance matrix using least-wise deletion, so we only use complete cases. But this is not the only way of calculating these estimates, and there's actually another interesting way of calculating likelihood that makes it possible to calculate the maximum likelihood estimates under missing data. So we don't actually need to calculate this observed correlation matrix and compare it against the implied correlation matrix. Instead what we can do is go observation by observation and calculate observation level likelihoods, or in practice we would calculate this for groups of observations with the same missing data pattern, but the idea is the same. So instead of comparing two matrices and checking if one matrix is close to another one, we ask the question how likely would an observation for one case be given this covariance matrix. So let's simply look at the variables A1 and A2. So just two variables, and if these two variables are correlated, we can calculate the likelihood of one observation, probability of one observation from the bivariate normal distribution. So we can see that here these variables are positively correlated, so getting a large value in both is more likely than getting a large value in one and a small value in other one. Also getting more extreme values, values of four and minus four is less likely than getting values that are close to zero. So we can calculate the likelihood of an individual observation from a multivariate normal distribution. Here we have two variables, but this of course generalizes to how many variables you could ever imagine, but it's just difficult to visualize this beyond two dimensions. So how the full information maximum like a estimation proceeds in principle is that you go observation by observation or you could go missing data pattern at the time and you calculate individual likelihoods. So let's assume that we have this data. So this is our example data set and we have no missingness for the first case and we have different pattern for each first five cases and then we have more data that we are not interested in. So calculating the likelihood for the first observation we simply look at these six values A1, A2, A3, B1, B2 and B3. How likely we would be to observe those six values from a population with this covariance matrix and that gives us the likelihood. Now the second observation has missing data. So what we do is that we use the same implied covariance matrix or implied correlation matrix, but we just leave the missing variable out. So we look at how likely we are to get these five values from a five-dimensional multivariate normal distribution characterized by this covariance matrix. Then we move on to the next one. We have four observed values, two missing values. We calculate the likelihood for that observation from this subset of the model implied covariance matrix. So we basically proceed this way and we calculate using the part of the covariance matrix for which we observe data to calculate the likelihood for one observation and this way we calculate the likelihood for every possible case or every possible missing data pattern. In the final case we have data for just A1 and A2 and those give us information about these factor loadings and these error variances. We can use the case even if we don't have data for the other variables. We simply compare that case against this bivariate normal distribution. So it takes a bit more to calculate using the computer, but this is generally very fast. So it's almost instantaneous using a model computer. So there's really not many downsides to using full information maximum likelihood or maximum likelihood missing data. And this is implemented in all modern SCM software and it's simply a matter of switching the estimation approach on. So you might have something like ADFWL weighted least squares, maximum likelihood, robust maximum likelihood, FIML, different estimator, simply choose the estimator FIML. There's a robust variant that includes robust standard errors and you run the software. So there's no specification involved. It's simply a switching the different estimator and you're done. So this is very convenient and it's very useful to do. There are a couple of things that you should consider. This is based on multivariate normality and like normal maximum likelihood estimates. The multivariate normality assumption, it's more relevant for standard errors and test statistics. If your data are not normal, then what you can do is to use robust standard errors. Robust standard errors have been developed for normal maximum likelihood estimates and they have also been developed for this FIML estimation technique. And they are generally available near statistical software. When you calculate the standard errors and test statistics, there are two ways of doing that and I will not go into the technical details, but there is expected information and observed information. You should make sure that the standard errors are based on the observed information instead of the expected information if you have missing data. This is generally the default, but it's a good idea to check. Another thing that you should consider is the role of X and Y variables. So X variables are observed variables that don't have any incoming rigors and paths and Y variables have incoming paths. So if you have indicators of latent variables, then all those variables are Y variables. X variables are observed predictors. The full information maximum likelihood estimation is based on considering the Y variables. So you might still do list-wise deletion of X variables. But there is a workaround to this issue, which is treating the X variables as Y variables. And this again is a bit of a technicality that I will not go into this video, but in practice, switching an X variable to a Y variable is just that you tell the statistical software to treat all X variables as Y variables and then it will use the missing data algorithm for that. The difference of treating a variable as an X or Y variable if there is full data for that variable, it typically does not make a difference. But you should be aware that the statistical software can still drop some observations. For example, in the R-package LaVanne, there is fixed X option and that should be set to false if you do missing data analysis. Another thing that you should consider is that if you have observed predictors, but then you treat those as Y variables, then the statistical software might correlate those to be uncorrelated with any other Y variable by default. And that's typically not something that you would like to have in this case. So after you do full information maximum likelihood, you should check that the number of observations that was used in the estimation matches the number of observations in your data and you should also inspect the parameter matrices to make sure that you actually estimated all correlations that you wanted to have in the data instead of accidentally constraining some correlations to be zero. Beyond these are small practical things that you should check after estimation using full information maximum likelihood estimation. This is simply a matter of changing the estimator option and then estimating as usual. So this is very simple thing to do and there is really no reason not to do this if you have any missing data.


What's going on, everyone? Sam here with Leighton Sports Guard, Drippin' 22. Miniam City in football hobby, six bucks, half case break, number six. Pick your team style. Read off a list of our names and our teams. Alex T. with the Chiefs. Anthony P. football team. Armando B. with the Chargers. Bob S. Rams. Cooper J. Niners. Daniel M. Falcons. Daniel B. Eagles. Dean I. Steelers. Greg E. Patriots. Harper B. Bucks. Henrik J. St. Bears. James H. Giants. Keelen S. Cardinals. Kevin B. Dolphins. Lenny N. with the Texans. Lindsay H. Cowboys, Lions and Raiders. Macaulay T. with the Vikings. Martin T. Bills. Mitch M. Seahawks. Paul B. Ravens. Riley D. Bangles. Ryan S. Jets. Ryan F. Browns. Scott T. with the Broncos. Scott S. with the Colts. Stephen W. Panthers. Thomas R. Packers. Jags. And Will L. with the Titans. I hope he had a product hit today, man. One-on-one picket. One-on-one Purdy. I think Purdy's in here. Pretty sure he is. Let me see. He's probably got like a rookie auto. I mean, if some of these names have one, then Purdy's got to have one. Yeah, base rookie auto and base rookie Purdy. I haven't seen any. No, I know. Yeah, they've been tough to come by here for sure. Some more spots coming in. Thank you guys. All right, we've got a Michael Carter, to 100. And Julian Chestnut, 16 of 50. Jake Chestnut. Yeah. Hey, thank you there. I think Lewis just sold us out on number seven. Thank you there, Lewis. You're the man. Let's go. We're sold out on seven. Everybody. Let's get eight filled up now. Jack Leonard. That is 61 of 125. Josh Allen for the bills. Got 25 of 99 is auto. A Samari Torre for the Packers. Got eight of 25. That is a Nick Bosa on the Magnetic Signatures. Baby Bear Bosa. Nice one there, San Fran. We've got 14 of 75 is Davis Mills on the Orange. Number two. There's Arnold Obakite, Orange, two at 75. We've got a Volcanix, Justin Fields, eight of 10. A nice one there for the Bears. Henrik J. One of the last teams taken. There we go, Henrik. Congrats, buddy. Nice Volcanix Fields. Second year. Kyla. 66 of 75 is going to be Vilish Jones Jr. on the Unbreakable for the Bears as well. A little secondary color match there. We've got left at number eight now. Got one, two, three, four, five, six, seven, eight to go at number eight. DK Metcalf. That is Equinox material or Equinox gear, 24 of 75. Of course, dude. Of course, we got Agalore instead of DJ Char. Raven's Instagram and Twitter is lighting up Nelson Agalore right now, I have to say. 59 of 99. That is A, Malcolm Rodriguez, rookie auto for the Lions. How do you let Char go to the Panthers? 64 of 175. Christian Watson, two-color Jersey auto for the Packers. Nice one there. Cal picking up the Niners at number nine. Thank you there, buddy. That's their new Y receiver one right there. No, that is not. Wait, you mean the Panthers? Yeah, that is. We're talking about Agalore for the Ravens, like absolutely not. Man, I thought the Hawks were an exhausting team to be a fan of, and the Ravens are really making their case to be an exhausting fan base. Michael Carter, orange to 75. And Rashad Bateman, purple to 100. There you go, Paul. The Marvin Leal, rookie. 33 of 75. That is going to be Garrett Wilson. Nice one there for the Jets. Five of 25. Brian Dawkins, three-color patch. That's sweet. Player of War. Weapon X going to the Eagles. Cool one there. Eagles have a really good vet checklist in this. Dude, I'm sorry, but I don't care. I don't care.  Forrest, does that go to the Chiefs? No, Forrest, go to your face. 42 of 75. Magnetic signatures. David Montgomery. Nice one there. What is the biggest hit so far? What do you say? We get a Kyle Pitts 101. That was pretty good. Sauce, RPA to 25. Bunch of color blasts, too. Yeah. It's going to be a redemption is Damian Pierce, rookie jersey ink, etch electric green. Nice one there for the Texans. Rookie jersey ink. Rookie jersey ink. Or are you rookie jersey ink? Green is the 50. To add some context here, we're doing honors first off the line case break on Wednesday. We hit Brian Dawkins that had the Eagles logo. It said Eagles on it, but it also had a little silhouette of him in the top left corner with him on the Broncos. It said Broncos underneath it. I texted the breaker group chat. I'm like, what do I do here? Does this go Eagles? Forrest is like, yeah, Eagles on the team logo. So it'll go Eagles. I'm like, all right, cool. And then I hit the Mahomes 101 auto and I sent it to the group chat right away. And Forrest was like, does that go to the Chiefs? Patrick Mahomes, six of 75. And I said, no, it goes to your face. There's Deandre Swift, supernova. That is 12 of 25. Jalen Tolbert, rookie. Packer's gone in 10. Niner's gone in 10 as well. Got to 125. That is Derek Carr. Will Duvon. Got 44 of 75. Chad Johnson for the Bengals. Nice one there. Chad Johnson. Oh, I know Shane. Sure he does. 110 out of 199. Carson Strong. Nice one there for the Eagles on the rookie auto. And 25 of 25. Sauce Gardner. Another one of these. We've pulled two of the two 25ths of this card right here. Nice one there. Yes we have. We'll mag that for the Jets. Congrats Jets. Saucy. Very saucy. Saucy card right there. Is that making you more enticed on getting a saw subsidy in Wahoos? Christian Kirk to 75. And a tunnel vision. Aaron Donald, 16 of 99 for the Rams. Amari Cooper. That is going to be 21 of 75. Dallas Goddard on the atomic material. Niner's gone in 12. Thank you, Michael. Got Sam Howell, 65 of 75. Nice one there for the Commanders. Fair. That's smart actually. Vikings gone in 10. Thank you, Colton. We've got 19 of 49. That is Jonathan Taylor on the Aurora signatures. There you go again, Colts. Colts low key doing well. And 174 out of 175. Sam Howell, rookie jersey auto. Going to the Commanders. Panther's gone in nine. Thank you there Luke. Panther's gone now in nine. Spot slowly but surely. Dwindling down. Got like a spot in this morning's release day madness. Make sure to check out the break schedule. Oh, that's nasty. Zach Wilson, 32 of 50. Vitrious. Got super short print on the Contra. Isaiah Pacheco. There we go, Chiefs. It's a big card right there. Congrats on that KC. That's really cool. That's awesome, man. That'll get put right into a mag. Nice Pacheco.  Zumir White rookie.  Thank you, buddy. We've got a 55 of 75. Devante Adams adds a sweet card right there for sure. Got the check out. Really cool. Followed by four of 10. J.J. Watt. Three-colored patch. J.J. Watt. Got 157 out of 199. There is an Aiden Hutchinson. Nice one there for the old Lions. And to finish this off here, guys, for the Bills, 165 out of 175 is Velis Jones Jr. I think so. Is it Devante or Packers? I'm assuming it was Raiders, right? Yeah, it was Raiders. And if I said Packers, I apologize, but yeah, it is Raiders. All right, guys, let's do a quick recap here. Pretty fun break as well. Really clean Contra coming out of there. Derek Cork. Josh Allen. Yep, Devante Adams. He got Raiders down there. Devante Adams. Velis Jones. Sam Howell. Dallas Goddard. Garrett Wilson. DK. Chad Johnson. Ryan Dawkins.  Gotcha. You're good. You're good. There is Damian Pierce. Aiden Hutchinson. Carson Strong. Velis Jones. Sam Howell. Christian Watson. Malcolm Rodriguez. Samari Torre. Davis Mills. David Montgomery. Jonathan Taylor. Nick Bosa. We had a Sauce Gardener 25 of 25. That is Isaiah Pacheco. Nice one there on the white Contra. That'll do it for the break, guys. Thanks again for the film. Next up, number seven, which is sold out, so thank you, everybody.


Hello everyone, it's Chi-Man again. Remember I told you before how hard it is to find a good interactive whiteboard that you can do almost everything with it without even having to use other third-party apps? Well, I think I discovered the gem and in this video, I'll share it with you. So the gem that I discovered was called Hey Hi. Thankfully, I was introduced to this recently and I would really, really recommend you to try it out because I actually fell in love with it immediately. So what you need to do is just go to heyhi.sg as you can see here. I recommend you to use Google Chrome because that is a better lightweight solution when you're using this application. So what you need to do is go to heyhi.sg, click try this now or you can even go to login and sign up. You can login with Google if you want to or you can quickly sign up by clicking this new to Hey Hi and fill in the details and then you will get an account because I have an account already. So I'm going to log in with Google. So once you sign in, this is how a dashboard look like. As you can see here, it's pretty clean without complicated navigation, which I really like because it's minimalistic and you can see here. This is the dashboard where it shows the upcoming meeting. I have none so far ongoing and finished. And then you have your library where you can store your materials, your documents and even poll questions and all that. And then you have support tickets where you can submit any question to the support team in case you need any help. There is also a notification button here, which you can see any latest announcement. This is your account. You can edit your profile and get information about the invoices if you sign up for the premium account and also the safety guide and so on. So what I like is that Hey Hi is not merely an interactive whiteboard. It's like a whole package of a live classroom which you can use for your online teaching. So in this video, I'll be highlighting some features which I really like about Hey Hi and I recommend you to try it out because it's really worth your time to explore this new tool. What you can do now is go to this section where it shows your calendar. So I pick a date, let's say today, I'm going to set a new meeting. So you can name your meeting, right, like class one and then you get to choose the meeting mode. It can be up to four, up to 12, up to 30, live stream and whatnot. And as you can see, there are different features for different numbers of participants. If it's classroom, up to four, you get to see all the participant interact using video call. And then if it's live stream, you get to share it out like a normal Facebook live or YouTube live and so on. And the whiteboard is where you communicate via chat messages. Let's say I'm going to go for the normal lecture up to 30. So I'm going to start meeting. And this is the meeting ID and access code, which you will have to give it to your participants or your students. You have to copy the meeting link and then share it out with your students through different channels like email, WhatsApp or Telegram and whatnot. Also you can also screen log for all upon entry. This is like they cannot really manipulate the screen so that they don't disturb you or you can also disable chat box for this meeting. Well in this case, I'm going to enable the chat box. So back to dashboard. Now the thing is the link is given to your students or your participants. But in your case, you have to join or start the meeting from here. I'm going to join meeting now. So before you join the meeting, you can actually test your connectivity. How good is your connection? And to me, this is a very interesting feature because in most live conferencing or live teaching tools, you don't really get this. So I think this would be really good for those who would like to check on their connectivity before they join any meeting just in case the connection is bad. So I'm going to join meeting now. Immediately Google Chrome will prompt me about this. So you have to allow it because it's allowing Chrome to access our camera and all. So right before you finish, you can actually test your camera microphone. In my case, my camera is disabled because I'm using it for recording this video. So I'm going to click finish. And here it is, you get your whiteboard as well as your webcam view here. In my case, it's disabled because I'm using it to record this video for you. All right. So it's really expandable. You can go as large as you want and really like this. And then you can even add more whiteboard if you need to have multiple whiteboards. You can just click the plus sign here. So if you would like to write anything, so you just click the pen tool here and then choose the thickness of your pen and pen tip and then the color. So let's say I'm just going to choose this color. So I'm going to write like grammar. So that's writing. You can also use the highlighter to highlight something. And there's also laser pointer in case you need to show your students what to focus on. This is the eraser, you can rub off something. You can also draw shape by clicking this button here. Draw shape. You have line, rectangle, circle, triangle, polygon. So you can just draw one. If you need to duplicate it, just click this button and then you will duplicate. If you need to arrange them, you can click F or B, F or front, B for back. Same thing for everything here. So let's say I put it front or back. You can see the difference. And you can also lock the item in case you don't want it to be moved or change or transform. Just lock it out and so on. So these are the basic features that you have. If you need to clear the board, just click the three dots here and clear board. So yep, so it's clear. Or if you have a very nice white boarding or done already, you can just download the current board or the other boards. So it will be downloaded in the form of JPEG, which you can save it. Now this is where you show your guests. At the moment, I don't have anyone. If you have another guest coming in, then you will be able to see the list of guests here. You can also set the guest setting. You are the host now. In my case, I'm the host. And you can invite people in. You can also control editing like this one. You can also control if they can speak or show webcam and chat and so on. So these are some setting for your guests or your, basically your participants or your students in this case. Another good feature in Hey Hi is you get to insert image or document for your participant or your student to interact together or collaboratively. So all you have to do is go to this button here, insert image. You can click here to find your image or just drag and drop here. In this case, I just drag and then you can insert. So this is one picture that I inserted. And you can also insert document. Same thing. If you have uploaded your PDF into your library, then it will appear here. At the moment, I don't have anything. You can also click here to find a folder or just drag the file here. So it will process it and then upload to the Hey Hi whiteboard. So you can see once it's uploaded, you get to see the pages from your PDF. You can actually select which page you want it to be displayed on your screen or you can upload everything or select all. Let's say I'm going to do one. You get an option to an image per screen means it will divide by screen or just put everything in one selected images to one screen. I'm going to get one only. And then you can also save images to folder if you want to. So you can have a folder or you can name it folder. So insert. So now I have the worksheet done here, for example. And once your students come in, your participant comes in, they can look at the worksheet together and you can discuss with them. Like in this case, if you are looking for this image as a game, then they will be able to try and find the word, for example, or things like that. And you can even use it to explain things and scribble, annotate. Or use the highlighter to highlight certain words and so on. So pretty, pretty amazing because you get everything together. You have you have the Hay-High webcam, you know, live session. You can even look at your students. You can interact using the whiteboard. You can interact with your documents and all that. This is like pretty wholesome solution for your online teaching, which without having to switch from one platform to another platform, which I think is really, really awesome and you should really try this out. Another amazing feature in Hay-High is actually this draw with touch feature in which you can generate a QR code and sync it with your mobile phone or tablet and it supports iOS and also Android. So you can download Hay-High app in App Store or Play Store and get it installed. And then click this button and you will get this QR code. So I'm going to show you how it looks like in the mobile format as well. As you can see. So once you have the Hay-High app, you just click on the Hay-High app. And click the scan QR code on top there, on top right and scan the QR code on the screen. And voila, I am in control of the screen now. So I get to see. So you can see as I'm going to close this for a while. As you can see, I'm controlling it from my phone. It's the same thing. And I can actually draw. I'm drawing this from my phone. All right. So I can navigate and can annotate directly using my phone if I do not have a writing tablet, for example, pretty cool because it also allows you to control more using your touch. You can connect it to iPad as well. So I really like this because it supports synchronous usage real time. So in Hay-High, you can also have this chat feature like the normal web conferencing tool that you have. You have you can chat here like hi here. You can share files. Pretty cool, right? And then you have poll. You can set the poll like how are you today, right? So you can set some option here like awesome. And all that. If you want it to be a quiz, then you can set it as a correct answer. If not, then just leave it be. So publish. And when it's published, your guest or your participant will be able to see the question and they will be able to respond. And then you get to get the feedback from your participants. So what can I say? You just have to try it out and get this whole new experience of conducting online teaching or online session with your participants or your students. Really, just go straight away to Hay-High.sg and experience for yourself. I would pretty much assure you that you will be amazed by its capability and features. If you need further help about Hay-High, you can also subscribe to the channel on YouTube. Just search Hay-High and you will be able to find their channel. I also provide the link to the channel down there. You might want to subscribe and look through their other tutorials to really, really experience the benefit of Hay-High. So that's it for this video. Don't forget to subscribe to my channel as well and give a thumbs up for my video. Thank you so much until we meet again.


Becoming a better player does not have to be complicated so don't make it any harder than it has to be. In this video I've outlined a five-step formula that I want you to follow and I guarantee if you follow this formula you will become a better player. First, you must believe that you can become better. You must believe that personally you can make yourself better. There's so many players that message me every single day and I get this feeling of helplessness. It's like I can't do anything to become better when in reality it's all up to you to become better. Believe me you can improve all your skills. You can improve every area of your fitness. You can become smarter if you take responsibility and put it under your own control. Instead of feeling helpless like I can't do anything to improve my skills. I can't do anything to become smarter. I need someone else to help me. Hey you need to look inside yourself and say hey what can I do to improve this? What can I do to become better at that? And if you take that mentality that I believe in my ability to make myself better and I know I can become better if I just start focusing on finding solutions rather than crying and complaining about my problems then you will become a better player. Yes it's going to require some effort. You're going to have to put in time. You're going to have to put in hard work, some sacrifice, some discipline but you will become better if you believe in yourself. If you don't believe in yourself you think you need to pay someone a million dollars or you think you need the best coaching in the world to become better then you're lost already okay. Believe you have the power inside of yourself you right there it's inside of you and when you start looking inside and asking yourself okay how can I become better I know I can do this if I just start asking the questions and putting in the work then you're already moving in the right direction. So there will be people along the way your coaches will help you trainers will help you you may get some ideas and advice from teammates and other players that you respect I will help you along the way but if you aren't helping yourself then you will not become better so that's where this all starts. Start by believing in yourself. The second thing you need to start doing right away is start playing as much as possible you may have heard the term baptism by fire and basically that means just putting yourself in there even if you're the worst player ever and everyone else is ten times better than you you will become better by putting yourself in that awkward position where everyone is too good for you you don't know what to do you can't keep up okay you need to put yourself in those uncomfortable situations because it will force you to improve I get messages from players and they say things like hey I'm really training hard on my own but I'm not on a team what are you waiting for even if you're the worst player on the team just being on that team putting yourself in that environment will force you to become better so you need to get on a team right away ask your friends do a Google search look up on Facebook okay there are different ways to find teams if you just start asking the questions like we talked about in the first part of this you will find the answers so get yourself on a team even if it's the worst team even if it's a div 5 team you will work your way up okay but you need to put yourself on a team you need to start gaining experience there is no substitute for match experience yes training by yourself is fantastic and we'll talk about that a little later on but you need to get that match experience put yourself in an environment where people are trying to tackle you they're trying to hurt you they're trying to take the ball away from you they're trying to make you screw up and that will force you to become a better player so once you get on that team make the most of every single opportunity even if in the very beginning you're only getting 10 minutes of playing time nobody trusts you you need to take that time and you need to make the most of it work extremely hard learn from your mistakes and just be positive about the whole environment and the whole experience in the whole situation as I said in the beginning you may only get 10 minutes but make the most of those 10 minutes next time it might be 20 you keep doing well next time it might be a half then you're playing the full game it's about taking those little steps but if you're negative and you're afraid of these challenges you're never going to get there one step at a time but you need to start playing as much as possible you can play every day fantastic get improved way faster than someone who only plays one game a week so step number two play as much as possible the third thing you need to do if you want to become a better player is train by yourself train individually why because when you're training by yourself 100% of the focus is on you yes games are fantastic yes training with your team is very important but when you're training with your team or you're in a game you're not always on the ball you're not always involved yes you may be involved indirectly working on your movement but when you're training by yourself you can focus on exactly what you need to improve so you should be training by yourself every single day yes sometimes you may only have 20 minutes to work on your skills sometimes you may have two hours as long as you have the attitude like hey today I'm gonna put in some work to become a better player then you're gonna be moving in the right direction so the best thing you can do especially if you're a beginner is just get that ball go and find a wall start pinging the ball against that wall get thousands of touches hundreds of thousands millions of touches the more touches you get on the ball the better you will become the sad truth is most players they don't get touches on the ball they just show up to their team practice once a week and they show up to their team's game once a week and they expect to be better than they were last week and they're frustrated when they don't play well the truth is you don't deserve to play well because you haven't put in the work so get to the wall get your ball just get those touches start working on your footwork start working on your skills hitting passes against the wall shooting against a wall just getting lots of touches in the beginning don't worry so much about oh I need the perfect training program I need to do this drill after this drill for this many minutes and this many repetitions just get on the ball just start practicing and improving yourself the next thing you can do as far as training individually to get your game up right your game up right away is become extremely fit okay there's no excuse for you not being fit yes you may not have the best skills at this moment but you'll be working to improve those but you can be fit very quickly if you just put in the work so start going for runs I recommend when you're going for runs don't just jog at a slow pace because that's not what you do in a game sprint jog sprint jog sprint walk sprint jog mix it up but put in those short bursts because that's what soccer that's what football is all about so get your fitness up work on your speed do some sprint drills do some agility drills there's tons on my channel just search on YouTube search for agility training speed training soccer and fitness training you'll get tons of ideas but it's about you putting in the work getting your fitness up is one of the easiest things you can do to become better on the field because if you're fitter than everyone else you can run longer than everyone else you can get to the ball quicker especially in the later periods of the game when everyone's getting tired you're gonna stand out and it's gonna make the game a lot easier for you finally about training individually I just want to say become a well-rounded player don't just focus on one thing don't just do skills because that's what you like to do think about how can I become a complete player what are all the different areas of your game ball control dribbling passing receiving shooting perfect all these different things both feet right foot left foot don't be a one-footed player okay work to become better player work to become a well-rounded player focus on your weaknesses and improve them focus on your strengths and make them better so number three if you want to become a better player train individually the next thing you can do to become a better player and this one is fantastic because you can do it from the comfort of your own home is just watch more football study the game become a fan of this game I know so many players who especially when I was growing up I always remember they would be like oh yeah I don't like to watch soccer I just like to play it and I can't understand that if you want to be a better player you need to watch as much as possible you need to study this game study these players have your favorite team have your favorite player watch them analyze them honestly I'm a football neutral I love all teams yes I know real Madrid just won the Champions League but I'm rocking Barcelona I love them all I love good football because I love to learn from everyone and if you can learn from the best players in the world the best teams in the world they're out there they're waiting to teach you just want to learn and study them so for example if you're watching a game study a player what does he do when he has the ball what does he do when he doesn't have the ball what is his movement what are his decisions what does his technique look like when he does something how did he dribble through three guys how did he score that incredible goal don't just be amazed ask why analyze and then you can apply it when you're practicing by yourself or you pick up a few things that you use yourself on the field you can just watch YouTube compilations of your favorite players watch players of different positions players who play your position how are they successful what do they do what do they do in certain situation what makes them so great ask these questions and you will get these answers and I guarantee you it will make you a smarter player honestly I think the players who watch the most usually have the best style of play in my experience players that I play with the guys who watch the most they're probably the smartest players they're the most intelligent they make the right decisions so the more you watch the smarter you will become yes it will make you a better player so number four study this game become a fan of this game become passionate about this game love to watch this game but learn as you watch the fifth thing I want you to do if you're serious about becoming a better player is stay motivated stay consistent and stay patient it takes time to become better it takes time to become great and so many of us out there we're frustrated with where we are and we're just focused on where we want to be and that's great that's great that you're focusing on the future and you want to get there but realize it takes time you're not going to become the best player in the world overnight you're not going to become the best player on your team overnight but you need to have that mentality that no matter how long it takes I'm just going to keep chipping away and you don't have to become the best overnight you just have to become better overnight every day you get a little bit better I improved my skills a bit today I improved my fitness a bit today I became a little smarter I understand the game better I understand my position better so it's just about making tiny improvements every day and then when you look back in a couple months at the end of the season next year you'll be amazed at the improvements that you've made so please please stay patient about your journey stay motivated and stay positive what motivates you maybe you need some reasons maybe you want to make a team maybe you want to prove that coach wrong maybe you want to show up that kid at school who's a jerk to you this whole time maybe you want to win an award maybe you just want to do this for yourself or your family to impress your parents your friends whatever find your motivation find reasons to keep you moving forward so please stay positive stay patient there will be ups and downs sometimes you'll play horribly sometimes you'll play great but whatever happens stay positive and come back to point number one believe in yourself to become better so in those hard times you need to realize those are the most important times because if you give up if you start getting negative you're moving backwards you can still move forwards in bad times you can still move forward when you play poorly when your team loses when nothing's going your way you can still move forward if you learn from those experiences you stay positive and you believe in your ability to become better so the fifth and final thing I want you to do is please please please stay patient stay positive stay motivated stay consistent it takes time you can't just train and then drop off come back and drop off stay consistent focus on every day make the most of every day and you're guaranteed to become a better player and obviously if you want to become a better player you got to stick with me I'm here to help you I've helped thousands hundreds of thousands tens I don't know I've helped a lot of people people are becoming professional people making colleges people just making their top teams so if you want to become a better player I'm here to help you obviously these are just my opinions this is just my advice but if it's work for other people it can work for you as well so what I want you to do is make sure you're subscribed make sure you go to my website if you haven't already progressive soccer training calm because there's tons of free training material for you that I'm gonna give you if you go to that website and finally follow me on social media there'll be some links at the end of this and come back tomorrow for another video I hope this helped you give you some ideas on how to improve and I guarantee if you fall this advice you are going to become a better player I'll talk to you soon