COM-порт С# замедляется и читает один байт в секунду после отправки сообщенияC#

Место общения программистов C#
Ответить
Anonymous
 COM-порт С# замедляется и читает один байт в секунду после отправки сообщения

Сообщение Anonymous »

Это поставило меня в тупик на несколько дней, и после исчерпания всех поисков и поисков я пишу здесь, потому что так и не понял. Извините, я знаю, что это много. Я действительно пытался решить эту проблему самостоятельно, но понятия не имею, в чем причина моей проблемы.
Немного предыстории моего кода:
Пишу библиотеку для связи с 8-дорожечным рекордером Sound Devices 788T. Я использую его USB-порт для связи с ним по собственному протоколу RS232 под названием «C. Link», разработанному Sound Devices. Используя документацию по протоколу, выпущенную Sound Devices, я успешно смог отправлять команды, читать настройки и, по сути, выполнять все необходимые мне задачи по одной. Проблема, с которой я сталкиваюсь, возникает, когда я отправляю запрошенное пользователем сообщение во время обычной функции «тик», которая обновляет постоянно меняющиеся переменные с машины, т. е. сгенерированный тайм-код SMPTE, показания счетчиков и т. д.
Сообщение отправляется, я получаю ответ, и функция галочки продолжает обновляться как следует еще несколько секунд. После этого чтение из открытого последовательного порта замедляется до одного байта в секунду. Я не понимаю, почему. Если я не отправлю сообщение, моя тестовая программа сможет бесконечно отправлять и получать обычные тиковые сообщения с ожидаемой скоростью. Но я сам отправляю команду и получаю ответ, тиковые сообщения принимаются с ожидаемой скоростью только в течение нескольких секунд, а затем резко останавливаются со скоростью один байт в секунду. Он не падает или что-то в этом роде. Он продолжает отправлять и получать правильные данные, он просто считывает их из последовательного порта со скоростью один байт в секунду.
И пользовательские сообщения, и тиковые сообщения используют одну и ту же функцию для отправки и получать данные через последовательный порт. Вот код с кратким объяснением классов. Пожалуйста, извините меня за все мои команды Debug.WriteLine. Я использовал их и счетчик, чтобы выяснить, все ли работает в правильном порядке, и это так.
Буду очень признателен за любую помощь!
VM - виртуальная машина, представляющая реальный рекордер 788T. Он получает такие вещи, как тайм-код физического устройства, счетчики, статистику записи и т. д., и сохраняет их, чтобы мы могли получить к ним доступ без необходимости постоянно запрашивать их у реальной машины или до тех пор, пока они не изменятся. Этот класс обрабатывает генерацию сообщений C. Link и отправляет их командиру для отправки через последовательный порт.
Commander — отвечает за все, что связано с последовательным соединением. Он отправляет и получает последовательные данные, а также отправляет все ответы, полученные от физической машины, обратно на виртуальную машину.
Вот процедура проверки виртуальной машины:

Код: Выделить всё

        private void DoPreTick(object ?source, ElapsedEventArgs e)
{
Debug.WriteLine("DoPreTick()" + counter + ": Tick timer triggered!  Disabling timer...");
tickTimer.Enabled = false;

if(!bIsTickAllowed)
{
Debug.WriteLine("DoPreTick()" + counter + ": Tick not allowed.   Won't be ticking this go around!");
}

if (!IsTicking())
{

Debug.WriteLine("DoPreTick()" + counter + ": Doing pre-tick!");
if (GetCLinkState() == CLinkState.Online && !commander.CommsAreBusy())
{
//Process our outbox first

if (bOutboxFullToken && !bIsProcessingUserMessage && !bOutboxProcessedToken)
{
Debug.WriteLine("DoPreTick()" + counter + ": Processing user message: " + outbox.ToBytes()[3]);
Task t = Task.Factory.StartNew(() => ProcessNextUserMessage());
t.Wait();
}

Debug.WriteLine("DoPreTick()" + counter + ": Ending pre-tick!");

if (!IsTicking() && bIsTickAllowed)
{
Debug.WriteLine("DoPreTick()" + counter + ": Tick allowed, running tick!");
DoTick();
}

}

}
Debug.WriteLine("DoPreTick()" + counter + ": All ticking completed!  Re-enabling tick timer...");
tickTimer.Enabled = true;
}

