using System.IO;
using System.IO.Ports;
private void Form1_Load(object sender, EventArgs e)
{
//чтение портов доступных в системе
string[] ports = SerialPort.GetPortNames();
//Очистка содержимого бокса
comboBox1.Items.Clear();
//Добавление найденных портов в бокс
comboBox1.Items.AddRange(ports);
}
private void button1_Click(object sender, EventArgs e)
{
//выбранный порт
Object selectedItem = comboBox1.SelectedItem;
//Создаю объект port1 с параметрами.
//selectedItem.ToString() - порт к которому подключено устройство.
//9600 скорость передачи данных в порт, как я понял 9600 бод - 38400 бит/сек.
//Parity.None бит четности установил в отсутствие так как пока не сильно понимаю что с ним делать об этом далее.
//416 бит данных т.е. 8*52 = 416.
//один стоп бит
SerialPort port1 = new SerialPort(selectedItem.ToString(), 9600, Parity.None, 416, StopBits.One);
//Открываю порт.
port1.Open();
//тут я писал разного рода код для вывода полученных данных в текстовое поле но получал один бред.
}
private void button1_Click(object sender, EventArgs e)
{
Object selectedItem = comboBox1.SelectedItem;
SerialPort port1 = new SerialPort(selectedItem.ToString(), 9600, Parity.None, 416, StopBits.One);
port1.Open();
//создаю массив размером 52 т.е на запись 52 байт переданного с устройства пакетов
byte[] data1 = new byte[52];
//Ну и запускаю команду чтения в массив data1
port.Read(data1, 0, data1.Length);
int databyte = port.ReadByte();
}
// Наследуем наш клас от SerialPort для более красивого кода
public class MySerialPort : SerialPort
{
private const int DataSize = 54; // я так и не понял, какой размер данных нужен. Укажите правильное число в байтах
private readonly byte[] _bufer = new byte[DataSize];
private int _stepIndex;
private bool _startRead;
public MySerialPort(string port)
: base()
{
// все папаметры вы должны указать в соответствии с вашим устройством
//base.PortName = COM1;
base.BaudRate = 115200;
base.DataBits = 8;
base.StopBits = StopBits.Two;
base.Parity = Parity.None;
base.ReadTimeout = 1000;
// тут подписываемся на событие прихода данных в порт
// для вашей задачи это должно подойт идеально
base.DataReceived += SerialPort_DataReceived;
}
// открываем порт передав туда имя
public void Open(string portName)
{
if (base.IsOpen)
{
base.Close();
}
base.PortName = portName;
base.Open();
}
// эта функция вызвется каждый раз, когда в порт чтото будет передано от вашего устройства
void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
var port = (SerialPort)sender;
try
{
// узнаем сколько байт пришло
int buferSize = port.BytesToRead;
for (int i = 0; i < buferSize; ++i)
{
// читаем по одному байту
byte bt = (byte)port.ReadByte();
// если встретили начало кадра (0xFF) - начинаем запись в _bufer
if (0xFF == bt)
{
_stepIndex = 0;
_startRead = true;
// раскоментировать если надо сохранять этот байт
//_bufer[_stepIndex] = bt;
//++_stepIndex;
}
// дописываем в буфер все остальное
if (_startRead)
{
_bufer[_stepIndex] = bt;
++_stepIndex;
}
// когда буфер наполнлся данными
if (_stepIndex == DataSize && _startRead)
{
// по идее тут должны быть все ваши данные.
// .. что то делаем ...
// var item = _bufer[7];
_startRead = false;
}
}
}
catch {}
}
}
var port = new MySerialPort();
port.Open("COM5");
new SerialPort(selectedItem.ToString(), 9600, Parity.None, 416, StopBits.One);
private void TransferWorker_DoWork(object sender, DoWorkEventArgs e)
{
// переменная для снятия из очереди
Packet pkt;
// массив для передачи
byte[] wr_buf = new byte[6];
// массив для приема
byte[] rd_buf = new byte[6];
// цикл до отмены работы или опустошения очереди запросов
/// TODO теперь не выходит по завершению очереди - уменьшить на переключение контекста задач
while ((_TransferWorker.CancellationPending == false))// && (_toTransfer.Count != 0))
{
case Mode_transfer.Read_ADC:// Чтение данных
Массив data = pkt.obj as Массив;
// читаем АЦП
wr_buf[0] = Convert.ToByte('A');
wr_buf[1] = (byte)0;
// Пишем отправляеммый пакет
_Serial.Write(wr_buf, 0, 2);
// ждем пока весь пакет уйдет или запросят отбой
while ((_TransferWorker.CancellationPending == false) && (_Serial.BytesToWrite != 0)) ;
// попытка поймать заголовок
try
{
int dummy = 0, lenghtReadingPacket;
bool end = false;
int counter =0;
while (end != true){
dummy = _Serial.BytesToRead;
if (dummy <= 3)
{
System.Threading.Thread.Sleep(1);
if (counter++ > _Serial.ReadTimeout)
{
_dataLostArgs.ErrorPreambulaLen++;
throw new TimeoutException("Preambula not full!");
}
}
else end = true;
}
dummy = _Serial.Read(rd_buf, 0, 3);
var dummy2 = dummy;
if ((dummy != 3))
{
_dataLostArgs.ErrorPreambulaLen++;
throw new TimeoutException("Preambula not full!");
}
if (rd_buf[(int)ADC_Packet.Name] != 'D'){
_dataLostArgs.PreambulaLost ++;
throw new TimeoutException("Data preambula lost!");
}
// длина пакета в словах
lenghtReadingPacket = rd_buf[(int)ADC_Packet.LenghtOfPacket];
byte[] rd_buf_ADC = new byte[lenghtReadingPacket * 2 + 1];
end = false;
counter = 0;
while (end != true){
dummy = _Serial.BytesToRead;
if (dummy < (lenghtReadingPacket * 2 + 1))
{
System.Threading.Thread.Sleep(1);
if (counter++ > _Serial.ReadTimeout + 100)
{
var dummy3 = _Serial.Read(rd_buf_ADC, 0, lenghtReadingPacket * 2 + 1);
_dataLostArgs.PoorPacket++;
throw new TimeoutException();
}
}
else end = true;
}
dummy = _Serial.Read(rd_buf_ADC, 0, lenghtReadingPacket * 2 + 1);
if (dummy == (lenghtReadingPacket * 2 + 1))
for (Int32 i = 0; i < lenghtReadingPacket * 2 ; i += 2)
{
int a = rd_buf_ADC[i];
int b = rd_buf_ADC[i + 1];
if (a != 0 || b != 0) data.Add(rd_buf_ADC[i] * 256 + rd_buf_ADC[i + 1]);
}
else {
_dataLostArgs.PoorPacket++;
throw new TimeoutException("Not all bytes received!");
}
}
catch (TimeoutException)
{
/// TODO ПОдумать при зависании считывания АЦП
OnADCDataLost(this, _dataLostArgs);
}
finally
{
// Чистим за собой
_Serial.DiscardInBuffer();
_Serial.DiscardOutBuffer();
}
break;