Nicht in der Lage zu Lesen über die Serielle Schnittstelle mittels C# - Mono (RaspberryPi)
Ich bin versucht zu schreiben Sie eine C# - Bibliothek, die die sucht an allen verfügbaren seriellen USB-ports auf einem Raspberry Pi, so dass ich auflisten können, zu identifizieren und kommunizieren mit einer Reihe von Arduinos angeschlossen an den Pi über einen USB-hub.
Ich bin in der Lage, diese Arbeit auf meinem windows-Rechner (mehrere Arduinos verbunden mit meinem desktop-computer) und haben sogar in der Lage, damit es funktioniert auf meinem Pi, aber ich bin kämpfen, um zu verstehen, wie die Verallgemeinerung der fix.
Wenn ich Versuch zu laufen, das Programm selbst auf dem Pi, ich bin in der Lage, öffnen Sie den seriellen port Daten senden kann ich jedoch nicht erhalten nichts von der Arduinos: ich bekomme timeout Ausnahmen. Ich verstehe, dass die Mono-Implementierung von SerialPort ist begrenzt und ich muss SerialPort verwenden.ReadByte() anstelle von Readline() und die empfangenen Daten Ereignisse (meine Lösung basiert auf code von HowToSystemIOPorts). Meine Serielle Schnittstelle enumeration ist eine Methode beschrieben, die in einem anderen stack-exchange-Reaktion hier.
Mein timeout ist derzeit festgelegt auf 4 Sekunden, das ist um Größenordnungen mehr, als ich erwarten, um die Nachricht zu empfangen.
Nach viel googeln, stieß ich auf Erwähnung der Verwendung von minicom initialisiert die serielle Schnittstelle hier, die zu meiner überraschung erlaubt, mich zu empfangen, Daten aus dem Arduino. Der größte Nachteil ist, dass ich zu initialisieren Sie die port mit minicom und verlassen des Prozesses öffnen, jedes mal wenn ich Booten des Pi. Ich kann auch nicht scheinen, um herauszufinden, wie man diese Arbeit mit mehreren Arduinos.
Hier ist, was ich bisher versucht habe:
- Aktualisiert der Pi-firmware und-software, um Ihre neuesten Versionen
- Versucht, auf beide ein Arduino MEGA 2560 R3 und Arduino UNO
- Geändert der Eigentümer des tty* Schnittstellen (ttyACM0 und ttyUSB0 in diesem Fall) meine beiden Benutzer-und Gruppen -
- Erfolgreich konfiguriert den port an, über minicom, Links der Prozess ausgeführt wird, und starten Sie das Programm und lese/schrieb-Daten. Ein manueller Prozess, die nur scheint zu funktionieren für ein Arduino-zu einer Zeit,
- Erfolgreich ausführen des Programms in Windows ohne Fehler
- Überprüft die Arduinos sind anerkannt von der Pi laufen "dmesg | grep tty"
Hier ist, was ich hoffe, zu lösen:
- Automatisches setup/die Initialisierung der Arduino-serial-ports. Ob durch ein shell-Skript ausgeführt wird, bevor das main-Programm oder innerhalb von Mono-code, sodass der untenstehende code kann ausgeführt werden als vorgesehen.
Hier ist meine Verbindungs-code:
public bool StartArduinoComms()
{
string[] ports = GetPortNames();
foreach (string port in ports)
{
mLogger.LogMessage(ProsthesisCore.Utility.Logger.LoggerChannels.Arduino, string.Format("Found serial port {0}", port));
}
bool foundCorrectArduino = false;
var idPacket = new ArduinoMessageBase();
idPacket.ID = ArduinoMessageValues.kIdentifyValue;
string jsonOutput = Newtonsoft.Json.JsonConvert.SerializeObject(idPacket);
foreach (string port in ports)
{
SerialPort serialPort = new SerialPort(port, kArduinoCommsBaudRate);
serialPort.Parity = Parity.None;
serialPort.DataBits = 8;
serialPort.StopBits = StopBits.One;
//Only check unopened ports
if (!serialPort.IsOpen)
{
serialPort.Open();
//Disable telemtry just incase
var toggle = new { ID = ArduinoMessageValues.kTelemetryEnableValue, EN = false };
string disableTelem = Newtonsoft.Json.JsonConvert.SerializeObject(toggle);
serialPort.Write(disableTelem);
//Discard any built up data
serialPort.DiscardInBuffer();
serialPort.Write(jsonOutput);
serialPort.ReadTimeout = kIDTimeoutMilliseconds;
string response = string.Empty;
for (int i = 0; i < kNumRetries; ++i)
{
try
{
//This is guaranteed to timeout if not configured through minicom
response = ReadLine(serialPort);
break;
}
//Catch case where the serial port is unavailable. MOve to next port
catch (TimeoutException)
{
continue;
}
}
if (!string.IsNullOrEmpty(response))
{
//Perform response validation
}
else
{
//Got no response
}
if (!foundCorrectArduino)
{
serialPort.Close();
}
}
}
return foundCorrectArduino;
}
///<summary>
///From https://stackoverflow.com/questions/434494/serial-port-rs232-in-mono-for-multiple-platforms
///</summary>
///<returns></returns>
private static string[] GetPortNames()
{
int p = (int)Environment.OSVersion.Platform;
List<string> serial_ports = new List<string>();
//Are we on Unix?
if (p == 4 || p == 128 || p == 6)
{
string[] ttys = System.IO.Directory.GetFiles("/dev/", "tty*");
foreach (string dev in ttys)
{
//Arduino MEGAs show up as ttyACM due to their different USB<->RS232 chips
if (dev.StartsWith("/dev/ttyS") || dev.StartsWith("/dev/ttyUSB") || dev.StartsWith("/dev/ttyACM"))
{
serial_ports.Add(dev);
}
}
}
else
{
serial_ports.AddRange(SerialPort.GetPortNames());
}
return serial_ports.ToArray();
}
Du musst angemeldet sein, um einen Kommentar abzugeben.
Haben Sie einen Blick auf stty-Befehl. Es wird lassen Sie Sie setzen/Lesen teminal-Einstellungen
http://linux.about.com/od/lna_guide/a/gdelna38t01.htm geben einen überblick über den Einsatz.
Es wäre einfacher zu rufen als minicom, und die Einstellungen bleiben auf dem Gerät.
Habe ich etwas getan, wie das gleiche wie du vor.
Ich musste Lesen und schreiben von Daten über USB-Seriell-adapter, und nicht minicom verwenden.
Es kann nicht sein, Gott-code, aber ich fand, dass inorder, um Daten zu Lesen, ich könnte einen neuen thread erstellen und haben Sie, dass der check für Daten, mein code gehören eine Menge Sachen, aber im Grunde habe ich diese:
und die check_get_data Methode
dies ist derzeit mit zwei usbserials. weiß nicht, ob es hilft, aber hoffe, Sie finden Ihre Lösung