Browse code

upgrade to python 3

gandolf authored on 07/11/2022 00:41:49
Showing 4 changed files
... ...
@@ -21,57 +21,58 @@ also handle formatting of CAT commands and their associated parameters,
21 21
 while 'get' functions handle parsing of data returned from CAT commands
22 22
 that return status information.
23 23
 
24
-Email bug reports and comments to: fractal@intravisions.com
24
+Email bug reports and comments to: ka7jlo@gmail.com
25 25
 
26 26
 Notes
27 27
 -----
28 28
 1. The files ft991utility.py and ft991.py should be downloaded from the
29 29
    github repository and placed in the same folder.
30
-2. To run the utility, open a terminal session in directory containing
30
+2. Before running the utility you may need to edit line 39 or line 40 in
31
+   the "environment setup" section of the file "ft991utility.py".  Be sure
32
+   the com port is correct.  This will depend on whether you are running
33
+   Linux or Windows and on the default serial port assigned to the FT991.  
34
+3. To run the utility, open a terminal session in directory containing
31 35
    the ft991utility.py and ft991.py files.  Then simply type the utility
32 36
    file name after the command line prompt, e.g.,
33 37
        ~$ ./ft991utility.py
34 38
    If necessary, change the permissions on ft991utility.py to allow the file
35
-   to be run as an executable.  To change the permissions run the command
36
-       chmod +x ft991utility.py
37
-3. Windows users will need to have the python 2.7 framework installed.
39
+   to be run as an executable.  To change the permissions on Linux run the
40
+   command
41
+       ~$ chmod +x ft991utility.py
42
+4. Windows users will need to have the python 3.8 framework installed.
38 43
    Probably, the easiest way to get the framework is to install the
39 44
    Windows Subsystem for Linux Ubuntu platform.  Note that the utility
40
-   has not been tested on Windows and the developer makes no guarentees.
41
-4. While it is possible to run the utility completely from the command
42
-   line using options, beginning users are encouraged to use the
43
-   interactive mode.  To use the interactive mode simply type the file
45
+   has not been tested on Windows and the developer makes no guarantees.
46
+5. While it is possible to run the utility completely from the command
47
+   line using command line options, beginning users are encouraged to use
48
+   the interactive mode.  To use the interactive mode simply type the file
44 49
    name of the utility with no command line arguments, e.g.,
45 50
            ./ft991utility.py
46
-5. The utility saves memory settings in a comma-delimited file that
51
+6. The utility saves memory settings in a comma-delimited file that
47 52
    can be imported into a spreadsheet application for ease in viewing
48
-   and editing.  A LibreOffice Calc template 'ft991_memory_settings.ots'
49
-   has been provided to facilitate creating a spreadsheet to upload memory
50
-   settings to the FT991.
51
-6. The verbose mode, available both as a command line option and in
53
+   and editing.
54
+7. The verbose mode, available both as a command line option and in
52 55
    interactive mode, echos raw commands sent to the FT991, as well as
53 56
    raw status returned by the FT991.  This feature is useful for development
54 57
    and debugging purposes.
55
-7. If you already have repeater frequencies and such programmed
58
+8. If you already have repeater frequencies and such programmed
56 59
    in memory, you should first run the 'bm' command in interactive mode
57 60
    to back up your current memory settings.  Unless you change the default
58 61
    file name, this file should appear in your current working directory as
59 62
    'ft991mem.csv'.  Change this file name to something else such as
60 63
    'ft991mem_todaysDate.csv so that you can restore from this file at a
61 64
    later date if necessary.
62
-8. By the same token you should immediately back up your menu settings using
65
+9. By the same token you should immediately back up your menu settings using
63 66
    the 'bu' command in interactive mode.  The default file name is
64 67
    'ft991menu.cfg'.  Likewise change this file name to something else.
