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) |