christianrauch / msp

Implementation of the MultiWii Serial Protocol (MSP) for MultiWii and Cleanflight flight controller
http://www.multiwii.com/wiki/index.php?title=Multiwii_Serial_Protocol
GNU Lesser General Public License v3.0
73 stars 26 forks source link

Can't use MSP on quadrino #35

Closed PatrickCesar closed 5 years ago

PatrickCesar commented 5 years ago

Hi,

I can't connect my quadrino nano to MSP. The client_read_test always returns the following:

./client_read_test / dev / ttyUSB0
message failed to send
unsupported: 100
message failed to send
unsupported: 101
message failed to send
unsupported: 102
message failed to send
unsupported: 103
message failed to send
unsupported: 104
message failed to send
unsupported: 105
message failed to send
unsupported: 108
message failed to send
unsupported: 109
message failed to send
unsupported: 110
message failed to send
unsupported: 111
message failed to send
unsupported: 112
message failed to send
unsupported: 113
message failed to send
unsupported: 114
message failed to send
unsupported: 115
message failed to send
unsupported: 116
message failed to send
unsupported: 117
message failed to send
unsupported: 119
message failed to send
unsupported: 120
message failed to send
unsupported: 253
message failed to send
unsupported: 254
PROGRAM COMPLETE

I've enabled #define USE_MSP_WP in multiwii 2.4 code.

wx4cb commented 5 years ago

You dont have spaces in your device node. It should be /dev/ttyUSB0

On Tue, Apr 23, 2019, 11:29 PatrickCesar notifications@github.com wrote:

Hi,

I can't connect my quadrino nano to MSP. The client_read_test always returns the following:

./client_read_test / dev / ttyUSB0 message failed to send unsupported: 100 message failed to send unsupported: 101 message failed to send unsupported: 102 message failed to send unsupported: 103 message failed to send unsupported: 104 message failed to send unsupported: 105 message failed to send unsupported: 108 message failed to send unsupported: 109 message failed to send unsupported: 110 message failed to send unsupported: 111 message failed to send unsupported: 112 message failed to send unsupported: 113 message failed to send unsupported: 114 message failed to send unsupported: 115 message failed to send unsupported: 116 message failed to send unsupported: 117 message failed to send unsupported: 119 message failed to send unsupported: 120 message failed to send unsupported: 253 message failed to send unsupported: 254 PROGRAM COMPLETE

I've enabled #define USE_MSP_WP in multiwii 2.4 code.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/christianrauch/msp/issues/35, or mute the thread https://github.com/notifications/unsubscribe-auth/AALNCAJF7N3MLTO47MAJFOLPR4TMJANCNFSM4HHZDBZA .

PatrickCesar commented 5 years ago

I have the same output even without the spaces. With MultiwiiConf a can see every controller parameters, but using MSP I have this output

christianrauch commented 5 years ago

I do not have a real flight controller at hand, but I am getting the same message if I try to connect to an unavailable serial device. The example programs are trying to open a connection without checking the return value of the open method. With PR https://github.com/christianrauch/msp/pull/36, I replaced this with exceptions. Can you try to connect with the open_exception branch and check for unhandled exceptions? When connecting to an unavailable device, an error message like Error when opening '/dev/ttyUSB0': No such file or directory (error code: 2) should be thrown.

PatrickCesar commented 5 years ago

It was a permission problem, Error when opening '/dev/ttyUSB0': Permission denied (error code: 13), but now when I run the program nothing appears, no error or anything. But when I use the MultiwiiConf, i can get all the parameters from the controller.

PatrickCesar commented 5 years ago

Using msp_connection_test from the async branch, I have this output:

./msp_connection_test 
Connected to: /dev/ttyUSB0
Waiting for flight controller to become ready...

And nothing more happens. When I interrupt, the controller beeps as if it has just been turned on.

christianrauch commented 5 years ago

Make sure that you use the correct baudrate. The examples use 115200 baud by default.

Is your flight controller connected via USB (with integrated converter) or is it directly connected via serial? There are some Arduino boards which reset themself when establishing a connection via the integrated USB-to-serial converter. In this case, the micro controller misses first message (request) and the library is blocking since it waits indefinitely for a response.

You can try to insert a delay of multiple seconds between opening the serial connection and sending the first messages.

PatrickCesar commented 5 years ago

The baud rate is correct, and the controller is connected via USB. I've inserted a delay of 1s and the msp_read_test worked. Now I'm trying to use fcu_test, but it doesn't work. No error is displayed

christianrauch commented 5 years ago

Which version of the library are you actually using? The examples msp_read_test and msp_connection_test do not exist for the current version. In any case, you will need to add this delay after every opening of the port, i.e. after each call to Client::connectPort.

If there is need for this delay functionality, I could make it part of the API as optional parameter for connectPort. But it is merely a workaround for the strange behaviour of the Arduino.

PatrickCesar commented 5 years ago

I've modified the Client::connectPort putting a delay at the end, like this:

