for some reason, when I try to call the python script alone it does not
open. I have to be in Pycharm in order to open.
Also, I was able to turn another python script into exe but I gave it to
somebody else to run who was working another windows version, it could open
but did not do anything

Le lun. 9 nov. 2020 à 15:16, Nurul Carvalho <[email protected]> a
écrit :

> haham i'm seeing.. i thought this guide could help u...
> but i want too..
> please send screenshot of ur code..
> i'm working with linux and my compile process is lil bit different
> but anyway u just need to check if ur script (source code) is running like
> ur compiled program..
> (in the same folder with the same file locations)
>
> don't worry i'm here to help  with anything that i can...
>
>
> melissa makonga <[email protected]> escreveu no dia segunda,
> 9/11/2020 à(s) 20:58:
>
>> I am still getting the same output. Maybe it is because the file that I
>> am working are on an external hard drive. Do you think that would cause an
>> issue because I also tried to run it on powershell but got the same output
>>
>> On Mon, Nov 9, 2020, 1:05 PM Nurul Carvalho <[email protected]>
>> wrote:
>>
>>> definitely, it's very strange...
>>> but are u sure that u didn't use any extra file in ur script?
>>> anyway, u can put the PressureGauge.exe file in the same folder as ur
>>> PressureGauge.py script and rerun it to see what's going next...
>>>
>>> melissa makonga <[email protected]> escreveu no dia segunda,
>>> 9/11/2020 à(s) 19:22:
>>>
>>>> No, I am only using --onefile but to package the exe I am using Pycharm.
>>>> This is what happen when I try to run it using command line
>>>>
>>>> On Mon, Nov 9, 2020, 11:42 AM Brenainn Woodsend <[email protected]>
>>>> wrote:
>>>>
>>>>> It sounds like you are using the `--windowed` option? If you are then
>>>>> don't. It means no output meaning you can never see any errors. Or 
>>>>> possibly
>>>>> you are using Conda?
>>>>>
>>>>> --
>>>>> You received this message because you are subscribed to a topic in the
>>>>> Google Groups "PyInstaller" group.
>>>>> To unsubscribe from this topic, visit
>>>>> https://groups.google.com/d/topic/pyinstaller/HYmG_zasD6o/unsubscribe.
>>>>> To unsubscribe from this group and all its topics, send an email to
>>>>> [email protected].
>>>>> To view this discussion on the web visit
>>>>> https://groups.google.com/d/msgid/pyinstaller/CAFLMo5_Yei_wTihS_YKdENLWnQFftPObAzVO5MKrrOd%3DBpjtLw%40mail.gmail.com
>>>>> <https://groups.google.com/d/msgid/pyinstaller/CAFLMo5_Yei_wTihS_YKdENLWnQFftPObAzVO5MKrrOd%3DBpjtLw%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>>> .
>>>>>
>>>> --
>>>> You received this message because you are subscribed to the Google
>>>> Groups "PyInstaller" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>> an email to [email protected].
>>>> To view this discussion on the web visit
>>>> https://groups.google.com/d/msgid/pyinstaller/CAF13mUwgv7utAytG3W_z1qfeU%3DvWd5c9cuw%2BSm-JPX6KN7ObuQ%40mail.gmail.com
>>>> <https://groups.google.com/d/msgid/pyinstaller/CAF13mUwgv7utAytG3W_z1qfeU%3DvWd5c9cuw%2BSm-JPX6KN7ObuQ%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>> .
>>>>
>>> --
>>> You received this message because you are subscribed to a topic in the
>>> Google Groups "PyInstaller" group.
>>> To unsubscribe from this topic, visit
>>> https://groups.google.com/d/topic/pyinstaller/HYmG_zasD6o/unsubscribe.
>>> To unsubscribe from this group and all its topics, send an email to
>>> [email protected].
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/pyinstaller/CADcH5neOJ8y7_7OohfdS6B_Wn0CPsYj1vZfaDhCUo_z9zYab_Q%40mail.gmail.com
>>> <https://groups.google.com/d/msgid/pyinstaller/CADcH5neOJ8y7_7OohfdS6B_Wn0CPsYj1vZfaDhCUo_z9zYab_Q%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "PyInstaller" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected].
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/pyinstaller/CAF13mUwFPYguc%3DR1NNDB2sQWm%3DdpX%3Dbwiv__V10uffY7R%3DZTvA%40mail.gmail.com
>> <https://groups.google.com/d/msgid/pyinstaller/CAF13mUwFPYguc%3DR1NNDB2sQWm%3DdpX%3Dbwiv__V10uffY7R%3DZTvA%40mail.gmail.com?utm_medium=email&utm_source=footer>
>> .
>>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "PyInstaller" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/pyinstaller/HYmG_zasD6o/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/pyinstaller/CADcH5neMLmynQ9n7P%2B%2BKJR%2BoYQvXXMtNqHOn8mp3nJnbeFS44Q%40mail.gmail.com
> <https://groups.google.com/d/msgid/pyinstaller/CADcH5neMLmynQ9n7P%2B%2BKJR%2BoYQvXXMtNqHOn8mp3nJnbeFS44Q%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"PyInstaller" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/pyinstaller/CAF13mUyVa4%3D9m4Nj-yEcgrTJVvznQX426Qq_Vm%2BMbJyR8HoM-A%40mail.gmail.com.
"""
Michael Fusco - 12/14/2018
This script is intended to read data from certain pressure gauges and 
continuously plot pressure data.
This script also generates a GUI with several buttons for starting and stopping 
data aquisition/plotting
and also for recording pressure data to a text file. Currently supported 
pressure gauge controllers include:
-Granville-Phillips 275 Mini-Convectron Module (RS485)
-MKS 650 series Baratron controller (RS232)
-MKS PDR2500 Baratron controller (RS232)

More pressure gauge options may be added at a later date

The type of controller should be specified in the Pgauge_info.txt file within 
the Configuration Files folder.
Accepted designations are: '275c' for 275 Mini-Convectron, '650b' for 650 
series Baratron, and 
'2500b' for pdr2500 series Baratron controller. 
*Note: the 275 convectron module uses RS485 communication. The COM port must be 
set to a baud rate of 19200 and
2-Wire Auto setting. Otherwise, communication with the unit will fail.

The data recording module is connected to the valve control GUI using the 
python socketserver module.
When a recipe is started in the valve control program, pressure data recording 
will begin, provided the PressureGauge.py
script is running. This data will be written to a file located in the Pressure 
Data folder within the Pressure_Gauge
 folder.
"""
# ------------Imports ------------------------------------------
from Pressure_Gauge.Config import get_inst, get_press_dir, get_press_lim

