Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Run BT and WiFi Simultaneously on Pico W #1837

Open
CliveMcF opened this issue Nov 22, 2023 · 10 comments
Open

Feature Request: Run BT and WiFi Simultaneously on Pico W #1837

CliveMcF opened this issue Nov 22, 2023 · 10 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@CliveMcF
Copy link

Google tells me that I can run Bluetooth and WiFi simultaneously on the Raspberry Pi Pico W, but no luck so far! I'm trying to send the WiFi network credentials to the Pico via BT which works fine, but as soon as the Pico connects to the WiFi network it drops the BT connection.

I'm programming the Pico via the Arduino IDE and running the code below. To reproduce the error:
With the code running on the Pico, pair it to a BT Terminal app (in my case, running on an Android phone)
Send a newline from the terminal app to let the Pico it's connected
The Pico sends the SSID prompt text to the terminal
Send the correct SSID from the terminal
The Pico prompts for the password
Send the correct password to the Pico
The BT connection to the terminal drops out
The serial monitor on the Arduino IDE displays the "WiFi connected" message with the IP address

Here are the results from the possible combinations of correct/incorrect SSID and password:
SSID correct, password correct -> BT disconnects, WiFi connects
SSID wrong, password correct -> BT stays connected, WiFi doesn't connect
SSID correct, password wrong -> BT disconnects, WiFi doesn't connect
SSID wrong, password wrong -> BT stays connected, WiFi doesn't connect

Not as logical as I'd thought it would be!
Here's the code:
`#include <SerialBT.h>
#include <WiFi.h>

char ssid[32]; // Character array to store SSID
char password[32]; // Character array to store password
bool DEBUG = true;

WiFiMulti multi;

void setup() {
if (DEBUG) Serial.begin(9600);
SerialBT.begin();
while (!SerialBT.available()) // Wait for BT Terminal to connect
;
int bytesRead = SerialBT.read();
SerialBT.println("Please enter the WiFi SSID: ");
while (!SerialBT.available())
;
bytesRead = SerialBT.readBytesUntil('\n', ssid, sizeof(ssid));
ssid[bytesRead] = '\0';
if (DEBUG) Serial.println(ssid);

SerialBT.println("Please enter the WiFi Password: ");
while (!SerialBT.available())
;
bytesRead = SerialBT.readBytesUntil('\n', password, sizeof(password));
password[bytesRead] = '\0';
if (DEBUG) Serial.println(password);

multi.addAP(ssid, password); // Connect to WiFi network

if (DEBUG) {
if (multi.run() != WL_CONNECTED) Serial.println("Unable to connect to network");
else {
Serial.print("WiFi connected via IP address: ");
Serial.println(WiFi.localIP());
}
}
}

void loop(){

}`

@earlephilhower
Copy link
Owner

WiFi.begin and the equivalent BT/BLE calls all basically restart the CYW43 chip to ensure it's in a safe state to start their respective operations. Kicking the CYW43 will, of course, kill whatever was running before. When WiFi.end is called behind the scenes the same effect happens.

While I'm sure it's possible to rearchitect the WiFi and BT stacks to share state and let it happen, it's definitely a very low priority for me.

If you'or someone else is very interested, though, I'd be happy to get a PR or two implementing it, though!

@earlephilhower earlephilhower added the help wanted Extra attention is needed label Nov 22, 2023
@CliveMcF
Copy link
Author

Thanks Earle, I think reworking the stacks would be well beyond my meagre capabilities but hopefully some generous soul with more expertise will take it on. I imagine there would be many many situations where BT/BLE & WiFi would need to coexist.

@earlephilhower earlephilhower added the enhancement New feature or request label Nov 29, 2023
@earlephilhower earlephilhower changed the title Can't Run BT and WiFi Simultaneously on Pico W Feature Request: Run BT and WiFi Simultaneously on Pico W Nov 29, 2023
@djpearman
Copy link
Contributor

Hi,

