How to send message to drone via visual C# program, Serial Port

I am trying to create a small GCS Program, but i was not able to find how can i use the header files generated from mavlink, i am not able to find any documentaion, can someone point me to the documentation? or give me a sample code, for the heartbeat message , or how can i create it? and send using System.IO.SerialPort?

i tried understanding from mission planner, bt its too vast to understand

Thanks in advance

Here is a link to the code: Github Mavlink

C and C++ are prebuilt but C# requires that you download a Python environment to generate the C# files needed.

I was lost like you too until I piece this together.

Mike

Thanks for reply, I generated the header files, but i am not able to understand the basic flow of packing the data and sending it via serial port.so i need a sample code for the basic flow of sending and receiving. i tried one example given on qgroundcontrol, but serial.writeline takes only one string

I am using visual studio 2015, and SerialPort.writeline, but its not working, am i missing something here?
is there any other serial port library which i can use?

Mavlink code wants to do everything. What happens is you get some raw data in and you pass that packet of data to Mavlink and it does it thing looking for stuff that matches and then builds a Message.

The then does a call to your function with this decoded packed and you need to cast it back to the right packet.

Things get a little strange with C# since it doesn’t like you playing around with binary data and then stuffing it into and object. The C version is a little more straight forward but works the same.

To send Mavlink packets you fill in the object you want to send and it will build and send the packet or you can use the build function to just build the packet and you have to convert it to a serial object to send.

It’s been a while since I did this and it took some time to understand what was happening.

Here is a GitHub sample that reads from a com port: MavlinkReader

It’s from a couple of year ago so the Mavlink libraries are not up to date.

Mike

1 Like

Thank You Mike, I will try it and see if i can understand. also i am fine with C/C++, if that makes it easier.

Thanks for the help :slight_smile:

Hey, that code helped me a lot in receiving data, but i am unable to pack the code for arming the rotor. how can i send the code for arming ?

thanks in advance :slight_smile:

Is been a while and I don’t remember what I did. But here is some sample code that I wrote for a microcontroller to read Mavlink data from one copter and send to another copter. Whatever height the first copter was at it would tell the second copter to change to that height.

This was written in C code so it should be similar to C#. I don’t think I implemented an arm and takeoff command so that may take some work. My code stepped in once the copters were off the ground.

Mike
Coptering

1 Like

Thanks a lot, i will check it out :slight_smile:

Hello @iseries
Thank you very much for your code sharing, it is a excellent working. Your c# code worked for me too with pixhawk.
I can read mavlink data from pixhawk. But I couldnt see how can write mavlink data to pixhawk. I want to do this with your c# project code. Your code can do that ??? can you help me ?

edit: I checked your https://github.com/iseries1/Coptering code. you write mavlink command. But I am not good at microcontroller C programming, so I need to do this with c#.
thank you…

Sorry, never got that far with the application. C# got in the way of the code and was easier to do in standard c code.

You may want to look at Mission Planner or QGround Control to see how they built there mavlink messages.

Mike

Hello, Guys i have the same problem as you
i did a program but i’m just receiving the heartbeat can anyone help please. i’m sending a request to receive attitude (id==30) but don’t receive anything. I am desperate
Can you check my code please

    public int i;
    MAVLink.MAVLinkMessage t = new MAVLink.MAVLinkMessage();
    SerialPort mySerialPort = new SerialPort("COM14");
    public static MAVLink.Mavlink_heartbeat_t hb = new MAVLink.Mavlink_heartbeat_t();
    List<byte> heartbeatData = new List<byte>();

    public Form1()
    {
        InitializeComponent();
        OpenSerialPort();
    }
    private void OpenSerialPort()
    {

        mySerialPort.BaudRate = 57000;
        mySerialPort.Parity = Parity.None;
        mySerialPort.StopBits = StopBits.One;
        mySerialPort.DataBits = 8;
        mySerialPort.Handshake = Handshake.None;

        try
        {
            mySerialPort.DataReceived += SerialPortDataReceived;
            mySerialPort.Open();
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(ex.Message + ex.StackTrace);
        }
    }

    private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        Mavlink_request_data(30, 0x02);
        var serialPort = (SerialPort)sender;
        var data = serialPort.ReadByte();
        Console.WriteLine("Data : " + data);
        heartbeatData.Add((byte)data);
    }

    void Mavlink_request_data(byte id, byte rate)
    {
        
        MAVLink.MAVLinkMessage mAVLinkMessage = new MAVLink.MAVLinkMessage();

        uint[] buffer = new uint[MAVLink.MAVLINK_MAX_PACKET_LEN];
        MAVLink.MAVLinkParamList mAVLinkParams = new MAVLink.MAVLinkParamList();
        MAVLink.Mavlink_request_data_stream_t req = new MAVLink.Mavlink_request_data_stream_t
        {
            target_system = 1,
            target_component = 1,

            req_message_rate = rate,
            start_stop = 1, // start
            req_stream_id = (byte)id // id
        };

        // send each one twice.
        GeneratePacket((byte)MAVLINK_MSG_ID.REQUEST_DATA_STREAM, req);
        GeneratePacket((byte)MAVLINK_MSG_ID.REQUEST_DATA_STREAM, req);

    }

    void GeneratePacket(byte messageType, object indata)
    {
        if (!mySerialPort.IsOpen)
        {
            return;
        }            

       
            byte[] data;

            data = MavlinkUtil.StructureToByteArray(indata);

            //Console.WriteLine(DateTime.Now + " PC Doing req "+ messageType + " " + this.BytesToRead);
            byte[] packet = new byte[data.Length + 6 + 2];

            packet[0] = 254;
            packet[1] = (byte)data.Length;
            packet[2] = (byte)0; //numero de la sequence ici

            

            packet[3] = 255; // this is always 255 - MYGCS
            packet[4] = (byte)MAV_COMPONENT.MAV_COMP_ID_MISSIONPLANNER;
            packet[5] = messageType;

            int i = 6;
            foreach (byte b in data)
            {
                packet[i] = b;
                i++;
            }

            ushort checksum = MavlinkCRC.crc_calculate(packet, packet[1] + 6);

            checksum = MavlinkCRC.crc_accumulate(MAVLINK_MESSAGE_CRCS[messageType], checksum);

            byte ck_a = (byte)(checksum & 0xFF); ///< High byte
            byte ck_b = (byte)(checksum >> 8); ///< Low byte

            packet[i] = ck_a;
            i += 1;
            packet[i] = ck_b;
            i += 1;

            if (mySerialPort.IsOpen)
            {
                mySerialPort.Write(packet, 0, i);
            }                

    }

Hello Sharma did you find how to read the mavlink message, i didn’t understood how to use the github code gived by iseries, and i did my version so can you help please .
I am desperate :stuck_out_tongue:

ArduPilot/MissionPlanner GCS is an open-source software written in c# and uses Mavlink Library.

You can find the library in the below link and can see how it is used inside the MissionPlanner project:

Is this code created with Visual Studio?

Yes, I think with Visual Studio 2017.

Mike