2010-03-05 5 views
5

Sto leggendo in dati seriali usando Pyserial, per popolare una lista di 17 valori (1 byte ciascuno) ad una frequenza di campionamento di 256Hz.Riordina la lista in Python per assicurarti che inizi con i valori di controllo

I byte che alla fine voglio utilizzare sono il 5 ° all'8 ° nell'elenco. Se non vengono rilasciati byte, i primi due valori dello stream sono sempre gli stessi ('165', '90'). Tuttavia, sto ottenendo alcuni valori scartati e i miei valori di lista si stanno spostando, quindi quando leggo il 5 °-ottavo byte, non sono i valori corretti.

Ho parzialmente contrastato questo assicurando che prima che venga catturato il segmento desiderato, i primi valori vengono controllati rispetto a quello che dovrebbero essere (cioè se mylist [0] == 165 & ....).
Questo è grezzo ma ok poiché le probabilità che questi due valori compaiano l'una accanto all'altra nella lista altrove sono ridotte. Il problema è che questo significa non appena i byte si spostano, sto perdendo un carico di valori, fino a quando non si riallinea.

La mia domanda è: che cosa codice posso usare per uno:

a) forza la lista di riallineare una volta che è stato rilevato che non è più inizia con 165,90. (Elif ....).

b) Rileva dove '165' & '90' sono (uno accanto all'altro) nella lista ed estraggono i valori che voglio in relazione alla loro posizione (successiva ma una, in avanti).

Grazie in anticipo

S_S

appena notato dai relativi Qs che potrei usare

mylist.append(mylist.pop(0)) 

più volte fino a quando sono nel posto giusto. C'è un modo migliore che chiunque può suggerire?

+0

È davvero necessario affrontare il motivo per cui si stanno perdendo così tanti byte. Cosa succede se si rilascia il byte dopo (165,90)? Otterrete il sesto nono byte che sarà spazzatura. Stai usando un cavo seriale di buona qualità? Quanto tempo è? –

+0

Il problema è dovuto al fatto che si tratta di un adattatore RS232-USB, è anche lungo solo 1 metro! Saluti. –

risposta

2

Nel caso in cui vi capito bene, si supponga di avere una lista come questa:

l = [67, 126, 165, 90, 11, 1, 3, 5, 151, 99, 23] 

che ci si vuole ottenere: utile = [3,5,151,99]

Poi, Si potrebbe fare:

# obtain places where 165 is followed by 90 
match = [x for x in xrange(len(l)-1) if l[x]==165 and l[x+1]==90] 
# obtain range of useful values 
useful = l[match[0]+4:match[0]+8] 

Potrebbe essere necessario modificare i numeri in caso io abbia frainteso il problema. Speranza che aiuta,

Manuel

0

Se ho ben capito il problema corretto, si dispone di dati in continuo arrivo, in blocchi da 17 byte. Supponendo che è di destra, come su qualcosa di simile:

while True:  
    mylist.extend(get_more_data()) 

    # If we're misaligned, skip bytes until we're aligned again 
    while mylist and mylist[0] != 165 or mylist[1] != 90: 
     mylist.pop(0) 

    # If we've skip bytes, we might not have enough data, so get more 
    if len(mylist) < 17: 
     continue 

    # Process one chunk of data and remove it from the list 
    process_data(mylist[:17]) 
    del mylist[:17] 
0

Vorrei utilizzare il 165 e il 90 come valori di intestazione, controllando sempre il byte in entrata per una partita. Questa soluzione ri-sincronizza automaticamente in sé ed è semplice come:

def get_message(): 
    while True: #Some timeout functionality is useful here ;-) 
     message = [] 
     byte = xxx.get_byte() 
     if byte == 165: 
      byte = xxx.get_byte() 
      if byte == 90: 
      xxx.get_byte() #drop it 
      xxx.get_byte() #drop it 
      message[0] = xxx.get_byte() 
      message[1] = xxx.get_byte() 
      message[2] = xxx.get_byte() 
      message[3] = xxx.get_byte() 
      #Break out of loop. We have a message! 
      return message 

Se la progettazione di entrambe le parti, si dovrebbe inserire una sorta di checksum. Se stai solo hackerando qualcosa, cerca nei byte un checksum. Probabilmente è già lì.

Problemi correlati