SATSAGEN v.0.9.3.3 / Supporto GPIB

Supporto GPIB

Mediante l’utilizzo di un adattatore GPIB->USB seriale come il progetto AR488, Satsagen può pilotare dispositivi dotati di interfaccia IEEE488 GPIB/HP-IB.

La versione 0.9.3.3 permette di pilotare generatori sintetizzati e power meter come rispettivamente device TX ed RX di Satsagen.

Alcuni antichi dispositivi sono direttamente supportati e sono elencati tra i dispositivi utilizzabili in Settings->Devices, mentre è possibile configurare mediante due modelli di template altri generatori sintetizzati e power meter conoscendone la sintassi dei comandi.

Perché utilizzare Satsagen per pilotare dispositivi dotati di GPIB/HP-IB?

Oltre a poter agire semplicemente come un comando remoto dei dispositivi, Satsagen può funzionare come anello di congiunzione tra più dispositivi eterogenei per creare strumenti SNA/VNA, per esempio Satsagen diventa uno strumento scalare SNA connettendo un generatore e un power meter entrambi in GPIB/HP-IB, oppure un SNA/VNA abbinando un generatore GPIB/HP-IB e un ricevitore SDR come ADALM-PLUTO.

E’ consentito con Satsagen pilotare più dispositivi GPIB/HP-IB mediante un’interfaccia dedicata per ogni dispositivo o con una singola interfaccia collegata su un BUS GPIB/HP-IB dove sono attestati i dispositivi da controllare con indirizzi diversi, ma non è permesso utilizzare contemporaneamente due dispositivi dello stesso BUS GPIB/HP-IB.

GPIB template

I GPIB template sono file di configurazione in formato .ini che permettono a Satsagen di pilotare dispositivi su bus GPIB.

In Satsagen versione 0.9.3.3 sono previsti due modelli di configurazione, uno per pilotare generatori sintetizzati e un altro per i power meter.

Nella directory Documenti\Satsagen\Settings si trovano due file modelli da copiare e modificare in base alle proprie esigenze per generare i template finali da importare in Satsagen: templatePLL_commented.ini per i generatori sintetizzati e templatePM_commented.ini per i power meter.

Copiare quindi i modelli con un nome a piacimento nella stessa directory Documenti\Satsagen\Settings e modificarli con blocco note.

Template PLL

I template PLL consentono a Satsagen di pilotare generatori sintetizzati su bus GPIB. Hanno una unica sezione chiamata CUSTOMGPIBPLL.

