Q: Why is the WF121/WGM110 throughput lower when the module is in AP mode?
A: When WF121/WGM110 is in AP mode it must re-transmit multicast traffic coming from any of its clients. The multicast traffic has to be sent right after a beacon and until it is sent all the unicast TX traffic is blocked.
If there is on-going TCP communication this can cause lost frames, forcing the TCP to re-transmit and decreasing the throughput. This is mostly observable when the clients are Windows/MAX/Linux PCs which use multicast traffic for service discoveries and other purposes.
Also multicast sent from the module itself (by the application) causes the same behavior, not just re-transmitting multicast coming from the clients.
On Windows this can be improved by disabling some of the native discovery services as shown below if they are not required.
The Wizard Gecko WGM110 Wi-Fi module supports AP (Access Point) or station mode and the role can change during run-time without having to reset the module.
Command/Event Sequence Flowchart
Attached is a project that exemplifies how to switch between AP and station modes in run-time (you have to fill-in your AP details in the bgscript code). With this project the WGM110 boots into AP mode and then by pressing PB0 in the WSTK it will switch between AP and station modes.
If you have PB1 pressed while pressing PB0 to switch from station to AP it will start AP mode with WPA2 security, otherwise it will be an open AP. You can follow the BGScript code execution by opening BGTool and looking at the command window.
The flowchart below shows the recommended commands/events sequence to switch modes in a safe way. It's worth pointing out that:
Before switching from station to AP you should disconnect from the AP.
Before switching from AP to station you should stop AP mode. If you don't do this and go straight to turning off the Wi-Fi then the firmware becomes stuck and can only be recovered through a reset.
AP to Station
The image below shows the commands (or more accurately, the command responses) and events between pressing PB0 and receiving the sme_interface_status event which confirms that the Wi-Fi interface is ready.
This trace is taken with BGTool and edited to remove some of the events for simplicity purposes. When a BGScript application is running and there is a UART enabled in BGAPI mode all the command responses and events are sent out via the BGAPI UART and they can be parsed with BGTool.
The time to switch from AP to station depends strongly on the AP that the module is connecting to, more specifically how fast it can assign an IP with DHCP protocol. In this example the total time to switch from AP to station mode is about 7 seconds.
Station to AP
The image below shows the switch from station to AP with WPA2 security.
When WPA2 security is enabled it takes longer to have the AP ready. The switch time is more deterministic in switching from station to AP as there are no external dependencies. Switching from station to a WPA2 secured AP takes about 6 seconds.
The image below shows the switch from station to an open AP. When the AP is insecure it takes significantly less time than with a secure AP, which is about 2 seconds.
This article aims to explain the differences between WF111 and WF121/WGM110 modules in terms of their built-in functionality and host requirements to integrate them into your application.
In practice we are here summarizing information which you can find across a few documents, in order to help you understand better what are the benefits and trade-offs of each of the modules so that you can pick the most suitable module for your application.
What's on Board?
The WF121/WGM110 modules contain a Wi-Fi chipset and an MCU. The Wi-Fi chipset runs the PHY and lower MAC layers and the MCU runs the upper MAC and TCP/IP stack.
On the other hand the WF111 only contains the Wi-Fi chipset so there is no on-board TCP/IP stack. This means that the upper MAC and TCP/IP stack must run on the host controller.
Software Architecture
Let's now look at the software architecture for WF111 and WF121/WGM110 so that it helps understanding the different host requirements for each.
WF111
On WF111 the Wi-Fi chipset runs the radio (PHY) and lower MAC and everything else runs on the host.
As the TCP/IP stack must run on the host and that prevents this module from being used with 'less resourceful' processors which might not have enough Flash/RAM or other resources to run the stack. It's also worth noting that you cannot run your application on the WF111, it must run on the host device.
WF121/WGM110
For WF121/WGM110 the TCP/IP stack runs on the module and the module's functionality is controlled through the BGAPI protocol.
* Note: This diagram represents both WF121 and WGM110 but WF121 does not support TLS
On WF121/WGM110 there are 3 development options:
Standalone mode: all software including the application software runs on the module. The application must be written using BGScript.
Hosted mode: an external host runs the application software which controls the module using a well-defined binary based transport protocol called BGAPI.
Mixed mode: a part of the application runs on the module while the rest of the application runs on an external host. One example is to have the network management part in BGScript while the host handles the higher level application tasks.
Host Requirements
Now that we are more aware of what each module offers we can understand the different host requirements. For the case of standalone mode on WF121/WGM110 there is no requirement to have a host at all so we will leave that out of the discussion.
WF111
The WF111 requires an SDIO interface to the host and also that the host is running Linux operating system (typically ARMvX based processors). The software package provided by Silicon Labs includes the Linux drivers which must be cross compiled in a separate build machine running Linux. Instructions on how to build and install the drivers can be found in AN995: WF111 Android Driver Installation.
Once the drivers are installed the standard Linux wireless tools can be used to manage the new wireless interface such as iwlist for scanning for Access Points or iwconfig to connect to a wireless network.
WF121/WGM110
WF121/WGM110 can be interfaced via UART/USB/SPI using BGAPI protocol. Because the TCP/IP stack is running on the modules they can be controlled by very small and resource constrained MCUs, depending of course on the use case and the needs of the actual application.
The SDKs contain the BGLib which is a lightweight host library in C that implements the BGAPI binary protocol and parser so that you can abstract from the binary format of the protocol.
The host controller doesn't have any visibility to the IP frames or TCP/UDP/TLS protocols. From a data transfer stand-point it only exchanges raw TCP/UDP/TLS payload using either BGAPI commands or transparent data connection (UART/USB in streaming mode). The exception is with higher level or application specific protocols (e.g. SMTP) which then need to be handled by the host and channeled through a TCP/UDP/TLS connection.
FAQ
Q: Is it possible to use SPI with WF111?
A: No, it's not possible. The drivers are only prepared to use SDIO interface.
Q: Can I bypass the TCP/IP stack on WF121/WGM110?
A: This is only possible on WF121 when using bridge mode. In this mode the RMII interface must be used (connected to an ethernet PHY or another device) and the WF121 only bridges the MAC frames between the Wi-Fi and ethernet interfaces.
Q: Can I get higher throughput with WF111?
A: Yes because the Wi-Fi chipset is being handled by a more powerful processor compared to the MCUs running the TCP/IP stack on WF121/WGM110. The throughput will be mostly dependent on how much CPU time can be dedicated to the Wi-Fi interface compared to other tasks running on the CPU. As a ballpark we have tried and tested up to 12Mbps but in ideal conditions, with the device fully dedicated to the Wi-Fi.
This article shows how you can use the Wizard Gecko WGM110 Wi-Fi Module to trigger actions using IFTTT.
The example shown here allows you to add a row into a spreadsheet in your google drive by double tapping the accelerometer in the WSTK expansion board. For the accelerometer configuration it uses code from the spi_master example from the WGM110 SDK which configures the accelerometer to give an interrupt signal when you double-tap it.
To run the example code you need:
- IFTTT account
- Google account
- AP with Internet access (you need to write your AP's SSID and password in the sta.bgs file of the attached project so that the WGM110 can connect to it) -> LED0 in the WSTK will turn on once the WGM110 connection to the AP is up and running
IFTTT - Creating a Recipe
To get this up and running on the cloud side you need to create an IFTTT account and connect to the Maker and Google Drive channels. These should be pretty simple steps: once your account is created you can go to the IFTTT channel page and search for the two aforementioned channels and connect them to your IFTTT account.
When you connect to the Maker channel you'll be given a key which you need to use to trigger the actions. This key will always be visible when you access the Maker channel page while logged in as depicted below.
Now we need to setup a recipe which will use the maker channel as a trigger to add a row into a spreadsheet in your google drive. Here goes a short guide on how to do this:
1. There are several ways to create a recipe (like through the Maker channel page) but assuming you're on the IFTTT homepage press on your username on the top-right of the IFTTT page to pull-down the menu and then press 'Create'. Afterwards press "this" in "ifthisthenthat" to continue creating the recipe.
2. Write "Maker" in the channel list and select the maker channel as your recipe's trigger.
3. Choose the web request trigger (it's the only option).
4. Name your event and press "Create Trigger". In this example the trigger is named double_tap.
5. Now press "that" in "ifthisthenthat" and choose Google Drive as the action channel.
6. Choose the action which for this example is "Add row to spreadsheet".
7. To finalize give further details on how you want the data to be written into the spreadsheet. For this example we left it with the default options.
8. To test your recipe just make a POST or GET request as instructed in the Maker channel usage page. Essentially you just need to open a browser window and write https://maker.ifttt.com/trigger/YOUR_EVENT_NAME/with/key/YOUR_KEY and that will trigger the action you created with the recipe. There is an optional JSON body that can be used to send additional data but for this example this is not being used.
Creating the Trigger from WGM110
What we want to do now is to send this POST or GET request from the WGM110 to trigger the action. To do this we need to behave like an HTTP client which means we must open a TCP connection to port 80 in the IFTTT maker channel server and send the HTTP request through that TCP pipe.
To know what to actually put into the HTTP request there is a handy site called Request Maker where you can simply copy the URL used to trigger the event, select POST request type (or GET, but in this example we will use POST) and press Submit. It will then show you the HTTP request content as well as the response (if any).
BGScript implementation
Now that we know what to place in the HTTP POST request it's just a matter of creating some constant buffers with the data.
# IFTTT Maker POST request - generated through http://requestmaker.com/ - You need to replace YOUR_EVENT and YOUR_KEY according to what you setup on IFTTT
const ifttt_trigger_1() = "POST /trigger/YOUR_EVENT/with/key/YOUR_KEY HTTP/1.1\r\n"
const ifttt_trigger_length_1 = 67
const ifttt_trigger_2() = "Host: maker.ifttt.com\r\n"
const ifttt_trigger_length_2 = 23
const ifttt_trigger_3() = "Accept: */*\r\n"
const ifttt_trigger_length_3 = 13
const ifttt_trigger_4() = "Content-Length: 0\r\n"
const ifttt_trigger_length_4 = 19
const ifttt_trigger_5() = "Content-Type: application/x-www-form-urlencoded\r\n\r\n"
const ifttt_trigger_length_5 = 51
const ifttt_response() = "HTTP/1.1 200 OK"
const ifttt_response_length = 15
As the accelerometer interrupt is the trigger for the request the first thing we need to do is to resolve the hostname in the interrupt event. In addition we will turn on LED1 in the WSTK to indicate to the user that the process is on-going. We also trigger a failsafe timer with a 10 second timeout period in case something doesn't go well (like the server not being able to accept our TCP connection request).
event hardware_interrupt(interrupts, timestamp)
if (interrupts & WSTK_ACC_INT_PIN_MASK) && (status = STATUS_READY) then # When double tapping the accelerometer
status = STATUS_REQUEST_ONGOING
# Resolve ifttt maker server hostname
call tcpip_dns_gethostbyname(maker_ifttt_server_name_len, maker_ifttt_server_name(:))
# Turn ON LED1 - indicates request on-going
call hardware_write_gpio(GPIO_PORTC, $0002, $0002)
# Failsafe timeout - if we don't get an HTTP response to our POST request within 10 seconds then we'll stop the process
call hardware_set_soft_timer(10000, 0, 1)
end if
end
Once the hostname is resolved we can initiate the TCP connection and send the data contained the request buffers. To check if the request was successful we also catch the endpoint_data event and look for the HTTP response. If the response is "HTTP/1.1 200 OK" then we stop the failsafe timer and turn off LED1.
event tcpip_dns_gethostbyname_result(dns_result, server_ip_address, name_len, name_data)
# Hostname was resolved, now we make a TCP connection to the HTTP server which is on TCP Port 80
call tcpip_tcp_connect(server_ip_address, maker_ifttt_server_tcp_port, -1)(result, endpoint_maker_ifttt_server_tcp)
end
# Event received when an endpoint status changes.
event endpoint_status(endpoint, type, streaming, destination, active)
if (active = 1) && (endpoint = endpoint_maker_ifttt_server_tcp) then
# Connection to IFTTT HTTP server is now ready, let's send the POST request
call endpoint_send(endpoint, ifttt_trigger_length_1, ifttt_trigger_1(:))
call endpoint_send(endpoint, ifttt_trigger_length_2, ifttt_trigger_2(:))
call endpoint_send(endpoint, ifttt_trigger_length_3, ifttt_trigger_3(:))
call endpoint_send(endpoint, ifttt_trigger_length_4, ifttt_trigger_4(:))
call endpoint_send(endpoint, ifttt_trigger_length_5, ifttt_trigger_5(:))
end if
if type = 128 then # The IFTTT HTTP server will eventually close the TCP connection after a few seconds
call endpoint_close(endpoint)
end if
end
event endpoint_data(endpoint,data_len, data_data)
# Received some data back from the server, let's see if it was an OK response to our request
if (endpoint = endpoint_maker_ifttt_server_tcp) && memcmp(data_data(0), ifttt_response(0), ifttt_response_length)
# IFTTT response successful (HTTP/1.1 200 OK) - stop the failsafe timer
call hardware_set_soft_timer(0, 0, 1)
# Turn OFF LED1
call hardware_write_gpio(GPIO_PORTC, $0002, $0000)
status = STATUS_READY
end if
end
Once LED1 goes off the WGM110 is ready to make a new request so you can double tap the accelerometer again to trigger the action.
Final result
Double tap the expansion board -> LED1 goes on -> LED1 goes off -> New row is added to the google drive spreadsheet
Wi-Fi Knowledge Base
WF121/WGM110: Throughput in AP mode
WGM110 - Switching between AP and Station mode in run-time
WF111 vs WF121/WGM110
WGM110 - Using IFTTT Maker channel to trigger recipes