cleanup
This commit is contained in:
parent
81d1b12079
commit
3d78a2a733
|
@ -1,8 +0,0 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
|
@ -1 +0,0 @@
|
|||
SeeDatResistance
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$/test.txt" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
|
@ -1,11 +1,14 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||
<option name="ignoredErrors">
|
||||
<list>
|
||||
<option value="N806" />
|
||||
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoredPackages">
|
||||
<value>
|
||||
<list size="2">
|
||||
<item index="0" class="java.lang.String" itemvalue="wxPython" />
|
||||
<item index="1" class="java.lang.String" itemvalue="requests" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9" project-jdk-type="Python SDK">
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9 (Read-Sensor-Resistances)" project-jdk-type="Python SDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
|
@ -2,7 +2,7 @@
|
|||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/SeeDatResistance.iml" filepath="$PROJECT_DIR$/SeeDatResistance.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/Read-Sensor-Resistances.iml" filepath="$PROJECT_DIR$/Read-Sensor-Resistances.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,126 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="76f71a68-f2de-44e3-b845-3cd5ad93cdd1" name="Default Changelist" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/Read-Sensor-Resistances.iml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/.gitignore" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/.name" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/encodings.xml" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/inspectionProfiles/Project_Default.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/inspectionProfiles/Project_Default.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/modules.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/modules.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/ReadAnalog/.gitignore" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/ReadAnalog/.vscode/extensions.json" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/ReadAnalog/flash.py" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/ReadAnalog/include/README" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/ReadAnalog/lib/README" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/ReadAnalog/platformio.ini" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/ReadAnalog/src/main.cpp" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/ReadAnalog/test/README" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/espVoltmeter/espVoltmeter.ino" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/read_arduino.py" beforeDir="false" afterPath="$PROJECT_DIR$/read_arduino.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/requirements.txt" beforeDir="false" afterPath="$PROJECT_DIR$/requirements.txt" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/sealammonia.fbp" beforeDir="false" afterPath="$PROJECT_DIR$/sealammonia.fbp" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/serial_plot.py" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/test.py" beforeDir="false" afterPath="$PROJECT_DIR$/test.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/toplevel.py" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/ui.py" beforeDir="false" afterPath="$PROJECT_DIR$/ui.py" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="PUSH_TAGS">
|
||||
<GitPushTagMode>
|
||||
<option name="argument" value="--tags" />
|
||||
<option name="title" value="All" />
|
||||
</GitPushTagMode>
|
||||
</option>
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="ProjectId" id="2LOnAsJg3v8rGTYtWcMJdPjM4DK" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
|
||||
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
|
||||
<property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" />
|
||||
<property name="WebServerToolWindowFactoryState" value="true" />
|
||||
<property name="aspect.path.notification.shown" value="true" />
|
||||
<property name="nodejs_package_manager_path" value="npm" />
|
||||
</component>
|
||||
<component name="RunManager">
|
||||
<configuration default="true" type="ArquillianJUnit" factoryName="" nameIsGenerated="true">
|
||||
<option name="arquillianRunConfiguration">
|
||||
<value>
|
||||
<option name="containerStateName" value="" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="TEST_OBJECT" value="class" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration name="test" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||
<module name="Read-Sensor-Resistances" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs>
|
||||
<env name="PYTHONUNBUFFERED" value="1" />
|
||||
</envs>
|
||||
<option name="SDK_HOME" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="IS_MODULE_SDK" value="true" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/test.py" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||
<option name="EMULATE_TERMINAL" value="false" />
|
||||
<option name="MODULE_MODE" value="false" />
|
||||
<option name="REDIRECT_INPUT" value="false" />
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<recent_temporary>
|
||||
<list>
|
||||
<item itemvalue="Python.test" />
|
||||
</list>
|
||||
</recent_temporary>
|
||||
</component>
|
||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="76f71a68-f2de-44e3-b845-3cd5ad93cdd1" name="Default Changelist" comment="" />
|
||||
<created>1675750856334</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1675750856334</updated>
|
||||
<workItem from="1675750858175" duration="2126000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
<component name="Vcs.Log.Tabs.Properties">
|
||||
<option name="TAB_STATES">
|
||||
<map>
|
||||
<entry key="MAIN">
|
||||
<value>
|
||||
<State />
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
<component name="com.intellij.coverage.CoverageDataManagerImpl">
|
||||
<SUITE FILE_PATH="coverage/Read_Sensor_Resistances$test.coverage" NAME="test Coverage Results" MODIFIED="1675751285394" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
||||
</component>
|
||||
</project>
|
33
README.md
33
README.md
|
@ -1,5 +1,5 @@
|
|||
# Read Resistances
|
||||
Read the resistance of a voltage divider using ESP32
|
||||
Read the resistance of a voltage divider using Arduino boards
|
||||
|
||||
## Required & Dependencies
|
||||
### Required
|
||||
|
@ -8,20 +8,23 @@ Read the resistance of a voltage divider using ESP32
|
|||
- matplotlib
|
||||
- pyserial
|
||||
- wxPython
|
||||
- PlatformIO IDE, which could be downloaded as an extension in vs code
|
||||
- ESP32 WROOM-32 Development Board
|
||||
- PlatformIO extension, if you use VSCode for embedded programmings
|
||||
- An Arduino-based microcontroller
|
||||
- ADS1115 16-bit ADC chip
|
||||
### Recommended
|
||||
- Code Runner (for VSCode only)
|
||||
- wxFormBuilder
|
||||
- [Arduino IDE](https://makeabilitylab.github.io/physcomp/arduino/arduino-ide.html)
|
||||
|
||||
## How to use
|
||||
To get a general idea of this project as well as hardware setup, please refer to [this video demo](https://youtu.be/vbVPXj8gbmI)
|
||||
### Direct use
|
||||
First download the `.ino` file from `espVoltmeter` folder using Arduino IDE. ~~Or if you are using Arduino Mega 2560 you can
|
||||
First open the `.ino` file from `nano_c_mk1` directory using Arduino IDE and download it onto an Arduino board. ~~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)
|
||||
For Windows you can just [download the released executable](https://github.com/Seal-Ammonia/Read-Sensor-Resistances/releases/download/beta/SeeDatResistance.exe) to use. Make sure to disable any virus-scanning software when download as Microsoft incorrectly recognized PyInstaller as virus. For non-Windows systems you can just run `python test.py` and start from the UI. Enter the relevant information and start collect and measuring data. If you do not have a board avaliable, leave the dropdown menu in the UI as "no device" and it will run a simulation.
|
||||
~~(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)~~ (There's a hardware upgrade so that the firmware has been re-written for the new hardware.
|
||||
Therefore the old hardware are no longer in use. You may still find them in `OldFirmware` directory for reference but we are not using them anymore)
|
||||
For Windows you can just [download the released executable](https://github.com/Seal-Ammonia/Read-Sensor-Resistances/releases/download/beta/SeeDatResistance.exe) from the release section to use. Make sure to disable any virus-scanning software when download as Microsoft incorrectly recognized PyInstaller as virus. For non-Windows systems you can just run `python test.py` and start from the UI. Enter the relevant information and start collect and measuring data. If you do not have a board avaliable, leave the dropdown menu in the UI as "no device" and it will run a simulation.
|
||||
### 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 `test.py`, which calls `UI.py` to prompt for input. It is NOT recommended modifying the `ui.py`
|
||||
|
@ -29,22 +32,22 @@ as it is generated from wxFormBuilder from `sealammonia.fbp`, which could be mod
|
|||
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.py` read raw data from Arduino board and convert it to the correct resistance, which could be plotted out
|
||||
using `serial_plotter.py`. `frontend.py` is the alternative version of the frontend writting using `tkinter`, and `serial_plot.py`
|
||||
was an older version of `serial_plotter.py`. They are not longer supported.
|
||||
using `serial_plotter.py`. To make your own executable, use `PyInstaller` using this command in your python environment:
|
||||
`pyinstaller build.spec`.
|
||||
ATTENTION MAC USER: currently the software cannot correctly functional on mac (especially arm-based ones). You might need to consider to use it on a windows VM or using parallel desktop
|
||||
|
||||
## Issues
|
||||
- Newer hardware will require 3.3V. ~~Currently can only use 5V as input voltage.~~ May need to change the algorithm in `read_arduino.py`.
|
||||
- axis window size is not correct
|
||||
- on PyInstaller, windows misdetected our executable as a virus
|
||||
- on PyInstaller, windows misdetected our executable as a virus (seems resolved)
|
||||
- change the scale on Y-axis so that graph looks smoother
|
||||
- Errors thrown when >1 reference resistances entered
|
||||
- ~~Errors thrown when >1 reference resistances entered~~
|
||||
|
||||
## Todos & [Old Specs](https://docs.google.com/document/d/1Km2HZel7rILOvgHG5iXlUcXFx4Of1ot2I7Dbnq8aTwY/edit?usp=sharing):
|
||||
## Todos:
|
||||
- [ ] Fix Issues
|
||||
- [ ] Automatically setup the driver for ESP32
|
||||
- [ ] programically to stablize the graph (change the y-scale of the graph to make the less dramatic)
|
||||
- [ ] (not urgent) make if runnable on Mac
|
||||
- [ ] (not urgent) make it runnable on Mac
|
||||
- [x] display sensor value in either the UI or on the plot
|
||||
- [x] Reopen plot window from the UI when closed
|
||||
- [x] Need to continue writing to file when graphing window is closed
|
||||
|
@ -55,8 +58,8 @@ ATTENTION MAC USER: currently the software cannot correctly functional on mac (e
|
|||
- [x] Accept any inputs (such as resistor values, plot window size, base voltage etc.) as either command line argument or as input at beginning of program
|
||||
- [x] Write random values to simulate a sensor if no sensor available (this feature might be removed in the future)
|
||||
- [x] 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)
|
||||
- [X] Add resolution option in the UI to allow interchange between arduino (10bit) and esp32 (12 bits) (Not Applicable in new hardware)
|
||||
- [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
|
||||
- [ ] Possibly adding new module to support Arduino MEGA and older firmwares (Need testing)
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
|
@ -0,0 +1,42 @@
|
|||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
|
||||
block_cipher = None
|
||||
|
||||
|
||||
a = Analysis(['test.py', 'serial_plotter.py', 'read_arduino.py', 'ui.py'],
|
||||
pathex=['D:\\github\\Read-Sensor-Resistances'],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
noarchive=False)
|
||||
splash = Splash('splash.png',
|
||||
binaries=a.binaries,
|
||||
datas=a.datas,
|
||||
text_pos=(145, 142),
|
||||
text_size=8,
|
||||
text_color='black')
|
||||
pyz = PYZ(a.pure, a.zipped_data,
|
||||
cipher=block_cipher)
|
||||
exe = EXE(pyz,
|
||||
a.scripts,
|
||||
splash, # <-- both, splash target
|
||||
splash.binaries, # <-- and splash binaries
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
[],
|
||||
name='SeeDatResistance',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=False )
|
|
@ -16,7 +16,7 @@ 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
|
||||
# resolution = settings["resolution"] # this is not in use, but just in case if we decide to switch back to analogRead()
|
||||
v_in = settings["v_in"]
|
||||
refRes = np.array(settings["refRes"])
|
||||
sensor_ports = np.array(settings["sensor_ports"]) # ports that sensor(s) are connected to
|
||||
|
@ -44,19 +44,9 @@ def read():
|
|||
writer.writerow(header)
|
||||
f.close()
|
||||
while True:
|
||||
#dat_list = np.random.randint(0, v_in * 1000, SENSORS_MAX) # create a randomized voltage data
|
||||
dat_list = np.random.randint(0, v_in * 1000, SENSORS_MAX) # 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
|
||||
'''ser = serial.Serial(port)
|
||||
ser.flushInput()
|
||||
while True:
|
||||
try:
|
||||
ser_bytes = ser.readline()
|
||||
decoded_bytes = float(ser_bytes[0:len(ser_bytes)-2].decode("utf-8"))
|
||||
except:
|
||||
print("Keyboard Interrupt")
|
||||
break'''
|
||||
#dat_sel = np.trunc((np.take(decoded_bytes, sensor_ports) / 1000) * 10**2) / 10**2
|
||||
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) # *2 <-- change with actual formula for ammonia concentration
|
||||
# created a new array to convert resistance values to sci notation
|
||||
r_arr2 = np.empty(len(r_arr), dtype=object)
|
||||
|
@ -91,19 +81,14 @@ def read():
|
|||
f.close()
|
||||
while controller.isOpen():
|
||||
try:
|
||||
#controller.flushInput()
|
||||
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.float32)[:SENSORS_MAX]
|
||||
#ser_bytes = controller.readline()
|
||||
#decoded_bytes = float(ser_bytes[0:len(ser_bytes)-2].decode("utf-8"))
|
||||
#dat_sel = np.trunc((np.take(dat_list, sensor_ports) / 1000) * 10**2) / 10**2
|
||||
dat_sel = np.take(dat_list, sensor_ports)
|
||||
# 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) # *2 <-- change with actual formula for ammonia concentration
|
||||
# created a new array to convert resistance values to sci notation
|
||||
r_arr2 = np.empty(len(r_arr), dtype=object)
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
matplotlib
|
||||
pyserial
|
||||
wxPython
|
||||
os
|
||||
requests
|
||||
urllib.requests
|
||||
zipfile
|
||||
datetime
|
||||
serial
|
||||
time
|
||||
json
|
||||
numpy
|
||||
pyinstaller
|
184
sealammonia.fbp
184
sealammonia.fbp
|
@ -1024,186 +1024,6 @@
|
|||
<event name="OnUpdateUI"></event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="gbsizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="colspan">1</property>
|
||||
<property name="column">0</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
|
||||
<property name="row">1</property>
|
||||
<property name="rowspan">1</property>
|
||||
<object class="wxStaticText" expanded="0">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">ADC bit rate</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">vadc_prompt</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style">wxALIGN_RIGHT|wxST_ELLIPSIZE_END</property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">-1</property>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus"></event>
|
||||
<event name="OnLeaveWindow"></event>
|
||||
<event name="OnLeftDClick"></event>
|
||||
<event name="OnLeftDown"></event>
|
||||
<event name="OnLeftUp"></event>
|
||||
<event name="OnMiddleDClick"></event>
|
||||
<event name="OnMiddleDown"></event>
|
||||
<event name="OnMiddleUp"></event>
|
||||
<event name="OnMotion"></event>
|
||||
<event name="OnMouseEvents"></event>
|
||||
<event name="OnMouseWheel"></event>
|
||||
<event name="OnPaint"></event>
|
||||
<event name="OnRightDClick"></event>
|
||||
<event name="OnRightDown"></event>
|
||||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="gbsizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="colspan">1</property>
|
||||
<property name="column">1</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxALL</property>
|
||||
<property name="row">1</property>
|
||||
<property name="rowspan">1</property>
|
||||
<object class="wxTextCtrl" expanded="0">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="maxlength"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">adjusted_volt</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip">Bit size of the board's ADC, default is 12 bits (4096) minus 1</property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="value">4095</property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus"></event>
|
||||
<event name="OnLeaveWindow"></event>
|
||||
<event name="OnLeftDClick"></event>
|
||||
<event name="OnLeftDown"></event>
|
||||
<event name="OnLeftUp"></event>
|
||||
<event name="OnMiddleDClick"></event>
|
||||
<event name="OnMiddleDown"></event>
|
||||
<event name="OnMiddleUp"></event>
|
||||
<event name="OnMotion"></event>
|
||||
<event name="OnMouseEvents"></event>
|
||||
<event name="OnMouseWheel"></event>
|
||||
<event name="OnPaint"></event>
|
||||
<event name="OnRightDClick"></event>
|
||||
<event name="OnRightDown"></event>
|
||||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnText"></event>
|
||||
<event name="OnTextEnter"></event>
|
||||
<event name="OnTextMaxLen"></event>
|
||||
<event name="OnTextURL"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="gbsizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="colspan">1</property>
|
||||
|
@ -1351,7 +1171,7 @@
|
|||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="value">480</property>
|
||||
<property name="value">50</property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
|
@ -1883,7 +1703,7 @@
|
|||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="checked">1</property>
|
||||
<property name="checked">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
import matplotlib.pyplot as plt
|
||||
import matplotlib.animation as animate
|
||||
import math, json, traceback
|
||||
|
||||
try:
|
||||
import matplotlib
|
||||
|
||||
matplotlib.use("WXAgg") # to force use one of the matplot's UI backend instead of an IDE's choice
|
||||
except ImportError:
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
def plotter():
|
||||
a = json.load(open('settings.json', 'r'))
|
||||
sensors = len(a['sensor_ports'])
|
||||
windowsize = a['winSize']
|
||||
delay = a["delay"] / 1000
|
||||
file = open(a["file_name"], "r")
|
||||
|
||||
colors = ['blue', 'orange', 'green', 'yellow']
|
||||
|
||||
fig, axs = plt.subplots(1, 1)
|
||||
|
||||
timeStamps = []
|
||||
sensorsData = []
|
||||
|
||||
i = 0
|
||||
while i <= sensors:
|
||||
sensorsData.append([])
|
||||
i = i + 1
|
||||
|
||||
def animation(t):
|
||||
next_line = file.readline()
|
||||
if next_line:
|
||||
line = next_line.split(',')
|
||||
if len(line) >= sensors:
|
||||
i = 1
|
||||
timeStamps.append(line[0])
|
||||
# get rid of the zeroth value if it exceeds pre-defined window size
|
||||
if windowsize != 0 and len(timeStamps) > windowsize:
|
||||
timeStamps.pop(0)
|
||||
val_lists = []
|
||||
while i <= sensors:
|
||||
if not line[i]: # pass on invalid values
|
||||
continue
|
||||
sensorsData[i - 1].append(float(line[i])) # cast it to float so the y-axis will not jump around
|
||||
# get rid of the zeroth value if it exceeds pre-defined window size
|
||||
if windowsize != 0 and len(sensorsData[i - 1]) > windowsize:
|
||||
sensorsData[i - 1].pop(0)
|
||||
val_lists.append(sensorsData[i - 1])
|
||||
i += 1
|
||||
for j in range(len(val_lists)):
|
||||
axs.plot(timeStamps, val_lists[j], color=colors[j],
|
||||
label=f'sensor {j + 1}') # TODO: display sensor number to the actual arduino's port &
|
||||
# axs.annotate('%0.2f' % val_lists[j][-1], xy=(1, val_lists[j][-1]), xytext=(8, 0),
|
||||
# xycoords=('axes fraction', 'data'), textcoords='offset points')
|
||||
|
||||
# Acknowledgement: https://stackoverflow.com/a/13589144
|
||||
handles, labels = plt.gca().get_legend_handles_labels()
|
||||
by_label = dict(zip(labels, handles))
|
||||
axs.legend(by_label.values(), by_label.keys(), loc='best')
|
||||
print(by_label.items())
|
||||
|
||||
return animate.FuncAnimation(plt.gcf(), func=animation) # , interval=delay * 500)
|
||||
# ani.save("plot.gif")
|
||||
# plt.ion()
|
||||
# plt.show(block=True)
|
||||
|
||||
# plotter()
|
Binary file not shown.
After Width: | Height: | Size: 529 KiB |
15
test.py
15
test.py
|
@ -29,9 +29,9 @@ def main():
|
|||
r_ref[r_ref == ''] = '0' # correcting the emply values
|
||||
resistors = r_ref.astype(np.float32).tolist() # convert string to numbers
|
||||
input_voltage = float(frame.input_voltage.GetValue())
|
||||
bit_rate = float(frame.adjusted_volt.GetValue())
|
||||
# bit_rate = float(frame.adjusted_volt.GetValue())
|
||||
port = frame.dev_list.GetValue()
|
||||
# typical window size: 480
|
||||
# typical window size: 50
|
||||
window_size = int(frame.m_textCtrl26.GetValue())
|
||||
|
||||
#################### END USER INPUTS ########################
|
||||
|
@ -46,10 +46,10 @@ def main():
|
|||
if not (len(resistors) == 5):
|
||||
raise ValueError(f"expecting 5 resistor values, but got {len(resistors)}!!!")
|
||||
|
||||
gen_settings(resistors, input_voltage, bit_rate, port, filename, window_size, delay)
|
||||
gen_settings(resistors, input_voltage, port, filename, window_size, delay)
|
||||
|
||||
|
||||
def gen_settings(resistors, input_voltage, bits, port, filename, window_size, delay):
|
||||
def gen_settings(resistors, input_voltage, port, filename, window_size, delay):
|
||||
"""
|
||||
export all inputs from main() to a .json file
|
||||
:param resistors: list of reference resistances of the sensors
|
||||
|
@ -66,7 +66,7 @@ def gen_settings(resistors, input_voltage, bits, port, filename, window_size, de
|
|||
settings["sensor_ports"] = np.where(np.array(resistors) > 0)[0].tolist()
|
||||
settings["v_in"] = input_voltage
|
||||
settings["port"] = port
|
||||
settings["resolution"] = bits
|
||||
# settings["resolution"] = bits
|
||||
settings["winSize"] = window_size
|
||||
settings["file_name"] = filename
|
||||
settings["delay"] = delay
|
||||
|
@ -104,7 +104,6 @@ if __name__ == '__main__':
|
|||
if sys.platform.startswith('win'):
|
||||
# On Windows calling this function is necessary.
|
||||
freeze_support()
|
||||
#global t1
|
||||
app = wx.App(useBestVisual=True)
|
||||
frame = Frame(None)
|
||||
app.SetTopWindow(frame)
|
||||
|
@ -115,7 +114,7 @@ if __name__ == '__main__':
|
|||
sys.stdout.write("this is an alpha version of the design. This debug terminal will be gone on official release\n")
|
||||
ports = [comport.device for comport in serial.tools.list_ports.comports()] # get all available ports
|
||||
frame.dev_list.AppendItems(ports)
|
||||
frame.SetTitle("SeeDatResistance - Beta 0.1.0 RC2")
|
||||
frame.SetTitle("SeeDatResistance - Beta 0.1.1")
|
||||
frame.btLaunch.Bind(wx.EVT_BUTTON, run)
|
||||
if os.path.isfile("settings.json"):
|
||||
try:
|
||||
|
@ -126,7 +125,7 @@ if __name__ == '__main__':
|
|||
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.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"])
|
||||
|
|
183
toplevel.py
183
toplevel.py
|
@ -1,183 +0,0 @@
|
|||
"""
|
||||
Top level script to prompt user for inputs, and then make those input as a .json file so that other modules can use it.
|
||||
to run stuff. This module can have the frontend UI merged into, or can have separate one but should be the first things
|
||||
to call from frontend before running other stuff.
|
||||
"""
|
||||
from datetime import datetime
|
||||
from threading import *
|
||||
import os, json, sys, subprocess
|
||||
import serial.tools.list_ports
|
||||
import numpy as np
|
||||
import tkinter as tk
|
||||
|
||||
HEIGHT = 800
|
||||
WIDTH = 800
|
||||
|
||||
|
||||
def main():
|
||||
#################### USER INPUTS ###########################
|
||||
# TODO: if there is already a setting.json exist, loads all inputs from there as 'default'
|
||||
# 9840
|
||||
resistors = [int(text3.get()), int(text4.get()), 0, 0, 0] # resisters for each An port, where n is an integer from 0-3. Use 0 if none. in Ohms
|
||||
input_voltage = 5
|
||||
adjusted_volt = 5
|
||||
port = get_devices()[0]
|
||||
# typical window size: 480
|
||||
window_size = 480
|
||||
|
||||
#################### END USER INPUTS ########################
|
||||
|
||||
# filename, disable customize name but should inform the user the current name of the data file on the front end
|
||||
# alternatively, could be default input if no other input given. But if there is might have problem...
|
||||
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)
|
||||
return filename
|
||||
|
||||
|
||||
def gen_settings(resistors, input_voltage, adjusted_volt, port, filename, resolution, window_size, delay):
|
||||
name = "settings.json"
|
||||
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["port"] = port
|
||||
settings["resolution"] = resolution
|
||||
settings["winSize"] = window_size
|
||||
settings["file_name"] = filename
|
||||
settings["delay"] = delay
|
||||
open(name, 'w').write(json.dumps(settings, indent=4))
|
||||
open(filename, "a", newline="", encoding="utf-8")
|
||||
|
||||
|
||||
def get_devices():
|
||||
ports = [comport.device for comport in serial.tools.list_ports.comports()] # get all available ports
|
||||
if not ports:
|
||||
raise ConnectionError("No devices detected!") # TODO: set to writerandomvalues.py thing instead raise error
|
||||
return ports
|
||||
|
||||
|
||||
# for scheduler maybe?
|
||||
def task1():
|
||||
print("run task 1")
|
||||
# exec(open("read_arduino.py").read())
|
||||
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)
|
||||
running = True
|
||||
init = 0
|
||||
while running:
|
||||
cline = out2.stdout.readline()
|
||||
print(cline.decode())
|
||||
if not cline and init > 0:
|
||||
print(cline.decode())
|
||||
running = False
|
||||
init += 1
|
||||
|
||||
if out2.returncode:
|
||||
print('Something went wrong:', out2.returncode)
|
||||
|
||||
|
||||
def test_func():
|
||||
file = main()
|
||||
label['text'] = f"File has saved as {os.path.split(file)[1]} under {os.path.split(file)[0]} directory!\n"
|
||||
t1 = Thread(target=task1, args=())
|
||||
t1.setDaemon(True)
|
||||
t1.start()
|
||||
|
||||
t2 = Thread(target=task2, args=())
|
||||
t2.setDaemon(True)
|
||||
t2.start()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# file = main()
|
||||
# print(f"File has saved as {os.path.split(file)[1]} under {os.path.split(file)[0]} directory!")
|
||||
# t1 = Thread(target=task1, args=())
|
||||
# t1.setDaemon(True)
|
||||
# t1.start()
|
||||
#
|
||||
# t2 = Thread(target=task2, args=())
|
||||
# t2.setDaemon(True)
|
||||
# t2.start()
|
||||
# # while True:
|
||||
# # pass
|
||||
# t1.join()
|
||||
# t2.join()
|
||||
root = tk.Tk()
|
||||
|
||||
canvas = tk.Canvas(root, height=HEIGHT, width=WIDTH)
|
||||
canvas.pack()
|
||||
|
||||
# backgroud_image = tk.PhotoImage(file='im1.gif')
|
||||
backIm = tk.Label(root, bg='#80c1ff')
|
||||
backIm.place(relwidth=1, relheight=1)
|
||||
|
||||
frame = tk.Frame(root, bg="#80c1ff", bd=5)
|
||||
frame.place(relx=0.5, rely=0.1, relwidth=0.75, relheight=0.1, anchor='n')
|
||||
|
||||
button1 = tk.Button(frame, text="update", font=50, fg='green', bg='grey', command=lambda: test_func())
|
||||
button1.place(relx=0.8, relheight=0.5, relwidth=0.2)
|
||||
|
||||
button2 = tk.Button(frame, text="clear", font=50, fg='red', bg='grey')
|
||||
button2.place(relx=0.8, rely=0.5, relheight=0.5, relwidth=0.2)
|
||||
|
||||
lb1 = tk.Label(frame, text="filename")
|
||||
lb1.place(relx=0.1, relheight=0.4, relwidth=0.2)
|
||||
|
||||
text1 = tk.StringVar()
|
||||
box1 = tk.Entry(frame, textvariable=text1)
|
||||
box1.place(relx=0.1, rely=0.5, relheight=0.5, relwidth=0.2)
|
||||
|
||||
lb2 = tk.Label(frame, text="num of sensor")
|
||||
lb2.place(relx=0.3, relheight=0.4, relwidth=0.2)
|
||||
|
||||
text2 = tk.StringVar()
|
||||
box2 = tk.Entry(frame, textvariable=text2)
|
||||
box2.place(relx=0.3, rely=0.5, relheight=0.5, relwidth=0.2)
|
||||
|
||||
lb3 = tk.Label(frame, text="res1")
|
||||
lb3.place(relx=0.5, relheight=0.4, relwidth=0.1)
|
||||
|
||||
text3 = tk.StringVar()
|
||||
box3 = tk.Entry(frame, textvariable=text3)
|
||||
box3.place(relx=0.5, rely=0.5, relheight=0.5, relwidth=0.1)
|
||||
|
||||
lb4 = tk.Label(frame, text="res2")
|
||||
lb4.place(relx=0.6, relheight=0.4, relwidth=0.1)
|
||||
|
||||
text4 = tk.StringVar()
|
||||
box4 = tk.Entry(frame, textvariable=text4)
|
||||
box4.place(relx=0.6, rely=0.5, relheight=0.5, relwidth=0.1)
|
||||
|
||||
lower_frame = tk.Frame(root, bg="#80c1ff", bd=10)
|
||||
lower_frame.place(relx=0.5, rely=0.25, relwidth=0.75, relheight=0.6, anchor='n')
|
||||
|
||||
label = tk.Label(lower_frame, font=40)
|
||||
label.place(relwidth=1, relheight=1)
|
||||
|
||||
root.mainloop()
|
13
ui.py
13
ui.py
|
@ -8,6 +8,7 @@
|
|||
###########################################################################
|
||||
|
||||
import wx
|
||||
import wx.xrc
|
||||
|
||||
###########################################################################
|
||||
## Class Frame
|
||||
|
@ -16,7 +17,7 @@ import wx
|
|||
class Frame ( wx.Frame ):
|
||||
|
||||
def __init__( self, parent ):
|
||||
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 470,337 ), style = wx.DEFAULT_FRAME_STYLE )
|
||||
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 470,330 ), style = wx.DEFAULT_FRAME_STYLE )
|
||||
|
||||
self.SetSizeHintsSz( wx.Size( 470,330 ), wx.DefaultSize )
|
||||
self.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNTEXT ) )
|
||||
|
@ -78,15 +79,6 @@ class Frame ( wx.Frame ):
|
|||
|
||||
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 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"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 )
|
||||
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 )
|
||||
|
@ -140,7 +132,6 @@ 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 )
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue