Hola:
Lo que cuenta el compañero, usar delimitadores y costar con split para obtener datos deseados en una trama de bytes.
Hice un ejemplo que es este. Arduino tiene en su interior una imagen o foto, en este caso dos. Tiene que identificar cual envio de los dos que hay.
Código C#:
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Ports;
using System.Text;
using System.Threading;
namespace Recibir_archivo_desde_Arduino_consola_03
{
class Program
{
static void Main(string[] args)
{
string COM = "";
// Tamaño ventana consola.
Console.WindowWidth = 55; // X. Ancho.
Console.WindowHeight = 15; // Y. Alto.
Console.Title = "Recoger foto desde Arduino y crearlo en el disco duro"; // Título de la ventana.
// Crear un nuevo objeto SerialPort con la configuración predeterminada.
SerialPort Puerto_serie = new SerialPort();
// Configuración.
Console.Write(@"
Introduzca un número para seleccionar puerto COM.
Por ejemplo el 4, sería COM4.
Puerto: ");
COM = Console.ReadLine(); // Escribir el número del puerto.
Console.Clear();
Puerto_serie.PortName = "COM" + COM; // Número del puerto serie.
Puerto_serie.BaudRate = 115200; // Baudios. 115200.
Puerto_serie.Parity = Parity.None; // Paridad.
Puerto_serie.DataBits = 8; // Bits de datos.
Puerto_serie.StopBits = StopBits.One; // Bits de parada.
Puerto_serie.Handshake = Handshake.None; // Control de flujo.
// Establecer la lectura / escritura de los tiempos de espera.
Puerto_serie.ReadTimeout = -1; // 500.
Puerto_serie.WriteTimeout = -1; // 500.
try
{
Puerto_serie.Open(); // Abrir el puerto serie.
}
catch (IOException)
{
Console.ForegroundColor = ConsoleColor.Red; // Texto en rojo.
Console.CursorVisible = false;
Console.SetCursorPosition(16, 6);
Console.WriteLine(@"El puerto " + Puerto_serie.PortName + @" no existe
o no lo encuentra.");
Console.ReadKey(); // Pulse cualquier tecla para salir.
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine(e);
}
Puerto_serie.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
Console.WriteLine("Esperando datos desde Arduino...");
Console.Read();
Puerto_serie.Close(); // Cerrar puerto.
}
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
try
{
SerialPort sp = (SerialPort)sender;
int contador = 0;
string indata = sp.ReadExisting(); // A la espera que lea el tamaño del array "datosArray".
int cantidadBytes = int.Parse(indata);
byte[] datosArray = new byte[cantidadBytes];
Console.WriteLine(datosArray);
switch (indata)
{
case "A1":
Thread.Sleep(100); // Retardo.
byte[] miBuffer = Encoding.ASCII.GetBytes("OK1"); // Codificación ASCII.
sp.Write(miBuffer, 0, miBuffer.Length); // Envía OK1 al puerto serie.
break;
case "A2":
Thread.Sleep(100); // Retardo.
byte[] miBuffer2 = Encoding.ASCII.GetBytes("OK2"); // Codificación ASCII.
sp.Write(miBuffer2, 0, miBuffer2.Length); // Envía OK2 al puerto serie.
break;
default:
// Código si no es A1 ni A2.
break;
}
while (contador < datosArray.Length)
{
contador += sp.Read(datosArray, contador, datosArray.Length - contador);
Console.SetCursorPosition(10, 2);
Console.Write("Datos recibidos: {0}", contador);
Console.WriteLine(" ");
if (contador == cantidadBytes) // 17729.
{
Console.WriteLine();
Console.WriteLine("Creando archivo al disco duro...");
File.WriteAllBytes("fotón.jpg", datosArray); // Crear archivo en el disco duro.
Console.WriteLine();
Console.WriteLine("Archivo creado. Ejecutando imagen.");
Process.Start("fotón.jpg"); // Ejecutar visualizador de imágenes.
Console.WriteLine();
Console.WriteLine("Imagen ejecutada.");
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Yellow; // Letras amarillas.
Console.WriteLine("FIN DE PROGRAMA.");
Console.ForegroundColor = ConsoleColor.Gray; // Letras grises otra vez.
}
}
}
catch (FormatException)
{
// La cadena de entrada no tiene el formato correcto.
}
catch (OutOfMemoryException ex)
{
Console.WriteLine(ex);
}
}
}
}
Arduino tiene dos pulsadores, si pulsas uno de ellos envia una foto, si pulsas el otro, pues la otra foto guardado.
Tiene cadenas juntas y tengo que separarlas para que C# lo entienda.
Si en C# te da por enviar estos caracteres, estas tramas de bytes que cada ciertas partes tiene su significado com puedes ver un epqueño ejemplo abajo.
String cmd = "500000FF03FF000018000A04010000D*0095000001";
Puedes hacerlo como indica abajo para documentarlo con más calma, tiene más orden y vas directo a lo quie quieres modificar si realmente lo deseas, solo tienes que concatenarlo para tener el mismo resultado que arriba.
String cmd = "";
String OutAddress = "0001";
cmd = "";
cmd = cmd + "5000";// sub HEAD (NOT).
cmd = cmd + "00";// Número de red de trabajo (NOT.)
cmd = cmd + "FF";// NÚMERO PLC.
cmd = cmd + "03FF";// DEMANDA OBJETO MÓDULO I/0.
cmd = cmd + "00";// DEMANDA OBJETO NÚMERO DE DISPOSITIVO
cmd = cmd + "001C";// LONGITUD DEMANDA DE DATOS.
cmd = cmd + "000A";// DATOS DE LA CPU.
cmd = cmd + "0401";// LEER COMANDO.
cmd = cmd + "0000";// Sub commanO.
cmd = cmd + "D*";// CÓDIGO DE DISPOSITIVO.
cmd = cmd + "009500"; // AD BASE.
cmd = cmd + OutAddress; //BASE DE DIRECCIONES.
Saludos.
Enviar_foto_puerto6_LCD.ino (123 KB)