import visa
import os
import tornado
import datetime
import threading
import collections
import matplotlib
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import tkinter.messagebox
import tkinter as tk
from tkinter import ttk
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import socketserver
import socket
# -------------- End of Imports --------------------------------------

# ---------------- Functions ----------------------------------------


def exit_handler():
    """
    Function to handle times when python exits. Shuts down the communication 
server and closes and saves the data file
    (if open). This function is only called if python exits normally. It does 
not handle program crashes
    """
    global stop, data_file, record, server
    stop = True
    server.shutdown()
    if record:
        data_file.close()
    root.destroy()


def read_data(j):
    """
    Function to communicate with several types of pressure gauge controllers. 
The instrument is queried each time this
    function is called, returning the time elapsed since data recording began 
and the current measured pressure.
    """
    global t_init
    try:
        if gauge_type[j].lower() == '275c':
            try:
                p_str = p_inst[j].query('#01RD')
                p_vals = p_str.split(" ")
                pressure = float(p_vals[1])
            except visa.VisaIOError:
                pressure = None
                print('IO Error')
        elif gauge_type[j].lower() == '650b':
            try:
                p_str = p_inst[j].query('R5')
                p_val = p_str.split('+')
                pressure = p_max[j] * float(p_val[1]) / 100
            except visa.VisaIOError:
                pressure = None
                print('IO Error')
        elif gauge_type[j].lower() == '146': #TODO - make this work
            """RS-232 communication is found on page 255 of manual 
            Commands are on 259 (!Commands)
            Error coes are on 287 (!Error messages)
            checksum note on 280 (annotated with !Checksum)"""
            try:
                p_str = p_inst[j].query('@6021?\r') #Which channel? (1,2,3,4 - 
5 (Dual 1), 6 (dual 2))
                #Original: p_str = p_inst[j].query('@602<para>?')
                #is carriage retun in ascii he same as \r?
                p_val = p_str.split('\r')
                pressure = p_max[j] * float(p_val[1]) / 100
            except visa.VisaIOError:
                pressure = None
                print('IO Error')
        elif gauge_type[j].lower() == '2500b':
            try:
                p_str = p_inst[j].query('p')
                p_vals = p_str.split(' ')
                pressure = float(p_vals[1])
            except visa.VisaIOError:
                pressure = None
                print('IO Error')
        t_elapsed = datetime.datetime.now() - t_init
        mins, sec = divmod(t_elapsed.days * 86400 + t_elapsed.seconds, 60)
        microsec = t_elapsed.microseconds / 1000
        t = mins * 60 + sec + round(microsec / 1000, 2)

    except TypeError:
        t = None
        pressure = None
    return t, pressure


def queue_data():
    """
    Function to get data from the controller and place it in a queue to be 
accessed by the update_graph function.
    This function runs continuously while the play button is active. The 
read_data function is called to get data from
    the controller.
    """
    def update_queue():
        """
        This function continuously updates the data queue and writes that data 
to a file if recording is active.
        Recording only takes place every 5th? data point to prevent files from 
becoming too large.
        """
        global t_rec_int, t_rec_start, press_file_path
        pressure = []
        for j in range(len(p_inst)):
            t, press = read_data(j)
            pressure.append(press)

        if pressure is None:
            pass
        else:
            data_queue.append((t, pressure))
            if record:
                if (t - t_rec_start) >= t_rec_int-.003: #Data collection loop, 
with lag factor
                    data_file.write(str(round(t, 2)))
                    for j in range(len(p_inst)):
                        data_file.write("\t" + str(round(pressure[j], 3)))
                    data_file.write("\n")
                    t_rec_start += t_rec_int
                if os.path.getsize(press_file_path) >= 1e7:
                    data_file.close()
                    open_p_file()

    global stop, record, data_file
    while not stop:
        update_queue()
    

def gen():
    """
    Generator function to generate frame numbers for the plot animation. When 
the pause button is pressed, the
    generator continues yielding the same number over and over, effectively 
pausing the plot animation. When play is
    resumed, the generator continues incrementing n
    """
    global stop
    n = 0
    while True:
        if not stop:
            n += 1
        yield n


def update_graph(n):
    """
    Function to update the graph with newly-collected data every 100 ms. Only 
120 seconds worth of data is kept at
    a time. Beyond that, earlier data is replaced with the most recent data.
    :param n: Keeps track of the graph frames; n is passed to this function via 
a generator
    """
    global xlist, ylist_t, ylist_m, ax_scale, p_scale
    try:
        (t, pressure) = data_queue.popleft()

        for j in range(len(p_inst)):
            if pressure[j] <= 0:
                pressure[j] = 1e-6
        
        if len(xlist) > 2 and xlist[-1] - xlist[0] > 120:
            xlist.popleft()
            ylist_t.popleft()
            ylist_m.popleft()

        xlist.append(t)
        ylist_t.append([round(pressure[j], 3) for j in range(len(p_inst))])
        ylist_m.append([round(pressure[j]*1000, 1) for j in range(len(p_inst))])

    except IndexError:
        pressure = [0.0]

    if p_scale == 'Torr':
        p_val.config(text=str(round(pressure[0], 3)) + " " + p_scale)
        line.set_data(xlist, ylist_t)
    else:
        p_val.config(text=str(round(pressure[0] * 1000, 1)) + " " + p_scale)
        line.set_data(xlist, ylist_m)

    ax.set_ylabel('Pressure (' + p_scale + ')')
    ax.set_xlabel('Time (s)')
    ax.set_yscale(ax_scale)
    
    ax.relim()
    ax.autoscale_view(True, True, True)

    return line,


