2016-12-31 12 views
1

Я пишу программу python, чтобы заменить программу C, которая, помимо прочего, получила данные от микроконтроллера. Это было сделано на 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

Любая помощь будет принята с благодарностью, я боролся с этим в течение нескольких недель. Я могу загрузить файл необработанных данных, но я не был уверен, как это сделать, поскольку он довольно большой.

Итак, на мой вопрос, почему мой вопрос заключается в том, почему программа создает данные для первого изображения, а не второго, и есть ли что-то явно неправильное в том, как я читаю и преобразую данные.

Заранее благодарен!

EDIT/UPDATE:

Благодаря больших ответов ниже, я теперь я использую это:

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

conv.write(unpack) 

и данные выглядят лучше! Первое изображение с dtype ('int16'), а второе - с dtype ('int32'). Я также узнал, что данные, которые я читаю, состоят из чередующихся реальных/мнимых чисел, если это изменит строку формата, которую я использую для numpy dtype? Насколько мне известно, в коде C не было шага, который учитывал это.

Final Update:

Чтобы избежать путаниц, для кого-то еще, вторых двух изображений выше, читающих данные правильно, это было проблема в фактических данных, заставляя их не выглядеть правильно.

int16 int32

+2

Вы должны удалить гр тег. Потому что в вашем вопросе нет кода 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 

Вы должны использовать range(0, length-size, 2) для итерации с шагом 2.

Однако диапазоны Python являются половинной open, они исключают последнее значение. Таким образом, вы отбрасываете последний образец в настоящее время. Если вы этого не хотите, оставьте -size.

Это не идиоматический способ петли над байтами. Лучше всего было бы перебирать их напрямую:

for idata in rawdata[::2]: 

Это будет перебирать пары байтов.

Но это круговой способ сделать это, если вы уже используете numpy. numpy имеет очень быстрый способ распаковать весь массив из двоичных данных: fromstring. Вы можете просто прочитать данные сразу, как так:

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

Кроме того, ваш формат size или неправильно, h 2 байта, но size равно 4. Кроме того, вы затенение встроенной функции size. Используйте другое имя переменной.

Кроме того, это обрабатывается как двоичные данные, поэтому вы должны открыть файл как двоичный. Если вы сделаете это, вы можете использовать NumPy-х fromfile таким же образом, но без того, чтобы сделать read первый, который был бы еще быстрее:

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

Большое вам спасибо за помощь, что np.fromfile намного проще. Ive изменил вопрос с обновлением, и я понял, что данные чередуются реальными и мнимыми? Я пробую разные типы, чтобы увидеть, какой эффект у них есть, но любые идеи, которые у вас могут возникнуть, будут действительно полезны! – user2769075

+0

Поцарапал, что мне нужно было настроить частоту импульсов для данных, ваше решение полностью работало с новыми данными. Большое вам спасибо, я боролся с этим в течение нескольких недель – user2769075

0

Поскольку фактические данные выглядят квантуется по вертикали, вы, вероятно, поменять местами порядок байтов.

Пробег: unpack[m] = (inter[0] % 0x100) * 0x100. Если это выглядит хорошо, вам нужно распаковать данные, используя другой порядок байтов.

Смежные вопросы