Ich habe einen Raspberry Pi 3B und einen CRIUS All in One Pro (v2.0) MultiWii Flugcontroller. Ich benutze die MultiWii 2.4 Version und die neuesten NOOBS. Ich war in der Lage, beides in Ordnung zu bringen, und nun versuche ich, den Raspberry Pi über ein USB/Micro-USB-Kabel, das die beiden Boards verbindet, mit dem MultiWii zu kommunizieren.Raspberry Pi erhält Daten von MultiWii
Momentan gibt das MultiWii keine Daten zurück, und ich bin nicht sicher warum. Von dem, was ich sehen kann, habe ich das Protokoll korrekt. Ich habe mehrere Arbeitscode-Repos (geschrieben in Python von Java für Arduino) angeschaut und bin dem MultiWii documentation gefolgt und habe den zugehörigen forum post gelesen.
Hier ist der Client-Code, den ich geschrieben habe.
package com.jmace.MaceDrone.msp;
import com.pi4j.io.serial.Baud;
import com.pi4j.io.serial.DataBits;
import com.pi4j.io.serial.FlowControl;
import com.pi4j.io.serial.Parity;
import com.pi4j.io.serial.Serial;
import com.pi4j.io.serial.SerialConfig;
import com.pi4j.io.serial.SerialDataEvent;
import com.pi4j.io.serial.SerialDataEventListener;
import com.pi4j.io.serial.SerialFactory;
import com.pi4j.io.serial.StopBits;
import java.io.IOException;
import java.math.BigInteger;
public class MultiWiiClient {
private final Serial serial;
//The preamble is defined by the protocol.
//Every message must begin with the characters $M
private static final String PREAMBLE = "$M";
//Character that denotes information being passed to the MultiWii
private static final char TO_MUTLIWII = '<';
//Character that denotes information being requested from by the MultiWii
private static final char FROM_MUTLIWII = '>';
public MultiWiiClient(String usbPort) {
SerialConfig config = new SerialConfig();
config.device(usbPort)
.baud(Baud._115200)
.dataBits(DataBits._8)
.parity(Parity.NONE)
.stopBits(StopBits._1)
.flowControl(FlowControl.NONE);
this.serial = SerialFactory.createInstance();
serial.addListener(new SerialDataEventListener() {
@Override
public void dataReceived(SerialDataEvent event) {
try {
System.out.println("[HEX DATA] " + event.getHexByteString());
System.out.println("[ASCII DATA] " + event.getAsciiString());
} catch (IOException e) {
e.printStackTrace();
}
}
});
try {
this.serial.open(config);
} catch (Exception e) {
e.printStackTrace();
}
}
public String sendRequest(MultiWiiRequest request) throws IllegalStateException, IOException {
String message = createMessage(request.getId(), false, null);
//////////////////////////////////////////////////////////////////////////////////
System.out.println(message);
System.out.println(String.format("%040x", new BigInteger(1, message.getBytes())));
//////////////////////////////////////////////////////////////////////////////////
return sendMessage(message);
}
public String sendCommand(MultiWiiCommand command, String payload) throws IllegalStateException, IOException {
String message = createMessage(command.getId(), true, payload);
return sendMessage(message);
}
/**
* This method creates the message that will be sent to the MultiWii
*
* Message format is as follows:
* +--------+---------+----+-------+----+---+
* |preamble|direction|size|command|data|crc|
* +--------+---------+----+-------+----+---+
*
* Preamble (2 bytes):
* Marks the start of a new message; always "$M"
*
* Direction (1 byte):
* Either '<' for a command going to the MultiWii or '>' for
* information being requested from the MultiWii
*
* Size (1 byte):
* The number of bytes in the payload
*
* Command (1 byte):
* The message ID of the command, as defined in the protocol
* 100's for requesting data, and 200's for requesting an action
*
* Data (variable bytes):
* The data to pass along with the command
*
* CRC (1 byte):
* Calculated with an XOR of the size, command, and each byte of data
*/
private String createMessage(int mutliWiiCommandnumber, boolean isCommand, String payload) {
StringBuilder message = new StringBuilder(PREAMBLE);
byte checksum=0;
//Get the direction of the message
if (isCommand) {
message.append(TO_MUTLIWII);
} else {
message.append(FROM_MUTLIWII);
}
int datalength = (payload != null) ? payload.length() : 0;
message.append((char) datalength);
checksum ^= datalength;
message.append((char) mutliWiiCommandnumber);
checksum ^= ((int) mutliWiiCommandnumber);
if (payload != null) {
for (char c : payload.toCharArray()){
message.append(c);
checksum ^= (int) c;
}
}
message.append((char) checksum);
return message.toString();
}
private String sendMessage(String message) throws IllegalStateException, IOException {
serial.write(message.getBytes());
serial.flush();
System.out.println("TESTING ------------------");
return "";
}
}
I „/ dev/ttyUSB0“ bin mit zu verbinden, was ich bestätigt ist die korrekte Lage und es scheint (keine Fehler zu arbeiten, wenn ich es laufen, und wenn ich anfangen zu laufen und dann den USB trennen , es löst eine Ausnahme aus, weil es die Verbindung verloren hat).
Beim Laufen, erhalte ich die folgende Ausgabe (Sendebefehl 100, MSP_IDENT):
$M>dd
00000000000000000000000000244d3e006464
TESTING ------------------
Siehe my Git repo für mehr Code Kontext.
EDIT: Der Fehler, der Prüfsummencodes in meinem Beitrag
Sie haben Recht. Ich endete mit einer Weile (serial.available() == 0), um stattdessen auf die Daten zu warten. Ich habe eine Zählung hinzugefügt, um sicherzustellen, dass ich nicht zu lange auf die Daten warte, um zurück zu kommen, sonst könnte ich Threads binden. – Jason