2013-04-30 3 views
3

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

def BUTTON_Clicked(self, widget, data= None): 

     ser = serial.Serial("/dev/ex_device", 115200, timeout=3) 

     RECEIVEDfile = open("RECIEVED.txt", "r+", 0) #unbuffered 


     #Commands sent out 
     ser.write("*n\r") 
     time.sleep(1) 
     ser.flush() 
     ser.write("*E") 
     ser.write("\r") 

     #Read back string rx'd 
     RECEIVED= ser.read() 


     RECEIVED= re.sub(r'[\W_]+', '', RECEIVED) #remove non-alphanumeric characters (caused by noise maybe?) 
     RECEIVEDfile.write(re.sub("(.{4})", "\\1\n", RECEIVED, 0, re.DOTALL)) #new line every 4 characters 


     RECEIVEDfile.close    
     ser.write("*i\r") 
     ser.close 

Это скрипт, используемый для извлечения данных, скорость передачи данных и последовательные команды установлены правильно и скрипт запускается как «небуферизован» (-u), но все же полная строка не сохраняется. Строка составляет примерно 16384 символов, но сохраняется только около 9520 символов (она меняется) (невозможно передать строку для анализа). Кто-нибудь знает, что мне не хватает? Приветствия за любую помощь, которую вы можете мне дать.

+0

Что вы теряете на шаге 'remove not-alphanumeric characters'? Возможно, стоит использовать одно и то же регулярное выражение для подсчета количества удаленных символов и посмотреть, совпадает ли он с отсутствующими данными. – mfitzp

+0

Это тайм-аут на 3 секунды, чтобы получить данные? Можете ли вы попробовать его с тайм-аутом = Нет? – mfitzp

+0

Я полностью удалил синтаксический анализ, чтобы убедиться, что это проблема, но, к сожалению, не имеет успеха. – CaramelElectron

ответ

2

Рад, что мой комментарий помог!

Установите тайм-аут на небольшое количество, например. 1 секунда. Тогда попробуйте что-то вроде этого. Он пытается читать большой кусок, но быстро вылетает и не блокируется в течение длительного времени. Все, что было прочитано, помещается в список (rx_buf). Затем цикл навсегда, пока у вас есть ожидающие чтения байты. Реальная проблема заключается в том, чтобы «знать», когда не следует ожидать больше данных.

rx_buf = [ser.read(16384)] # Try reading a large chunk of data, blocking for timeout secs. 
while True: # Loop to read remaining data, to end of receive buffer. 
    pending = ser.inWaiting() 
    if pending: 
     rx_buf.append(ser.read(pending)) # Append read chunks to the list. 
    else: 
     break 

rx_data = ''.join(rx_buf) # Join the chunks, to get a string of serial data. 

Причина я кладу куски в списке является то, что операция соединения является гораздо более эффективным, чем «+ =» на струнах.

+0

Создает очарование, спасибо за вашу помощь – CaramelElectron

+1

Это также устраняет «шум», который я испытывал, должно быть, были артефакты, вызванные тем, что буфер не был счастлив – CaramelElectron

0

Согласно this question вам необходимо прочитать данные из буфера в кусках (здесь один байты):

out = '' 
# Let's wait one second before reading output (let's give device time to answer). 
time.sleep(1) 
while ser.inWaiting() > 0: 
    out += ser.read(1) 

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

+0

Возможно, вы сможете выполнить 'out + = ser.read (ser.inWaiting())', чтобы получить его в больших кусках? В настоящий момент это невозможно проверить. – mfitzp