Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Fabio Eboli 01-2013
- # functions useful for connecting to FE5680A
- # tested with python 2.6, should work with all versions
- # you need python itself and pyserial module.
- # (basic) usage:
- # Open pytohn into a shell (in the same directory where is this file, that
- # will be FE5680A.py) and import these fuctions: >>> from FE5680A import*
- # Then configure the port
- # p=SetPort(portnumber) note the in windows 0 is COM1, 1 is COM2 etc
- # if there are no errors get the Offset:
- # value=GetOffs(p)
- # SetOffsRam(p,1000) 1000 is the new momentary offset
- # SetOffsRelRam(p,-30) the new momentary offset s 30 units less than last one i.e. 970
- # StoreOffsEE(p) stores the actual momentary offset into EEPROM
- # SetOffsEE(p,500) 500 is the new offset, and is permanently saved into EEPROM
- # ChangeFreqHz(p,1) move the output frequency 1Hz high
- # ChangeFreqP(p,-2.5e-10) move the output frequency -2.5x10^-10
- # PrintStatus(p) prints all the info knows to date on the screen
- # SendCommandChar(p,0x22,'',True) check and print in readable format the result of 0x2D command
- # To use SendCommandChar fully you may need to pack bytes in a string as
- # third argument, the simplest way is this: "\x01\x02\x03\x04" packs
- # the values 0x01 0x02 0x03 0x04 into a string.
- # Send Command Char can be used to for undocumented commands, a pair of examples are provided,
- # see GetADC and GetDDS
- import serial
- from struct import *
- import time
- import math
- lastcommandtime=0
- resolution_parts_per_bit=6.80789e-13 # internal resolution used by ChangeFreq functions
- DDSinputFreq=20000000 # frequency input of the DDS, used by GetDDS()
- # prepares the communication serial port to the FE5680A
- # portno is the port number, in win 0 for COM1 etc
- # returns the port that will be passed to the other functions
- def SetPort(portno):
- global lastcommandtime
- port=serial.Serial(portno)
- print("Connected to "+port.name)
- port.baudrate=9600
- port.timeout=.1
- port.close()
- lastcommandtime=time.time()
- return port
- # builds and sends a command to the FE5680A
- # port : serial port returned by SetPort()
- # ID : command code number
- # Data : command data, string
- # ReadBack : True if an answer from the FE5680A is expected
- # Returns : [rtncode,rtndata,error]
- # rtncode: -1 error in answer
- # 0 no answer expected
- # 1 correct answer received
- # rtndata: payload data returned from FE5680A, binary string
- # error: error description
- def SendCommand(port,ID,Data,ReadBack):
- global lastcommandtime
- IDstring=pack('B',ID)
- datalen=len(Data)
- if datalen>128:
- return -1
- if len(Data)>0:
- totlen=datalen+5 # total message lenght ID+Lenght(2)+Checksum1+Data Lenght+Checksum2
- else:
- totlen=datalen+4
- totlenstr=pack('<H',totlen)
- cs1str=pack('B', (ID ^ (unpack('B',totlenstr[0])[0]) ^ (unpack('B',totlenstr[1])[0])))
- cs2=0
- for chars in Data:
- cs2 ^= unpack('B',chars)[0]
- cs2str=pack('B',cs2)
- timefromlastcommand=(time.time())-lastcommandtime
- while timefromlastcommand<2: #wait at least 2s between communications to FE5680A
- timefromlastcommand=(time.time())-lastcommandtime
- port.open()
- port.write(IDstring+totlenstr+cs1str+Data+cs2str)
- # print(IDstring+totlenstr+cs1str+Data+cs2str)
- ret=[0,'','']
- if ReadBack==True:
- answer=port.readall()
- # answer=input("Answer? ")
- if answer != '' : #answer not empty
- ansID=unpack('B',answer[0])[0]
- anslen=unpack('<H',answer[1:3])[0]
- anscs1=unpack('B',answer[3])[0]
- calccs2=0
- #check command code
- if ansID == ID:
- #check total lenght
- if len(answer) == anslen:
- #check command checksum
- calccs1=(unpack('B',answer[0])[0]) ^ (unpack('B',answer[1])[0]) ^ (unpack('B',answer[2])[0])
- if anscs1 == calccs1:
- anscs2=unpack('B',answer[anslen-1])[0]
- # calculate data checksum
- for d in answer[4:anslen-1] :
- calccs2^=unpack('B',d)[0]
- #check data checksum
- if anscs2 == calccs2 :
- ret=[1,answer[4:anslen-1],"No Errors"]
- else:
- ret=[-1,answer[4:anslen-1],"Error: wrong data checksum"]
- else:
- ret=[-1,answer[4:anslen-1],"Error: wrong command checksum"]
- else:
- ret=[-1,answer[4:anslen-1],"Error: wrong packet lenght"]
- else:
- ret=[-1,'',"Error: bad command code returned"]
- else:
- ret=[-1,'',"Error: no answer received"]
- port.close()
- lastcommandtime=time.time()
- return ret
- # Same as SendCommand but prints the payload in readable string format
- def SendCommandChar(port,ID,Data,ReadBack):
- answer=SendCommand(port,ID,Data,ReadBack)
- # answer=input("Answer? ")
- answerstring=''
- for i in answer[1]:
- answerstring+=(hex(unpack('B',i)[0]))+ "\n"
- print(str(len(answer[1]))+" Bytes in answer")
- print(answerstring)
- return answer
- # Returns the Offset from the FE5680A
- def GetOffs(port):
- commandcode=0x2D
- data=''
- ret=SendCommand(port,commandcode,data,True)
- if ret[0]==1:
- return unpack('>i',ret[1])[0]
- else:
- print("Error code "+str(ret[0]))
- print(ret[2])
- return 0
- # Sets the offset, without saving the value
- def SetOffsRam(port,value):
- commandcode=0x2E
- data=pack('>i',value)
- return SendCommand(port,commandcode,data,False)[2]
- # Sets the offset relative to the value stored in the FE5680A,
- # without saving the value, useful for incremental changes
- def SetOffsRelRam(port,value):
- refoffs=GetOffs(port)
- newoffs=refoffs+value
- return SetOffsRam(port,newoffs)
- # Sets the offset, saving the value into the EEPROM of the FE5680A
- def SetOffsEE(port,value):
- commandcode=0x2C
- data=pack('>i',value)
- return SendCommand(port,commandcode,data,False)
- # Reads the offset from internal ram and Stores it to EEPROM
- def StoreOffsEE(port):
- value=GetOffs(port)
- return SetOffsEE(port,value)
- # Change the frequency output of valueHz Hz, not stored
- def ChangeFreqHz(port,valueHz):
- Offs=int(float(valueHz)/(resolution_parts_per_bit*1e7))
- print("new offset: "+str(Offs))
- return SetOffsRelRam(port,Offs)
- # Change the frequency output of valueP parts, not stored
- def ChangeFreqP(port,valueP):
- Offs=int(float(valueP)/resolution_parts_per_bit)
- print("Offset: "+str(Offs))
- return SetOffsRelRam(port,Offs)
- # Read the DDS setting
- # returns a list containing DDS values and frequencies
- def GetDDS(p):
- global DDSinputFreq
- commandcode=0x22
- answ=SendCommand(p,commandcode,'',True)
- if answ[0] == 1:
- DDS1=(unpack('>I',answ[1][0:4])[0])
- DDS2=(unpack('>I',answ[1][4:8])[0])
- F1=DDS1/(pow(2.0,32))*DDSinputFreq
- F2=DDS2/(pow(2.0,32))*DDSinputFreq
- return [DDS1,DDS2,F1,F2]
- else:
- print("Error")
- return [0,0,0,0]
- # Read the ADC settings (unsure)
- # returns a list containing ADC values
- def GetADC(p):
- global DDSinputFreq
- commandcode=0x5A
- answ=SendCommand(p,commandcode,'',True)
- if answ[0] == 1:
- ADC1=(unpack('<H',answ[1][0:2])[0])
- ADC2=(unpack('<H',answ[1][2:4])[0])
- ADC3=(unpack('<H',answ[1][4:6])[0])
- ADC4=(unpack('<H',answ[1][6:8])[0])
- return [ADC1,ADC2,ADC3,ADC4]
- else:
- print("Error")
- return [0,0,0,0]
- # Prints the status of the device
- def PrintStatus(p):
- offs=GetOffs(p)
- dds=GetDDS(p)
- adc=GetADC(p)
- print("Offset word: "+str(offs))
- print("Equivalent shift of "+str(offs*resolution_parts_per_bit))
- print("Equivalent to "+str(offs*resolution_parts_per_bit*(1.0e7))+"Hz")
- print("Based on an internal resolution of "+str(resolution_parts_per_bit)+" parts per bit")
- print("DDS status:")
- print("DDS Word 1: "+str(dds[0]))
- print("DDS Word 2: "+str(dds[1]))
- print("DDS Frequencies, values based on "+str(DDSinputFreq)+"Hz DDS input Frequency:")
- print("Frequency 1: "+str(dds[2])+"Hz")
- print("Frequency 2: "+str(dds[3])+"Hz")
- print("ADC status:")
- print("ADC Word 1 (trimpot? ): "+str(adc[0]))
- print("ADC Word 2 (supply V? ): "+str(adc[1]))
- print("ADC Word 3 (temperature? ): "+str(adc[2]))
- print("ADC Word 4 (VCXO Voltage?): "+str(adc[3]))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement