2016-02-28 25 views
5

20バイトのデータパケットを形成し、ペイロードをブルートゥース経由でハードウェア周辺機器に送信する必要があります。Swiftでのビット操作の操作方法は?

この20バイトのデータパケットは内部で14個のデータセットに分割され、それぞれ11ビット、最後の6ビットはヌル文字でなければなりません。

したがって、合計: 160ビット(20バイト)= 14(セット)* 11(ビット)+ 6(ヌル文字)

が11ビットを再び2ビットの3組、3に分割されそれぞれ6ビットである。しかし、それは重要な質問には重要ではない、私は現在、Int16を取ることによって、11ビットを形成することができます。私は11ビットをフィルタリングするためのシフト操作を行うだろう、私はそれを知っている。

データセットが1つしかない場合は、最初の11ビットをヌル文字で除外して、2つのデータセットが22ビット以外のすべてがヌル文字でなければなりません。

私が直面する問題は、奇数ビットが11であるためにこの連続した160ビットを形成することです。私は 'Int'を取ってシフト(< <)の演算を行い、ビットごとにOR Intは64ビットです。

現在、私は20の固定サイズの文字配列を取ることはこの状況に合うと思います。概念的には最良の方法だと思いますが、プログラムでは、これを達成するためのすべての条件でロジックを形成することができません。私はすべてのロジックをループに入れる必要があると思う。

これを達成するための正しい方法は誰にも分かりますが、これが最良の方法であれば、解決に向けて私を導くことができます。可能であれば、他の方法を指摘してください。

答えて

1

非常に最後まで20バイトの配列にすべてのデータセットをパックする必要はありません。長さがIntの配列を長さ14に保ちます。この方法で簡単に作業できます。あなたは、ハードウェアにそれを介して送信する必要がある場合には、長さ20のUInt8配列に変換します

struct DataPacket { 
    var dataSets = [Int](count: 14, repeatedValue: 0) 

    func toCArray() -> [UInt8] { 
     var result = [UInt8](count: 20, repeatedValue: 0) 
     var index = 0 
     var bitsRemaining = 8 
     var offset = 0 

     for value in self.dataSets { 
      offset = 10 

      while offset >= 0 { 
       let mask = 1 << offset 
       let bit = ((value & mask) >> offset) << (bitsRemaining - 1) 
       result[index] |= UInt8(bit) 

       offset -= 1 
       bitsRemaining -= 1 
       if bitsRemaining == 0 { 
        index += 1 
        bitsRemaining = 8 
       } 
      } 
     } 

     return result 
    } 
} 

// Usage: 
var packet = DataPacket() 
packet.dataSets[0] = 0b11111111111 
packet.dataSets[1] = 0b00000000011 
// etc... 

let arr = packet.toCArray() 

ので、私はそれらすべてを説明することはできませんが起こってシフト操作がたくさんあります。一般的な理想は、これらの11ビットデータセットのそれぞれをバイトに割り当て、必要に応じて次のバイトに書き戻します。

+0

は、詳細なコードをありがとうございました。コードを遊び場に置き、サンプルテストを少し試しました。うまくいきましたし、完全なコードも理解していました。もう一度ありがとうございます。 :) –

1

異なるコードによって提案された解決策の変種:

struct DataPacket { 
    var dataSets = [Int16](count: 14, repeatedValue: 0) 

    func getPacket() -> [UInt8] { 
     var packet = [UInt8](count: 20, repeatedValue: 0) 
     var idxPacket = 0 

     for dataSet in dataSets { 
      for idxBit in 1...11 { 
       if dataSet & 1 << (11 - idxBit) != 0 { 
        packet[idxPacket/8] |= UInt8(0b1000_0000 >> (idxPacket % 8)) 
       } 
       idxPacket += 1 
      } 
     } 

     return packet 
    } 
}