mavlink / MAVSDK-Swift

MAVSDK client for Swift.
https://mavsdk.mavlink.io
BSD 3-Clause "New" or "Revised" License
27 stars 25 forks source link

Not connecting to ESP8266 WiFi Module #134

Closed JonasVautherin closed 5 years ago

JonasVautherin commented 5 years ago

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 https://github.com/mavlink/MAVSDK-Swift/issues/133#issuecomment-505839948

JonasVautherin commented 5 years ago

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?).

unipheas commented 5 years ago

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.

JonasVautherin commented 5 years ago

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) :+1:. 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.

unipheas commented 5 years ago

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.

JonasVautherin commented 5 years ago

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

unipheas commented 5 years ago

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.

julianoes commented 5 years ago

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

unipheas commented 5 years ago

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

JonasVautherin commented 5 years ago

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.

julianoes commented 5 years ago

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

hamishwillee commented 5 years ago

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.

unipheas commented 5 years ago

@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.

hamishwillee commented 5 years ago

@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.

julianoes commented 5 years ago

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.

unipheas commented 5 years ago

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).

julianoes commented 5 years ago

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?

unipheas commented 5 years ago

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.

julianoes commented 5 years ago

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 commented 5 years ago

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

JonasVautherin commented 5 years ago

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?

hamishwillee commented 5 years ago

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).

unipheas commented 5 years ago

@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.

unipheas commented 5 years ago

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.

JonasVautherin commented 5 years ago

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?

unipheas commented 5 years ago

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.

unipheas commented 5 years ago

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)
JonasVautherin commented 5 years ago

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

unipheas commented 5 years ago

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.

JonasVautherin commented 5 years ago

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.

unipheas commented 5 years ago

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.

JonasVautherin commented 5 years ago

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 commented 5 years ago

@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.

unipheas commented 5 years ago

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.

julianoes commented 5 years ago

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

dogmaphobic commented 5 years ago

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.

julianoes commented 5 years ago

@unipheas so all that should be required is:

drone.setMavlinkPort(mavlinkPort: "udp://:14550")
unipheas commented 5 years ago

@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)
JonasVautherin commented 5 years ago

@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?

JonasVautherin commented 5 years ago

Some more information after discussing with @unipheas:

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

dogmaphobic commented 5 years ago

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.

unipheas commented 5 years ago

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?

JonasVautherin commented 5 years ago

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 :confused:.

unipheas commented 5 years ago

@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.

unipheas commented 5 years ago

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.

julianoes commented 5 years ago

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

unipheas commented 5 years ago

@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.

unipheas commented 5 years ago

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

julianoes commented 5 years ago

Yep, thanks for following up!

hamishwillee commented 5 years ago

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

unipheas commented 5 years ago

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