新しい更新: 外部ボックスをいじって、彼が受信できるようにしましたが、送信はできませんでした。外部ボックスが静かで、問題のシリアル ポートがデータを受信していない場合、ここで説明した問題は解消されます。つまり、受信していない限り送信できます。それで、、、これはバグなのか、それとも機能なのか、それとも私が対処すべき「既知の問題」なのか?
この件に関するアドバイスと指示は (非常に) 歓迎されます。3つの文での私の問題は...
シリアル ポートから 1 セットのバイトを送信できます。
シリアルポートは受信を開始し、受信を続けます。
別のバイト セットを送信できません。
システムが応答していないように見えます。Visual Studio 2010 にすべてを中断するように指示します。私のコードは常に、曲がった緑色の矢印が指し示す一列に並んでいます。カーソルを合わせると、次のような文字が表示されます...
現在のスレッドがスリープ、待機、または結合中であるため、式を評価できません
この複雑さをより簡単な英語の説明に分散させることができる専門家が読んでいるなら、そのような人々は長い間私の友人になるでしょう.
これは行き詰まっている方法です...
public static void Tell_Box_To_Stop_Sending()
{
int Length;
int StartingPosition;
byte[] TheBytesToSend;
Length = TheseBytesAreThe.Command_06_Stop_Data_Flood.Length;
StartingPosition = 0;
TheBytesToSend = TheseBytesAreThe.Command_06_Stop_Data_Flood;
OurSpecificPorts.TheActivePortWeAreUsing.Write(TheBytesToSend, StartingPosition, Length); ////// The green arrow is on this line
}
これは、ポートを開くために使用されるクラスです。このクラスから開いているポートを削除する必要がありますか?
/**********************************************************************************
* Class Name: UART
*
* Constructor: Takes the string name, stores it, and does nothing else
*
* Methods: -- Open_TheActivePortWeWillUse --
*
**************************************************************************************/
class UART
{
public SerialPort OurMainActiveSerialPort;
public byte[] The_Immediate_Rx_Buffer;
String The_Name_Of_The_Serial_Port;
public UART(String ThePortNameTheCallerGaveUs)
{
The_Name_Of_The_Serial_Port = ThePortNameTheCallerGaveUs;
}
public static void send_command(byte[] The_Byte_Array, int Starting_Place, int Length)
{
///OurMainActiveSerialPort.Write(The_Byte_Array, Starting_Place, Length);
OurSpecificPorts.TheActivePortWeAreUsing.Write(The_Byte_Array, Starting_Place, Length);
}
/*****************************************************************
* Method: Open_TheActivePortWeWillUse
*
* On Entry: Caller gives us a name, in a string. C# and
* Windows almost probably always use a format
* like "COM1" or "COM37" or some such scheme.
*
* Class: OurSpecificPorts
* Item: .TheActivePortWeAreUsing
* Has been defined as a serial port in the RegularVariables.cs file
*
*
* Actions: That serial port will be opened
*
*
* On Exit: The port will be connected, doing 8-N-1.
*
*
* We will store the port in a variable that's
* widely available to just about everybody.
*
* It will be in the class: OurSpecificPorts
*
* Its name will be: TheActivePortWeAreUsing
*
* Another method, in this class, will take on
* the Event Handler which will respond to new
* bytes in the buffer. (Don't be misled, this
* is not the UART FIFO buffer that you may be
* thinking; but a buffer that Windows and C#
* arrange for us.)
*
* The name of that method will be...
*
* OurBackGroundSerialPortReceiver
*
*
* Be Aware: If this is a bluetooth connection, we get
* 921600 bps irrespective of what we
* say we want for speed.
*
*
*****************************************************************/
public static void Open_TheActivePortWeWillUse(String Drone_StringNameFromUser)
// First, open the port
SerialPort TempSerialPort = new SerialPort (Drone_StringNameFromUser, int) SerialPortParameter.TheSerialPortSpeed);
OurSpecificPorts.TheActivePortWeAreUsing = TempSerialPort; // Now we have a name that anybody can see and use
OurSpecificPorts.TheActivePortWeAreUsing.DataBits = 8;
OurSpecificPorts.TheActivePortWeAreUsing.Parity = Parity.None;
OurSpecificPorts.TheActivePortWeAreUsing.StopBits = StopBits.One;
OurSpecificPorts.TheActivePortWeAreUsing.DataReceived += new SerialDataReceivedEventHandler(OurBackGroundSerialPortReceiver);
OurSpecificPorts.TheActivePortWeAreUsing.Open();
}
/*************************************************************************************************
* Method Name: OurBackGroundSerialPortReceiver
*
* Called By: Windows internal things
*
* Root Cause: The UART generates an event
*
* On Entry: There is hopefully some data in the Uart's buffer
*
* Windows and C# will set up two calling arguments
* -- object sender
* -- SerialDataReceivedEventArgs e
*
* Actions: This method sets flags and semaphores to alert other parts of our code
* of what we are doing, then it moves data out of the latest buffer that
* the serial port provides, into another buffer. We'll use a trailer and
* header scheme, much like our own box uses its interrupt handler with a
* background/foreground scheme.
*
* On Exit: Whatever was in the buffer is moved to the trailer/leader buffer which
* other parts of the code will take and use
*
* Other References: http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.datareceived
*
* http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.aspx
*
* http://msdn.microsoft.com/en-us/library/ms143549.aspx
*
* Microsoft actually has example code there which makes sense.
*
*
* ***********************************************************************************************/
public static void OurBackGroundSerialPortReceiver(object sender, SerialDataReceivedEventArgs e )
{
SerialPort CurrentPort = (SerialPort)sender; // Int routine gave is this in the arguments
int LastByteInUartBuffer = CurrentPort.ReadBufferSize;
int TheNumberOfBytes = CurrentPort.BytesToRead;
byte[] inputData = new byte[TheNumberOfBytes];
int WeGotThisMany = CurrentPort.Read(inputData, 0, TheNumberOfBytes);
int Dest;
Dest = UartPlaceHolders.RxBufferLeader; // Will index into buffer for Chief dispatch
int Source; // Will index into Uart buffer to fish it out
Source = 0; // therefore, we start at zero
int TopEdge; // We'll calculate this here once instead of in the loops below
TopEdge = (int)TheSizeOf.OneSecondsWorthOfData; // This will tell us when to wrap around
if (Dest < UartPlaceHolders.RxBufferTrailer) // Half the time we'll have wrap-around
{ // If that's the case, then the trailer > the leader
while (
(Dest < UartPlaceHolders.RxBufferTrailer) // If we are wrapped, make sure we don't
&& // overtake either the trailer or
(Dest < TopEdge) // go over the top edge
&& // At the same time, make sure that
(Source <= LastByteInUartBuffer) // we don't fish out more than is there
)
{ // Move bytes into buff for chief
UartData.TheImmediateSecondOfData[Dest] = inputData[Source];
Dest = Dest + 1;
Source = Source + 1;
}
if (Source >= LastByteInUartBuffer) // Have we done all the bytes for this event ?
{ // Yes, therefore we will update the leader
UartPlaceHolders.RxBufferLeader = Dest; // This tells us where to start next time
aUartSemaphoreThatTells.WhatTheUartBackgroundRxIsDoing = (int)aValueWhichIndicatesThat.WeHaveReceivedSomeData;
return; // and we are done
}
// // Else no, more bytes so...
else if (Dest >= TopEdge) // Did we wrap around ?
{ // Yes, so
Dest = 0; // wrap around to the start
while ( // Now we do the same thing again
Dest < UartPlaceHolders.RxBufferTrailer // C# and windows keep buffers at 4K max,
&& // so we will wrap only once
Source < LastByteInUartBuffer // May not even need that other test
) // This will finish the rest of the bytes
{
UartData.TheImmediateSecondOfData[Dest] = inputData[Source]; // There they go
Dest = Dest + 1;
Source = Source + 1;
}
UartPlaceHolders.RxBufferLeader = Dest; // This tells us where to start next time
return;
}
else // Dest is neither <, >, nor =, we have logic error
{
ErrorFlags.SerialPortErrorDescription = (int)AnError.ExistsInTheSerialPortBufferPointers;
return;
}
}
// We now take this case when the leader is up
// ahead of, or equal to, the trailer. In that
// case, we change the while loop to check for
// the leader overtaking the top edge, but not
// the trailer. Since the buffer will be about
// 4x the size of what we get from the Uart it
// is approximately guaranteed not to overtake
// the trailer; do the arithmetic and you will
// probably agree.
// I am purposely using to large, similar, but
// not completely identical schemes instead of
// another "else" appended to the previous bag
// of code. This will greatly improve debug.
if (Dest >= UartPlaceHolders.RxBufferTrailer) // Now, if the Trailer is ahead of the leader, here we go
{
while (
(Dest < TopEdge) // We still want to stop before we hit the top edge
&& // At the same time, make sure that we don't go past...
(Source < LastByteInUartBuffer) // ... the end of the Uart buffer
&& // Nor do we want to go past...
(Source < TheNumberOfBytes) // ...the last byte the Uart gave us
)
{
UartData.TheImmediateSecondOfData[Dest] = inputData[Source]; // Move bytes into buff for chief
Dest = Dest + 1;
Source = Source + 1;
}
if (Source >= LastByteInUartBuffer) // Have we done all the bytes for this event ?
{ // Yes, therefore we will update the leader
UartPlaceHolders.RxBufferLeader = Dest; // This tells us where to start next time
aUartSemaphoreThatTells.WhatTheUartBackgroundRxIsDoing = (int)aValueWhichIndicatesThat.WeHaveReceivedSomeData;
return; // and we are done
} // // Else no, we have more bytes to move, so...
else if (Dest >= TopEdge) // Did we wrap around ?
{ // Yes, so...
Dest = 0; // wrap around to the start
while ( // Now we do the same thing again
Dest < UartPlaceHolders.RxBufferTrailer // C# and windows keep buffers at 4K max,
&& // so we will wrap only once
Source < LastByteInUartBuffer
)
{
UartData.TheImmediateSecondOfData[Dest] = inputData[Source];
Dest = Dest + 1;
Source = Source + 1;
}
UartPlaceHolders.RxBufferLeader = Dest; // This tells us where to start next time
aUartSemaphoreThatTells.WhatTheUartBackgroundRxIsDoing = (int)aValueWhichIndicatesThat.WeHaveReceivedSomeData;
return;
}
else // Dest is neither <, >, nor =, we have logic error, so debug this
{
ErrorFlags.SerialPortErrorDescription = (int)AnError.ExistsInTheSerialPortBufferPointers;
return;
}
}
}
}
あまり多くのコードを含めていないことを願っています。ここでの最初のいくつかの質問は、常に人々がより多くのコードを見たいという結果になるようです。私はここに来て 2 週間経ったと思います。