Electron Spin Resonance – Parte SW

Abstract: Nei precedenti post (Risonanza Elettronica di Spin, Risonanza Elettronica di Spin – Parte HW) abbiamo descritto i principi generali e la parte hardware del nostro apparato ESR DIY. Nel presente post completiamo la descrizione dell’apparato soffermandoci sulla parte firmware di gestione e sulla parte software di registrazione dei dati.

Firmware

La gestione dell’apparato per la risonanza elettronica di spin è fatta con un microcontrollore della serie PSoC 5lp della Cypress. Si tratta di un cosìdetto “system on chip”. Oltre alle classiche funzionalità di un microcontrollore, questo componente integra funzionalità avanzate che includono ADC e DAC di precisione, op amp programmabili e logica FPGA-like, il tutto configurabile tramite una comoda interfaccia grafica e programmabile in C.

Il convertitore ADC è del tipo delta-sigma a 18 bit, con range 0 – 6V e la conversione avviene in modalità multiplexer. I canali acquisiti sono il trimmer presente sulla scheda, il segnale del sensore Hall per il campo magnetico ed il segnale ESR rilevato e amplificato dal lock-in detector. L’immagine seguente mostra lo schema della parte ADC dello PSoC.

La lettura del segnale prodotto dal sensore Hall va convertita nel corrispondente valore del campo magnetico misurato in mT. Il codice seguente mostra la funzione di conversione.

/*******************************************************************************
* Function Name: CalcBfield
********************************************************************************
* Summary:
* 
********************************************************************************/
double CalcBfield(double HallSensorReading){
  int offsetHallSensor = 2585; // 2585mv means 0mT
  int HallSensorRatio = 100; // 100mV/mT
  double Bfield = (HallSensorReading-offsetHallSensor)/HallSensorRatio; // mag. field in mT 
  return Bfield;
}

Il PSoC ci serve anche per la misura della frequenza del segnale generato dall’oscillatore Robinson. Come descritto nel post precedente sulla parte HW, il segnale viene diviso per un fattore 128 da un circuito prescaler. La frequenza viene misurata dal componente counter come descritto nello schema seguente.

Il codice seguente mostra l’istruzione per il calcolo della frequenza.

/* Counter pulse reading - frequency calculation*/
osc_freq = ((Counter_ReadCounter()*(1000.0/readingPeriod))/1000000)*128; //128 presc. factor

Il nostro PSoC effettua anche la generazione del segnale di pilotaggio delle bobine di Helmholtz e del segnale modulante a 1KHz. Per questa operazione vengono utilizzati i componenti DAC dello PSoC, tra i quali anche il WaveDAC che permette la generazione di forme d’onda prestabilite, come mostrato nello schema seguente.

Il segnale di pilotaggio delle bobine di Helmholtz è una rampa crescente che parte da un valore iniziale di 200mV e termina al valore massimo determinato dalla lettura del trimmer; gli step di incremento sono di 16mV ed avvengono con cadenza determinata dalla variabile stepPeriod; il codice seguente mostra l’implementazione della rampa.

/* DAC Variables */
static int sweepValue = 0;       // sweep value (mV)
static int sweepInitValue = 200; // init value 200mV
static int sweepEndValue;        // from trimmer
static int stepValue = 16;       // step value 16mV
static int stepPeriod = 250;     // step period 250ms

/*******************************************************************************
* Function Name: SweepingTimerInt_ISR
*******************************************************************************
* Summary:
* Sweeping Timer Interrupt (every period).
*******************************************************************************/
CY_ISR(SweepingTimerInt_ISR){
  /* Calculation of the sweep value */
  sweepValue = sweepInitValue + stepValue*stepCount;
  /* Assign DAC value */
  DACvalue = (uint8)((sweepValue*256)/4096);
  CoilDriver_SetValue(DACvalue);
  /* increment number of steps */
  stepCount++;
  /* check final value reached */
  if(sweepValue >= sweepEndValue){
    /* Reset */
    stepCount = 0;
  }
  /* Reset timer */
  Sweeping_Timer_ReadStatusRegister();
}