65
-9. The example file 'example.csv' shows how a memory settings file should
66
-   appear.  To load these settings in your FT991, run the 'rm' command in
67
-   interactive mode.  When prompted to enter a file name type 'example.csv'. 
68
-   For example,
69
-       Enter file name or <CR> for default: example.csv
70
-10. Backup and restore of split frequency memory settings is not yet implemented.
71
-    The 'Tx Frequency' and 'Offset' columns in the memory settings file should
72
-    be left blank.
73
-11. Please do not edit the menu settings file unless you absolutely know
68
+10. The example file 'example.csv' shows how a memory settings file should
69
+    appear.  To load these settings in your FT991, run the 'rm' command in
70
+    interactive mode.  When prompted to enter a file name type 'example.csv'. 
71
+    For example,
72
+        Enter file name or <CR> for default: example.csv
73
+11. Backup and restore of VHF/UHF split frequency repeater settings is not
74
+    supported by the FT991.
75
+12. Please do not edit the menu settings file unless you absolutely know
74 76
     what you are doing.  There should rarely be a need to edit this file.
75 77
     Menu changes should be made on the FT991, itself, and then backed up.
76 78
 
77
-
... ...
@@ -1,4 +1,4 @@
1
-#!/usr/bin/python -u
1
+#!/usr/bin/python3 -u
2 2
 # The -u option turns off block buffering of python output. This assures
3 3
 # that output streams to stdout when output happens.
4 4
 #
... ...
@@ -31,11 +31,12 @@
31 31
 #
32 32
 # Revision History
33 33
 #   * v10 24 Nov 2019 by J L Owrey; first release
34
+#   * v11 03 Oct 2020 by J L owrey; upgraded to Python 3
34 35
 #
35 36
 # This script has been tested with the following
36 37
 #
37
-#     Python 2.7.15rc1 (default, Nov 12 2018, 14:31:15) 
38
-#     [GCC 7.3.0] on linux2
38
+#     Python 3.8.10 (default, Mar 15 2022, 12:22:08) 
39
+#     [GCC 9.4.0] on linux
39 40
 #2345678901234567890123456789012345678901234567890123456789012345678901234567890
40 41
 
41 42
 import sys, serial, time
