Sending Data from Raspberry Pi to QgroundControl

Hi,
After some attempts to write custom drivers for a sensor I am hoping to integrate, I have decided that the best way to use it is by having an Arduino read all the data and send that over serial to the Raspberry Pi.

I was wondering therefore how to get the data from Raspberry Pi to Qgroundcontrol. I understand that I should use NAMED_VALUE_FLOAT, but I was wondering where I should place the code.

Thanks for all your help

You may read the sensor with the python serial module. Then you may send the value with the pymavlink module using the named_float_send function. This code needs to live on the Raspberry Pi.

Yes, I understand that. Where should I put the code on the Raspberry Pi, so that it’ll be running all the time?

You can add a line to /etc/rc.local to start the program at boot

Great. So I have this code now.

import serial
from pymavlink import mavutil

master = mavutil.mavlink_connection(‘udp:192.168.2.1:14550’)

ser = serial.Serial(‘/dev/ttyACM1’, 9600)

while 1:
read_ser = ser.readline()
data = [int(s) for s in read_ser.split() if s.isdigit()]
temp = data[0]
humidity = data[1]

CHECK_PAYLOAD_SIZE(NAMED_VALUE_INT)
send_named_int(“intTemp”, temp)

CHECK_PAYLOAD_SIZE(NAMED_VALUE_INT)
send_named_int(“intHum”, humidity)

Would this be the proper way to implement the named_float_send function? What would be if not?

Something like that, it looks like you have pulled some code out of ardupilot, which is written in c++, not python. I think the CHECK_PAYLOAD_SIZE macro does not exist in your python code.

Do you know exactly how I’d be able to implement it?

You don’t need to, just take it out and use the send_* methods only like the examples here: Pymavlink · GitBook

Alright. One more question: I am getting this error:

Traceback (most recent call last):
File “send_sensors.py”, line 5, in
master = mavutil.mavlink_connection(‘udp:192.168.2.1:14550’)
File “/usr/local/lib/python2.7/dist-packages/pymavlink-2.2.4-py2.7-linux-armv7
l.egg/pymavlink/mavutil.py”, line 1221, in mavlink_connection
return mavudp(device[4:], input=input, source_system=source_system, source_c
omponent=source_component, use_native=use_native)
File “/usr/local/lib/python2.7/dist-packages/pymavlink-2.2.4-py2.7-linux-armv7
l.egg/pymavlink/mavutil.py”, line 880, in init
self.port.bind((a[0], int(a[1])))
File “/usr/lib/python2.7/socket.py”, line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 99] Cannot assign requested address

This seems to me as if I can not assign that as the address to send the message to, however that is the address for QGroundcontrol no? What is the problem?

You can only receive data at your address. 192.168.2.1 is not the raspberry pi’s ip address and that is your problem.

You should use 0.0.0.0:9000. You can configure other addresses to send your data to at http://192.168.2.2:2770/mavproxy.

So now with this:

master.mav.send_named_float(“intTemp”, temp)
master.mav.send_named_float(“intHum”, humidity)

I get the error:

Traceback (most recent call last):
File “send_sensors.py”, line 24, in
master.mav.send_named_float(“intTemp”, temp)
AttributeError: ‘MAVLink’ object has no attribute ‘send_named_float’

Do you know what the actual command I should use is?

So I believe that it should be sending the values now. How can I view them in QGC?

If they are coming, they should show up in the mavlink inspector widget. You will probably need to modify QGC code to handle the data in a useful way.

I’m not seeing anything…

I was mistaken here, you do want to use udpout:192.168.2.1:14450

It goes message_name_send, so you should do named_value_float_send.

Make sure you are using udpout:192.168.2.1:14550, and try sending a heartbeat message using sysid=2, compid=2, then it should show a heartbeat separately from the normal autopilot telemetry. (I know the widget will show heartbeats, maybe it will not show named_value_int).

You can use network tools like netcat or wireshark to verify that data is coming in on the expected port (maybe unplug the autopilot so that telemetry does not come through while you are working on it).

How would I do that? Just looking at the parameters for the heartbeat message, they seem to be:

Field Name Type Description
type uint8_t Type of the MAV (quadrotor, helicopter, etc., up to 15 types, defined in MAV_TYPE ENUM)
autopilot uint8_t Autopilot type / class. defined in MAV_AUTOPILOT ENUM
base_mode uint8_t System mode bitfield, as defined by MAV_MODE_FLAG enum
custom_mode uint32_t A bitfield for use for autopilot-specific flags
system_status uint8_t System status flag, as defined by MAV_STATE enum
mavlink_version uint8_t_mavlink_version MAVLink version, not writable by user, gets added by protocol because of magic data type: uint8_t_mavlink_version

You would use the heartbeat_send function. All mavlink messages take this form, with the fields of the message as arguments to the function.

Yes, I was wondering how to have sysid and compid be 2, when there seems to be no way to do that in the heartbeat message