[{"element_type":"alert","content":"\u003cp\u003eThis requires the most recent libraries to work - make sure to update. If you are using a board with ESP32SPI code frozen (like the PyPortal), you'll need CircuitPython 9.1.0 Beta 3 (or newer)\u003c/p\u003e","metadata":{"class":"element row-fluid alert-element build-alert alert-primary","markdown":"This requires the most recent libraries to work - make sure to update. If you are using a board with ESP32SPI code frozen (like the PyPortal), you'll need CircuitPython 9.1.0 Beta 3 (or newer)","alert_type":"primary"}},{"element_type":"markdown","content":"\u003cp\u003eI've been spending a bunch of time testing code across different MCUs and networking chips. It started with my work with \u003ca href=\"https://github.com/adafruit/Adafruit_CircuitPython_ConnectionManager\"\u003eConnection Manager\u003c/a\u003e. Then I was digging into \u003ca href=\"https://github.com/adafruit/Adafruit_CircuitPython_Requests\"\u003eRequests\u003c/a\u003e and \u003ca href=\"https://github.com/adafruit/Adafruit_CircuitPython_MiniMQTT\"\u003eMiniMQTT\u003c/a\u003e . Which of course lead me to places like \u003ca href=\"https://github.com/adafruit/Adafruit_CircuitPython_NTP\"\u003eNTP\u003c/a\u003e, \u003ca href=\"https://github.com/adafruit/Adafruit_CircuitPython_AzureIoT\"\u003eAzureIoT\u003c/a\u003e and \u003ca href=\"https://github.com/adafruit/Adafruit_CircuitPython_AWS_IOT\"\u003eAWS_IOT\u003c/a\u003e.\u003c/p\u003e\n\n\u003cp\u003eAs I jumped around, I needed a way to always get the right radio. Sometimes it's native WiFi, which is easy: \u003ccode class=\"inline\"\u003ewifi.raidio\u003c/code\u003e, but other times, it's some SPI based FeatherWing or maybe a M4 with and AirLift (talking to you \u003ccode class=\"inline\"\u003ePyPortal\u003c/code\u003e and \u003ccode class=\"inline\"\u003eMatrixPortal M4\u003c/code\u003e)...\u003c/p\u003e\n\n\u003ch1\u003eIntroducing: \u003ccode class=\"inline\"\u003eget_radio\u003c/code\u003e\n\u003c/h1\u003e\n\n\u003cp\u003eIt's not perfect, and I'm guessing there are things I haven't thought of, but it works for me so far.\u003c/p\u003e\n\n\u003cp\u003eThe only thing a normal developer, with the right libraries installed and only one radio needs to do is:\u003c/p\u003e\n","metadata":{"markdown":"I've been spending a bunch of time testing code across different MCUs and networking chips. It started with my work with [Connection Manager](https://github.com/adafruit/Adafruit_CircuitPython_ConnectionManager). Then I was digging into [Requests](https://github.com/adafruit/Adafruit_CircuitPython_Requests) and [MiniMQTT](https://github.com/adafruit/Adafruit_CircuitPython_MiniMQTT) . Which of course lead me to places like [NTP](https://github.com/adafruit/Adafruit_CircuitPython_NTP), [AzureIoT](https://github.com/adafruit/Adafruit_CircuitPython_AzureIoT) and [AWS_IOT](https://github.com/adafruit/Adafruit_CircuitPython_AWS_IOT).\n\nAs I jumped around, I needed a way to always get the right radio. Sometimes it's native WiFi, which is easy: `wifi.raidio`, but other times, it's some SPI based FeatherWing or maybe a M4 with and AirLift (talking to you `PyPortal` and `MatrixPortal M4`)...\n\n# Introducing: `get_radio`\n\nIt's not perfect, and I'm guessing there are things I haven't thought of, but it works for me so far.\n\nThe only thing a normal developer, with the right libraries installed and only one radio needs to do is:"}},{"element_type":"code","content":"radio = get_radio()","metadata":{"language":"python","linenums":false}},{"element_type":"markdown","content":"\u003cp\u003eLet's say you have native WiFi and an ESP32SPI and you want the esp?\u003c/p\u003e\n","metadata":{"markdown":"Let's say you have native WiFi and an ESP32SPI and you want the esp?"}},{"element_type":"code","content":"radio = get_radio(force=\"esp32spi\")","metadata":{"language":"python","linenums":false}},{"element_type":"markdown","content":"\u003cp\u003eThe nice thing is it will connect for you and everything! Store your creds as \u003ccode class=\"inline\"\u003eWIFI_SSID\u003c/code\u003e? Got you covered. What about \u003ccode class=\"inline\"\u003eCIRCUITPY_WIFI_SSID\u003c/code\u003e? Got you covered there too. What about in \u003ccode class=\"inline\"\u003esecrets.py\u003c/code\u003e? Sadly not there, \u003ccode class=\"inline\"\u003esettings.toml\u003c/code\u003e is the way to go.\u003c/p\u003e\n\n\u003cp\u003eNow let's say you aren't using a FeatherWing, or you are connecting things to different pins? Well your set there too!\u003c/p\u003e\n","metadata":{"markdown":"The nice thing is it will connect for you and everything! Store your creds as `WIFI_SSID`? Got you covered. What about `CIRCUITPY_WIFI_SSID`? Got you covered there too. What about in `secrets.py`? Sadly not there, `settings.toml` is the way to go.\n\nNow let's say you aren't using a FeatherWing, or you are connecting things to different pins? Well your set there too!"}},{"element_type":"markdown","content":"\u003cp\u003eFor the ESP32SPI (aka AirLift) you just need to set the following in your \u003ccode class=\"inline\"\u003esettings.toml\u003c/code\u003e (just set the right pins):\u003c/p\u003e\n","metadata":{"markdown":"For the ESP32SPI (aka AirLift) you just need to set the following in your `settings.toml` (just set the right pins):"}},{"element_type":"code","content":"ESP32SPI_CHIP_SELECT = \"D13\"\nESP32SPI_READY = \"D11\"\nESP32SPI_RESET = \"D12\"","metadata":{"language":"terminal","linenums":false}},{"element_type":"markdown","content":"\u003cp\u003eAnd for a WIZnet5k, even simpler:\u003c/p\u003e\n","metadata":{"markdown":"And for a WIZnet5k, even simpler:"}},{"element_type":"code","content":"WIZNET_CHIP_SELECT = \"D10\"","metadata":{"language":"terminal","linenums":false}},{"element_type":"markdown","content":"\u003cp\u003eSo now, on a device like the \u003ccode class=\"inline\"\u003ePyPortal\u003c/code\u003e, you can simply do:\u003c/p\u003e\n","metadata":{"markdown":"So now, on a device like the `PyPortal`, you can simply do:"}},{"element_type":"code","content":"import adafruit_connection_manager\nimport adafruit_requests\nfrom connection_helper import get_radio\n\nradio = get_radio()\npool = adafruit_connection_manager.get_radio_socketpool(radio)\nssl_context = adafruit_connection_manager.get_radio_ssl_context(radio)\nrequests = adafruit_requests.Session(pool, ssl_context)\n\nwith requests.get(\"http://wifitest.adafruit.com/testwifi/index.html\") as response:\n    print(response.text)","metadata":{"language":"python","linenums":false}},{"element_type":"markdown","content":"\u003cp\u003eOh and you know where else this works? \u003ccode class=\"inline\"\u003eCPython\u003c/code\u003e!!!\u003c/p\u003e\n\n\u003cp\u003e\u003ccode class=\"inline\"\u003eConnection Manager\u003c/code\u003e now has a radio that's a wrapper for the native \u003ccode class=\"inline\"\u003esocket\u003c/code\u003e and \u003ccode class=\"inline\"\u003essl\u003c/code\u003e methods. Adding this was a life-saver, because now for network only code, if somethings not working I can work directly in \u003ccode class=\"inline\"\u003eCpython\u003c/code\u003e which of course is a lot faster (you just need to be careful, since if can make new sockets all day long, where your MCU can only manage a few).\u003c/p\u003e\n\n\u003cp\u003eSo again, in CPython, just that simple \u003ccode class=\"inline\"\u003eget_radio()\u003c/code\u003e will work and you can pass that to the other helpers. Bam!\u003c/p\u003e\n","metadata":{"markdown":"Oh and you know where else this works? `CPython`!!!\n\n`Connection Manager` now has a radio that's a wrapper for the native `socket` and `ssl` methods. Adding this was a life-saver, because now for network only code, if somethings not working I can work directly in `Cpython` which of course is a lot faster (you just need to be careful, since if can make new sockets all day long, where your MCU can only manage a few).\n\nSo again, in CPython, just that simple `get_radio()` will work and you can pass that to the other helpers. Bam!"}},{"element_type":"markdown","content":"\u003cp\u003eAt some point, I might make this a little more formal and add it to the community bundle But until then, you can download this and save it as \u003ccode class=\"inline\"\u003econnection_helper.py\u003c/code\u003e on your CircuitPython drive:\u003c/p\u003e\n","metadata":{"markdown":"At some point, I might make this a little more formal and add it to the community bundle But until then, you can download this and save it as `connection_helper.py` on your CircuitPython drive:"}},{"element_type":"embed","content":"https://github.com/boxpet/circuitpython_scripts/blob/main/circuitpython_scripts/connection_helper.py"}]