Photon2 external antenna software selection?

Okay, found the command to use for the Photon2 to select internal and external antenna. But curious if anyone has any code they’d be willing to share that will try the external antenna and then fall back to internal if the external isn’t better? Need it for WiFi, not Bluetooth.

I would be very surprised if the external antenna was not better than the internal antenna. You could use the Auto setting:

STARTUP(WiFi.selectAntenna(ANT_INTERNAL)); // selects the CHIP antenna

STARTUP(WiFi.selectAntenna(ANT_EXTERNAL)); // selects the u.FL antenna

STARTUP(WiFi.selectAntenna(ANT_AUTO)); // continually switches at high speed between antennas

However, for the P2 and Photon2 - This function does not work on the P2 and Photon 2. Use BLE.selectAntenna() to set the antenna for both BLE and Wi-Fi.

1 Like

I should have been more clear…I only care about Photon 2. And the reason I care is I want to make one firmware that will work with or without an external antenna, so I said “better than” as a way to know if there is an antenna at all. And I’d like it to be able to fall back to the built in antenna if the external one came unplugged or something.

Photon2 same as P2 - ANT_AUTO still sounds like the best setting.

I don’t understand…you have to pick one or the other in software. I assume if I choose the external one and there is no external one, I’m gonna lose Wi-Fi. So I’m hoping someone already wrote the code to check the signal strength and chose the best one from between the two.

I’m guessing it’s not that hard to do, I was just hoping someone had already done it and wouldn’t mind a quick cut and paste share.

Alright, started working on my own code. Maybe I'm blind or dumb, but this is having very unexpected results.

        BLE.selectAntenna(BleAntennaType::INTERNAL);
        WiFiSignal sig = WiFi.RSSI();
        sigInternal = sig.getQuality();
        Log.info("Internal WiFi signal strength: %.02f%%", sigInternal);
        delay(5000);
        BLE.selectAntenna(BleAntennaType::EXTERNAL);
        sig = WiFi.RSSI();
        sigExternal = sig.getQuality();
        Log.info("External WiFi signal strength: %.02f%%", sigExternal);
        if (sigInternal > sigExternal) {
                Log.info("Internal Wifi greater than External");
                BLE.selectAntenna(BleAntennaType::INTERNAL);
        } else {
                Log.info("External Wifi greater than internal");
                BLE.selectAntenna(BleAntennaType::EXTERNAL);
        }

sigInternal and sigExternal and just defined as floats. The above code is in setup(). But if I completely disconnect the external antenna at the board itself and boot it, I see this:

0000009292 [app] INFO: Internal WiFi signal strength: 41.93%
0000014462 [app] INFO: External WiFi signal strength: 100.00%
0000014467 [app] INFO: External Wifi greater than internal

I plopped another signal grab in a function I can call remotely so I can remotely trigger signal strength lookups. Seems like the internal functions are backwards. But surely that's not the case. Am I missing something bad here? No matter what I do, I'm getting the external antenna selected.

It’s really like it has these two backwards.

Ugh, the point of the delay(5000); was to give the WiFi chipset time to settle on the new signal, but I put it in the wrong place. It should be after the switch to the external antenna but before I check the strength a second time. One thing I also don’t know is if I need to do the sig = WiFi.RSSI(); a second time or not. Does that JUST setup the data structure and then the sig.getQuality() populates or does it populate and the sig.getQuality() just returns the result?

Can’t test the change in delay() until later, but I don’t think that’s the answer anyway. The behavior still seems completely backwards.

1 Like

Well crap. I moved the delay() to right after setting the antenna to external. Then I compiled and booted with the external antenna completely unplugged from the Photon 2 board itself. I got 51% signal quality from the internal antenna and 54% from the external. So it did set itself to external.

Then I pinged it a couple times to ask the signal strength and got 54% again.

Then I plugged in the external antenna and pinged it for strength and it went to 100%. And it's holding there over time. I am pretty close to an AP.

But it's still very annoying that the unplugged external antenna connector is so close or even better than the internal antenna in my current situation. Like, uh, why have an internal antenna at all? Obviously the answer is "because it usually works better", but it's frustrating. I'm guessing I need to check for the external antenna to be like 20 points better than internal before switching to it?

I guess in absence of any comment from anyone at Particle and nobody else here seeming to know what's up with this, maybe I'll just punt on automatic antenna selection and create an externally triggered function to set it. Supposedly it keeps the setting across reboots. shrug

I would not try to do automatic antenna selection on the P2/Photon 2. You'll always run into the problem that the bare U.FL antenna connector often works surprisingly well as an antenna. You can see this with cellular devices as well.

The reason the P1/Photon 1 had ANT_AUTO mode is that the Broadcom/Cypress BCM43362 theoretically supports antenna diversity with two 2.4 GHz Wi-Fi antennas using two separate RF circuits. The Particle devices never supported antenna diversity, however automatic mode enabled both antennas so it could pick the stronger antenna.

This is way different than how you'd have to do it on the P2/Photon 2 which has an antenna switch in front of a single Wi-Fi radio circuit. Switching the antenna is likely to cause poor performance mainly because there's no way to see what the Wi-Fi and BLE modules are actually doing at the time of the switch.

2 Likes

Thanks for that info.

I'm not worried about switching during action so much. My only reason for automatic switching is just to not have to tell the thing I plugged an external antenna in. Purely convenience one time as I don't plan to be plugging and unplugging antennas, I just might have one in the build and I might not and I wanted "one size fits all code" that could just work it out.

But that seems like a little bit of a pipe dream, so I'll just write a cloud function that can set the antenna state and I'll do it manually.

Hopefully last question...when you set the antenna type, the docs say "this is a persistent setting." Does that mean it will stay set across power outage?

Correct. The antenna selection is saved in the flash file system, so it persists not only over removing power, but also replacing user firmware and Device OS. It also persists across resetting Wi-Fi credentials (long press of MODE).

Alright, one more question: I don't see a function to query the antenna setting. Am I missing it, or does that not exist currently?

So I put this in setup:

        Particle.function("Antenna: 0 int, 1 ext", changeAntenna);

And then this in code:

int changeAntenna(String command){
        int antennaSetting = command.substring(0,1).toInt();
        if (antennaSetting) {
                // set external if 1
                BLE.selectAntenna(BleAntennaType::EXTERNAL);
                Log.info("ExternalAnt");
                return 1;
        } else {
                // set internal if zero
                BLE.selectAntenna(BleAntennaType::INTERNAL);
                Log.info("InternalAnt");
                return 0;
        }
}       
 

Seems to work. I'd love to be able to query the antenna switch state in setup() and spit out that to the log, though.

Oh, that's weird. There's WiFi.getAntenna() and WiFi.selectAntenna() but there is no get for BLE. In current versions of Device OS for the P2/Photon 2 you can use the WiFi calls which will affect both Wi-Fi and BLE.

Maybe I'm blind, but I'm not finding docs on this.

Added documentation forWiFi.getAntenna function which was not previously documented (but present since 0.8.0-rc.2).

1 Like