def record_click():
    """
    Records time and pressure data to a text file. File name is the date with a 
number appended at the end:
    i.e. 2019-01-04_1
    """
    global data_file, record, t_rec_int, t_rec_start

    if record:
        data_file.close()
        record = False
        record_button.config(bg='green', text='Record')
    else:
        try:
            t_rec_int = float(rec_int_entry.get().replace(' ', ""))
        except ValueError as ve:
            print(ve)
            t_rec_int = 0.2     # Record interval defaults to 0.2 s

        open_p_file()
        record_button.config(bg='lime green', text='Recording')
        record = True
        t_rec_start = 0.0
        clear_click()
        play_click()


def open_p_file():
    global data_file, press_file_path

    date = datetime.date.today()
    a = False
    h = 0
    while not a:
        h += 1
        press_file_name = str(date) + "_" + str(h) + ".txt"
        press_file_path = os.path.join(press_dir, press_file_name)
        if os.path.exists(press_file_path):
            pass
        else:
            a = True
    data_file = open(press_file_path, 'w')
    data_file.write(str(datetime.datetime.now()) + "\n")
    data_file.write('Time (s)' + "\t" + 'Pressure (Torr)' + "\n")


def pause_click():
    """
    Pauses data collection and plotting.
    """
    global stop
    if not stop:
        stop = True
        data_queue.clear()
        play_button.config(state='normal')
        pause_button.config(state='disabled')
    else:
        pass


def play_click():
    """
    Starts or resumes data collection and plotting. If the graph was paused, 
plotting will begin from the time at
    which it was paused plus the time elapsed during the pause.
    """
    global stop
    if stop:
        stop = False
        play_button.config(state='disabled')
        pause_button.config(state='normal')

        # Start communicating with pressure controller to collect data
        data_thread = threading.Thread(target=queue_data)
        data_thread.start()

        # Monitor pressure and compare to limit
        alarm_thread = threading.Thread(target=monitor_pressure)
        alarm_thread.start()

    else:
        pass


def clear_click():
    """
    Clears the graphs and restarts from time 0
    """
    global xlist, ylist_t, ylist_m, t_init
    data_queue.clear()
    xlist.clear()
    ylist_t.clear()
    ylist_m.clear()
    t_init = datetime.datetime.now()


def axis_select(event=None):
    """
    Function to change axis type of graph between linear and log pressure. It 
gets the ax_type from a combobox in the
    interface
    """
    global ax_scale

    ax_scale = axis_type.get()


def p_scale_select(event=None):
    """
    Function to change axis type of graph between linear and log pressure. It 
gets the ax_type from a combobox in the
    interface
    """
    global p_scale

    p_scale = p_scale_cb.get()


def monitor_server():
    """
    Function to create a local server for communication with another python 
program.
    Specifically, this function receives messages from the ALD sequencer 
(Main.py) telling this program when to
    record pressure data.
    """
    global server

    class MyHandler(socketserver.BaseRequestHandler):

        def handle(self):
            self.msg = self.request.recv(1024)
            if self.msg.decode("utf-8") == 'start' or self.msg.decode("utf-8") 
== 'stop':
                record_click()

    server = socketserver.TCPServer(("localhost", 9999), MyHandler)
    server.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server.serve_forever()


def feedback_server(msg):
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(2)
        sock.connect(('localhost', 8888))
        sock.send(msg.encode('utf-8'))
        sock.close()
    except ConnectionRefusedError as e:
        print(e)


def monitor_pressure():
    global stop, alarm
    alarm_count = 0
    while not stop:
        try:
            pressure = ylist_t[-1]
        except IndexError as ie:
            print(ie)
            if pressure > press_lim:
                alarm_count += 1
                if not alarm and alarm_count >= 3:
                    msg = 'alarm'
                    feedback_server(msg)
                    alarm = True
            else:
                if alarm:
                    msg = 'normal'
                    feedback_server(msg)
                    alarm = False
                    alarm_count = 0

# ----------------------------- End of Functions 
---------------------------------------

# ----------------------------- Main program 
--------------------------------------------