bool Client::connectPort(const std::string& device, const size_t baudrate) {
    asio::error_code ec;
    port.open(device, ec);
    if(ec) return false;
    port.set_option(asio::serial_port::baud_rate(baudrate));
    port.set_option(asio::serial_port::parity(asio::serial_port::parity::none));
    port.set_option(asio::serial_port::character_size(
        asio::serial_port::character_size(8)));
    port.set_option(
        asio::serial_port::stop_bits(asio::serial_port::stop_bits::one));
    std::this_thread::sleep_for(std::chrono::seconds(1));
    return true;
}

Now the fcu_test works, but I'm still having problem with client_read_test and client_async_test. The fcu_arm is not arming either

./fcu_arm 
making FC
#Status:
 Cycle time: 2800 us
 I2C errors: 0
 Sensors:
    Accelerometer: ON
    Barometer: ON
    Magnetometer: ON
    GPS: OFF
    Sonar: OFF
 Active Boxes (by ID):
#Ident:
 MultiWii Version: 240
 MSP Version: 0
 Type: Quadrocopter Plus
 Capabilities:
    Bind:   OFF
    DynBal: OFF
    Flap:   OFF
# Box names:
 0: ARM
 1: ANGLE
 2: HORIZON
 3: BARO
 4: MAG
 5: BEEPER

#Box IDs:
 0: 0
 1: 1
 2: 2
 3: 3
 4: 5
 5: 13

#Channel mapping:
 0: 0
 1: 0
 2: 0
 3: 0
ready after: 1732 ms
rx config: 0
Armed? 0
Arming...
Disarming...
disarmed after: 0 ms
christianrauch commented 5 years ago

@PatrickCesar According to https://tushev.org/articles/arduino/22/preventing-arduino-from-auto-reset-when-com-port-opens-closes, the reset behaviour can be changed by disabling Data Terminal Ready (DTR). And according to https://raspberrypi.stackexchange.com/a/27706, this can be done on the command line via stty -F /dev/ttyUSB0 -hupcl. Can you test if you can connect without the delay but by disabling DTR?

Arming: Can you check out the most recent version of the library? The example programs you are referring too have been removed. The dedicated arming method has been removed because it causes a transition into failsafe mode right after if there is no constant stream of RC values send to the FC. You need to arm via the stick configuration that is set up for your FC. There is no dedicated MSP message to arm the FC.

Which issues are persistent after a successful connection?

christianrauch commented 5 years ago

@PatrickCesar I disabled the DTR after establishing the serial connection. Can you test if the example program in the disable_dtr branch work, without any of the other workarounds (adding the delay, manually disabling DTR on the command line via stty)?

PatrickCesar commented 5 years ago

Before I was using msp 3.0.0, now I tested cloning the master an worked with the delay. I had already tried the command to disable the DTR and it hadn't worked. The disable_dtr hadn't worked as well. Using the delay in the client is working so far for what I need, considering that now I can control the motors and receive messages using the FCU. Now I will try to use the ros-multiwii package to connect to the drone.

Update: client_async_test works using the delay, but client_read_test don't works.

christianrauch commented 5 years ago

I tested with MultiWii 2.4 on an Arduino Nano with the integrated USB-to-serial converter. After stty -F /dev/ttyUSB0 -hupcl I am able to run the fcu_test example successfully, but the client_read_test still hangs at some point. You should be able to run fcu_test without the delay workaround by executing stty -F /dev/ttyUSB0 -hupcl beforehand.

The change to the DTR settings on the disable_dtr branch only takes effect after the process exits, i.e. it is only effective when connecting the second time. This is probably because the Arduino restarts the first time (before the DTR settings becomes active) and is still rebooting after the DTR settings have changed and the second connection via ASIO is established. It takes a restart of the process (or a delay again), to connect successfully. I would basically recommend to change the DTR setting outside of the library (e.g. via stty or a script), because setting this inside the library would require to have some cumbersome workaround that includes a delay. This could be automated with a script that runs once a USB-to-serial device gets connected.

christianrauch commented 5 years ago

@PatrickCesar I got client_read_test working by setting the MSP version to the default (1). The example set the MSP version via setVersion(2) to version 2, which is a remnant from the big MSPv2 merge. The original MultiWii firmware only supports MSP version 1.

I believe that https://github.com/christianrauch/msp/pull/36 should allow you to run all the examples if you properly deactivate DTR via stty -F /dev/ttyUSB0 -hupcl beforehand. At least the examples client_async_test, client_read_test, fcu_custom_type and fcu_test work on my setup with the Arduino Nano and MultiWii 2.4

PatrickCesar commented 5 years ago

Sorry for taking a while to respond, I have not been to the lab in the past few days. Using the open_exception branch, it worked with the delay workaround, but it did not work with the command stty -F /dev/ttyUSB0 -hupcl. Now I can run all the examples, however I'm having problems using ros-multiwii, having subscription errors.

christianrauch commented 5 years ago

Ok, in this case, one needs to add this delay workaround manually to user code. I do not want to add an additional delay after connection as a workaround for a very small set of FC hardware.

I added the information about deactivating the DTR line via stty -F /dev/ttyUSB0 -hupcl to the documentation since it worked for connecting to the Arduino Nano.

For other ROS related issues, please open an issue in the corresponding repo.