これを達成するには、ターゲットとするオペレーティングシステムとプラットフォームに完全に依存することになります。あなたが言及しているデバイスは一般的なユースケースでは航空機の内部に搭載されているので、Windowsプラットフォームをターゲットにしていないと想定しますが、Linuxまたは組み込みシステムをターゲットにしている可能性があります。このようなプラットフォーム(たとえば:Serial Programming HOW-TO)でシリアルI/Oを実行するために利用可能なリソースがいくつかあります。また、装置のインストールマニュアル(hereのページの途中にあります)のように、「」メッセージフォーマットとメッセージタイプの選択については、SP-4 OEMマニュアルを参照してください。「最も関連性が高く有用ですその文書からの情報。メーカーが実際の通信ルーチンを実装する必要性を否定するため、製造元がプラットフォームにAPIを提供しているかどうかを確認したい場合があります。あなたは、シリアルインターフェースからバイトを読み取ることができたら、あなたはより多くのプログラマに優しいあなたのデータにアクセスするためにstruct
sおよびunion
秒を活用できる限りデータの感覚を作るとして
、。あなたが提供する大まかなメッセージ概要については、このようなものが適している場合があります:
struct _message
{
uint8_t DestinationAddress;
uint8_t MessageLength;
uint8_t MessageType;
uint8_t MessageSubtype;
int32_t BankAngle; //assuming an int is 32 bits
int32_t PitchAngle;
int32_t YawAngle;
sint_t Slip; //not sure what a 'sint' is
fps_t GForce; //likewise 'fps'
uint8_t MISC;
uint16_t Heading; //assuming a word is 16 bits
uint8_t Unused[UNUSED_BYTES]; //however many there are
uintt_t Voltage;
}
struct myMessage
{
union
{
char raw[MAX_MESSAGE_SIZE]; //sizeof(largest possible message)
struct _message message;
}
}
この方法であなたはstruct myMessage serialData;
を宣言した場合、あなたはserialData.raw
にあなたのメッセージを読むことができますし、便利な(例えばserialData.message.DestinationAddress
)、そのメンバーにアクセス。
編集:編集に応じて、データを理解する方法の例を示します。この例では、心配する必要のあるメッセージタイプは1つしかないと想定していますが、他のタイプに簡単に拡張できます。
struct myMessage serialData;
memcpy(serialData.raw, serialDataBuffer, MAX_MESSAGE_SIZE); //copy data from your buffer
if(serialData.message.MessageType == SOME_MESSAGE_TYPE)
{
//you have usable data here.
printf("I am a SOME_MESSAGE!\n");
}
さて、これらの整数型は、データ伝送のために本当に唯一有用であることを想定し、あなたは、「使用可能なデータ」にこれらのビットを変換する必要があります。これらのフィールドの1つが実際に符号化された浮動小数点数であるとします。 1つの一般的な方式は、ビットウェイト(時に解像度とも呼ばれる)を選択することです。これがあなたのデバイスに直接当てはまるのか、それとも実際の値であるのか分かりませんが、説明のためにフィールドの解像度が0.00014 degrees/bit
であるとしましょう。
double YawAngleValue = 0.00014 * serialData.message.YawAngle;
を...そして、それはそれについてです:double
へのuint32_t
値からメッセージ(serialData.message.YawAngle
)の値を変換するには、たとえば、あなたはこれを行う可能性があります。 OEMのマニュアルでは、データがどのようにエンコードされているかを教えてください。また、そこからデコードする方法を理解する必要があります。
ここで、処理するメッセージタイプが2つあるとします。私がすでにあなたに紹介したものと、理論的にはCRITICAL_BITS
というメッセージです。
struct _critical_bits
{
uint8_t DestinationAddress;
uint8_t MessageLength;
uint8_t MessageType;
uint8_t MessageSubtype;
uint32_t SomeCriticalData;
}
を...そしてそのようstruct myMessage
定義に追加:私がレイアウトされてきた方式を使用して、そのタイプを追加するには、まず(以下のおそらくのように)CRITICAL_BITS
構造を定義し
struct myMessage
{
union
{
char raw[MAX_MESSAGE_SIZE]; //sizeof(largest possible message)
struct _message message;
struct _critical_bits critical_message;
}
}
...他のフィールドと同様にSomeCriticalData
にアクセスできます。
if(serialData.message.MessageType == CRITICAL_MESSAGE_TYPE)
{
uint32_t critical_bits = serialData.critical_message.SomeCriticalData;
}
詳細については、struct
sを参照してください。念頭に置いて、struct myMessage
タイプのインスタンスには、一度に意味のあるデータが1セットしか含まれません。より簡単に言えば、にCRITICAL_MESSAGE_TYPE
のデータが含まれている場合は、serialData.critical_message
のデータが有効ですが、serialData.message
のデータは要求してもそのデータにアクセスできません。
編集:さらに1つの例;
は uint8_t calculate_checksum(struct myMessage *data)
{
uint8_t number_bytes = data->message.MessageLength;
uint8_t checksum = 0;
int i;
for(i=0; i<number_bytes; ++i)
{
//this performs a XOR with checksum and the byte
//in the message at offset i
checksum ^= data->raw[i];
}
return checksum;
}
あなたはそれを調整する必要があります:あなたが指定したアルゴリズムを使用して、メッセージのチェックサムを計算するために、あなたはおそらくこのような何か(すでにメッセージがバッファ内に完全に知っていると仮定)を望みます関数は含まれていないバイトのために、data != NULL
などを確認してくださいが、それはあなたを開始する必要があります。
この質問に対する答えとして、誰かがあなたにバイトストリームの "合意"を示すコードを表示できたら、私は驚くでしょう。 – unwind
これでシリアルプロトコルは何ですか?両側にどのようなコードがありますか(TX/RX)? – L7ColWinters
あなたはどのコンパイラとOSを使用していますか?あなたのデバイスが接続されていることを確認し、シリアルターミナルエミュレータを使用して期待されるデータを送信しましたか? – tinman