Formato dati per trasferimento dati binario

4

Devo fare un oscilloscopio. Idealmente, l'oscilloscopio si collega a una sonda. Questo probe dovrebbe essere un altro programma e potrebbe ottenere i dati localmente o da una rete. Questi dati sono numeri, float e / o interi. Il numero di canali può variare. E cambiano col tempo. Non tutti i canali devono avere la stessa frequenza.

Ora, a volte la frequenza può essere 1KHz, quindi usare json non è ok perché spreca molte risorse poiché si basa sul testo. Sto cercando un formato dati binario, quindi il trasferimento dei dati è più veloce.

Quindi la prima parte della domanda è: conosci un formato per trasferire dati binari come questo? Dovrebbe avere una sorta di intestazione e quindi solo numeri. La mia ipotesi è che qualcuno deve aver avuto questo problema prima e dovrebbe esserci un qualche tipo di libreria per usarlo.

Poi arriva la seconda parte della domanda: quale protocollo dovremmo usare per trasferire i dati?

Forse usare json ma con un codificatore base 64 per i dati usando le chiamate http standard potrebbe funzionare, ma per il segnale a 1KHz che non ha senso. Mi chiedo che cosa facciano le persone per risolvere questo problema.

    
posta cauchy 12.05.2015 - 18:25
fonte

3 risposte

5

Potresti anche considerare di cercare l'argomento di "ber tlv"

link

Questo è il formato del flusso di dati utilizzato dalla rete di elaborazione finanziaria mondiale ed è la spina dorsale di Chip & Terminali pin, bancomat e molti altri sistemi bancari.

La parte migliore è che è molto semplice da usare.

La parte T, L, V sta per

  • T AG
  • L ength
  • V alore

Il tag è un identificatore numerico che specifica il tipo di messaggio, nel tuo caso se utilizzi semplicemente il formato, puoi molto probabilmente definire i tuoi tag per questo, ma se tu dovessi effettivamente gestendo dati finanziari reali dovresti usare i numeri di tag definiti nello standard.

La parte Lunghezza è di nuovo semplice, specifica quanti byte di dati ha la parte valore, come qualsiasi valore, maggiore è il numero di byte che si allocano alla lunghezza, maggiore sarà il carico utile.

La parte Valore è quindi solo il payload del tuo messaggio effettivo e il modo in cui i byte vengono formattati per questo dipende interamente da te.

Beacuse è un protocollo di codifica / codifica così semplice (puoi farlo interamente usando gli array di byte) puoi facilmente inviarlo su UDP usando una dimensione di pacchetto molto piccola e molto veloce.

È anche adatto per lo streaming e più messaggi possono essere inviati indietro in una connessione continua non di chiusura, il che è ideale se decidi di utilizzare TCP.

In teoria funzionerebbe bene anche su HTTP usando un socket web, ma non l'ho mai provato, quindi non ho potuto commentare quanto bene.

Per quanto riguarda le librerie che lo supportano, l'ultima volta ho guardato "Craig's Utility Library"

link

aveva un ottimo supporto per le strutture basate su TLV, così come molte delle librerie di smart card che sono in giro (TLV è usato anche su molte schede)

Se TLV non è il tuo genere, allora definirò sicuramente ciò che gli altri hanno detto e daremo un'occhiata da vicino a "Protobuf"

Aggiornamento

Non so in che lingua stai lavorando, o anche se quello che sto per pubblicare ti sarà di qualche utilità :-), ma qui va comunque.

Questo è un decodificatore TLV (Notare che non ha capacità di codifica, ma dovrebbe essere facile invertirlo) Ho scritto nel 2008 (ish) usando C #, è stato progettato per decodificare pacchetti tlv che escono da una smart card in un terminale di pagamento, ma potrebbero servire come punto di partenza per trasformarlo in una forma più utile.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Card_Analyzer
{
  public class tlv
  {
    public int tag = 0;
    public int length = 0;
    public byte tagClass = 0;
    public byte constructed = 0;
    public List<byte> data = new List<byte>();
  }

  public class tlvparser
  {
    // List of found TLV structures
    public List<tlv> tlvList = new List<tlv>();

    // Constructor
    public tlvparser(byte[] data)
    {
      if (data != null)
      {
        this.doParse(data);
      }
    }

    // Main parsing function
    public void  doParse(byte[] data)
    {
      int fulltag = 0;
      int tlvlen = 0;
      int dptr = 0;

      while (dptr < data.Length)
      {
        byte temp = data[dptr];
        int iclass = temp & 0xC0;
        int dobj = temp & 0x20;
        int tag = temp & 0x1F;

        if (tag >= 31) // Using extracted vars, decide if tag is a 2 byte tag
        {
          fulltag = (temp << 8) + data[dptr + 1];
          tlvlen = data[dptr + 2];
          dptr += 3;
        }
        else
        {
          fulltag = temp;
          tlvlen = data[dptr + 1];
          dptr += 2;
        }// End if tag 16 bit

        if ((tlvlen & 128) == 128)
        {
          tlvlen = (tlvlen << 8) + data[dptr];
          dptr++;
        }

        tlv myTlv = new tlv();
        myTlv.tag = fulltag;
        myTlv.length = tlvlen;
        myTlv.tagClass = Convert.ToByte(iclass >> 6);
        myTlv.constructed = Convert.ToByte(dobj >> 5);

        for (int i = 0; i < tlvlen; i++)
        {
          if(dptr < data.Length)
            myTlv.data.Add(data[dptr++]);
        }

        if (myTlv.constructed == 1)
          this.doParse(myTlv.data.ToArray());

        tlvList.Add(myTlv);

      }// End main while loop
    }// End constructor
  }// end class tlvparser
}// end namespace

