View difference between Paste ID: VpZVuw0t and KEr1hZW9
SHOW: | | - or go back to the newest paste.
1
# Fabio Eboli 01-2013
2-
# functions to connect to FE5680A
2+
# functions useful for connecting to FE5680A
3
# usage:
4
# p=SetPort(portnumber)  note the in windows 0 is COM1, 1 is COM2 etc
5
# value=GetOffs(p)
6
# SetOffsRam(p,1000) 1000 is the new momentary offset
7
# SetOffsRelRam(p,-30) the new momentary offset s 30 units less than last one i.e. 970
8
# StoreOffsEE(p) stores the actual momentary offset into EEPROM
9
# SetOffsEE(p,500) 500 is the new offset, and is permanently saved into EEPROM
10
# ChangeFreqHz(p,1) move the output frequency 1Hz high
11
# ChangeFreqP(p,-2.5e-10) move the output frequency -2.5x10^-10
12
# SendCommandChar(p,0x22,'',True) check and print in readable format the result of 0x2D command
13
14
import serial
15
from struct import *
16
import time
17
18
lastcommandtime=0
19
resolution_parts_per_bit=6.80789e-13
20
21
# prepares the communication serial port to the FE5680A
22
# portno is the port number, in win 0 for COM1 etc
23
# returns the port that will be passed to the other functions
24
def SetPort(portno):
25
    global lastcommandtime
26
    port=serial.Serial(portno)
27
    print("Connected to "+port.name)
28
    port.baudrate=9600
29
    port.timeout=.1
30
    port.close()
31
    lastcommandtime=time.time()
32
    return port
33
34
# builds and sends a command to the FE5680A
35
# port : serial port returned by SetPort()
36
# ID : command code number
37
# Data : command data, string
38
# ReadBack : True if an answer from the FE5680A is expected
39
# Returns : [rtncode,rtndata,error]
40
# rtncode: -1 error in answer
41
#          0 no answer expected
42
#          1 correct answer received
43
# rtndata: payload data returned from FE5680A, binary string
44
# error: error description
45
def SendCommand(port,ID,Data,ReadBack):
46
    global lastcommandtime
47
    IDstring=pack('B',ID)
48
    datalen=len(Data)
49
    if datalen>128:
50
        return -1
51
    if len(Data)>0:
52
        totlen=datalen+5 # total message lenght ID+Lenght(2)+Checksum1+Data Lenght+Checksum2
53
    else:
54
        totlen=datalen+4
55
    totlenstr=pack('<H',totlen)
56
    cs1str=pack('B', (ID ^ (unpack('B',totlenstr[0])[0]) ^ (unpack('B',totlenstr[1])[0])))
57
    cs2=0
58
    for chars in Data:
59
        cs2 ^= unpack('B',chars)[0]
60
    cs2str=pack('B',cs2)
61
62
    timefromlastcommand=(time.time())-lastcommandtime
63
    while timefromlastcommand<2: #wait at least 2s between communications to FE5680A
64
        timefromlastcommand=(time.time())-lastcommandtime    
65
    port.open()
66
    port.write(IDstring+totlenstr+cs1str+Data+cs2str)
67
#    print(IDstring+totlenstr+cs1str+Data+cs2str)
68
    ret=[0,'','']
69
    if ReadBack==True:
70
        answer=port.readall()
71
#        answer=input("Answer? ")
72
        ansID=unpack('B',answer[0])[0]
73
        anslen=unpack('<H',answer[1:3])[0]
74
        anscs1=unpack('B',answer[3])[0]
75
        calccs2=0
76
        #check command code
77
        if ansID == ID:
78
            #check total lenght
79
            if len(answer) == anslen:
80
                #check command checksum
81
                calccs1=(unpack('B',answer[0])[0]) ^ (unpack('B',answer[1])[0]) ^ (unpack('B',answer[2])[0])
82
                if anscs1 == calccs1:
83
                    anscs2=unpack('B',answer[anslen-1])[0]
84
                    # calculate data checksum
85
                    for d in answer[4:anslen-1] :
86
                        calccs2^=unpack('B',d)[0]
87
                    #check data checksum
88
                    if anscs2 == calccs2 :
89
                        ret=[1,answer[4:anslen-1],"No Errors"]
90
                    else:
91
                        ret=[-1,answer[4:anslen-1],"Error: wrong data checksum"]
92
                else:
93
                    ret=[-1,answer[4:anslen-1],"Error: wrong command checksum"]
94
            else:
95
                ret=[-1,answer[4:anslen-1],"Error: wrong packet lenght"]
96
        else:
97
            ret=[-1,'',"Error: bad command code returned"]
98
    port.close()
99
    lastcommandtime=time.time()
100
    return  ret
101
102
# Same as SendCommand but returns the payload in readable string format
103
# and prints on stdout
104
def SendCommandChar(port,ID,Data,ReadBack):
105
    answer=SendCommand(port,ID,Dara,ReadBack)
106
#    answer=input("Answer? ")
107
    answerstring=''
108
    for i in answer[1]:
109
        answerstring+=(hex(unpack('B',i)[0]))+ "\r\n"
110
    print(str(len(answer[1]))+" Elements in answer")
111
    print(answerstring)
112
    return [answer[0],answerstring,answer[2]]
113
114
115
# Returns the Offset from the FE5680A         
116
def GetOffs(port):
117
    commandcode=0x2D
118
    data=''
119
    ret=SendCommand(port,commandcode,data,True)
120
    if ret[0]==1:
121
        return unpack('>i',ret[1])[0]
122
    else:
123
        print("Error code "+str(ret[0]))
124
        print(ret[2])
125
        return 0
126
    
127
# Sets the offset, without saving the value
128
def SetOffsRam(port,value):
129
    commandcode=0x2E
130
    data=pack('>i',value)
131
    return SendCommand(port,commandcode,data,False)[2]
132
133
# Sets the offset relative to the value stored in the FE5680A,
134
# without saving the value, useful for incremental changes
135
def SetOffsRelRam(port,value):
136
    refoffs=GetOffs(port)
137
    newoffs=refoffs+value
138
    return SetOffsRam(port,newoffs)
139
140
# Sets the offset, saving the value into the EEPROM of the FE5680A
141
def SetOffsEE(port,value):
142
    commandcode=0x2C
143
    data=pack('>i',value)
144
    return SendCommand(port,commandcode,data,False)
145
146
# Reads the offset from internal ram and Stores it to EEPROM
147
def StoreOffsEE(port):
148
    value=GetOffs(port)
149
    return SetOffsEE(port,value)
150
151
# Change the frequency output of valueHz Hz, not stored
152
def ChangeFreqHz(port,valueHz):
153
    Offs=int(float(valueHz)/(resolution_parts_per_bit*1e7))
154
    print("new offset: "+str(Offs))
155
    return SetOffsRelRam(port,Offs)
156
157
# Change the frequency output of valueP parts, not stored
158
def ChangeFreqP(port,valueP):
159
    Offs=int(float(valueP)/resolution_parts_per_bit)
160
    print("Offset: "+str(Offs))
161
    return SetOffsRelRam(port,Offs)