 The second part of this webinar will be much more technical than the first one. So I will basically do a hands-on. I will first show you some of the CICADA models and some of the hardware I have available. Then I will start a live demonstration running it on a STM nuclear microcontroller and forwarding the output to the computer. And then I will actually do a code walkthrough through this example code that I just showed before. And I just fell down, I have these CICADA modules here, just show them into the camera. So this is basically the Wi-Fi module based on the expressive 8266 microcontroller. Then we have a 2G cellular module here. This is based on the quite popular SIM 800 module. And then there is this 4G module, it's based on the SIM 7600 module. And yeah, these small PCBs I just showed, they are also published in GitHub and available as open source hardware. So the hardware is actually rather simple. So it's basically just this module on a PCB with a power supply and some antenna networks depending on the module you use. So this is rather simple, but it's still very useful to use as a reference design. And basically you can just, you probably don't want to use the modules exactly as they are if you build a product, but it's still a very good reference. You can just copy and paste the hardware design into your own design and use that one. So basically the Wi-Fi module is just a power supply and the expressive modules. The 2G and 4G modules are a bit more sophisticated. They also have an antenna network, they have obviously the SIM card reader. And what's also important there is to have a very stable power supply because one of the problems we have is there are some pre-made modules you can order on AliExpress or whatever, but the power supplies on them were actually too weak to support the current spikes the module used. So we had to create our own power supplies. So let me quickly show one more thing. This is basically at Okra. This is the main board of our solar controllers. And whenever you want to change your communications modules, it just plugs in here. And yeah, basically just plug and play solution. So when we want to use it with a different module, we just chip the main board with a different module installed and we don't have to change anything at our firmware. So it's just the SIM card to transfer all of them. Yeah, that was a little introduction to the hardware. And the next thing is I will actually start with the 5th demonstration. Let me again first show the hardware. So I have a little SCM nuclear developer board here. So you can see the microcontrollers over here, this chip. And this has currently connected to modules. In that case, I don't use the Ccalor PCBs, I just connected the modules directly with these wires over here. It has a Wi-Fi modem which you see on the top here. And with these wires here, it has again a SIM 800 module connected to it. And yeah, now you've seen the hardware, I will start sharing my screen and show you some code. Just select the right screen over here. Okay, yeah, you should now be able to see my VSCode with the example code. And yeah, so this around 200 lines file is basically the example I will walk you through now. On a high level, what it does basically is it initializes all the drivers. Then it detects the modem with that modem detector. Then it connects to a web server, sends a HTTP request, receives the website from a web server and actually forwards it from the microcontroller to the terminal on my computer so that we can see the website. Let me quickly check which is enabled. So we will first start with the Wi-Fi module. So here I have two terminals. One is for flashing and compiling code. And here we actually have the serial UR part which gives the output from the, displays the output from the microcontroller. And we start with compiling. We use nasenet ninja as the build system. And then we actually flash. Now writes the binary to the microcontroller. Now you see here on the output that it actually detected the expressive module. It's happening faster than I can talk. So it detected the expressive Wi-Fi module. Then it connected to the web server, receives the HTTP header and finally fetches this weather report from the website. Sorry to interrupt, but we still see in your code. We don't see the live demo screen. Oh, that's very weird actually. Okay, I saw this share my screen. Okay, just give me a second. Okay, sorry for that. I'm probably just shared just one window instead of sharing my screen. Yeah. So we use code you've seen. But yeah, here it's basically, just quickly repeat what I did. So I called ninja, which compiles the code, then I flashed it to the microcontroller. And this is the output from everything where it detects. It says detected the expressive Wi-Fi module, then it connected, and then it fetches this weather report from the website. But yeah, and I wanted to show it again anyway, because I want to do the same procedure now with 2G module. So as I said before, I have two modules connected to this, it's just another module and another UART port. So I comment out this part of the code, and instead comment in this part of the code. So it's the same object, which is created just with different pins, with a different UART port and different pins of the other module connected. So we do the same thing again. I'll flash, now you see it live, what I just did before. And if you change terminal now, you see that it actually detects the 2G or 4G modem. It says 2G 4G because it's actually a different drivers, but they inherit one base instance. So we can just use the SIMCOM driver in this case. And again it fetches the weather report from the website. So yeah, this was the live demonstration, and now I probably use around 10 more minutes to walk you through that code. So yeah, now you should be able to see the VS code again. So this is, everything is happening in the main function over here. You have basically some initializations. You have the Zikata, the buffer initializations for all the drivers. So basically in Zikata all buffers are user supplied. This is useful because there are different ways how you want to actually initialize your buffer. It could be in the heap, it could be in the stack, it could be on a local function stack, or it could be a global stack, whatever. So you just create your buffer wherever you want to create it. And then when you actually create one of the driver objects, you will hand in that user created buffers over here. So these lines actually create, there's also serial drivers included in the library. In this case, we used the STM32 serial driver. We also create the serial driver for the debug yard, which we just used to connect to the PC. Then we create a serial driver here for the specific modules. And then we actually start creating the modem detector object, which has this auto-detect feature. So how the detector basically works is you create this modem detector object. Then you run, you add it to the Zikata internal task handler. And then you have to go to the main loop and call its run method, which we do here. And basically what the modem detector does is it tries to send 80 comments to the modem to figure out which module is installed. And then it gives you back the correct C++ driver object of that specific modem you want to use. So that basically happens here. First you start the detector, then you go to the main loop. And as soon as you have this flex set modem detected, you basically assign your common device to the actual modem driver object, which happened here. And then you can basically figure out which device you actually got. A common way to do this in C++ is with your dynamic cast. So you try to cast it to a SIMCOM device, which is for these 2G or 4G modems. If you have a SIMCOM device, you still have to set the APN, which we do here. If it's not the 2G or 4G modem, this dynamic cast will just return zero. And the function goes on. And the same thing we do for Wi-Fi. If it's a Wi-Fi module, we set some username and password. So this password is actually the one of our co-working space. It's not committed to GitHub. And depending on if you have some other modems, you can do other casts. For example, you can cast the 2G modem to a 4G modem or whatever, but this way you can determine which modem it actually has. This is, again, generic, which is valid for all the communication devices. You set host and port, and then you can actually call connect. So the next event here in this main loop is the actual connection app. So as soon as the modem is connected, you will have the COM device is connected method returning true. Within this method, what we do here is we print, obviously, the line to the debug yard, and then we actually build up the HTTP header, which we write to the COM device. And then we set this flag to true because we don't want to call this event ever again. And the next event is the actual receive event. So you have another method, COM device, but it's available, which basically tells you that there is new data and how much new data. So this is called whenever there's data available, and what it basically does is it just reads the data from the COM device and forwards it to the debug yard so we can see it on the computer's modem screen. And at the end, finally, so basically, as you see here, we have set the connection close flag in the HTTP header. So the remote host closes the connection as soon as it has sent all the data from the website. And this is basically the close event. So once the communication device is again back to idle state, we just print the debug message that we disconnected, and we exit the main event loop. So this was pretty much all you have to do for this example to detect the modem and fetch the website, probably some more words to this event loop. So how it basically works, this is, I think, quite a common pattern in microcontroller development, you basically have just one big main loop which just runs over and over again. And within this main loop, you call different task methods and handle your events. So for Cicada, we have an internal task scheduler. It's a very simple scheduler. It's not like what you know from high-end operating system schedules. It basically just checks if all the tasks in the list are due to run. And if it's due to run, meaning it has a certain timeout, then actually it runs the task. So basically what you have to do is you have to create a Cicada scheduler. You have to add your tasks to the task list, which in our case is just a modem detector. And then within a main loop of your microcontroller, you call this Cicada task scheduler run task method, you have to call it repeatedly. Yeah, that's basically how this works. I can quickly show you how an internal driver works. For example, if I open this SIM 800, the TPP driver, this is also only 400 lines, source code file, which is implementation of the full SIM 800 driver. And basically this run method is what I showed before, has to be called periodically from the main event loop. With all the internal tasks in Cicada, mainly the drivers, but also like the detector, serial driver, whatever, all those are implemented as state machines internally. So it basically means, for example, here you have the main state machine for sending out the comment, sorry, this was for receiving your replies. So this is the state machine for actually sending the AT comments. So you have different states, first not connected, then you handle your states, you usually send a bunch of AT comments, and then you go to your next state. So for example here, you send first a comment to not reply, to not echo the characters which go to the modem, then you go to the next state, then you send a bunch of configuration for those modems. In this case, it's the active or passive mode basically, but the flow control of the modem and then you actually set APN, then you actually set up your connection, which is over here first cellular connection, then the actual TCP or UDP connection, and then you finally are in the connected states, which is actually for handing incoming and outgoing data. Yeah, there are different states also for actually processing the data, and in the end, you basically just have to disconnect and finalize states again. Yeah, that was a quick introduction how modem driver looks like. Let me probably finally go back to the main example. So I already went through the main loop, and everything that comes after is just boilerplate code to initialize your main MCU. This is just copied from this, there's this program where I can create boilerplate codes for SDM for do micro, cube Mx is the name. So this is just auto-generated with cube Mx, and yeah, that's basically it. Let me quickly check in the chat. Okay, I see that there is a bunch of questions in the chat, so I think it's a good opportunity to end this demonstration.