Se non serve, sentiti libero di ignorarlo.

    
risposta data 12.05.2015 - 19:58
fonte
2

Esiste un formato di file chiamato EDF , destinato a serializzare un flusso di multicanale, multi-campione dati di valutazione. Usare una struttura di file come esempio è buono perché è un flusso, proprio come un flusso di rete o qualsiasi altro flusso di byte tra la sonda e l'oscilloscopio.

L'idea del formato EDF consiste nel multiplexare i vari canali di dati in "blocchi" di dati, in cui ogni blocco contiene un determinato intervallo di tempo da ciascun canale e i blocchi vengono salvati in serie in file.

Il file stesso contiene un'intestazione del file con informazioni sul file e sui canali, quindi le intestazioni dei canali N contenenti informazioni su ciascun canale e allora si hanno solo dati grezzi. Quindi, se ipoteticamente perdi i dati di intestazione, non puoi (almeno facilmente) ricomporre i segnali.

Finalmente, la parte numerica (i dati grezzi) di questo formato di file è semplice perché è rigida: ogni valore è di tipo Int16 (numero intero breve, due byte, piccolo-endian).

Ora vediamo come questo formato di file potrebbe essere utile nel contesto del trasferimento di rete:

  • Il trasferimento di rete presuppone che tu abbia una sessione, questa sessione è configurata (ovvero, hai un contratto tra mittente e destinatario) e la configurazione della sessione non cambia in modo imprevisto. Ciò significherebbe che è possibile ottenere informazioni dalla sonda (o, al contrario, configurarla) e questa informazione di configurazione dovrebbe essere sufficiente per consentire al ricevitore di conoscere la struttura di ciascun frame di dati. Quindi, avresti due momenti: uno per configurare il trasferimento dei dati (inviando i dati di "intestazione" tra sonda e oscilloscopio) e il trasferimento dei dati stesso (invio seriale di frame di dati con un determinato formato).

  • Ora per il data-frame, è (come al solito) un flusso / array di byte con una determinata lunghezza, e dovrebbe codificare in qualche modo le informazioni. Di solito, usi qualcosa di simile a Tipo-Lunghezza-Valore , dove "Tipo" è un campo di un lunghezza predefinita che descrive "cosa" sta arrivando, "Lunghezza" è un altro campo che descrive quanti byte avrà il seguente campo Lunghezza, e infine il "Valore" stesso è il dato stesso.

Dalla tua domanda, le variabili configurabili sembrano essere:

  • Numero di canali;
  • Frequenza di campionamento per un determinato canale;
  • Tipo numerico: int, float, double;

Non ho ben capito cosa intendi per formato "binario", ma credo che questo sarebbe paragonato al testo (ascii, utf, ecc.). Ricorda che ogni trasferimento basato sul flusso sarebbe composto da byte e ci sono modi standard per rappresentare valori numerici come una matrice di byte ( float ha 4 byte, double ha 8 byte, Uint16 (alias short ) ha 2 byte, ecc.). Inoltre, ogni lingua ha la sua libreria per convertire tra i numeri digitati in memoria e i byte in un flusso.

Spero che questo aiuti e commenta qualcosa se ne hai voglia, perché attualmente sto lavorando con un formato di file binario personalizzato per l'acquisizione di dati multicanale nel mio progetto attuale, e sicuramente potremmo scambiarci qualche opinione a riguardo.

    
risposta data 12.05.2015 - 19:12
fonte
1

La codifica Base 64 viene utilizzata per l'invio di dati binari su un canale di testo. È esattamente l'opposto di quello che vuoi. Richiederà semplicemente il codice di codifica / decodifica e ingrandirà i tuoi messaggi.

È difficile formulare una raccomandazione senza sapere esattamente quali dati è necessario inviare. Potresti voler esaminare Buffer del protocollo poiché è progettato per essere compatto.

    
risposta data 12.05.2015 - 18:33
fonte

Leggi altre domande sui tag