... ...
@@ -68,7 +69,7 @@ dMode = { 'LSB':'1', 'USB':'2', 'CW':'3', 'FM':'4', 'AM':'5',
68 69
 dShift = { 'OFF':'0', '+RPT':'1', '-RPT':'2' }
69 70
 
70 71
 # Power settings
71
-dPower = { 'LOW':5, 'MID':020, 'HIGH':50, 'MAX':100 }
72
+dPower = { 'LOW':'5', 'MID':'020', 'HIGH':'50', 'MAX':'100' }
72 73
 
73 74
 # Repeater signaling modes
74 75
 dEncode = { 'OFF':'0', 'ENC/DEC':'1', 'TONE ENC':'2',
... ...
@@ -154,11 +155,11 @@ def getMemory(memloc):
154 155
     dMem['memloc'] = str(int(memloc))
155 156
     dMem['vfoa'] = str(float(vfoa) / 10**6)
156 157
     dMem['clarfreq'] = str(int(clarfreq))
157
-    dMem['rxclar'] = bState.keys()[bState.values().index(rxclar)]
158
-    dMem['txclar'] = bState.keys()[bState.values().index(txclar)]
159
-    dMem['mode'] = dMode.keys()[dMode.values().index(mode)]
160
-    dMem['encode'] = dEncode.keys()[dEncode.values().index(encode)]
161
-    dMem['rpoffset'] = dShift.keys()[dShift.values().index(rpoffset)]
158
+    dMem['rxclar'] = list(bState.keys())[list(bState.values()).index(rxclar)]
159
+    dMem['txclar'] = list(bState.keys())[list(bState.values()).index(txclar)]
160
+    dMem['mode'] = list(dMode.keys())[list(dMode.values()).index(mode)]
161
+    dMem['encode'] = list(dEncode.keys())[list(dEncode.values()).index(encode)]
162
+    dMem['rpoffset'] = list(dShift.keys())[list(dShift.values()).index(rpoffset)]
162 163
     dMem['tag'] = tag.strip()
163 164
 
164 165
     return dMem
... ...
@@ -173,7 +174,7 @@ def getCTCSS():
173 174
     # Get result CTCSS tone
174 175
     sResult = sendCommand('CN00;')
175 176
     tone = sResult[4:7]
176
-    return dTones.keys()[dTones.values().index(tone)]
177
+    return list(dTones.keys())[list(dTones.values()).index(tone)]
177 178
 ## end def
178 179
 
179 180
 def getDCS():
... ...
@@ -185,7 +186,7 @@ def getDCS():
185 186
     # Get result of CN01 command
186 187
     sResult = sendCommand('CN01;')
187 188
     dcs = sResult[4:7]
188
-    return dDcs.keys()[dDcs.values().index(dcs)]
189
+    return list(dDcs.keys())[list(dDcs.values()).index(dcs)]
189 190
 ## end def
190 191
 
191 192
 def getRxClarifier():
... ...
@@ -198,7 +199,7 @@ def getRxClarifier():
198 199
     # supplied - most likely a "key not found" error.
199 200
     sResult = sendCommand('RT;')
200 201
     state = sResult[2]
201
-    return bState.keys()[bState.values().index(state)]
202
+    return list(bState.keys())[list(bState.values()).index(state)]
202 203
 ## end def
203 204
 
204 205
 def getTxClarifier():
... ...
@@ -211,7 +212,7 @@ def getTxClarifier():
211 212
     # supplied - most likely a "key not found" error.
212 213
     sResult = sendCommand('XT;')
213 214
     state = sResult[2]
214
-    return bState.keys()[bState.values().index(state)]
215
+    return list(bState.keys())[list(bState.values()).index(state)]
215 216
 ## end def
216 217
 
217 218
 def getPower():
... ...
@@ -233,7 +234,7 @@ def getPreamp():
233 234
     # Get result of PA0 command
234 235
     sResult = sendCommand('PA0;')
235 236
     ipo = sResult[3:4]
236
-    return dPreamp.keys()[dPreamp.values().index(ipo)]
237
+    return list(dPreamp.keys())[list(dPreamp.values()).index(ipo)]
237 238
 ## end def
238 239
 
239 240
 def getRfAttn():
... ...
@@ -246,7 +247,7 @@ def getRfAttn():
246 247
     if sResult == '?;':
247 248
         return 'NA'
248 249
     attn = sResult[3:4]
249
-    return bState.keys()[bState.values().index(attn)]
250
+    return list(bState.keys())[list(bState.values()).index(attn)]
250 251
 ## end def
251 252
 
252 253
 def getNoiseBlanker():
... ...
@@ -257,7 +258,7 @@ def getNoiseBlanker():
257 258
     """
258 259
     sResult = sendCommand('NB0;')
259 260
     nb = sResult[3:4]
260
-    return bState.keys()[bState.values().index(nb)]
261
+    return list(bState.keys())[list(bState.values()).index(nb)]
261 262
 ## end def
262 263
 
263 264
 def getIFshift():
... ...
@@ -324,7 +325,7 @@ def getDNRstate():
324 325
     if sResult == '?;':
325 326
         return 'NA'
326 327
     state = sResult[3:4]
327
-    return bState.keys()[bState.values().index(state)]
328
+    return list(bState.keys())[list(bState.values()).index(state)]
328 329
 ## end def
329 330
 
330 331
 def getDNRalgorithm():
... ...
@@ -348,7 +349,7 @@ def getDNFstate():
348 349
     if sResult == '?;':
349 350
         return 'NA'
350 351
     state = sResult[3:4]
351
-    return bState.keys()[bState.values().index(state)]
352
+    return list(bState.keys())[list(bState.values()).index(state)]
352 353
 ## end def
353 354
 
354 355
 def getNARstate():
... ...
@@ -361,7 +362,7 @@ def getNARstate():
361 362
     if sResult == '?;':
362 363
         return 'NA'
363 364
     state = sResult[3:4]
364
-    return dNAR.keys()[dNAR.values().index(state)]
365
+    return list(dNAR.keys())[list(dNAR.values()).index(state)]
365 366
 ## end def
366 367
 
367 368
 def getNotchState():
... ...
@@ -376,7 +377,7 @@ def getNotchState():
376 377
     if sResult == '?;':
377 378
         return ('NA', 'NA')
378 379
     state = sResult[6:7]
379
-    state = bState.keys()[bState.values().index(state)]
380
+    state = list(bState.keys())[list(bState.values()).index(state)]
380 381
     sResult = sendCommand('BP01;')
381 382
     freq = int(sResult[4:7])
382 383
     return (state, freq)
... ...
@@ -792,7 +793,7 @@ def sendCommand(sCmd):
792 793
     # correct formatting of commands before they are actually sent
793 794
     # to the FT991.
794 795
     if verbose:
795
-        print sCmd,
796
+        print(sCmd, end='')
796 797
     # In debug mode do not actually send commands to the FT991.
797 798
     if debug:
798 799
         return ''
... ...
@@ -804,7 +805,7 @@ def sendCommand(sCmd):
804 805
     sendSerial(sCmd)
805 806
     sResult  = receiveSerial();
806 807
     if verbose:
807
-        print sResult
808
+        print(sResult)
808 809
     return sResult
809 810
 ## end def
810 811
 
... ...
@@ -812,7 +813,7 @@ def sendCommand(sCmd):
812 813
 # Low level serial communications functions.                                #
813 814
 #############################################################################
814 815
 
815
-def begin(baud=9600):
816
+def begin(comPort, baud=9600):
816 817
     """
817 818
     Description: Initiates a serial connection the the FT991. Should
818 819
                  always be called before sending commands to or
... ...
@@ -823,28 +824,21 @@ def begin(baud=9600):
823 824
     """
824 825
     global ptrDevice
825 826
 
826
-    # Determine OS type and set device port accordingly.
827
-    OS_type = sys.platform
828
-    if 'WIN' in OS_type.upper():
829
-        port = 'COM5'
830
-    else:
831
-        port = '/dev/ttyUSB0'
832
-
833 827
     # In debug mode do not actually send commands to the FT991.
834 828
     if debug:
835 829
         return
836 830
 
837 831
     # Create a FT991 object for serial communication
838 832
     try:
839
-        ptrDevice = serial.Serial(port, baud,      
833
+        ptrDevice = serial.Serial(comPort, baud,      
840 834
                                   timeout=_INTERFACE_TIMEOUT)
841
-    except Exception, error:
835
+    except Exception as error:
842 836
         if str(error).find('could not open port') > -1:
843
-            print 'Please be sure the usb cable is properly connected to\n' \
837
+            print('Please be sure the usb cable is properly connected to\n' \
844 838
                   'your FT991 and to your computer, and that the FT991 is\n' \
845
-                  'turned ON.  Then restart this program.'
839
+                  'turned ON.  Then restart this program.')
846 840
         else:
847
-            print 'Serial port error: %s\n' % error
841
+            print('Serial port error: %s\n' % error)
848 842
         exit(1)         
849 843
     time.sleep(.1) # give the connection a moment to settle
850 844
     return ptrDevice
... ...
@@ -874,9 +868,14 @@ def receiveSerial(termchar=';'):
874 868
             if time.time() - startTime > _SERIAL_READ_TIMEOUT:
875 869
                 break # Character waiting timer has timed out.
876 870
         # Return empty string if a character has not become available.
877
-        if c == '':
871
+        if c == '' or c == b'\xfe':
878 872
             break;
879
-        answer += c # Form a string from the received characters.
873
+        try:
874
+            # Form a string from the received characters.
875
+            answer += c.decode('utf_8')
876
+        except Exception as e:
877
+            print('serial rx error: %s' % e)
878
+        #answer += str(c) # Form a string from the received characters.
880 879
         charCount += 1 # Increment character count.
881 880
         # If a semicolon has arrived then the FT991 has completed
882 881
         # sending output to the serial port so stop reading characters.
... ...
@@ -898,7 +897,7 @@ def sendSerial(command):
898 897
     # In debug we only want to see the output of the command formatter,
899 898
     # not actually send commands to the FT991.  Debug mode should be
900 899
     # used in conjunction with verbose mode.
901
-    ptrDevice.write(command) # Send command string to FT991
900
+    ptrDevice.write(command.encode('utf_8')) # Send command string to FT991
902 901
     ptrDevice.flushOutput() # Flush serial buffer to prevent overflows
903 902
 ## end def
904 903
 
... ...
@@ -918,8 +917,16 @@ def main():
918 917
     verbose = True
919 918
     debug = False
920 919
 
920
+    # Determine OS type and set device port accordingly.
921
+    OS_type = sys.platform
922
+    if 'WIN' in OS_type.upper():
923
+        port = 'COM5'
924
+    else:
925
+        port = '/dev/ttyUSB0'
926
+
921 927
     # Instantiate serial connection to FT991
922
-    begin()
928
+    begin(port, 9600)
929
+
923 930
     # Set and receive a memory channel
924 931
     dMem = {'memloc': '98', 'vfoa': '146.52', 'shift': 'OFF', \
925 932
             'mode': 'FM', 'encode': 'TONE ENC', 'tag': 'KA7JLO', \
926 933
deleted file mode 100644
927 934
Binary files a/ft991/ft991utility/ft991_memory_settings.ots and /dev/null differ
... ...
@@ -1,4 +1,4 @@
1
-#!/usr/bin/python -u
1
+#!/usr/bin/python3 -u
2 2
 # The -u option turns off block buffering of python output. This assures
3 3
 # that output streams to stdout when output happens.
4 4
 #
... ...
@@ -25,14 +25,21 @@
25 25
 #    along with this program.  If not, see http://www.gnu.org/license.
26 26
 #
27 27
 # Revision History
28
-#   * v10 23 Nov 2019 by J L Owrey; first release
28
+#   * v10 24 Nov 2019 by J L Owrey; first release
29
+#   * v11 03 Oct 2020 by J L owrey; upgraded to Python 3
29 30
 #
30 31
 # This script has been tested with the following
31 32
 #
32
-#     Python 2.7.15rc1 (default, Nov 12 2018, 14:31:15) 
33
-#     [GCC 7.3.0] on linux2
33
+#     Python 3.8.10 (default, Mar 15 2022, 12:22:08) 
34
+#     [GCC 9.4.0] on linux
34 35
 #2345678901234567890123456789012345678901234567890123456789012345678901234567890
35 36
 
37
+# Environment Setup
38
+
39
+_WINDOWS_COM_PORT = 'COM5'
40
+_LINUX_COM_PORT = '/dev/ttyUSB0'
41
+_FT991_BAUD_RATE = 9600
42
+
36 43
 import os, sys, serial, time
37 44
 import ft991 # module should be in same directory as this utility
38 45
 
... ...
@@ -67,7 +74,7 @@ def doUserCommand():
67 74
     # When command line arguments have not been provided,
68 75
     # use interactive mode and give the user a prompt.
69 76
     if commandLineOption == '':
70
-        cmd = raw_input('>').strip()
77
+        cmd = input('>').strip()
71 78
     # If command line arguments have been provided, then
72 79
     # execute the command non-interactively.
73 80
     else:
... ...
@@ -93,7 +100,7 @@ def doUserCommand():
93 100
     elif cmd == 'x':
94 101
         exit(0)
95 102
     else:
96
-        print "invalid command"
103
+        print("invalid command")
97 104
 ## end def
98 105
 
99 106
 def backupMemorySettings():
... ...
@@ -108,11 +115,11 @@ def backupMemorySettings():
108 115
     # backed up memory settings.
109 116
     fileName = getFileName(memoryBackupFile)
110 117
     # Read the memory settings from the FT991...
111
-    print 'Backing up memory settings...'
118
+    print('Backing up memory settings...')
112 119
     settings = readMemorySettings()
113 120
     # and write them to the file.
114 121
     writeToFile(settings, fileName)
115
-    print 'Memory settings backed up to \'%s\'' % fileName
122
+    print('Memory settings backed up to \'%s\'' % fileName)
116 123
 ## end def
117 124
 
118 125
 def restoreMemorySettings():
... ...
@@ -127,16 +134,16 @@ def restoreMemorySettings():
127 134
     # memory settings.  Also make sure the file exists.
128 135
     fileName = getFileName(memoryBackupFile)
129 136
     if not os.path.isfile(fileName):
130
-        print 'File not found.\n' \
137
+        print('File not found.\n' \
131 138
               'Please enter a valid file name.  Be sure to correctly ' \
132
-              'enter\nthe full path name or relative path name of the file.'
139
+              'enter\nthe full path name or relative path name of the file.')
133 140
         return
134 141
     # Read the memory settings from the file...
135
-    print 'Restoring memory settings...'
142
+    print('Restoring memory settings...')
136 143
     settings = readFromFile(fileName)
137 144
     # and write them to the FT991.
138 145
     writeMemorySettings(settings)
139
-    print 'Memory settings restored from \'%s\'' % fileName
146
+    print('Memory settings restored from \'%s\'' % fileName)
140 147
 ## end def
141 148
 
142 149
 def backupMenuSettings():
... ...
@@ -151,11 +158,11 @@ def backupMenuSettings():
151 158
     # backed up menu settings.
152 159
     fileName = getFileName(menuBackupFile)
153 160
     # Read the menu settings from the FT991...
154
-    print 'Backing up menu settings...'
161
+    print('Backing up menu settings...')
155 162
     settings = readMenuSettings()
156 163
     # and write them to the file.
157 164
     writeToFile(settings, fileName)
158
-    print 'Menu settings backed up to \'%s\'' % fileName
165
+    print('Menu settings backed up to \'%s\'' % fileName)
159 166
 ## end def
160 167
 
161 168
 def restoreMenuSettings():
... ...
@@ -170,16 +177,16 @@ def restoreMenuSettings():
170 177
     # menu settings.  Also make sure the file exists.
171 178
     fileName = getFileName(menuBackupFile)
172 179
     if not os.path.isfile(fileName):
173
-        print 'File not found.\n' \
180
+        print('File not found.\n' \
174 181
               'Please enter a valid file name.  Be sure to correctly ' \
175
-              'enter\nthe full path name or relative path name of the file.'
182
+              'enter\nthe full path name or relative path name of the file.')
176 183
         return
177 184
     # Read the menu settings from the file...
178
-    print 'Restoring menu settings...'
185
+    print('Restoring menu settings...')
179 186
     settings = readFromFile(fileName)
180 187
     # and write them to the FT991.
181 188
     writeMenuSettings(settings)
182
-    print 'Menu settings restored from \'%s\'' % fileName
189
+    print('Menu settings restored from \'%s\'' % fileName)
183 190
 ## end def
184 191
 
185 192
 def passThroughMode():
... ...
@@ -190,11 +197,11 @@ def passThroughMode():
190 197
     Parameters: none
191 198
     Returns: nothing
192 199
     """
193
-    print 'Entering passthrough mode. Type \'exit\' to exit mode.'
200
+    print('Entering passthrough mode. Type \'exit\' to exit mode.')
194 201
     while(True):
195 202
         # Prompt the user to enter an FT991 CAT command, and
196 203
         # process the  command string.
197
-        sCommand = raw_input('CAT# ').upper()
204
+        sCommand = input('CAT# ').upper()
198 205
         if sCommand == 'EXIT': # exit this utility
199 206
             break
200 207
         # If the user fails to end a CAT command with a semi-colon,
... ...
@@ -208,7 +215,7 @@ def passThroughMode():
208 215
             ft991.sendSerial(sCommand)
209 216
             sResult = ft991.receiveSerial();
210 217
             if sResult != '':
211
-                print sResult
218
+                print(sResult)
212 219
 ## end def
213 220
 
214 221
 def toggleVerboseMode():
... ...
@@ -222,10 +229,10 @@ def toggleVerboseMode():
222 229
     """
223 230
     if ft991.verbose:
224 231
         ft991.verbose = False
225
-        print 'Verbose is OFF'
232
+        print('Verbose is OFF')
226 233
     else:
227 234
         ft991.verbose = True
228
-        print 'Verbose is ON'  
235
+        print('Verbose is ON')  
229 236
 ## end def
230 237
 
231 238
 def getFileName(defaultFile):
... ...
@@ -242,7 +249,7 @@ def getFileName(defaultFile):
242 249
     if commandLineOption != '':
243 250
         return defaultFile
244 251
     # Otherwise query the user for a file name
245
-    fileName = raw_input('Enter file name or <CR> for default: ')
252
+    fileName = input('Enter file name or <CR> for default: ')
246 253
     if fileName == '':
247 254
         return defaultFile
248 255
     else:
... ...
@@ -366,11 +373,11 @@ def writeMemorySettings(lSettings):
366 373
             ft991.setNARstate(dItem['narstate'])
367 374
             # Set Notch state
368 375
             ft991.setNotchState((dItem['notchstate'], dItem['notchfreq']))
369
-        except Exception, e:
370
-            print 'Memory settings restore operation failed. Most likely\n' \
376
+        except Exception as e:
377
+            print('Memory settings restore operation failed. Most likely\n' \
371 378
                   'this is due to the backup settings file corrupted or\n' \
372
-                  'incorrectly formatted. Look for the following error: \n'
373
-            print e
379
+                  'incorrectly formatted. Look for the following error: \n')
380
+            print(e)
374 381
             raise
375 382
             #exit(1)
376 383
     # end for
... ...
@@ -411,7 +418,7 @@ def writeMenuSettings(lSettings):
411 418
         # Send the pre-formatted menu setting to the FT991.
412 419
         sResult = ft991.sendCommand(item)
413 420
         if sResult.find('?;') > -1:
414
-            print 'error restoring menu setting: %s' % item
421
+            print('error restoring menu setting: %s') % item
415 422
             exit(1)
416 423
 ## end def
417 424
 
... ...
@@ -486,7 +493,7 @@ p - enter pass through mode
486 493
 v - toggle verbose mode
487 494
 x - exit this program
488 495
 """
489
-    print splash
496
+    print(splash)
490 497
 ## end def
491 498
 
492 499
 def getCLarguments():
... ...
@@ -518,7 +525,7 @@ def getCLarguments():
518 525
         if sys.argv[index] == '-f': # Backup file provided.
519 526
             # Get the backup file name.
520 527
             if len(sys.argv) < index + 2:
521
-                print "-f option requires file name"
528
+                print("-f option requires file name")
522 529
                 exit(1);
523 530
             fileName = sys.argv[index + 1]
524 531
             index += 1
... ...
@@ -535,7 +542,7 @@ def getCLarguments():
535 542
         elif sys.argv[index] == '-d': # set debug mode 'ON'
536 543
             ft991.debug = True
537 544
         else:
538
-            print usage
545
+            print(usage)
539 546
             exit(-1)
540 547
         index += 1
541 548
     ## end while
... ...
@@ -553,8 +560,16 @@ def main():
553 560
     Returns: nothing
554 561
     """
555 562
     getCLarguments() # get command line options
556
-    
557
-    ft991.begin() # open com port session to FT991
563
+
564
+    # Determine OS type and set device port accordingly.
565
+    #OS_type = sys.platform
566
+    #if 'WIN' in OS_type.upper():
567
+    if 'WIN' in sys.platform.upper():
568
+        port = _WINDOWS_COM_PORT
569
+    else:
570
+        port = _LINUX_COM_PORT
571
+
572
+    ft991.begin(port, _FT991_BAUD_RATE) # open com port session to FT991
558 573
 
559 574
     # Process command line options (if any).
560 575
     if commandLineOption != '':