2016-12-31 10 views
1

私は、とりわけマイクロコントローラからのデータを受け取ったCプログラムを置き換えるPythonプログラムを書いています。これは、単純なソケットとread関数を使用してC言語で行われました。私のPythonプログラムでは、マイクロコントローラから一連のデータを読み取ることができますが、読み込み可能な形式にすることはできません。私は、この文字列を捕獲し、番号のリストだけにそれを変換しようとはるかに小さいプログラムを書かれている:ここでPythonでバイナリデータを読む(Cコードを置き換える)

import array 
import thread 
import socket 
import time 
import math 
import numpy as np 
import struct 

data = open("rawfile.txt", 'r') 
conv = open("conv.bin", 'wb') 
pack = open("pack.txt", 'w') 


# This line reads in the data string from the file 
rawdata = data.read() 

length = len(rawdata) 

unpack = np.zeros(length, dtype=np.int64) 
inter = np.int64 

size = 4 
m=0 

for n in range(0,length-size): 
    inter = struct.unpack_from('h',rawdata,n) 
    unpack[m] = inter[0] 
    m=m+1 
    n=n+4 

conv.write(unpack) 
for j in range(0,len(unpack)): 
    #print unpack[j] 
    stringtowrite = str(unpack[j]) 
    pack.write(stringtowrite) 
    pack.write(',') 

#conv.write(dat2) 
print "Done" 

は(MATLABでプロットされている)、このプログラムが生成するデータであり、どのようなデータが見えるはずです以下のように:(クリーナーパルスは、それがどのように見えるかである)

Data from program What the data should look like

すべてのヘルプは大幅に私は数週間のためにこれで苦労してきた、高く評価されるだろう。私は生データファイルをアップロードすることができますが、私はそれを非常に大きなものとしてどのように行うのかよく分かりませんでした。

要約すると、私の質問は、なぜプログラムが最初のイメージ用のデータを生成し、2番目のデータ用のデータを生成しないのかということであり、私が読み込んでデータを変換していることは明らかに間違っています。

ありがとうございます!

EDIT/UPDATE:

dt = np.dtype('int16') 
unpack = np.zeros(302000, dtype=dt) 
unpack = np.fromfile(data, dtype=dt) 

conv.write(unpack) 

を、データが良く見える:以下偉大な答えに

おかげで、私は今、これを使用しています!最初のイメージはdtype( 'int16')で、2番目のイメージはdtype( 'int32')です。私が読んでいるデータは、numpy dtypeに使用するフォーマット文字列を変更すると、実数/虚数が交互になっていることが分かりました。私が知っている限り、これを説明したCコードには一歩もありませんでした。

最終更新日:

誰の混乱を避けるために、上述した第2の2枚の画像が正しくデータを読んでいる、それは彼らが右に見ていないさせる実際のデータでは問題でした。

int16 int32

+2

あなたは、cタグを削除する必要があります。あなたの質問にはcコードがないからです。 – Stargateur

+0

それ以外の場合は、Cの古いソースコードをバイナリの参照用として提供してください。 –

答えて

2

ここには複数の問題があります。

データのバイトを反復処理していますが、そのデータを2バイト単位として解釈しています。 offsetはバイト単位のオフセットであり、オフセットはfmtの単位ではありません。だから、データは(数は整数の指数である)ので、同じようにレイアウトされています

1 1 2 2 3 3 4 4 5 5 6 6 

しかし、あなたは、このようなデータを読んでいる:

1 1 
    1 2 
    2 2 
     2 3 
     3 3 
      3 4 
      4 4 
       4 5 
       5 5 
        5 6 
        6 6 

のではなく、このような:

1 1 
    2 2 
     3 3 
      4 4 
       5 5 
        6 6 

あなたはしかし、Pythonの範囲はハーフです2.

のステップで反復するrange(0, length-size, 2)を使用する必要があります開いている場合は、最後の値が除外されます。だから、あなたは現在の最後のサンプルをドロップしています。あなたがすることを意味しなければ、-sizeを離れる。

しかし、これはバイトをループする慣用的な方法ではありません。より良い方法は、それらを直接反復することです:

for idata in rawdata[::2]: 

これは、バイトのペアを反復処理します。

これは既にnumpyを使用している場合にこれを行うためのラウンドアバウト方法です。 numpyはバイナリデータから配列全体を解凍する非常に高速な方法を持っています:fromstring。あなたはそうのように一度にすべてのデータを読み込むことができます。

unpack = np.fromstring(data.read(), dtype=np.int16) 

はまた、あなたのsizeやフォーマットが間違っている、hは2バイトですが、sizeはあなたが組み込みsize機能をシャドウイングされ、また、4です。別の変数名を使用してください。

また、これはバイナリデータとして扱われるため、ファイルをバイナリとして開く必要があります。あなたがこれを行う場合は、numpyののfromfile同じようにを使用することができますが、さらに高速化されるであろう、read最初の操作を行うことなく、:

unpack = np.fromfile(data, dtype=np.int16) 
+0

あなたの助けを借りてありがとう、そのnp.fromfileははるかに簡単です。 Iveはアップデートで質問を変更しました。データが現実と現実の間で交互に現れることを実感しましたか?私は彼らがどのような効果を持っているかを見るために異なるタイプを試していますが、あなたが持っているかもしれないアイデアは本当に役に立つでしょう! – user2769075

+0

私はデータのパルス周波数を調整する必要がありましたが、あなたのソリューションは新しいデータで完全に機能しました。本当にありがとう、私は数週間これに苦労してきた – user2769075

0

実際のデータが垂直方向に量子化されたに見えますので、あなたはおそらくバイト順序を入れ替え。

お試しくださいunpack[m] = (inter[0] % 0x100) * 0x100です。それがいいと思えば、別のバイトオーダーを使ってデータを展開する必要があります。

関連する問題