mavlink/MAVSDK-Swift

Not connecting to ESP8266 WiFi Module

JonasVautherin opened this issue ยท 52 comments

I tried the current version of the example app (with 0.4.1) and it wasn't establishing a connection with my ESP8266 WiFi Module, but QGC was able to. Not able to get it to connect with 0.5.0 either.

It's not crashing, just not connecting. Here is the log

2019-06-26 19:44:58.875767+0800 DronecodeSDK_Swift_Example[65517:4136020] [DYMTLInitPlatform] platform initialization successful
2019-06-26 19:44:59.109322+0800 DronecodeSDK_Swift_Example[65517:4135848] creating player instance using shared library
Running backend in background (MAVLink port: 14540
[07:44:59|Info ] DronecodeSDK version: 0.15.0 (dronecode_sdk_impl.cpp:25)
[07:44:59|Debug] New: System ID: 0 Comp ID: 0 (dronecode_sdk_impl.cpp:285)
[07:44:59|Info ] Server set to listen on 0.0.0.0:50051 (grpc_server.cpp:43)
[07:44:59|Info ] Server started (grpc_server.cpp:27)
[07:44:59|Info ] Waiting to discover system... (connection_initiator.h:57)

Originally posted by @unipheas in #133 (comment)

Can you describe the setup a bit more precisely? Like who is where (on the network), and broadcasting what?

In some cases it may be that QGC is a bit more tolerant on the network setup, where MAVSDK only listens to udp on 14540 (I assume you used udp://:14540 here, right?).

So, no settings where changed in the app, It's right out of the box. I cloned the repo then did the Carthage install and side loaded the app to my phone.

That said, I noticed that it shows it's listening on port 50051

[07:44:59|Info ] Server set to listen on 0.0.0.0:50051 (grpc_server.cpp:43)

I am using the ESP-12F (ESP8266) WiFi Module. It does have the MavLink ESP8266 Firmware V 1.2.2 installed. I did have to change the UART_BAUDRATE to 57600 because the Sik Radio isn't compatible with 921600. I'm using the Holybro 433Mhz 100mW Sik Telemetry Radio.

Here are the settings for the Wifi Module

Name | Value
-- | --
SW_VER | 16908290
DEBUG_ENABLED | 0
WIFI_MODE | 0
WIFI_CHANNEL | 11
WIFI_UDP_HPORT | 14550
WIFI_UDP_CPORT | 14555
WIFI_IPADDRESS | 17082560
WIFI_SSID1 | 1383622992
WIFI_SSID2 | 1919247201
WIFI_SSID3 | 0
WIFI_SSID4 | 0
WIFI_PASSWORD1 | 1920493936
WIFI_PASSWORD2 | 1919247201
WIFI_PASSWORD3 | 0
WIFI_PASSWORD4 | 0
WIFI_SSIDSTA1 | 1383622992
WIFI_SSIDSTA2 | 1919247201
WIFI_SSIDSTA3 | 0
WIFI_SSIDSTA4 | 0
WIFI_PWDSTA1 | 1920493936
WIFI_PWDSTA2 | 1919247201
WIFI_PWDSTA3 | 0
WIFI_PWDSTA4 | 0
WIFI_IPSTA | 0
WIFI_GATEWAYSTA | 0
WIFI_SUBNET_STA | 0
UART_BAUDRATE | 57600

Here is an image of the setup.

IMG_0582

The phone is connected directly to the Wifi Module

IMG_5575

I'm wondering if the baud rate has anything to do with it.

That said, I noticed that it shows it's listening on port 50051

That's fine, that's the mavsdk_server listening port (i.e. for gRPC) ๐Ÿ‘. That's not on the MAVLink side.

I'm wondering if the baud rate has anything to do with it.

I'm not sure to be honest. That may be something to explore indeed.

Running backend in background (MAVLink port: 14540

So on the MAVLink side, mavsdk_server listens on 14540. QGC would by default listen on 14550. Could you try to listening on 14550 with MAVSDK (to see if that's an issue with the 14540 mavlink interface)? Make sure that QGC is not running at the same time, as that would conflict.

Set to port 14550 with drone.setMavlinkPort(mavlinkPort: 14550)
Can confirm it is now listening on 14550 with output

Running backend in background (MAVLink port: 14550
[04:12:47|Info ] DronecodeSDK version: 0.15.0 (dronecode_sdk_impl.cpp:25)
[04:12:47|Debug] New: System ID: 0 Comp ID: 0 (dronecode_sdk_impl.cpp:285)
[04:12:47|Info ] Server set to listen on 0.0.0.0:50051 (grpc_server.cpp:43)
[04:12:47|Info ] Server started (grpc_server.cpp:27)
[04:12:47|Info ] Waiting to discover system... (connection_initiator.h:57)

Still not establishing connection.

And are we sure QGC is receiving on UDP, and on port 14550?

IMG_5578
IMG_5580

I tried 14555 as it's listed in Wifi Module as the CPort and that didn't work either. It does look like though that QGC is using 14550

That said, when I had the default Baudrate at 921600 QGC would not make a connection either. So, I'm starting to think it's that.

Does it work if you update the ESP8266 to the latest version from https://github.com/dogmaphobic/mavesp8266?

@julianoes Yes. It already has the latest V 1.2.2. I followed these instructions using the pre built binary.

Thanks to @MatejFranceskin, we realized that QGC has specific code for ESP8266. It is running as a "WiFi Bridge", I don't think MAVSDK supports that.

Does that make sense to you, @julianoes? It would mean that we should bring that into MAVSDK somehow.

Oh, maybe we just need to connect using TCP instead of UDP.

No, UDP should work. There is a page on using this in the PX4 user guide: https://docs.px4.io/master/en/telemetry/esp8266_wifi_module.html

Last time we had problems with this it proved to be a Windows firewall issue. It is also important to note that the firmware on the module must match the baud rate you are using to connect.

PS Gus is the expert on this module.

@hamishwillee I did have to modify the baud rate from 921600 to 57600 because I'm using a Sik telemetry radio. Is there anyway to set the baud rate in the SDK? I couldn't find anything in the documentation.

@unipheas I have no idea, but probably not. I was providing the info mostly so that @julianoes doesn't go off exploring TCP, and talks to Gus who wrote that ESP8266 module code. I'm sure Julian will be able to evaluate what now needs to happen with the SDK.

I did have to modify the baud rate from 921600 to 57600 because I'm using a Sik telemetry radio.

Now I'm confused. Which one are you using now?

A serial connection would be defined by the string: serial:///dev/ttyUSB0:57600 for example.

I am using the ESP-12F (ESP8266) WiFi Module. It does have the MavLink ESP8266 Firmware V 1.2.2 installed. I did have to change the UART_BAUDRATE to 57600 because the Sik Radio isn't compatible with 921600. I'm using the Holybro 433Mhz 100mW Sik Telemetry Radio.

I show an image of the setup above.

If I define that as the address will it still work on the iPhone/iPad? I'm connecting the iPhone/iPad to the Wifi of the ESP8266 (PixRacer).

Ok, got it. Can you connect to the wifi module using something other than the phone first and check with Wireshark if mavlink messages are arriving?

Sorry it took so long to get back to you on this @julianoes. So, the Sik Telemetry Radio is sending a broadcast to 192.168.4.255 of src-port: 14555 to dest-port: 14550. I am getting zero readouts from 192.168.4.2 (iPhone with Swift Example app). So, that leads me to believe it is not picking up anything and sending any handshakes or whatever back.

However, as soon as I boot up QGC then the network lights up and I see communication.

However, as soon as I boot up QGC then the network lights up and I see communication.

I wonder if it works with QGC because it emits heartbeats. You could disable the QGC heartbeats in the settings -> MAVLink -> Ground Station -> Emit heartbeat. Then you restart QGC and check if it still works.

And another thing that comes to mind is this: https://github.com/YUNEEC/Yuneec-SDK-iOS/pull/1/files

I wonder if it works with QGC because it emits heartbeats.

I could imagine that the iPhone ignores the broadcast messages coming from the Sik Telemetry Radio, whereas the Telemetry Radio gets the ones from the iPhone. Which would explain why QGC can connect, as it broadcasts the heartbeats.

Then you restart QGC and check if it still works.

Restart everything, including the drone side. If the connection is opened from one side, it may still work without the broadcast messages, I believe. So restarting the drone/Telemetry Radio together with QGC will make sure it is a fresh connection.

This said, @julianoes or @hamishwillee do you know why QGC has code specific to this device?

No, talk to Gus. As above though the most popular reasons for failure I've seen with QGC are mismatch of baud rate (ie does SDK use same rate as QGC and ESP...) and Windows firewall (though i assume you are working on Linux).

@hamishwillee Yea, I agree with you. I think it's the baud rate.

I'm going to test the heartbeat for QGC and get back to everyone here in a bit.

I just tested the heartbeat. After disabling it QGC was still able to connect.

I'm getting a different radio sent to me. I'll see if I can't connect without changing the baud rate and if it makes any difference.

Reading your discuss post here, can we say that setting the baudrate with drone.setMavlinkPort(mavlinkPort: "serial:///dev/ttyusb0:57600") solved it?

In which case we could close this issue, right?

Reading your discuss post here, can we say that setting the baudrate with drone.setMavlinkPort(mavlinkPort: "serial:///dev/ttyusb0:57600") solved it?

In which case we could close this issue, right?

I haven't yet been able to test this. I'm still waiting for parts in the mail. As soon as I can confirm this works then I will update here. It should be a few more days then I'll have the parts.

I've just tested and it didn't work. Here is the error message

2019-07-20 12:48:51.380155+0800 DronecodeSDK_Swift_Example[1074:1642001] [DYMTLInitPlatform] platform initialization successful
2019-07-20 12:48:51.521163+0800 DronecodeSDK_Swift_Example[1074:1641842] creating player instance using shared library
Running backend in background (MAVLink port: serial:///dev/ttyUSB0:57600
[12:48:51|Info ] DronecodeSDK version: 0.17.0 (dronecode_sdk_impl.cpp:25)
[12:48:51|Debug] New: System ID: 0 Comp ID: 0 (dronecode_sdk_impl.cpp:338)
[12:48:51|Info ] Server set to listen on 0.0.0.0:50051 (grpc_server.cpp:44)
[12:48:51|Info ] Server started (grpc_server.cpp:28)
[12:48:51|Info ] Waiting to discover system... (connection_initiator.h:58)
[12:48:51|Error] open failed: No such file or directory (serial_connection.cpp:87)
[12:48:51|Error] Connection failed: Connection error (connection_initiator.h:47)

And does it actually exist? E.g. ls /dev/ttyUSB0?

Well, I don't think so because it's on the iPhone and there is no USB on the iPhone. The iPhone is connected to the ESP8266 device through Wifi. This is what I was told to try so I gave it a shot.

So my guess (but I have not clue) is that maybe the code specific to ESP8266 in QGC tells ESP8266 to change the baudrate over the UDP connection. Because your iPhone sees a UDP connection to ESP8266, and ESP8266 has a serial connection to the drone. And the baudrate exists on the latter only, which your iPhone doesn't know.

Right.

@hamishwillee I did have to modify the baud rate from 921600 to 57600 because I'm using a Sik telemetry radio. Is there anyway to set the baud rate in the SDK? I couldn't find anything in the documentation.

I mentioned this earlier but I don't know how to change the baud rate through code so it'll work.

Now, I understand I could just wire the ESP8266 directly to the PX4 for development purposes, but if I were to do any field testing or build an app to do something specific then it wouldn't work because I do not have the range as with the telemetry radios, or am I wrong? I didn't think this little device would have that kind of range, so it made since to wire it to the telemetry radios for practical usage.

I've been told that the RFD900x is the only radio to support a 921600 baud rate, but it's a $300 radio.

If QGC can do it, we should find a way, too.

QGC has baudIndex() that returns an index depending on the baudrate of the module, which apparently supports 57600, 115200, 230400, 460800, and 921600.

And it can also setBaudIndex, somehow, with:

Fact* b = getParameterFact(MAV_COMP_ID_UDP_BRIDGE, QStringLiteral("UART_BAUDRATE"));
b->setRawValue(baud);

But I'm not sure how exactly this works.

@dogmaphobic: would you have some insight on that ESP8266 module? Do you connect on UDP, and then send a UDP message to set the baudrate of the module? Or is it all done on QGC's side?

@dogmaphobic: would you have some insight on that ESP8266 module? Do you connect on UDP, and then send a UDP message to set the baudrate of the module? Or is it all done on QGC's side?

The ESP8266 module has its own set of parameters. You set the baud rate (among other things) by setting the UART_BAUDRATE parameter to the MAV_COMP_ID_UDP_BRIDGE compID.

I've set the baud rate manually within the module. I've also set the baud rate within QGC, manually. They are communicating with each other.

@dogmaphobic what way does QGC connect to the ESP8266 on the iPhone then? Is it UDP on 14550 or something else?

The ESP8266 is the WiFi Access Point. Once you join the iPhone to it, it's part of the network. The module will broadcast MAVLink messages (to x.x.x.255). Once it receives a reply from a node, it changes the "255" to the node's actual IP address and resumes point-to-point communication. Messages are all UDP sent to x.x.x.x:14550.

@unipheas so all that should be required is:

drone.setMavlinkPort(mavlinkPort: "udp://:14550")

@unipheas so all that should be required is:

drone.setMavlinkPort(mavlinkPort: "udp://:14550")

I've tested this and it doesn't seem to work either. This is the response.

2019-07-24 14:16:24.494280+0800 MAVSDK_Swift_Example[1514:305035] [DYMTLInitPlatform] platform initialization successful
2019-07-24 14:16:24.593350+0800 MAVSDK_Swift_Example[1514:304991] creating player instance using shared library
Running backend in background (MAVLink port: udp://:14550
[02:16:24|Info ] MAVSDK version: 0.18.3 (mavsdk_impl.cpp:25)
[02:16:24|Debug] New: System ID: 0 Comp ID: 0 (mavsdk_impl.cpp:333)
[02:16:24|Info ] Server set to listen on 0.0.0.0:50051 (grpc_server.cpp:44)
[02:16:24|Info ] Server started (grpc_server.cpp:28)
[02:16:24|Info ] Waiting to discover system... (connection_initiator.h:58)

@julianoes: In my understanding, setting the baudrate may be necessary, and QGC does that. Or am I wrong?

Gus said:

The ESP8266 module has its own set of parameters. You set the baud rate (among other things) by setting the UART_BAUDRATE parameter to the MAV_COMP_ID_UDP_BRIDGE compID.

Which I understand as "ESP8266 is a MAVLink component on the system, and we can set its params, one of which is the baud rate". So if there is a need to set the baud rate, we need to send a MAVLink message to ESP8266. Does that make sense?

Some more information after discussing with @unipheas:

  • The setup works with QGC, not with MAVSDK
  • MAVSDK is started with drone.setMavlinkPort(mavlinkPort: "udp://:14550"), which should be correct
  • It seems like the baudrate is not the issue: it can be set through a web interface
  • @unipheas did not enter the IP of the ESP8266 module manually, so QGC does discover it
  • When using wireshark, @unipheas did not see any heartbeat

My question would be: how does QGC connect to ESP8266, if it doesn't listen to heartbeats? ๐Ÿ˜…

My question would be: how does QGC connect to ESP8266, if it doesn't listen to heartbeats?

QGC does wait for a heartbeat. Only once it receives a heartbeat from the autopilot will it create an instance of a vehicle and start a session.

However, as soon as I boot up QGC then the network lights up and I see communication.

I wonder if it works with QGC because it emits heartbeats. You could disable the QGC heartbeats in the settings -> MAVLink -> Ground Station -> Emit heartbeat. Then you restart QGC and check if it still works.

@julianoes Mentioned disabling the heartbeat in QGC, but it seems it's the other way around. So, basically, we need MAVSDK to listen for a heartbeat then. @JonasVautherin does it already do that?

So, basically, we need MAVSDK to listen for a heartbeat then. @JonasVautherin does it already do that?

Yes, and that's how it discovers all vehicles all the time. So I don't get why QGC receives heartbeats and not MAVSDK ๐Ÿ˜•.

@JonasVautherin Okay. Like I mentioned to you before, I'm going to play around with the MAVSDK on the MacBook and dig into this more.

UPDATE!! It now works, but I don't know why.

So, as you know when I side load the Example App onto my iPhone it wasn't establishing a connection using the ESP8266 Wifi Module wired to the HB Telemetry radio. However, today I used my computer and the Xcode Simulator to see if it would make the connection, and it did immediately. I was able to arm the drone and everything. So, I then connected my iPhone to the same Wifi network (Pixracer) and started the Example App. It took about 5 seconds to make a connection then after 4 seconds it disconnected. I waited another 15 second and it made the connection again. Now it seems to just be working.

I'm using drone.setMavlinkPort(mavlinkPort: "udp://:14550")

Do you think that because I first used the computer it somehow "enabled" something? I don't understand why it's working now.

@unipheas it's not this, right?
https://github.com/YUNEEC/Yuneec-SDK-iOS/pull/1/files

That might actually be the problem, a network request issue within the app. But I'm not sure why it would work now and not before since I haven't given the app permission since. That said, it wouldn't hurt to implement a dialog to ask for permission from the user. I think that's a separate issue though. Generally those dialogs would be used for production apps though, not something like this.

I think we can close this now. What does everyone think?

Yep, thanks for following up!

Makes sense to close - but I'd still like to know why this module is giving us so much pain.

I feel like we'll deal with this in a bug in the future or something, haha

I feel like we'll deal with this in a bug in the future or something, haha

I'm sure we will. Again and Again and again. @JonasVautherin Grab the module while you're in the office - I'm sure you'll need it one day :-)

I wonder if this has anything to do with the issues we are having

https://mavlink.io/en/guide/mavlink_version.html#semi-transparent-legacy-radios