diff --git a/README.md b/README.md index f5e2c87..00a7af4 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ - pyserial - wxPython - PlatformIO IDE, which could be downloaded as an extension in vs code +- ESP32 WROOM-32 Development Board ### Recommended - Code Runner (for VSCode only) - wxFormBuilder @@ -15,28 +16,32 @@ ## How to use ### Direct use - First download the `.ino` file from `ReadRaw` folder using Arduino IDE. Or if you are using Arduino Mega 2560 you can -use the code in `ReadAnalog` folder by open the folder in VSCode and run with PlatformIO, or just run `flash.py` in a terminal -Then you can just run `python toplevel.py` and start from the UI. Enter the relevant information and start collect and measuring data. + First download the `.ino` file from `espVoltmeter` folder using Arduino IDE. ~~Or if you are using Arduino Mega 2560 you can +use the code in `ReadAnalog` folder by open the folder in VSCode and run with PlatformIO, or just run `flash.py` in a terminal~~ + (Arduino Mega and Uno boards are no longer supported. Please use [this link](https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html) to + use on Arduino IDE or PlatformIO for VSCode) +Then you can just run `python test.py` and start from the UI. Enter the relevant information and start collect and measuring data. ### develop & build Beside the c-based code for the Arduino board to read raw data from the board, everything has now been done in the python -files. The main program is `toplevel.py`, which calls `UI.py` to prompt for input. It is NOT recommended modifying the `ui.py` +files. The main program is `test.py`, which calls `UI.py` to prompt for input. It is NOT recommended modifying the `ui.py` as it is generated from wxFormBuilder from `sealammonia.fbp`, which could be modified if any frontend feature need to change. the main program will generate `settings.json` which saves all required parameters needed to calculate and graph and save the sensor's values. It also creates a .csv file under `RecordedData` directory to save all recorded+calculated data. `read_arduino.pyw` read raw data from Arduino board and convert it to the correct resistance, which could be plotted out using `serial_plot.pyw`. Note that all .pyw are still Python files and should be correctly opened using any IDE/text edtiors -as .py file does, except not going to pop up a black terminal when running directly. `test.py` is the alternative version of the frontend writting using `tkinter`. +as .py file does, except not going to pop up a black terminal when running directly. `frontend.py` is the alternative version of the frontend writting using `tkinter` +and is not longer supported. ## Issues -- Currently can only use 5V as input voltage. May need to change the algorithm in `read_arduino.py`. Newer hardware will require 3.3V. +- Newer hardware will require 3.3V. ~~Currently can only use 5V as input voltage.~~ May need to change the algorithm in `read_arduino.py`. - Should call `writerandomvalues.py` to simulate Arduino data when nothing is connected but user still want to run. Currently just pop up error(fixed) - "plot" button is completely disabled, should be enabled whenever is not plotting but is reading data - Matplotlib cannot really run in multithread, this might going to be an issue for packing the program into an executable - Csv file is only created after you close the UI -## Todos & [Specs](https://docs.google.com/document/d/1Km2HZel7rILOvgHG5iXlUcXFx4Of1ot2I7Dbnq8aTwY/edit?usp=sharing): +## Todos & [Old Specs](https://docs.google.com/document/d/1Km2HZel7rILOvgHG5iXlUcXFx4Of1ot2I7Dbnq8aTwY/edit?usp=sharing): - [ ] Fix Issues +- [ ] Automatically setup the driver for ESP32 - [ ] display sensor value in either the UI or on the plot - [ ] Reopen plot window from the UI when closed - [x] Need to continue writing to file when graphing window is closed @@ -48,6 +53,7 @@ as .py file does, except not going to pop up a black terminal when running direc - [x] Write random values to simulate a sensor if no sensor available (this feature might be removed in the future) - [ ] Advanced option menu in the UI to allow user to make more adjustments - [ ] Add resolution option in the UI to allow interchange between arduino (10bit) and esp32 (12 bits) -- [ ] Possibly adding new module to support ESP32 -- [ ] Support for non-Windows platforms +- [x] Possibly adding new module to support ESP32 +- [ ] Support for non-Windows platforms (and maybe mobile) - [ ] Make it into one executable +- [ ] Possibly adding new module to support Arduino MEGA and older firmwares diff --git a/__pycache__/read_arduino.cpython-39.pyc b/__pycache__/read_arduino.cpython-39.pyc new file mode 100644 index 0000000..d00f49c Binary files /dev/null and b/__pycache__/read_arduino.cpython-39.pyc differ diff --git a/__pycache__/serial_plot.cpython-39.pyc b/__pycache__/serial_plot.cpython-39.pyc new file mode 100644 index 0000000..4a91683 Binary files /dev/null and b/__pycache__/serial_plot.cpython-39.pyc differ diff --git a/__pycache__/ui.cpython-39.pyc b/__pycache__/ui.cpython-39.pyc new file mode 100644 index 0000000..dc99c7c Binary files /dev/null and b/__pycache__/ui.cpython-39.pyc differ diff --git a/espVoltmeter/espVoltmeter.ino b/espVoltmeter/espVoltmeter.ino new file mode 100644 index 0000000..7b362b1 --- /dev/null +++ b/espVoltmeter/espVoltmeter.ino @@ -0,0 +1,57 @@ +// manually define all the An ports on ESP32 board +#if defined(ESP32) +#define A0 (36) +#define A1 (39) +#define A2 (34) +#define A3 (35) +#define A4 (32) +#define A5 (33) +#endif + +// define the divident of sizeof()'s return value +#if defined(ESP32) +#define SIZE_DIV 4 // for esp32, the resolution is doubled than the usual arduino board, so we double the factor, too +#else +#define SIZE_DIV 2 +#endif +#define WAIT_TIME 1000UL +#define SENSOR1 36 +// FILE *f = fopen("file.txt", "w"); +int pins[] = {A0, A1, A2, A3, A4, A5}; +int i, j; +unsigned long currTime; // non-blocking time tracker + +void setup() { + Serial.begin(19200); + currTime = millis(); + analogReadResolution(12); + // adcAttachPin(A0); + // analogSetClockDiv(255); + +} + +void loop() { + // we might need analogSetAttenuation to make the measurement more accurate and less noisy? + if (millis() - currTime >= WAIT_TIME) { // non-blocking time delay + // Serial.println(); + Serial.print("["); + for (i = 0; i < sizeof(pins)/SIZE_DIV; i++) { + + // float volts = analogRead(pins[i]); + // float result = volts * 3.3 / 4095; + // Serial.print(result); + + float volts = analogReadMilliVolts(pins[i]); + Serial.print(volts); + // Serial.print(61319 * (3.3/volts - 1)); + if (i != sizeof(pins)/SIZE_DIV - 1) { + Serial.print(", "); + } + + } + Serial.println("]"); + // Serial.println(analogReadMilliVolts(SENSOR1)); + currTime = millis(); + } + +} \ No newline at end of file diff --git a/read_arduino.py b/read_arduino.py new file mode 100644 index 0000000..919fe9b --- /dev/null +++ b/read_arduino.py @@ -0,0 +1,54 @@ +""" + 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.tools.list_ports +import numpy as np + +# constant settings +SENSORS_MAX = 4 # maximum sensor ports + +def read(): + baud = 19200 + settings = json.load(open('settings.json', 'r')) + resolution = settings["resolution"] # this is not in use, but just in case if we decide to switch back to analogRead() instead of ESP32's analogReadMiliVolts() on the firmware + v_in = settings["v_in"] + refRes = np.array(settings["refRes"]) + 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) + + if np.any(sensor_ports >= SENSORS_MAX): + raise ValueError("Port range is 0-3!") + + # TODO: separate data in each run but still keep them in one csv file + while controller.isOpen(): + try: + read_data = controller.readline().decode("utf-8") + # use numpy so it can make list calculations easier (and possibly faster) + dat_list = np.asarray(json.loads(read_data), dtype=np.uint32)[:SENSORS_MAX] + + # if we decided to switch back to analogRead(), replace this line of comment to the algorithm to something like the commented line below + # dat_sel = np.take(dat_list, sensor_ports) * v_in / resolution + + # 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() + # except KeyboardInterrupt as e: + # print(e.__class__.__name__) + # break + except (json.decoder.JSONDecodeError, UnicodeDecodeError): + print('decoder error') diff --git a/read_arduino.pyw b/read_arduino.pyw deleted file mode 100644 index a318b39..0000000 --- a/read_arduino.pyw +++ /dev/null @@ -1,49 +0,0 @@ -""" - 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.tools.list_ports -import numpy as np - -# constant settings -SENSORS_MAX = 4 # maximum sensor ports -baud = 19200 - -settings = json.load(open('settings.json', 'r')) -resolution = settings["resolution"] -v_src = settings["v_src"] -v_in = settings["v_in"] -refRes = np.array(settings["refRes"]) -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) - -if np.any(sensor_ports >= SENSORS_MAX): - raise ValueError("Port range is 0-3!") - -# TODO: separate data in each run but still keep them in one csv file -while controller.isOpen(): - try: - read_data = controller.readline().decode("utf-8") - # use numpy so it can make list calculations easier (and possibly faster) - dat_list = np.asarray(json.loads(read_data), dtype=np.int16)[:SENSORS_MAX] - dat_sel = np.take(dat_list, sensor_ports) * v_in / resolution - 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() - # except KeyboardInterrupt as e: - # print(e.__class__.__name__) - # break - except json.decoder.JSONDecodeError: - print('decoder error') diff --git a/sealammonia.fbp b/sealammonia.fbp index 0a3328a..af73cfe 100644 --- a/sealammonia.fbp +++ b/sealammonia.fbp @@ -507,7 +507,7 @@ wxFILTER_NONE wxDefaultValidator - + 0 @@ -598,7 +598,7 @@ wxFILTER_NONE wxDefaultValidator - + 0 @@ -689,7 +689,7 @@ wxFILTER_NONE wxDefaultValidator - + 0 @@ -780,7 +780,7 @@ wxFILTER_NONE wxDefaultValidator - + 0 @@ -823,7 +823,7 @@ 1 wxID_ANY - Additional Parameters + Additional Parameters (Do not change unless you know what you are doing!) v_entre wxVERTICAL @@ -986,12 +986,12 @@ ; ; forward_declare 0 - + Input voltage of the resistors, default 3.3 volts wxFILTER_NONE wxDefaultValidator - 5 + 3.3 @@ -1059,7 +1059,7 @@ 0 0 wxID_ANY - ADC Output Voltage + ADC bit rate 0 @@ -1166,12 +1166,12 @@ ; ; forward_declare 0 - + Bit size of the board's ADC, default is 12 bits (4096) minus 1 wxFILTER_NONE wxDefaultValidator - 5 + 4095 @@ -1419,7 +1419,7 @@ 0 0 wxID_ANY - Volts + 0 @@ -1974,7 +1974,7 @@ 1 0 - 0 + 1 1 1 diff --git a/serial_plot.py b/serial_plot.py index 0b25086..301516b 100644 --- a/serial_plot.py +++ b/serial_plot.py @@ -4,7 +4,7 @@ import math, json, traceback try: import matplotlib - matplotlib.use("QtAgg") # to force use one of the matplot's UI backend instead of an IDE's choice + matplotlib.use("WXAgg") # to force use one of the matplot's UI backend instead of an IDE's choice except ImportError: traceback.print_exc() diff --git a/serial_plot.pyw b/serial_plot.pyw index 82ae3ef..fa498eb 100644 --- a/serial_plot.pyw +++ b/serial_plot.pyw @@ -4,7 +4,7 @@ import math, json, traceback try: import matplotlib - matplotlib.use("QtAgg") # to force use one of the matplot's UI backend instead of an IDE's choice + matplotlib.use("WXAgg") # to force use one of the matplot's UI backend instead of an IDE's choice except ImportError: traceback.print_exc() diff --git a/test.py b/test.py index 219151f..e5f0964 100644 --- a/test.py +++ b/test.py @@ -1,11 +1,14 @@ from ui import Frame from datetime import datetime from threading import * -import os, json, sys, wx, subprocess +from read_arduino import * +import os, json, sys, wx, subprocess, warnings import serial.tools.list_ports from serial_plot import * import numpy as np +warnings.filterwarnings("ignore", category=DeprecationWarning) + HEIGHT = 800 WIDTH = 800 @@ -13,12 +16,12 @@ WIDTH = 800 def main(): #################### USER INPUTS ########################### # TODO: if there is already a setting.json exist, loads all inputs from there as 'default' - # 9840 + 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 input_voltage = float(frame.input_voltage.GetValue()) - adjusted_volt = float(frame.adjusted_volt.GetValue()) + bit_rate = float(frame.adjusted_volt.GetValue()) port = frame.dev_list.GetValue() # typical window size: 480 window_size = int(frame.m_textCtrl26.GetValue()) @@ -30,16 +33,15 @@ def main(): dat_folder = "RecordedData" os.makedirs(dat_folder, exist_ok=True) filename = os.path.join(os.getcwd(), dat_folder, f"{datetime.now().strftime('%Y-%m-%d_%H%M%S')}.csv") - resolution = 1023 # Arduino's analogRead()'s input resolution. We don't change this number usually. delay = 1000 # millisec pe r data, defined in the firmware if not (len(resistors) == 5): raise ValueError(f"expecting 5 resistor values, but got {len(resistors)}!!!") - gen_settings(resistors, input_voltage, adjusted_volt, port, filename, resolution, window_size, delay) + gen_settings(resistors, input_voltage, bit_rate, port, filename, window_size, delay) return filename -def gen_settings(resistors, input_voltage, adjusted_volt, port, filename, resolution, window_size, delay): +def gen_settings(resistors, input_voltage, bits, port, filename, window_size, delay): """ export all inputs from main() to a .json file """ @@ -47,10 +49,9 @@ def gen_settings(resistors, input_voltage, adjusted_volt, port, filename, resolu settings = {} settings["refRes"] = resistors settings["sensor_ports"] = np.where(np.array(resistors) > 0)[0].tolist() - settings["v_src"] = input_voltage - settings["v_in"] = adjusted_volt + settings["v_in"] = input_voltage settings["port"] = port - settings["resolution"] = resolution + settings["resolution"] = bits settings["winSize"] = window_size settings["file_name"] = filename settings["delay"] = delay @@ -66,29 +67,8 @@ def get_devices(): frame.dev_list.AppendItems(ports) -# return ports - - # for scheduler maybe? def task1(): - print("run task 1") - run_t1 = ["start", sys.executable, "read_arduino.pyw"] - out1 = subprocess.Popen(run_t1, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) - running = True - init = 0 - while running: - cline = out1.stdout.readline() - print(cline.decode()) - if not cline and init > 0: - print(cline.decode()) - running = False - init += 1 - - if out1.returncode: - print('Something went wrong:', out1.returncode) - - -def task2(): print("run task 2") run_t2 = ["start", os.path.join(sys.exec_prefix, 'pythonw'), "serial_plot.pyw"] out2 = subprocess.Popen(run_t2, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) @@ -109,29 +89,44 @@ def task2(): def run(e): file = main() save_diag = f"File has saved as {os.path.split(file)[1]} under {os.path.split(file)[0]} directory!\n" - t1 = Thread(target=task1, args=()) + + t1 = Thread(target=read, args=()) t1.setDaemon(True) t1.start() - t2 = Thread(target=task2, args=()) + t2 = Thread(target=task1, args=()) t2.setDaemon(True) t2.start() + frame.plot_but.Enable(True) # this might have some problem ... what happen if user spamming the plot button? if not frame.show_msg.GetValue(): - frame.Close() + frame.Hide() wx.MessageBox(save_diag, "Info", style=wx.ICON_INFORMATION) + def runPlot(e): plotter() - wx.MessageBox("Your data is being plotted", "Info", style = wx.ICON_INFORMATION) + wx.MessageBox("Your data is being plotted", "Info", style=wx.ICON_INFORMATION) if __name__ == '__main__': app = wx.App() frame = Frame(None) get_devices() - frame.SetTitle("Cease your resistance! - a0.0.0") + frame.SetTitle("Cease your resistance! - alpha 0.1.0") frame.btLaunch.Bind(wx.EVT_BUTTON, run) - frame.plot_but.Bind(wx.EVT_BUTTON, runPlot) # There is one problem with this approch: what happen if user spamming the plot button? + frame.plot_but.Bind(wx.EVT_BUTTON, + runPlot) # There is one problem with this approch: what happen if user spamming the plot button? + if os.path.isfile("settings.json"): + print("Found existing settings.json, auto-fill previous inputs!") + 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])) + frame.r_ref_3.SetValue(str(settings["refRes"][2])) + frame.r_ref_4.SetValue(str(settings["refRes"][3])) + frame.input_voltage.SetValue(str(settings["v_in"])) + frame.adjusted_volt.SetValue(str(settings["resolution"])) + frame.m_textCtrl26.SetValue(str(settings["winSize"])) + frame.Show() frame.m_textCtrl26.SetValue("480") app.MainLoop() diff --git a/ui.py b/ui.py index 4304a85..6cac331 100644 --- a/ui.py +++ b/ui.py @@ -46,16 +46,16 @@ class Frame ( wx.Frame ): self.r4_prompt.Wrap( -1 ) res_grid.Add( self.r4_prompt, 0, wx.ALIGN_BOTTOM|wx.ALIGN_CENTER_HORIZONTAL, 5 ) - self.r_ref_1 = wx.TextCtrl( ref_entre.GetStaticBox(), wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.r_ref_1 = wx.TextCtrl( ref_entre.GetStaticBox(), wx.ID_ANY, u"0", wx.DefaultPosition, wx.DefaultSize, 0 ) res_grid.Add( self.r_ref_1, 0, wx.ALIGN_CENTER_HORIZONTAL, 5 ) - self.r_ref_2 = wx.TextCtrl( ref_entre.GetStaticBox(), wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.r_ref_2 = wx.TextCtrl( ref_entre.GetStaticBox(), wx.ID_ANY, u"0", wx.DefaultPosition, wx.DefaultSize, 0 ) res_grid.Add( self.r_ref_2, 0, wx.ALIGN_CENTER_HORIZONTAL, 5 ) - self.r_ref_3 = wx.TextCtrl( ref_entre.GetStaticBox(), wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.r_ref_3 = wx.TextCtrl( ref_entre.GetStaticBox(), wx.ID_ANY, u"0", wx.DefaultPosition, wx.DefaultSize, 0 ) res_grid.Add( self.r_ref_3, 0, wx.ALIGN_CENTER_HORIZONTAL, 5 ) - self.r_ref_4 = wx.TextCtrl( ref_entre.GetStaticBox(), wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.r_ref_4 = wx.TextCtrl( ref_entre.GetStaticBox(), wx.ID_ANY, u"0", wx.DefaultPosition, wx.DefaultSize, 0 ) res_grid.Add( self.r_ref_4, 0, wx.ALIGN_CENTER_HORIZONTAL, 5 ) @@ -64,7 +64,7 @@ class Frame ( wx.Frame ): bSizer1.Add( ref_entre, 0, wx.EXPAND, 5 ) - v_entre = wx.StaticBoxSizer( wx.StaticBox( self, wx.ID_ANY, u"Additional Parameters" ), wx.VERTICAL ) + v_entre = wx.StaticBoxSizer( wx.StaticBox( self, wx.ID_ANY, u"Additional Parameters (Do not change unless you know what you are doing!)" ), wx.VERTICAL ) gbSizer8 = wx.GridBagSizer( 0, 0 ) gbSizer8.SetFlexibleDirection( wx.BOTH ) @@ -74,14 +74,18 @@ class Frame ( wx.Frame ): self.vin_prompt.Wrap( -1 ) gbSizer8.Add( self.vin_prompt, wx.GBPosition( 0, 0 ), wx.GBSpan( 1, 1 ), wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 5 ) - self.input_voltage = wx.TextCtrl( v_entre.GetStaticBox(), wx.ID_ANY, u"5", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.input_voltage = wx.TextCtrl( v_entre.GetStaticBox(), wx.ID_ANY, u"3.3", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.input_voltage.SetToolTipString( u"Input voltage of the resistors, default 3.3 volts" ) + gbSizer8.Add( self.input_voltage, wx.GBPosition( 0, 1 ), wx.GBSpan( 1, 1 ), wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5 ) - self.vadc_prompt = wx.StaticText( v_entre.GetStaticBox(), wx.ID_ANY, u"ADC Output Voltage", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT|wx.ST_ELLIPSIZE_END ) + self.vadc_prompt = wx.StaticText( v_entre.GetStaticBox(), wx.ID_ANY, u"ADC bit rate", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT|wx.ST_ELLIPSIZE_END ) self.vadc_prompt.Wrap( -1 ) gbSizer8.Add( self.vadc_prompt, wx.GBPosition( 1, 0 ), wx.GBSpan( 1, 1 ), wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, 5 ) - self.adjusted_volt = wx.TextCtrl( v_entre.GetStaticBox(), wx.ID_ANY, u"5", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.adjusted_volt = wx.TextCtrl( v_entre.GetStaticBox(), wx.ID_ANY, u"4095", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.adjusted_volt.SetToolTipString( u"Bit size of the board's ADC, default is 12 bits (4096) minus 1" ) + gbSizer8.Add( self.adjusted_volt, wx.GBPosition( 1, 1 ), wx.GBSpan( 1, 1 ), wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5 ) self.sizer_prompt = wx.StaticText( v_entre.GetStaticBox(), wx.ID_ANY, u"Window Size", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT|wx.ST_ELLIPSIZE_END ) @@ -93,7 +97,7 @@ class Frame ( wx.Frame ): 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 ) - self.unit2 = wx.StaticText( v_entre.GetStaticBox(), wx.ID_ANY, u"Volts", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.unit2 = wx.StaticText( v_entre.GetStaticBox(), wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) self.unit2.Wrap( -1 ) gbSizer8.Add( self.unit2, wx.GBPosition( 1, 2 ), wx.GBSpan( 1, 1 ), wx.ALIGN_CENTER_VERTICAL, 5 ) @@ -142,6 +146,7 @@ class Frame ( wx.Frame ): bSizer1.Add( launch_opt, 0, wx.ALIGN_CENTER_HORIZONTAL, 5 ) self.show_msg = wx.CheckBox( self, wx.ID_ANY, u"Make launcher stays open after started", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.show_msg.SetValue(True) bSizer1.Add( self.show_msg, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 )