private void DoTick()
{
Debug.WriteLine("DoTick()" + counter + ": Doing Tick!");
SetIsTicking(true);
if (GetCLinkState() == CLinkState.Online && !commander.CommsAreBusy() && !bIsProcessingUserMessage && !bOutboxFullToken)
{
//Regular upkeep
GetUnitTC();
GetUnitMeters();
}

SetIsTicking(false);
Debug.WriteLine("DoTick()" + counter + ": Tick Finished!");
} //Tick is called every tickInterval while we are connected to a 788

private void ProcessNextUserMessage()
{
counter++;
Debug.WriteLine("ProcessNextUserMessage()" + counter + ": Setting bIsProcessingUserMessage to true!");

bIsProcessingUserMessage = true;

if (outbox.GetUnitID() == 0xFE)
{
commander.SendCLinkBytes(outbox, false);
Debug.WriteLine("ProcessNextUserMessage()" + counter + ": Message was 0xFE, not getting reply!");
Thread.Sleep(250);

}
else
{
Debug.WriteLine("ProcessNextUserMessage()" + counter + ": Message needs a reply, overwriting outbox with reply!");
CLinkMessage reply = commander.SendCLinkBytes(outbox, true);
outbox = reply;
}

Debug.WriteLine("ProcessNextUserMessage()" + counter + ": All done.  Setting user message TCS to true, setting outboxfulltoken to false, setting outboxProcessedToken to true!");

bOutboxProcessedToken = true;
bIsProcessingUserMessage = false;
bOutboxFullToken = false;

Debug.WriteLine("ProcessNextUserMessage()" + counter + ": Re-enabling tick!");
bIsTickAllowed = true;

}

Вот функция, которую виртуальная машина использует для добавления сообщения пользователя в папку «Исходящие» и ожидания ответа перед его возвратом:

Код: Выделить всё

public CLinkMessage SendCLinkMessage(CLinkMessage message)
{
if (IsTicking())
{
Debug.WriteLine("SendCLinkMessage()" + counter + ": Message Received while ticking!");
}

lock (userMessageTCS)
{
Debug.WriteLine("SendCLinkMessage(): Disabling tick for next go around!");
bIsTickAllowed = false;

if (IsAcceptingCLinkMessages())
{

SetIsAcceptingUserMessages(false);

outbox = message;
counter++;
Debug.WriteLine("SendCLinkMessage()" + counter + ": Message added to outbox.  Setting outboxfulltoken to true, setting outboxprocessed token to false.");

bOutboxFullToken = true;
bOutboxProcessedToken = false;

Debug.WriteLine("SendCLinkMessage()" + counter + ": All done for now.  waiting for usermessagetcs result...");
userMessageTCS = new TaskCompletionSource();
userMessageTCS.Task.Wait();

}

}

Debug.WriteLine("SendCLinkMessage()" + counter + ": Message send successful.  Setting acceptingUsereMessages to true and returning contents of outbox...");
SetIsAcceptingUserMessages(true);
return outbox;

}
Вот функция, которую класс Commander использует для отправки последовательных данных:

Код: Выделить всё

public CLinkMessage SendCLinkBytes(CLinkMessage message, bool bReturnResponse = false)
{

if (CommsAreBusy())
{
Debug.WriteLine("Commander: ERROR Comms are busy!");
}

if (commPort.IsOpen && !CommsAreBusy())
{
Debug.WriteLine("Commander: Comms not busy, sending message -  " + BitConverter.ToString(message.ToBytes()));
SetCommsAreBusy(true);
byte[] messageBytes = message.ToBytes();

try
{
commPort.Write(messageBytes, 0, messageBytes.Length);
}
catch (Exception e)
{
Debug.WriteLine("Commander: ERROR writing bytes to commPort: " + e.Message);
}

if (bReturnResponse)
{
List reply = new List();

try
{
Debug.WriteLine("Commander.SendCLinkBytes(): Reading Byte 1: header");
byte b = new byte();

//Header check

//Debug.WriteLine("Commander: Reading reply...");
b = (byte)commPort.ReadByte();

if (b == 0xA5)
{
//Debug.WriteLine("Response detected!");
reply.Add(b);

//UnitID check
Debug.WriteLine("Commander.SendCLinkBytes(): Reading Byte 2: unitID");
b = (byte)commPort.ReadByte();

if (b < 63 || b == 0xFE)
{
reply.Add(b);

//Length
Debug.WriteLine("Commander.SendCLinkBytes(): Reading Byte 3: Length");
b = (byte)commPort.ReadByte();

if (b > 2 && b 

Подробнее здесь: [url]https://stackoverflow.com/questions/78172950/c-sharp-com-port-slowing-down-to-read-one-byte-a-second-after-sending-message[/url]
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»