I campi mandatori che occorre personalizzare per poter pilotare i generatori sintetizzati su GPIB sono:

  • DeviceAddr: indirizzo GPIB
  • fGEN: frequenza iniziale in Hz. Potrà essere modificata dal pannello Generatore di Satsagen. Mettere per esempio una frequenza a piacimento nel range del dispositivo.
  • TXAttGEN: impostazione attenuatore iniziale in dBm. Anche questo parametro potrà essere modificato dal pannello del Generatore. Mettere per esempio un valore per ottenere una potenza in output iniziale più bassa possibile.
  • XO_FREQUENCY: frequenza di riferimento in Hz del dispositivo. Buona parte dei dispositivi utilizza una frequenza di riferimento di 10 MHz, quindi compilare con 10000000. Questo parametro verrà utilizzato da Satsagen per calcolare l’offset sulla frequenza da generare in base ad una eventuale correzione da apportare.
  • REFTXPWR: compilare con la potenza massima in output del dispositivo espressa in dBm
  • MINFREQTX: compilare con la minima frequenza in Hz consentita dal dispositivo
  • MAXFREQTX: compilare con la massima frequenza in Hz consentita dal dispositivo
  • MINTXATT: compilare con il valore in dB dell’attenuatore del dispositivo per ottenere la minima potenza in uscita. Per esempio -110
  • MAXTXATT: compilare con il valore in dB dell’attenuatore del dispositivo per ottenere la massima potenza in uscita. Solitamente va posto a 0
  • TXATTNSTEP: compilare con la granularità in dB dell’attenuatore del dispositivo, solitamente 10, 1 o 0.1
  • CmdCWON: comando per attivare l’output, per esempio RF1
  • CmdCWOFF: comando per disattivare l’output, per esempio RF0
  • CmdDefSetPwrOut: comando per impostare il livello in uscita del dispositivo. Per esempio PL seguito da una delle seguenti variabili di Satsagen e terminato solitamente dal suffisso DB: %PWRDBMDEC% verrà sostituita con il valore in dBm compreso di segno e un decimale, %PWRDBMINT% verrò sostituita con il valore intero in dBm compreso di segno o %PWRDBMSIGN% che verrà sostituita solo dal carattere di segno. Un esempio di comando potrà essere PL%PWRDBMDEC%DB, Satsagen quindi invierà al dispositivo per impostare un valore di uscita per esempio di -30dBm il comando PL-30.0DB in questo caso.
  • CmdDefSetVFO: comando per impostare la frequenza in Hz del dispositivo. Per esempio CW seguito da una delle seguenti variabili di Satsagen e terminato solitamente dal suffisso HZ: %FREQGHZDEC% frequenza completa in GHz con decimali, per esempio 10,368200125. %FREQGHZ% frequenza solo in GHz, per esempio 10. %FREQMHZDEC% frequenza completa in MHz con decimali, per esempio 10368,200125. %FREQMHZ% frequenza in MHz senza decimali, per esempio 10368. %FREQMHZONLY% rappresenta solo la porzione in MHz, per esempio 368 se la frequenza completa in GHz è 10,368200125. %FREQKHZDEC% frequenza completa in kHz con decimali, per esempio 10368200,125. %FREQKHZ% frequenza espressa in kHz senza decimali, per esempio 10368200. %FREQKHZONLY% solo la porzione in kHz, per esempio 200. %FREQHZ% frequenza completa espressa in Hz, per esempio 10368200125. %FREQHZONLY% solo la porzione in Hz, per esempio 125. Un esempio di comando potrà essere: CW%FREQHZ%HZ, Satsagen quindi per impostare la frequenza nell’esempio 10368200125 Hz la seguente stringa: CW10368200125HZ.

Un file INI di template minimale per il funzionamento con generatori sintetizzati quindi potrebbe risultare come il seguente:

[CUSTOMGPIBPLL]
DeviceAddr=19
fGEN=2000000000
TXAttGEN=-60
XO_FREQUENCY=10000000
REFTXPWR=12
MINFREQTX=2000000000
MAXFREQTX=18000000000
MINTXATT=-110
MAXTXATT=0
TXATTNSTEP=1
CmdCWON=RF1
CmdCWOFF=RF0
CmdDefSetPwrOut=PL%PWRDBMDEC%DB
CmdDefSetVFO=CW%FREQHZ%HZ
Importazione (ed esportazione) dei template

Per rendere operativa la configurazione template, occorre importare il file appena creato nella memoria di Satsagen.

Dalla scheda Devices in Settings scegliere dalla lista Model la voce GPIB/Custom PLL Synthesizer e importare il file .ini tramite il pulsante Load Template.

Se il controllo della sintassi avrà avuto esito positivo, un messaggio di conferma dell’importazione verrà visualizzato da Satsagen e da quel momento il device GPIB/Custom PLL Synthesizer potrà essere utilizzato con la configurazione appena creata anche nelle sessioni successive.

Una nuova importazione di un altro file tramite il pulsante Load Template provocherà la sovrascrittura in memoria della configurazione.

E’ possibile esportare in un file .ini la configurazione attiva in memoria tramite il pulsante Export Template. E’ anche possibile esportare il contenuto della configurazione in memoria su un file .ini esistente, questo può essere utile per conservare eventuali commenti non presenti in memoria e che andrebbero persi se si esportasse la configurazione in un nuovo file.


Molti altri campi possono essere utilizzati nella configurazione di un template per ottimizzare il funzionamento di controllo del dispositivo GPIB ed aggiungere delle funzionalità.

