Hi! I have a Raspberry Pi 4B and a SpeedyBee F405WING and I’m trying to send and recieve MAVLink packets on my Pi with a JS script.
I connected the cables like this shown on the docs:
Ground to ground, FC RX to Pi TX, FC TX to Pi RX.
I put together this script (mostly took it from the this example on the repo)
#!/usr/bin/env -S npx ts-node
import { SerialPort } from "serialport";
import {
MavLinkPacketRegistry,
MavLinkPacketSplitter,
MavLinkPacketParser,
MavLinkPacket,
minimal,
common,
ardupilotmega,
waitFor,
send,
MavLinkProtocolV2,
} from "node-mavlink";
const REGISTRY: MavLinkPacketRegistry = {
...minimal.REGISTRY,
...common.REGISTRY,
...ardupilotmega.REGISTRY,
};
async function main() {
// Create an output stream to write data to the controller
const port = new SerialPort({ path: "/dev/serial0", baudRate: 115200 });
// Create the reader as usual by piping the source stream through the splitter
// and packet parser
const reader = port
.pipe(new MavLinkPacketSplitter())
.pipe(new MavLinkPacketParser());
// A flag that determines if the remote system is alive
let online = false;
reader.once("readable", () => {
console.log("ready to read");
});
reader.once("error", (err) => {
console.error(err);
});
// React to packet being retrieved.
// This is the place where all your application-level logic will exist
reader.on("data", (packet: MavLinkPacket) => {
// Output generic debug information about this packet
console.log(packet.debug());
online = true;
const clazz = REGISTRY[packet.header.msgid];
if (clazz) {
const data = packet.protocol.data(packet.payload, clazz);
console.log(">", data);
} else {
console.log("!", packet.debug());
}
});
// Wait for the remote system to be available
await waitFor(() => online);
const motorTestCommand = new common.DoMotorTestCommand();
motorTestCommand._param1 = 1; // motor id
motorTestCommand._param2 = common.MotorTestThrottleType.THROTTLE_PERCENT; // type of input
motorTestCommand._param3 = 100; // throttle percent
motorTestCommand._param4 = 1; // timeout
motorTestCommand._param5 = 4; // amount of motors to test
motorTestCommand._param6 = common.MotorTestOrder.DEFAULT;
// The default protocol (last parameter, absent here) is v1 which is
// good enough for testing. You can instantiate any other protocol and pass it
// on to the `send` method.
// The send method is another utility method, very handy to have it provided
// by the library. It takes care of the sequence number and data serialization.
console.log("Preparing to send motor test command...");
console.log("Motor test command:", motorTestCommand);
try {
await send(port, motorTestCommand, new MavLinkProtocolV2());
console.log("Motor test command sent successfully.");
} catch (err) {
console.error("Error sending motor test command:", err);
}
port.flush((err) => {
if (err) {
console.error("Error flushing port:", err);
} else {
console.log("Port flushed successfully.");
}
});
}
console.log("running main");
main();
It does recieve Heartbeat and TimeSync packets but it doesn’t send any packets.
To confirm it wasn’t an issue with my code I also tried using MAVProxy following the docs
And the same thing,
tulpar@tulparpi:~ $ python3 .local/bin/mavproxy.py --master=/dev/serial0 --baudrate 115200 --aircraft MyCopter
Connect /dev/serial0 source_system=255
no script MyCopter/mavinit.scr
Log Directory: MyCopter/logs/2025-04-15/flight12
Telemetry log: MyCopter/logs/2025-04-15/flight12/flight.tlog
Waiting for heartbeat from /dev/serial0
MAV> Detected vehicle 1:1 on link 0
online system 1
STABILIZE> Mode STABILIZE
STABILIZE> param show ARMING_CHECK
STABILIZE>
The log file (MyCopter/logs/2025-04-15/flight12/flight.tlog) does not contain any data and is 0 bytes.
Any guesses? Any help would be appriciated. Thanks in advance.