It appears to be possible to use Bluetooth LE (via BTStackLib.h's BTStackManager) simultaneously with WiFi (via WiFi.h). Since I just added WiFi to a somewhat larger project on the Raspberry Pi Pico W that already had BLE set up, I have not done much testing with it however. Here are some of my preliminary observations:

  1. During setup(), Wifi.begin is called before setting up BTStackManager. It appears to work since the latter is started with its .setup and .startAdvertising functions, which apparently don't restart the CYW43 chip.
  2. Calling 'WiFi.begin' after starting BLE caused the former to somewhat unpredictably with either a WL_CONNECT_FAIL' or a WL_DISCONNECTED, but didn't affect BLE. Not sure what is going on here, so I need to investigate further.
  3. Connecting WiFi takes quite a while, extending initial setup time from about 2 to 15 seconds.
  4. Calling 'WiFi.end` also kills Bluetooth LE, thus requiring the latter to be re-setup and re-connected.

I used the Arduino WiFi guide for setting up a web server, though I have yet to proceed past pinging the board once it is connected to WiFi. This is my very first foray into using WiFi, so I'm still finding my way around the library. Perhaps this information will help you. I'll update once I know more.

@CliveMcF
Copy link
Author

CliveMcF commented Dec 1, 2023

Thanks @djpearman, very helpful - look forward to hearing how you get on. I did have a cursory look at the order in which BT and WiFi were set up but then got distracted with the SSID/password issue. I'll revisit this and pay more attention this time.

Essentially I've been starting BT and then WiFi, which reproducibly caused BT to drop out when WiFi connected, in contrast to your observations in point 2 above. Possibly a difference between BT and BLE?

Like you, I found that connecting WiFi takes a while, long enough for me to add a "Starting up, please wait..." notification to the user. Other than that, I found WiFi to be straightforward to set up and implement. I based my code on the WiFi Client sketch from the Pico W examples in the Arduino IDE and with a few minor tweaks it worked just fine.

@CliveMcF
Copy link
Author

CliveMcF commented Dec 8, 2023

I took another look at the sequence in which BT and WiFi are started up and can happily confirm @djpearman 's observation that if WiFi successfully connects then BT doesn't drop out. So now my setup() process is:
Get WiFi credentials from a saved file
Attempt to connect to WiFi using these credentials
Start up BT

The problem comes if WiFi doesn't connect, in which case I need to prompt for WiFi credentials via BT, save the new credentials, connect to WiFi, then restart BT as it will have been kicked out by the WiFi connection. Clunky but doable at a pinch, and certainly an improvement on where I was. Would still love to have BT/BLE and WiFi just playing nice all the time, for a whole load of reasons!

@jhmaloney
Copy link

jhmaloney commented Dec 3, 2024

Just want to +1 this request.

Simultaneous use of BT and WiFi worked well for me back around 3.7.0. Contrary to what others report, I was actually able to do a WiFi.begin() without losing the current BT connection.

However, that no longer works in the latest release. I'm guessing things stopped working in the transition to 4.0.

I use PlatformIO. What's the recommended way to use earlier releases of the framework with PlatformIO? I'd like to use the latest release to build for the RP2530-based Pico 2 W while using the older release to build for the classic Pico W. Of course, it would be even better if the latest release supported smooth WiFi/Bluetooth co-existence, but I can wait for that as long as I can still build code that supports that on the classic Pico W.

Thanks!

@earlephilhower
Copy link
Owner

This seems like more of a housekeeping thing than anything more involved. Basically keep a refcount on the cyw43 driver and don't stop it if there is another user (BT/WiFi). IT sounds like you've got a use case (aka a really good test case) and a need, so why not give it a shot? I'd look in the lwip_cyw43 ::end method and the BT libs (which never really stop the HCI, IIRC).

@jhmaloney
Copy link

Thanks for the pointer to lwip_cyw43 ::end.

What's odd is that in the 3.x version it worked to start Bluetooth first, then do a WiFi.begin() to connect to a network. Earlier posts in this issue suggest that that would not work because WiFi.begin() restarted the CYW43 chip, but I think that issue must have gotten fixed in the cyw43 driver. Unfortunately, that no longer works in the latest release.

Is there a way to specify a specific arduino-pico release when using PlatformIO? I tried using something like:

platform = https://github.com/maxgerhardt/[email protected]

but ran into a error with one of the tools. (Can't remember the exact error.) I realize that PlatformIO support is done by Max Gerhardt, not you; just thought you might know.

@djpearman
Copy link
Contributor

djpearman commented Dec 5, 2024

Is there a way to specify a specific arduino-pico release when using PlatformIO?

You can use platform_packages, i.e. for release 3.9.5:

platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#3.9.5

@jhmaloney
Copy link

Thanks! That worked, but now I'm getting this mysterious linker error. Any ideas?

Linking .pio/build/pico-w-ble/firmware.elf
/Users/johnmaloney/.platformio/packages/toolchain-rp2040-earlephilhower/bin/../lib/gcc/arm-none-eabi/14.2.0/../../../../arm-none-eabi/bin/ld:
/workdir/repo/newlib/newlib/libc/stdio/findfp.c:93:(.text+0xda): undefined reference to __retarget_lock_init_recursive' /Users/johnmaloney/.platformio/packages/toolchain-rp2040-earlephilhower/bin/../lib/gcc/arm-none-eabi/14.2.0/../../../../arm-none-eabi/bin/ld: /Users/johnmaloney/.platformio/packages/toolchain-rp2040-earlephilhower/bin/../lib/gcc/arm-none-eabi/14.2.0/../../../../arm-none-eabi/bin/ld: /Users/johnmaloney/.platformio/packages/toolchain-rp2040-earlephilhower/bin/../lib/gcc/arm-none-eabi/14.2.0/../../../../arm-none-eabi/bin/ld: /workdir/repo/newlib/newlib/libc/stdio/findfp.c:201:(.text+0x1ea): undefined reference to __retarget_lock_init_recursive'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

4 participants