Campi di controllo stato dispositivo

In ordine di importanza, se il dispositivo lo permette, andrebbero aggiunti i campi che verificano lo stato di lock del PLL del generatore sintetizzato che si vuole controllare. Tale verifica è necessaria se in seguito all’invio dei comandi quali ON e OFF del CW, impostazione della potenza di uscita e della frequenza, il dispositivo non preveda un controllo automatico del lock in conferma dei comandi ricevuti. In tali condizioni, il controllo potrebbe non funzionare correttamente, generando errori o blocchi dell’applicazione durante l’utilizzo.

Solitamente il metodo più comune per la verifica del lock è offerto tramite il test di un bit dello status byte (o word) del dispositivo.

I campi PhaseLockedStatusMask e PhaseLockedStatusBitNegate definiscono come testare il bit dello status per la verifica del lock PLL.

Il campo PhaseLockedStatusMask definisce la maschera per “estrarre” il bit dallo status. Se per esempio, il bit che indica il lock del PLL è quello con peso 16 allora la maschera dovrà essere impostata a PhaseLockedStatusMask=16 (o 0x10 in esadecimale). Se il dispositivo indica che il lock del PLL avviene quando il suddetto bit è a zero, quindi con una logica negata, allora dovremmo impostare PhaseLockedStatusBitNegate=1.

Una metodologia alternativa per testare il lock del PLL offerta da Satsagen nel caso lo status byte (o word) del dispositivo non lo prevede, è l’invio di un comando e l’analisi del risultato a tale comando. Con il campo CmdGetPhaseLocked definiamo il comando da inviare al dispositivo e con RegEx2MatchMessagePhaseLocked definiamo l’espressione regolare da utilizzare per effettuare il match sul risultato quando il lock del PLL avviene. Per esempio, se il dispositivo prevede di testare il lock mediante il comando LOCK? allora impostiamo CmdGetPhaseLocked=LOCK? e se la risposta è semplicemente il numero 1 per il lock e 0 per l’unlock, allora dovremo impostare RegEx2MatchMessagePhaseLocked=[1]. Se CmdGetPhaseLocked è definito, la maschera sullo status byte vista in precedenza non avrà effetto.

E’ possibile inoltre regolare nelle tempistiche il suddetto meccanismo di verifica del lock, sia se si utilizza lo status byte che un comando. Mediante il campo timeoutPhaseLock definiamo il timeout in millisecondi scaduto il quale se i suddetti metodi non hanno riscontrato il lock, la procedura va in errore e l’applicazione si ferma informando l’utente. Con usSleepPhaseLockWaitCycle definiamo l’attesa in microsecondi tra un test e l’altro fino a quando non si riceve una risposta positiva o scade il timeout visto prima. Questo parametro è utile per non sovracaricare inutilmente il dispositivo di richieste.

Nel caso peggiore che il dispositivo non preveda nessun metodo per verificare lo stato del lock, è possibile inserire un’attesa fissa in millisecondi in seguito all’invio dei comandi, quantificabile in base a verifiche che andrebbero eseguite manualmente, per esempio inviando i comandi con il terminale GPIB a disposizione nell’applicazione Satsagen. Tali ritardi è possibile specificarli con i seguenti campi:

msSleepAfterCWTurnONOFF attesa in millisecondi in seguito all’invio del comando di CW ON o OFF

msSleepAfterSetPwrOut attesa in millisecondi in seguito all’invio del comando di potenza di uscita

msSleepAfterSetVFO attesa in millisecondi in seguito all’invio del comando di impostazione della frequenza

Identici nella sintassi del controllo del lock appena visto, sono disponibili altrettanti campi per la verifica dello stato di pronto (ready) del dispositivo, utili da testare soprattutto prima di inviare nuovi comandi. Nell’ordine, DeviceReadyStatusMask, DeviceReadyStatusBitNegate, CmdGetDeviceReady, RegEx2MatchMessageDeviceReady, timeoutDeviceBusy e usSleepDeviceBusyWaitCycle.

