recibir - No se puede leer desde el puerto serie usando C#Mono(RaspberryPi)
raspberry arduino serial (2)
Echa un vistazo a stty command. Le permitirá configurar / leer configuraciones teminal
http://linux.about.com/od/lna_guide/a/gdelna38t01.htm dará un resumen de su uso. Sería más fácil llamar a que minicom y la configuración permanecerá en el dispositivo.
Estoy intentando escribir una biblioteca de C # que examine todos los puertos serie USB disponibles en una Raspberry Pi para poder enumerar, identificar y comunicarme con un conjunto de Arduinos conectados al Pi a través de un concentrador USB.
Puedo hacer que esto funcione en mi máquina de Windows (varios Arduinos conectados a mi computadora de escritorio) e incluso he podido hacer que funcione en mi Pi. Sin embargo, estoy luchando por entender cómo generalizar la solución.
Si intento ejecutar el programa solo en el Pi, puedo abrir el puerto serie y enviar datos, sin embargo, no puedo recibir nada de los Arduinos: obtengo excepciones de tiempo de espera. Entiendo que la implementación de SerialPort de Mono es limitada y debo usar SerialPort.ReadByte () en lugar de Readline () y los datos recibidos (mi solución se basa en el código de HowToSystemIOPorts ). Mi enumeración de puerto serie está utilizando un método descrito en otra respuesta de intercambio de pila aquí .
Mi tiempo de espera actualmente se establece en 4 segundos, que es varios órdenes de magnitud más largos de lo que espero recibir el mensaje.
Después de buscar en Google, me enteré de que usaba minicom para inicializar el puerto serie aquí , lo que para mi sorpresa me permitió recibir datos del Arduino. El mayor inconveniente es que necesito inicializar el puerto con minicom y dejar el proceso abierto cada vez que arranque el Pi. Tampoco puedo entender cómo hacer que esto funcione con múltiples Arduinos.
Esto es lo que he intentado hasta ahora:
- Actualizó el firmware y el software Pi a sus últimas versiones
- Intento usar tanto un Arduino MEGA 2560 R3 como Arduino UNO
- Cambié el propietario de los puertos tty * (ttyACM0 y ttyUSB0 en este caso) a mi usuario y grupo
- Con éxito configuró el puerto a través de minicom, dejó el proceso en ejecución e inició el programa y leyó / escribió datos. Un proceso manual que solo parece funcionar para un Arduino a la vez
- Ejecute con éxito el programa en Windows sin error
- Verificado que los Arduinos son reconocidos por el Pi corriendo "dmesg | grep tty"
Esto es lo que espero resolver:
- Configuración / inicialización automática de los puertos serie Arduino. Ya sea a través de un script de shell ejecutado antes del programa principal o dentro del código de Mono para que el código a continuación pueda ejecutarse según lo previsto.
Aquí está mi código de conexión:
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();
}
He hecho algo como lo que tú hiciste antes. Tuve que leer y escribir datos a través del adaptador serial USB, y no usé minicom. Puede que no sea un código divino, pero descubrí que para leer los datos podía crear un nuevo hilo y tener esa verificación de datos, mi código incluye muchas cosas, pero básicamente hice esto:
System.Threading.Thread newThread;
newThread = new System.Threading.Thread(this.check_get_data);
y el método check_get_data
public void check_get_data ()
{
byte tmpByte = 0;
while (m_objSerialPort.BytesToRead != 0) {
tmpByte = (byte)m_objSerialPort.ReadByte ();
DoSomethingWithByte(tmpByte);
Thread.Sleep(20);
}
}
esto se está ejecutando actualmente con dos usbserials. no sé si ayuda, pero espero que encuentres tu solución