Software Python

I dati acquisiti con il PSoC vengono inviati via interfaccia USB/seriale ad un PC linux sul quale gira un programma python che legge i dati del campo magnetico e del segnale ESR e li visualizza in grafico (come quello mostrato nella immagine di copertina). I dati vengono inoltre registrati su file csv per analisi ulteriori.
Il codice riportato sotto mostra un esempio del programma python di acquisizione e plotting dati.

################################
# serial reading /dev/ttyACM0
# and plotting data
################################

import time
import serial
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

# file definition
filenameESR = "ESRData.csv"
outFile = open(filenameESR,"a+")
outFile.write("**************\n")
outFile.write("** ESR Data **\n")
outFile.write("**************\n")

# parameters
x_len = 500 # time interval 0.1s
y1_range=[0,5] # B field intensity mT
y2_range=[1000,3500] # ESR signal mv

# create figure for plotting
fig = plt.figure()
ax1 = fig.add_subplot(2,1,1)
ax2 = fig.add_subplot(2,1,2)
xs = list(range(0,x_len))
y1s = [0]*x_len
y2s = [0]*x_len
ax1.set_ylim(y1_range)
ax2.set_ylim(y2_range)

# create figure for plotting
ax1.set_title('Magnetic Field')
ax1.set_xlabel('time [0.1s]')
ax1.set_ylabel('B [mT]')
ax2.set_title('ESR Signal')
ax2.set_xlabel('time [0.1s]')
ax2.set_ylabel('Signal [mV]')
plt.subplots_adjust(hspace=0.5)

# init serial
ser=serial.Serial('/dev/ttyACM0')
ser.flushInput()
time.sleep(2) # give time to flush

# create blank line
linea1 = ax1.plot(xs,y1s)[0]
linea2 = ax2.plot(xs,y2s)[0]

# funcion called periodically from FuncAnimation
def animate(i,y1s,y2s,outFile):
  try:
    line=ser.readline().strip()
    BFieldTxt,ESRSignalTxt=line.decode('ascii').split(";",1)
    BField=round(np.float32(BFieldTxt),2)
    ESRSignal=np.int(ESRSignalTxt)
    #print('BField',BField)
    #print('ESRSignal',ESRSignal)
    outFile.write(BFieldTxt+","+ESRSignalTxt+"\n")
  except ValueError:
    print('failed to read serial')

# add data to lists
y1s.append(BField)
y1s=y1s[-x_len:]

y2s.append(ESRSignal)
y2s=y2s[-x_len:]

# update lines
linea1.set_ydata(y1s)
linea2.set_ydata(y2s)

return linea1,linea2

# animation
ani = animation.FuncAnimation(fig,animate,fargs=(y1s,y2s,outFile),interval=100,blit=True)
plt.show()

Conclusioni

Con questo post concludiamo la descrizione del nostro apparato DIY per la risonanza elettronica di spin. Nel prossimo post descriveremo alcune misure sperimentali effettuate con il nostro apparato.

Se ti è piaciuto questo articolo puoi condividerlo sui “social” Facebook, Twitter o LinkedIn con i pulsanti presenti sotto. In questo modo ci puoi aiutare ! Grazie !

Donazioni

Se vuoi contribuire allo sviluppo di questo sito ed allo sviluppo di nuove attività sperimentali puoi fare una donazione, Grazie !

Check Also

Spettrometro Thunder Optics & Spectragryph

Abstract: in questo post descriviamo lo spettrometro della Thunder Optics utilizzato con il software Spectrgrayph. Ci proponiamo di effettuare la configurazione e la calibrazione dello strumento e di utilizzarlo per l'acquisizione e lo studio dello spettro di alcune sorgenti luminose. Per le misurazioni utilizzeremo anche alcuni accessori come fibre ottiche, collimatori e sorgenti di calibrazione.