Sempre simili nella sintassi, sono anche disponibili i seguenti campi per la verifica di presenza di errori: ErrorStatusMask, ErrorStatusBitNegate, CmdTestError e RegExTestError. In questo caso, i parametri relativi ai timeout e attese non sono necessari, mentre sono disponibili due campi che consentono di leggere dal dispositivo una descrizione dell’errore appena riscontrato: CmdGetError e RegExGetError.

Per far sì che la definizione dei suddetti campi di controllo di lock, device ready e presenza di errori diventino operativi occorre attivarli dove serve, nelle “sezioni” relative ai comandi principali di CW ON e OFF, impostazione della potenza di uscita e della impostazione della frequenza. Questo lo si fa impostando a 1 i campi testPhaseLockedxxx, testDeviceReadyBeforexxx e testDeviceReadyAfterxxx e testErrorxxx.

L’esempio di configurazione per un template PLL visto in precedenza diventerà il seguente completo di campi di controllo lock, ready ed error:

[CUSTOMGPIBPLL]
;;;Definizione generale del dispositivo
DeviceAddr=19
fGEN=2000000000
TXAttGEN=-60
XO_FREQUENCY=10000000
REFTXPWR=12
MINFREQTX=2000000000
MAXFREQTX=18000000000
MINTXATT=-110
MAXTXATT=0
TXATTNSTEP=1
;;;Definizione dei test su lock PLL, device ready ed error
PhaseLockedStatusMask=16
PhaseLockedStatusBitNegate=1
timeoutPhaseLock=3000
usSleepPhaseLockWaitCycle=20000
;;;-------------------------------------------------------
DeviceReadyStatusMask=8
DeviceReadyStatusBitNegate=0
timeoutDeviceBusy=3000
usSleepDeviceBusyWaitCycle=20000
;;;-------------------------------------------------------
ErrorStatusMask=2
ErrorStatusBitNegate=0
;;;Definizione dei comandi principali e attivazione dei test
testDeviceReadyBeforeCWONOFF=1
CmdCWON=RF1
CmdCWOFF=RF0
testErrorCWONOFF=1
testDeviceReadyAfterCWONOFF=1
testPhaseLockedCWONOFF=1
;;;---------------------------------------------------------
testDeviceReadyBeforeSetPwrOut=1
CmdDefSetPwrOut=PL%PWRDBMDEC%DB
testErrorSetPwrOut=1
testDeviceReadyAfterSetPwrOut=1
testPhaseLockedSetPwrOut=1
;;;---------------------------------------------------------
testDeviceReadyBeforeSetVFO=1
CmdDefSetVFO=CW%FREQHZ%HZ
testErrorSetVFO=1
testDeviceReadyAfterSetVFO=1
testPhaseLockedSetVFO=1

Infine, tra i campi di controllo di stato dispositivo, ma che hanno solo una funzione visiva, sono quelli che permettono di leggere la temperatura o di monitorare l’oven del cristallo di riferimento del dispositivo, aggiornando nella finestra principale di Satsagen il colore e le informazioni tramite il LED posto accanto al pulsante Power On.

Specificare con CmdReadTemp il comando da inviare per ottenere la temperatura del dispositivo, per esempio CmdReadTemp=TEMP?. Nel contempo specificare RegEx2DecodeMessageReadTemp con l’espressione regolare che permette di estrarre dalla risposta al comando precedente il valore della temperatura comprensivo di segno e parte decimale, per esempio RegEx2DecodeMessageReadTemp=([-+]?\d+(?:.\d+)?)

Se il dispositivo non prevede un comando di lettura di temperatura, ma tramite un bit dello status byte se l’oven del cristallo di riferimento ha raggiunto la temperatura di esercizio, allora con OvenStatusMask specificare la maschera del bit in questione, per esempio se è il bit con peso 4, OvenStatusMask=4 e nel caso sia negato, cioè a zero quando l’oven è in temperatura, aggiungere OvenStatusBitNegate=1.

Comandi di inizio, fine connessione e modo alternativo al serial poll status byte

