diff --git a/read_arduino.py b/read_arduino.py index 919fe9b..3323a70 100644 --- a/read_arduino.py +++ b/read_arduino.py @@ -2,7 +2,7 @@ Read raw data from Arduino and then converted into actual resistance using parameters provided from top level """ from datetime import datetime -import serial, os, json +import serial, time, json import serial.tools.list_ports import numpy as np @@ -18,15 +18,26 @@ def read(): sensor_ports = np.array(settings["sensor_ports"]) # ports that sensor(s) are connected to file_name = settings["file_name"] port = settings["port"] - if "- No Device -" in port: - # TODO: set to writerandomvalues.py thing instead raise error - print("this should generate random values base on # sensors given") - exit(0) - else: - controller = serial.Serial(port, baudrate=baud) + delay = settings["delay"] if np.any(sensor_ports >= SENSORS_MAX): raise ValueError("Port range is 0-3!") + if "- No Device -" in port: + while True: + dat_list = np.random.randint(0, 3300, len(sensor_ports)) # create a randomized voltage data + # take only the nonzero indices, and truncated to two decimal places to "filter" out some hardware errors + dat_sel = np.trunc((np.take(dat_list, sensor_ports) / 1000) * 10**2) / 10**2 + r_arr = np.take(refRes, sensor_ports) * (v_in / dat_sel - 1) + # write + export values as .csv format + dat = f", ".join(np.insert(r_arr.astype(str), 0, datetime.now().strftime('%H:%M:%S'))) + print(dat) + f = open(file_name, "a", newline="", encoding="utf-8") + f.write(dat + '\n') + f.close() + time.sleep(delay / 1000) + exit(0) + else: + controller = serial.Serial(port, baudrate=baud) # TODO: separate data in each run but still keep them in one csv file while controller.isOpen(): diff --git a/test.py b/test.py index 92e1d3c..00e7c63 100644 --- a/test.py +++ b/test.py @@ -2,12 +2,18 @@ from ui import Frame from multiprocessing import * from read_arduino import * from serial_plotter import * -import os, json, wx, warnings +import os, sys, json, wx,importlib, warnings import serial.tools.list_ports import numpy as np warnings.filterwarnings("ignore", category=DeprecationWarning) +# acknowledgement: https://stackoverflow.com/a/68666505. handles splash screens +if '_PYIBoot_SPLASH' in os.environ and importlib.util.find_spec("pyi_splash"): + import pyi_splash + pyi_splash.update_text('UI Loaded ...') + pyi_splash.close() + HEIGHT = 800 WIDTH = 800 @@ -16,8 +22,6 @@ global ani, t1 def main(): #################### USER INPUTS ########################### - # TODO: if there is already a setting.json exist, loads all inputs from there as 'default' - resistors = [float(frame.r_ref_1.GetValue()), float(frame.r_ref_2.GetValue()), float(frame.r_ref_3.GetValue()), float(frame.r_ref_4.GetValue()), 0] # resisters for each An port, where n is an integer from 0-3. Use 0 if none. in Ohms @@ -59,14 +63,6 @@ def gen_settings(resistors, input_voltage, bits, port, filename, window_size, de open(filename, "a", newline="", encoding="utf-8") -def get_devices(): - """ - get all available devices connected, put them in the UI's dropdown menu - """ - ports = [comport.device for comport in serial.tools.list_ports.comports()] # get all available ports - frame.dev_list.AppendItems(ports) - - def run(e): """ run the read_arduino.py and Serial Plotter in parallel @@ -79,8 +75,7 @@ def run(e): # place the read() function from read_arduino into another process to run it in background t1 = Process(target=read, args=()) t1.start() - - # run the plotter. Note that we should not put the plotter class, or function, in another process since + # run the plotter. Note that we should not put the plotter class, or function, in another process since # matplot's FuncAnimation doesn't like that plotter = SerialPlotter() ani = plotter.plotting() @@ -92,14 +87,20 @@ def run(e): if __name__ == '__main__': + sys.stdout.write("this is an alpha version of the design. This debug terminal will be gone on official release\n") + # Acknowledgement: https://stackoverflow.com/a/27694505 + if sys.platform.startswith('win'): + # On Windows calling this function is necessary. + freeze_support() global t1 app = wx.App() frame = Frame(None) - get_devices() - frame.SetTitle("Cease your resistance! - alpha 0.1.1") + ports = [comport.device for comport in serial.tools.list_ports.comports()] # get all available ports + frame.dev_list.AppendItems(ports) + frame.SetTitle("Cease your resistance! - alpha 0.2.0") frame.btLaunch.Bind(wx.EVT_BUTTON, run) if os.path.isfile("settings.json"): - print("Found existing settings.json, auto-fill previous inputs!") + sys.stdout.write("Found existing settings.json, auto-fill previous inputs!\n") settings = json.load(open('settings.json', 'r')) frame.r_ref_1.SetValue(str(settings["refRes"][0])) frame.r_ref_2.SetValue(str(settings["refRes"][1])) @@ -108,8 +109,10 @@ if __name__ == '__main__': frame.input_voltage.SetValue(str(settings["v_in"])) frame.adjusted_volt.SetValue(str(settings["resolution"])) frame.m_textCtrl26.SetValue(str(settings["winSize"])) + if settings["port"] in ports: # auto-select device port if exist + frame.dev_list.SetValue(settings["port"]) frame.Show() app.MainLoop() if 't1' in globals(): - t1.terminate() # end the process if it has been started \ No newline at end of file + t1.terminate() # gracefully end the read_arduino process if it has been started diff --git a/ui.py b/ui.py index 89fef7e..2dd0dba 100644 --- a/ui.py +++ b/ui.py @@ -91,7 +91,7 @@ class Frame ( wx.Frame ): self.sizer_prompt.Wrap( -1 ) gbSizer8.Add( self.sizer_prompt, wx.GBPosition( 2, 0 ), wx.GBSpan( 1, 1 ), wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, 5 ) - self.m_textCtrl26 = wx.TextCtrl( v_entre.GetStaticBox(), wx.ID_ANY, u"480", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_textCtrl26 = wx.TextCtrl( v_entre.GetStaticBox(), wx.ID_ANY, u"50", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_textCtrl26.SetToolTipString( u"Window size for the plot window. If want infinite/maximum size, type 0" ) gbSizer8.Add( self.m_textCtrl26, wx.GBPosition( 2, 1 ), wx.GBSpan( 1, 1 ), wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER_HORIZONTAL|wx.TOP|wx.RIGHT|wx.LEFT, 5 )