if __name__ == "__main__":
    # Initialize instrument communication and directories
    p_inst, gauge_type, p_max = get_inst()
    press_dir = get_press_dir()
    press_lim = get_press_lim()

    # Initialize matplotlib properties
    matplotlib.use('TkAgg')
    matplotlib.interactive(False)

    # Initialize variables
    t_init = datetime.datetime.now()
    ax_scale = 'linear'
    p_scale = 'Torr'
    stop = True
    record = False
    
    # Create deques (double-sided queues)
    data_queue = collections.deque(maxlen=3)
    xlist = collections.deque()
    ylist_t = collections.deque()
    ylist_m = collections.deque()

    # -------------------- Create Tkinter window 
---------------------------------
    root = tk.Tk()
    root.title('Pressure Monitor')

    # --------------------- Create figure --------------------------------------
    fig = plt.Figure()
    ax = fig.add_subplot(111)
    ax.set_ylabel('Pressure (Torr)')
    ax.set_xlabel('Time (s)')
    line, = ax.plot([], [])

    # ---------------------- Create figure canvas 
---------------------------------
    canvas = FigureCanvasTkAgg(fig, master=root)
    canvas.get_tk_widget().pack(expand=True, side=tk.BOTTOM)

    # ------------------ Create the remaining Tk window features 
----------------------
    frame2 = tk.Frame(root)
    frame2.pack(expand=True, side=tk.BOTTOM)
    button_frame = tk.Frame(root)
    button_frame.pack(expand=True, side=tk.BOTTOM)

    record_button = tk.Button(button_frame, text='Record', width=10, 
bg='green', command=record_click)
    pause_button = tk.Button(button_frame, text='Pause', width=6, bg='yellow', 
state='disabled', command=pause_click)
    play_button = tk.Button(button_frame, text='Play', width=6, 
command=play_click)
    clear_button = tk.Button(button_frame, text='Clear Graph', 
command=clear_click)
    # check_button = tk.Checkbutton(button_frame)
    ax_type_label = tk.Label(button_frame, text='Axis Type: ')
    axis_type = ttk.Combobox(button_frame, values=["linear", "log"], 
state='readonly')
    axis_type.set('linear')
    axis_type.bind("<<ComboboxSelected>>", axis_select)
    p_scale_label = tk.Label(button_frame, text='Pressure Scale: ')
    p_scale_cb = ttk.Combobox(button_frame, values=["Torr", "mTorr"], 
state='readonly')
    p_scale_cb.set('Torr')
    p_scale_cb.bind("<<ComboboxSelected>>", p_scale_select)
    p_val = tk.Label(button_frame, bg='white', relief=tk.SUNKEN, width=13)

    rec_int_label = tk.Label(frame2, text='Record interval (s): ')
    rec_int_entry = tk.Entry(frame2, text=' ', width=7, justify='center')

    play_button.grid(row=0, column=0)
    pause_button.grid(row=0, column=1)
    record_button.grid(row=0, column=2)
    clear_button.grid(row=0, column=3)
    ax_type_label.grid(row=1, column=0, pady=5)
    axis_type.grid(row=1, column=1, columnspan=2, pady=5)
    p_val.grid(row=2, column=3, pady=5, padx=5)
    p_scale_label.grid(row=2, column=0, pady=5)
    p_scale_cb.grid(row=2, column=1, columnspan=2, pady=5)

    rec_int_label.grid(row=0, column=0, padx=5, pady=5)
    rec_int_entry.grid(row=0, column=1, padx=5, pady=5)
    
    # ----------------------- Create thread to monitor external server 
---------------------------
    server_thread = threading.Thread(target=monitor_server)
    server_thread.start()

    # --------------------- Start animating pressure vs. time plot 
-------------------------------------
    ani = animation.FuncAnimation(fig, update_graph, frames=gen, interval=100, 
blit=False, repeat=True, save_count=None)
    
    # Check if instrument was detected
    if p_inst == 0:
        tkinter.messagebox.showinfo('Warning', 'No Instrument Detected! Check 
COM port.')

        rec_int_entry.focus_force()

    # ---------------------- Call exit_handler when Tkinter window is closed 
---------------------------
    root.protocol('WM_DELETE_WINDOW', exit_handler)

    root.mainloop()

    # ------------------------------------- End of Program 
--------------------------------------

Reply via email to