Con i campi CmdInit e CmdEndConn è possibile specificare eventuali comandi da inviare al dispositivo rispettivamente all’atto della connessione e disconnessione di Satsagen. Con CmdInitResponseToTrace=1 si attiva l’invio della risposta al comando CmdInit sulla trace log, può essere utile se con CmdInit inviamo per esempio un comando per interrogare la versione del dispositivo, la quale potrà poi essere letta nella trace di Satsagen.

Infine è possibile far usare da Satsagen un metodo alternativo al GPIB serial poll per la lettura dello status byte (o word), se previsto dal dispositivo. Con il campo CmdGetDeviceStatus si definisce il comando da inviare per ottenere lo status byte e con RegEx2DecodeDeviceStatus l’espressione regolare da utilizzarsi per fare il match sul valore numerico dello status byte, per esempio semplicemente con RegEx2DecodeDeviceStatus=\d?

Template Power Meter

I template Power Meter consentono a Satsagen di pilotare i Power Meter su BUS GPIB. Hanno una unica sezione chiamata CUSTOMGPIBPM.

I campi mandatori che occorre personalizzare per poter pilotare i Power Meter su BUS GPIB sono:

  • DeviceAddr: indirizzo GPIB
  • REFGAIN0: offset rispetto alla lettura. Con questo campo possiamo specificare un offset in dB che Satsagen apporterà alla lettura prima della visualizzazione. Di norma va messo a zero REFGAIN0=0, ma può essere utile specificare un valore in offset per la calibrazione del dispositivo, se quest’ultimo non la prevede internamente.
  • MINFREQRX: specificare con questo campo la frequenza minima in Hz del dispositivo Power Meter.
  • MAXFREQRX: specificare con questo campo la frequenza massima in Hz del dispositivo Power Meter.
  • MAXINPUT: indica la potenza massima ammessa dal Power Meter espressa in dBm
  • DYNAMICRANGE: specificare con questo campo la dinamica del Power Meter espressa in dB. Per esempio con DYNAMICRANGE=106 e il precedente campo MAXINPUT=6, il Power Meter può misurare da -100 dBm a +6 dBm.
  • nreadsmeanTSA: è il numero di letture per il calcolo della media per ogni punto di scansione TSA se il Power Meter lo si utilizza come dispositivo RX in una configurazione SNA, cioè abbinato con un secondo device con ruolo di TX, generatore di tracking.
  • CmdReadPwr: è il comando da inviare al dipositivo per effettuare la lettura di potenza.
  • RegEx2DecodeMessageReadPwr: è l’espressione regolare da utilizzare per estrarre (fare il match) dalla risposta del comando precedente (CmdReadPwr) il valore della lettura.

Un file INI di template minimale per il funzionamento con i Power Meter quindi potrebbe risultare come il seguente:

DeviceAddr=8
REFGAIN0=0
MINFREQRX=1000000
MAXFREQRX=200000000
MAXINPUT=6
DYNAMICRANGE=106
nreadsmeanTSA=1
CmdReadPwr=IPW,TRG
RegEx2DecodeMessageReadPwr=([-+]?\d+(?:\.\d+)?)

I campi di controllo CmdGetDeviceReady, DeviceReadyStatusMask, CmdTestError e CmdGetError già visti nel precedente capitolo del template PLL, possono essere utilizzati con la stessa sintassi anche nella configurazione per i Power Meter. I campi che attivano i controlli per i Power Meter sono: testDeviceReadyBeforeRead, testErrorRead e testDeviceReadyAfterFailedRead.

Il suddetto esempio di configurazione diventerà quindi il seguente se completato dei campi di controllo:

;;;Definizione generale del dispositivo
DeviceAddr=8
REFGAIN0=0
MINFREQRX=1000000
MAXFREQRX=200000000
MAXINPUT=6
DYNAMICRANGE=106
nreadsmeanTSA=1
;;;Definizione dei test su device ready ed error
DeviceReadyStatusMask=8
DeviceReadyStatusBitNegate=0
timeoutDeviceBusy=3000
usSleepDeviceBusyWaitCycle=20000
;;;-------------------------------------------------------
ErrorStatusMask=2
ErrorStatusBitNegate=0
;;;Definizione del comando principale e attivazione dei test
testDeviceReadyBeforeRead=1
CmdReadPwr=IPW,TRG
testErrorRead=1
RegEx2DecodeMessageReadPwr=([-+]?\d+(?:\.\d+)?)
testDeviceReadyAfterFailedRead=1

Infine è possibile utilizzare anche i seguenti campi, identici nella sintassi a quelli già visti nel capitolo precedente Template PLL:

CmdInit, comando inviato nel momento della connessione e CmdInitResponseToTrace, se è 1 invia la risposta del CmdInit sulla trace log. CmdEndConn, comando inviato alla disconnessione. CmdGetDeviceStatus, comando alternativo al serial poll status byte e RegEx2DecodeDeviceStatus, espressione regolare per fare il match sul valore numerico dello status. CmdReadTemp, comando per leggere la temperatura del device e RegEx2DecodeMessageReadTemp per estrarre il valore double della temperatura con un espressione regolare. OvenStatusMask, in alternativa al comando precedente, bit dello status che determina se l’oven è in temperatura e OvenStatusBitNegate per negarlo.

Terminale GPIB

Satsagen include un terminale con il quale è possibile “dialogare” con il dispositivo collegato in GPIB a scopo di debug/troubleshooting.

Per aprire il terminale fare un click su Open GPIB terminal dal menu View, anche con Satsagen in Power Off.

A questo punto l’applicazione presenterà una lista delle interfacce disponibili:

Selezionare l’interfaccia desiderata e fare doppio-click o click su Ok.

A connessione avvenuta si aprirà un terminale in modalità verbose da dove è possibile inviare comandi sia all’interfaccia (preceduti da ++) o direttamente sul dispositivo all’indirizzo di default, 1.

Per cambiare l’indirizzo in uso dare il comando ++addr x, dove x è il numero del dispositivo GPIB. Con ++help otteniamo l’elenco e descrizione dei comandi dell’interfaccia preceduti da ++. Per una descrizione completa fare riferimento alla documentazione AR488.

Ricordarsi al termine delle operazioni, di chiudere il terminale in modo da liberare la porta seriale perché possa essere utilizzata da Satsagen per eventualmente connettersi al dispositivo e controllarlo.

Funzionamento del backspace nel terminale GPIB

Probabilmente riscontrerai che il tasto backspace non ha effetto durante l’utilizzo del terminale, o meglio, il cursore sembra retrocedere, però nella memoria buffer della riga questo non avviene, per cui se lo utilizzi per correggere un comando, questo comunque verrà inviato al dispositivo in modo errato.

Per risolvere tale problema, occorre modificare il file AR488.ino nei sorgenti del AR488 ed aggiungere le seguenti righe che permettono il funzionamento del backspace.

 // handle the backspace in verbose mode - albfer 21/12/2024
      case 0x7f:
      case 'x8:
      if(isVerb && pbPtr)
        pbPtr--;
        else
        {
        addPbuf(c);
        isEsc = false;
        }
      break;  

Le suddette righe vanno inserite all’interno della funzione parseInput(char c), dalla riga seguente a switch(c){ in modo da ottenere le prime righe di tale funzione in questo modo:

uint8_t parseInput(char c) {

  uint8_t r = 0;

  // Read until buffer full
  if (pbPtr < PBSIZE) {
    if (isVerb && c!=LF) dataPort.print(c);  // Humans like to see what they are typing...
    // Actions on specific characters
    switch (c) {
      // handle the backspace in verbose mode - albfer 21/12/2024
      case 0x7f:
      case 'x8:
      if(isVerb && pbPtr)
        pbPtr--;
        else
        {
        addPbuf(c);
        isEsc = false;
        }
      break;        
      // Carriage return or newline? Then process the line
      case CR:
      case LF:
.
.
.

Ricompilare con l’ambiente Arduino e ricaricare sull’interfaccia.