Fuck
This commit is contained in:
commit
4f359e604a
12 changed files with 1051 additions and 0 deletions
4
.idea/encodings.xml
Normal file
4
.idea/encodings.xml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
|
||||||
|
</project>
|
13
.idea/hit.iml
Normal file
13
.idea/hit.iml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
<component name="TestRunnerService">
|
||||||
|
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
|
||||||
|
</component>
|
||||||
|
</module>
|
7
.idea/misc.xml
Normal file
7
.idea/misc.xml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="JavaScriptSettings">
|
||||||
|
<option name="languageLevel" value="ES6" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6 (hit)" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/hit.iml" filepath="$PROJECT_DIR$/.idea/hit.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
271
.idea/workspace.xml
Normal file
271
.idea/workspace.xml
Normal file
|
@ -0,0 +1,271 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ChangeListManager">
|
||||||
|
<list default="true" id="74089eaa-e081-4df7-9c12-fd404f4aba9c" name="Default Changelist" comment="" />
|
||||||
|
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
|
||||||
|
<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="CoverageDataManager">
|
||||||
|
<SUITE FILE_PATH="coverage/hit$leds.coverage" NAME="leds Coverage Results" MODIFIED="1553307066056" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
||||||
|
<SUITE FILE_PATH="coverage/hit$main.coverage" NAME="main Coverage Results" MODIFIED="1553393814749" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
|
||||||
|
</component>
|
||||||
|
<component name="FileEditorManager">
|
||||||
|
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/main.py">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="510">
|
||||||
|
<caret line="42" column="55" selection-start-line="42" selection-start-column="55" selection-end-line="42" selection-end-column="55" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#10#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/settings.json">
|
||||||
|
<provider selected="true" editor-type-id="text-editor" />
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="true">
|
||||||
|
<entry file="file://$PROJECT_DIR$/leds.py">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="518">
|
||||||
|
<caret line="85" column="60" selection-start-line="85" selection-start-column="40" selection-end-line="85" selection-end-column="60" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#14#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
</leaf>
|
||||||
|
</component>
|
||||||
|
<component name="FileTemplateManagerImpl">
|
||||||
|
<option name="RECENT_TEMPLATES">
|
||||||
|
<list>
|
||||||
|
<option value="Python Script" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="FindInProjectRecents">
|
||||||
|
<findStrings>
|
||||||
|
<find>Swithc</find>
|
||||||
|
<find>Qtech</find>
|
||||||
|
</findStrings>
|
||||||
|
</component>
|
||||||
|
<component name="IdeDocumentHistory">
|
||||||
|
<option name="CHANGED_PATHS">
|
||||||
|
<list>
|
||||||
|
<option value="$PROJECT_DIR$/leds.py" />
|
||||||
|
<option value="$PROJECT_DIR$/main.py" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectFrameBounds" extendedState="6">
|
||||||
|
<option name="x" value="1992" />
|
||||||
|
<option name="width" value="1272" />
|
||||||
|
<option name="height" value="700" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectView">
|
||||||
|
<navigator proportions="" version="1">
|
||||||
|
<foldersAlwaysOnTop value="true" />
|
||||||
|
</navigator>
|
||||||
|
<panes>
|
||||||
|
<pane id="ProjectPane">
|
||||||
|
<subPane>
|
||||||
|
<expand>
|
||||||
|
<path>
|
||||||
|
<item name="hit" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="hit" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
|
</expand>
|
||||||
|
<select />
|
||||||
|
</subPane>
|
||||||
|
</pane>
|
||||||
|
<pane id="Scope" />
|
||||||
|
</panes>
|
||||||
|
</component>
|
||||||
|
<component name="PropertiesComponent">
|
||||||
|
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||||
|
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
||||||
|
<property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
|
||||||
|
<property name="nodejs_npm_path_reset_for_default_project" value="true" />
|
||||||
|
<property name="settings.editor.selected.configurable" value="com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable" />
|
||||||
|
</component>
|
||||||
|
<component name="RecentsManager">
|
||||||
|
<key name="CopyFile.RECENT_KEYS">
|
||||||
|
<recent name="$PROJECT_DIR$" />
|
||||||
|
</key>
|
||||||
|
</component>
|
||||||
|
<component name="RunDashboard">
|
||||||
|
<option name="ruleStates">
|
||||||
|
<list>
|
||||||
|
<RuleState>
|
||||||
|
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
|
||||||
|
</RuleState>
|
||||||
|
<RuleState>
|
||||||
|
<option name="name" value="StatusDashboardGroupingRule" />
|
||||||
|
</RuleState>
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="RunManager" selected="Python.main">
|
||||||
|
<configuration name="leds" type="PythonConfigurationType" factoryName="Python" temporary="true">
|
||||||
|
<module name="hit" />
|
||||||
|
<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$/leds.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>
|
||||||
|
<configuration name="main" type="PythonConfigurationType" factoryName="Python">
|
||||||
|
<module name="hit" />
|
||||||
|
<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$/main.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>
|
||||||
|
<list>
|
||||||
|
<item itemvalue="Python.main" />
|
||||||
|
<item itemvalue="Python.leds" />
|
||||||
|
</list>
|
||||||
|
<recent_temporary>
|
||||||
|
<list>
|
||||||
|
<item itemvalue="Python.leds" />
|
||||||
|
</list>
|
||||||
|
</recent_temporary>
|
||||||
|
</component>
|
||||||
|
<component name="SvnConfiguration">
|
||||||
|
<configuration />
|
||||||
|
</component>
|
||||||
|
<component name="TaskManager">
|
||||||
|
<task active="true" id="Default" summary="Default task">
|
||||||
|
<changelist id="74089eaa-e081-4df7-9c12-fd404f4aba9c" name="Default Changelist" comment="" />
|
||||||
|
<created>1553146393337</created>
|
||||||
|
<option name="number" value="Default" />
|
||||||
|
<option name="presentableId" value="Default" />
|
||||||
|
<updated>1553146393337</updated>
|
||||||
|
<workItem from="1553146396302" duration="955000" />
|
||||||
|
<workItem from="1553192418554" duration="36000" />
|
||||||
|
<workItem from="1553208814453" duration="7000" />
|
||||||
|
<workItem from="1553291403133" duration="660000" />
|
||||||
|
<workItem from="1553299189331" duration="12875000" />
|
||||||
|
<workItem from="1553314603230" duration="697000" />
|
||||||
|
<workItem from="1553315321224" duration="5682000" />
|
||||||
|
<workItem from="1553393747744" duration="683000" />
|
||||||
|
<workItem from="1553395471155" duration="986000" />
|
||||||
|
<workItem from="1553475449472" duration="47000" />
|
||||||
|
<workItem from="1554003982369" duration="4238000" />
|
||||||
|
<workItem from="1555360955184" duration="611000" />
|
||||||
|
<workItem from="1555370200529" duration="667000" />
|
||||||
|
<workItem from="1556855475859" duration="72000" />
|
||||||
|
</task>
|
||||||
|
<servers />
|
||||||
|
</component>
|
||||||
|
<component name="TimeTrackingManager">
|
||||||
|
<option name="totallyTimeSpent" value="28216000" />
|
||||||
|
</component>
|
||||||
|
<component name="ToolWindowManager">
|
||||||
|
<frame x="1356" y="0" width="1928" height="1060" extended-state="6" />
|
||||||
|
<editor active="true" />
|
||||||
|
<layout>
|
||||||
|
<window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.2886873" />
|
||||||
|
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
|
||||||
|
<window_info id="Favorites" order="2" side_tool="true" />
|
||||||
|
<window_info anchor="bottom" id="Message" order="0" />
|
||||||
|
<window_info anchor="bottom" id="Find" order="1" />
|
||||||
|
<window_info anchor="bottom" id="Run" order="2" weight="0.32903227" />
|
||||||
|
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
|
||||||
|
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
|
||||||
|
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||||
|
<window_info anchor="bottom" id="TODO" order="6" />
|
||||||
|
<window_info anchor="bottom" id="Docker" order="7" show_stripe_button="false" />
|
||||||
|
<window_info anchor="bottom" id="Version Control" order="8" />
|
||||||
|
<window_info anchor="bottom" id="Database Changes" order="9" />
|
||||||
|
<window_info anchor="bottom" id="Event Log" order="10" side_tool="true" />
|
||||||
|
<window_info anchor="bottom" id="Terminal" order="11" />
|
||||||
|
<window_info anchor="bottom" id="Python Console" order="12" />
|
||||||
|
<window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
|
||||||
|
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
|
||||||
|
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
|
||||||
|
<window_info anchor="right" id="SciView" order="3" />
|
||||||
|
<window_info anchor="right" id="Database" order="4" />
|
||||||
|
</layout>
|
||||||
|
</component>
|
||||||
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
|
<option name="version" value="1" />
|
||||||
|
</component>
|
||||||
|
<component name="editorHistoryManager">
|
||||||
|
<entry file="file://$PROJECT_DIR$/venv/lib/python3.6/site-packages/paho/mqtt/client.py">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="190">
|
||||||
|
<caret line="1577" selection-start-line="1577" selection-end-line="1577" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/hit.ui">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="390">
|
||||||
|
<caret line="26" column="10" selection-start-line="26" selection-start-column="10" selection-end-line="26" selection-end-column="10" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/main.py">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="510">
|
||||||
|
<caret line="42" column="55" selection-start-line="42" selection-start-column="55" selection-end-line="42" selection-end-column="55" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#10#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/settings.json">
|
||||||
|
<provider selected="true" editor-type-id="text-editor" />
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/leds.py">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="518">
|
||||||
|
<caret line="85" column="60" selection-start-line="85" selection-start-column="40" selection-end-line="85" selection-end-column="60" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#0#14#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</component>
|
||||||
|
</project>
|
BIN
__pycache__/agpib.cpython-310.pyc
Normal file
BIN
__pycache__/agpib.cpython-310.pyc
Normal file
Binary file not shown.
BIN
__pycache__/arduino.cpython-310.pyc
Normal file
BIN
__pycache__/arduino.cpython-310.pyc
Normal file
Binary file not shown.
168
agpib.py
Normal file
168
agpib.py
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright 2012,2013 Thibault VINCENT <tibal@reloaded.fr>
|
||||||
|
#
|
||||||
|
# This file is part of Agpib.
|
||||||
|
#
|
||||||
|
# Agpib is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Agpib is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Agpib. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
import re
|
||||||
|
from arduino import Arduino, ArduinoError
|
||||||
|
|
||||||
|
class AgpibError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Agpib(Arduino):
|
||||||
|
CMD_OUT = {
|
||||||
|
'PING' : 0x00,
|
||||||
|
'STATUS' : 0x01,
|
||||||
|
'INIT' : 0x02,
|
||||||
|
'LOCKREAD' : 0x03,
|
||||||
|
'CONTROLLER': 0x04,
|
||||||
|
'REMOTE' : 0x05,
|
||||||
|
'TALKER' : 0x06,
|
||||||
|
'LISTENER' : 0x07,
|
||||||
|
'UNLISTEN' : 0x08,
|
||||||
|
'UNTALK' : 0x09,
|
||||||
|
'LOCKOUT' : 0x0a,
|
||||||
|
'CLEAR' : 0x0b,
|
||||||
|
'UNLOCK' : 0x0c,
|
||||||
|
'TRIGGER' : 0x0d,
|
||||||
|
'READ' : 0x0e,
|
||||||
|
'WRITE' : 0x0f,
|
||||||
|
'CMD' : 0x10,
|
||||||
|
'ENGAGE_REQ': 0x11,
|
||||||
|
}
|
||||||
|
CMD_IN = {
|
||||||
|
'PONG' : 0x00,
|
||||||
|
'CHUNK' : 0x01,
|
||||||
|
'STRING' : 0x02,
|
||||||
|
'REQUEST' : 0x03,
|
||||||
|
}
|
||||||
|
FLAGS = {
|
||||||
|
'BOOLEAN' : 0x1,
|
||||||
|
}
|
||||||
|
|
||||||
|
def interface_ping(self):
|
||||||
|
self._write_command('PING')
|
||||||
|
try:
|
||||||
|
resp = self._read_command(timeout=1)
|
||||||
|
except ArduinoError:
|
||||||
|
return False
|
||||||
|
return resp[0] == 'PONG'
|
||||||
|
|
||||||
|
def status(self):
|
||||||
|
self._write_command('STATUS')
|
||||||
|
resp = self._read_command()
|
||||||
|
if resp[0] != 'STRING':
|
||||||
|
raise AgpibError('not getting a string in response of'
|
||||||
|
' bus status error but: %s' % resp[0])
|
||||||
|
pattern = '^E(\d)D(\d)N(\d)n(\d)I(\d)S(\d)A(\d)R(\d)(\d{8})$'
|
||||||
|
labels = ('EOI', 'DAV', 'NRFD', 'NDAC', 'IFC', 'SRQ', 'ATN',
|
||||||
|
'REN', 'DIO')
|
||||||
|
match = re.match(pattern, self._read_line().decode('UTF-8'))
|
||||||
|
return dict(list(zip(labels, match.groups())))
|
||||||
|
|
||||||
|
def init(self, address=0x00, controller=True):
|
||||||
|
self._write_command('INIT')
|
||||||
|
self._write(chr(address))
|
||||||
|
self._address = address
|
||||||
|
if controller:
|
||||||
|
self._write_command('CONTROLLER')
|
||||||
|
|
||||||
|
def lock_read(self, state):
|
||||||
|
flags = ['BOOLEAN'] if state else []
|
||||||
|
self._write_command('LOCKREAD', flags=flags)
|
||||||
|
|
||||||
|
def remote(self, state):
|
||||||
|
flags = ['BOOLEAN'] if state else []
|
||||||
|
self._write_command('REMOTE', flags=flags)
|
||||||
|
|
||||||
|
def talker(self, address):
|
||||||
|
self._write_command('TALKER')
|
||||||
|
self._write(chr(address & 0x1f))
|
||||||
|
|
||||||
|
def listener(self, address):
|
||||||
|
self._write_command('LISTENER')
|
||||||
|
self._write(chr(address & 0x1f))
|
||||||
|
|
||||||
|
def untalk(self):
|
||||||
|
self._write_command('UNTALK')
|
||||||
|
|
||||||
|
def unlisten(self):
|
||||||
|
self._write_command('UNLISTEN')
|
||||||
|
|
||||||
|
def lockout(self):
|
||||||
|
self._write_command('LOCKOUT')
|
||||||
|
|
||||||
|
def clear(self, bus=False):
|
||||||
|
flags = ['BOOLEAN'] if bus else []
|
||||||
|
self._write_command('CLEAR', flags=flags)
|
||||||
|
|
||||||
|
def unlock(self):
|
||||||
|
self._write_command('UNLOCK')
|
||||||
|
|
||||||
|
def trigger(self):
|
||||||
|
self._write_command('TRIGGER')
|
||||||
|
|
||||||
|
def read(self):
|
||||||
|
data = b''
|
||||||
|
# send initial read command
|
||||||
|
self._write_command('READ')
|
||||||
|
resp = self._read_command()
|
||||||
|
# strings are processed at once
|
||||||
|
if resp[0] == 'STRING':
|
||||||
|
data = self._read_line()
|
||||||
|
# chunked streams iteration
|
||||||
|
elif resp[0] == 'CHUNK':
|
||||||
|
while True:
|
||||||
|
size = ord(self._read())
|
||||||
|
data += self._read(size=size)
|
||||||
|
# transmission is over
|
||||||
|
if 'BOOLEAN' in resp[1]:
|
||||||
|
break
|
||||||
|
# ask for a new chunk
|
||||||
|
self._write_command('READ')
|
||||||
|
resp = self._read_command()
|
||||||
|
if resp[0] != 'CHUNK':
|
||||||
|
raise AgpibError('chunk stream interrupted by'
|
||||||
|
' command: %s' % resp[0])
|
||||||
|
else:
|
||||||
|
raise AgpibError('expected to get a data transfert but'
|
||||||
|
' received command: %s' % resp[0])
|
||||||
|
return data
|
||||||
|
|
||||||
|
def write(self, data):
|
||||||
|
for offset in range(0, len(data), 255):
|
||||||
|
size = min(255, len(data) - offset)
|
||||||
|
if size == 255:
|
||||||
|
self._write_command('WRITE')
|
||||||
|
else:
|
||||||
|
self._write_command('WRITE', flags=['BOOLEAN'])
|
||||||
|
self._write(chr(size))
|
||||||
|
self._write(data[offset : offset + size])
|
||||||
|
|
||||||
|
def output(self, address):
|
||||||
|
self.untalk()
|
||||||
|
self.unlisten()
|
||||||
|
self.talker(self._address)
|
||||||
|
self.listener(address)
|
||||||
|
|
||||||
|
def enter(self, address):
|
||||||
|
self.untalk()
|
||||||
|
self.unlisten()
|
||||||
|
self.talker(address)
|
||||||
|
self.listener(self._address)
|
||||||
|
|
117
arduino.py
Normal file
117
arduino.py
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright 2012,2013 Thibault VINCENT <tibal@reloaded.fr>
|
||||||
|
#
|
||||||
|
# This file is part of Agipibi.
|
||||||
|
#
|
||||||
|
# Agipibi is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Agipibi is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Agipibi. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
import serial
|
||||||
|
|
||||||
|
class ArduinoError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Arduino(object):
|
||||||
|
CMD_OUT = {}
|
||||||
|
CMD_IN = {}
|
||||||
|
FLAGS = {}
|
||||||
|
|
||||||
|
def __init__(self, device=None, debug=False):
|
||||||
|
if not device:
|
||||||
|
raise ArduinoError('No device specified')
|
||||||
|
self._arduino = serial.Serial(port=device, baudrate=115200)
|
||||||
|
self._debug = debug
|
||||||
|
|
||||||
|
def _read(self, size=1, timeout=None):
|
||||||
|
if timeout is not None:
|
||||||
|
self._arduino.timeout = timeout
|
||||||
|
|
||||||
|
received = self._arduino.read(size=size)
|
||||||
|
if self._debug:
|
||||||
|
print('R', ' '.join('{0:x}'.format(c) for c in received))
|
||||||
|
|
||||||
|
if timeout is not None:
|
||||||
|
self._arduino.timeout = None
|
||||||
|
|
||||||
|
if len(received) != size:
|
||||||
|
raise ArduinoError('received less bytes than expected'
|
||||||
|
' from Arduino: %d/%d' % (len(received), size))
|
||||||
|
|
||||||
|
return received
|
||||||
|
|
||||||
|
def _read_command(self, timeout=None):
|
||||||
|
byte = self._read(timeout=timeout)[0]
|
||||||
|
b_command = byte & 0x3f
|
||||||
|
b_flags = (byte & 0x60) >> 6
|
||||||
|
|
||||||
|
command = None
|
||||||
|
flags = []
|
||||||
|
|
||||||
|
for c_name, c_value in self.CMD_IN.items():
|
||||||
|
if b_command == c_value:
|
||||||
|
command = c_name
|
||||||
|
break
|
||||||
|
if command is None:
|
||||||
|
raise ArduinoError('received an unknown command from'
|
||||||
|
' Arduino: %x' % b_command)
|
||||||
|
|
||||||
|
flags_sum = 0
|
||||||
|
for f_name, f_value in self.FLAGS.items():
|
||||||
|
if b_flags & f_value:
|
||||||
|
flags.append(f_name)
|
||||||
|
flags_sum |= f_value
|
||||||
|
if b_flags != flags_sum:
|
||||||
|
raise ArduinoError('received an unknown flag bit: %x' % b_flags)
|
||||||
|
|
||||||
|
return (command, flags)
|
||||||
|
|
||||||
|
def _read_line(self, timeout=None):
|
||||||
|
line = b''
|
||||||
|
|
||||||
|
while True:
|
||||||
|
char = self._read(timeout=timeout)
|
||||||
|
if char == b'\n':
|
||||||
|
break
|
||||||
|
elif char != b'\r':
|
||||||
|
line += char
|
||||||
|
|
||||||
|
return line
|
||||||
|
|
||||||
|
def _write(self, data):
|
||||||
|
try:
|
||||||
|
if self._debug:
|
||||||
|
print('T', ' '.join('{0:x}'.format(ord(c)) for c in data))
|
||||||
|
written = self._arduino.write(data.encode('UTF-8'))
|
||||||
|
except serial.SerialTimeoutException as err:
|
||||||
|
raise ArduinoError('timeout while sending bytes: %s' % err)
|
||||||
|
|
||||||
|
if written != len(data):
|
||||||
|
raise ArduinoError('sent less bytes than expected to'
|
||||||
|
' Arduino: %d/%d' % (len(written), len(data)))
|
||||||
|
|
||||||
|
def _write_command(self, command, flags=None):
|
||||||
|
if command not in self.CMD_OUT:
|
||||||
|
raise ArduinoError('not sending invalid command: %s' % command)
|
||||||
|
|
||||||
|
flags_value = 0
|
||||||
|
if flags is not None:
|
||||||
|
for flag in flags:
|
||||||
|
if flag in self.FLAGS:
|
||||||
|
flags_value |= self.FLAGS[flag]
|
||||||
|
else:
|
||||||
|
raise ArduinoError('unknown flag: %s' % flag)
|
||||||
|
|
||||||
|
byte = ((self.CMD_OUT[command] & 0x3f) + (flags_value << 6)) & 0xff
|
||||||
|
self._write(chr(byte))
|
263
main.py
Normal file
263
main.py
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
import sys
|
||||||
|
import math
|
||||||
|
import json
|
||||||
|
import random
|
||||||
|
import time
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
from PyQt5.QtWidgets import QApplication, QWidget, QDialog, QMessageBox
|
||||||
|
from PyQt5.QtGui import QPalette, QColor
|
||||||
|
from PyQt5.uic import loadUi
|
||||||
|
from PyQt5.QtChart import QChart, QLineSeries, QChartView
|
||||||
|
|
||||||
|
from agpib import Agpib
|
||||||
|
|
||||||
|
|
||||||
|
class Main(QWidget):
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
QWidget.__init__(self, parent)
|
||||||
|
|
||||||
|
self._ui = loadUi('main.ui')
|
||||||
|
self._ui.show()
|
||||||
|
|
||||||
|
# self.settings = QDialog()
|
||||||
|
# loadUi('./settings._ui', self.settings)
|
||||||
|
|
||||||
|
self._v_set = 0
|
||||||
|
self._i_set = 0
|
||||||
|
|
||||||
|
self._config = {}
|
||||||
|
self._gpib = None
|
||||||
|
self._chart = None
|
||||||
|
|
||||||
|
self.load_settings()
|
||||||
|
|
||||||
|
self.init_gpib()
|
||||||
|
self.init_chart()
|
||||||
|
|
||||||
|
def closeEvent(self, event):
|
||||||
|
self.save_settings()
|
||||||
|
self.deleteLater()
|
||||||
|
|
||||||
|
def init_gpib(self):
|
||||||
|
self._gpib = Agpib('/dev/ttyACM0')
|
||||||
|
if not self._gpib.interface_ping():
|
||||||
|
print('Failed to connect to gateway')
|
||||||
|
exit()
|
||||||
|
self._gpib.init()
|
||||||
|
self._gpib.remote(True)
|
||||||
|
self._gpib.output(3)
|
||||||
|
|
||||||
|
def init_chart(self):
|
||||||
|
self._chart = QChart()
|
||||||
|
self._chart.setTitle('Test')
|
||||||
|
|
||||||
|
self._ui.chart.setMouseTracking(True)
|
||||||
|
self._ui.chart.setInteractive(True)
|
||||||
|
self._ui.chart.setChart(self._chart)
|
||||||
|
self._ui.chart.setRubberBand(QChartView.RectangleRubberBand)
|
||||||
|
|
||||||
|
def _cmd(self, mode, v, i):
|
||||||
|
self._v_set = v
|
||||||
|
self._i_set = i
|
||||||
|
self._gpib.output(3)
|
||||||
|
self._gpib.write(f'M{mode} P{v}V C{i}A G')
|
||||||
|
|
||||||
|
def read_vm(self):
|
||||||
|
self._gpib.output(3)
|
||||||
|
self._gpib.write(f'T')
|
||||||
|
self._gpib.enter(3)
|
||||||
|
res = self._gpib.read()
|
||||||
|
res = res.decode('UTF-8')
|
||||||
|
|
||||||
|
status = res[0]
|
||||||
|
v_a = res[1]
|
||||||
|
val = float(res[2:7])
|
||||||
|
|
||||||
|
v = 0
|
||||||
|
a = 0
|
||||||
|
|
||||||
|
if v_a == 'V':
|
||||||
|
i = self._i_set
|
||||||
|
v = val
|
||||||
|
else:
|
||||||
|
i = val
|
||||||
|
v = self._v_set
|
||||||
|
|
||||||
|
return status, v, i
|
||||||
|
|
||||||
|
def perform_experiment(self):
|
||||||
|
v_series = QLineSeries()
|
||||||
|
i_series = QLineSeries()
|
||||||
|
v_series.setName('V')
|
||||||
|
i_series.setName('I')
|
||||||
|
self._chart.addSeries(v_series)
|
||||||
|
self._chart.addSeries(i_series)
|
||||||
|
self._chart.createDefaultAxes()
|
||||||
|
|
||||||
|
start_time = time.time()
|
||||||
|
|
||||||
|
v_axis_x = self._chart.axisX(v_series)
|
||||||
|
v_axis_y = self._chart.axisY(v_series)
|
||||||
|
i_axis_x = self._chart.axisX(i_series)
|
||||||
|
i_axis_y = self._chart.axisY(i_series)
|
||||||
|
v_minx = 1000
|
||||||
|
v_miny = 1000
|
||||||
|
v_maxx = -1000
|
||||||
|
v_maxy = -1000
|
||||||
|
i_minx = 1000
|
||||||
|
i_miny = 1000
|
||||||
|
i_maxx = -1000
|
||||||
|
i_maxy = -1000
|
||||||
|
|
||||||
|
v_avg = 0
|
||||||
|
i_avg = 0
|
||||||
|
|
||||||
|
print('Performing experiment')
|
||||||
|
cmds = np.linspace(self._ui.start.value(), self._ui.end.value(), self._ui.steps.value())
|
||||||
|
for cmd in cmds:
|
||||||
|
mode = None
|
||||||
|
if self._ui.mode.currentIndex() == 0:
|
||||||
|
mode = 1 # CV
|
||||||
|
else:
|
||||||
|
mode = 2 # CC
|
||||||
|
|
||||||
|
v_cmd = None
|
||||||
|
i_cmd = None
|
||||||
|
if self._ui.control_variable.currentIndex() == 0:
|
||||||
|
v_cmd = cmd
|
||||||
|
i_cmd = self._ui.other_variable.value()
|
||||||
|
else:
|
||||||
|
v_cmd = self._ui.other_variable.value()
|
||||||
|
i_cmd = cmd
|
||||||
|
|
||||||
|
self._cmd(mode, v_cmd, i_cmd)
|
||||||
|
time.sleep(self._ui.settle_time.value())
|
||||||
|
for _ in range(self._ui.samples.value()):
|
||||||
|
status, v, i = self.read_vm()
|
||||||
|
print(v, i)
|
||||||
|
|
||||||
|
x = time.time() - start_time
|
||||||
|
v_avg = (v_avg + v) / 2
|
||||||
|
i_avg = (i_avg + i) / 2
|
||||||
|
v_y = v_avg
|
||||||
|
i_y = i_avg
|
||||||
|
|
||||||
|
|
||||||
|
v_minx = min(v_minx, x)
|
||||||
|
v_maxx = max(v_maxx, x)
|
||||||
|
v_miny = min(v_miny, v_y)
|
||||||
|
v_maxy = max(v_maxy, v_y)
|
||||||
|
i_minx = min(i_minx, x)
|
||||||
|
i_maxx = max(i_maxx, x)
|
||||||
|
i_miny = min(i_miny, i_y)
|
||||||
|
i_maxy = max(i_maxy, i_y)
|
||||||
|
v_series.append(x, v_y)
|
||||||
|
i_series.append(x, i_y)
|
||||||
|
|
||||||
|
time.sleep(self._ui.sample_time.value())
|
||||||
|
print('Done experiment')
|
||||||
|
self._cmd(1, 0, 0)
|
||||||
|
|
||||||
|
v_axis_x.setMin(v_minx)
|
||||||
|
v_axis_x.setMax(v_maxx)
|
||||||
|
v_axis_y.setMin(v_miny)
|
||||||
|
v_axis_y.setMax(v_maxy)
|
||||||
|
i_axis_x.setMin(i_minx)
|
||||||
|
i_axis_x.setMax(i_maxx)
|
||||||
|
i_axis_y.setMin(i_miny)
|
||||||
|
i_axis_y.setMax(i_maxy)
|
||||||
|
|
||||||
|
def init_connections(self):
|
||||||
|
#############
|
||||||
|
# LED TAB #
|
||||||
|
#############
|
||||||
|
self._ui.perform.clicked.connect(self.perform_experiment)
|
||||||
|
# Light switch and mode
|
||||||
|
#self._ui.leds_enable.stateChanged.connect(self.enable_toggled)
|
||||||
|
#self._ui.leds_mode.currentIndexChanged.connect(self.leds.set_effect)
|
||||||
|
|
||||||
|
# RGB sliders
|
||||||
|
#self._ui.leds_r.sliderReleased.connect(self.color_changed)
|
||||||
|
#self._ui.leds_g.sliderReleased.connect(self.color_changed)
|
||||||
|
#self._ui.leds_b.sliderReleased.connect(self.color_changed)
|
||||||
|
|
||||||
|
#self._ui.leds_r_b.editingFinished.connect(self.color_changed)
|
||||||
|
#self._ui.leds_g_b.editingFinished.connect(self.color_changed)
|
||||||
|
#self._ui.leds_b_b.editingFinished.connect(self.color_changed)
|
||||||
|
|
||||||
|
# Brightness and speed
|
||||||
|
#self._ui.leds_brightness.sliderReleased.connect(self.brightness_changed)
|
||||||
|
#self._ui.leds_speed.sliderReleased.connect(self.speed_changed)
|
||||||
|
|
||||||
|
#####################
|
||||||
|
# SETTINGS DIALOG #
|
||||||
|
#####################
|
||||||
|
#self._ui.show_settings.clicked.connect(self.show_settings)
|
||||||
|
pass
|
||||||
|
|
||||||
|
#############
|
||||||
|
# LED TAB #
|
||||||
|
#############
|
||||||
|
def enable_toggled(self, state):
|
||||||
|
self.leds.set_effect(1 if state else 0)
|
||||||
|
|
||||||
|
def color_changed(self):
|
||||||
|
self.leds.set_effect(1)
|
||||||
|
self.leds.set_color(self._ui.leds_r.value(), self._ui.leds_g.value(), self._ui.leds_b.value())
|
||||||
|
|
||||||
|
def brightness_changed(self):
|
||||||
|
self.leds.set_brightness(self._ui.leds_brightness.value())
|
||||||
|
|
||||||
|
def speed_changed(self):
|
||||||
|
self.leds.set_speed(self._ui.leds_speed.value())
|
||||||
|
|
||||||
|
#############
|
||||||
|
# SETTINGS #
|
||||||
|
#############
|
||||||
|
def show_settings(self):
|
||||||
|
self.settings.show()
|
||||||
|
|
||||||
|
def save_settings(self):
|
||||||
|
with open('settings.json', 'w') as f:
|
||||||
|
self._config['mode'] = self._ui.mode.currentIndex()
|
||||||
|
self._config['control_variable'] = self._ui.control_variable.currentIndex()
|
||||||
|
self._config['other_variable'] = self._ui.other_variable.value()
|
||||||
|
self._config['start'] = self._ui.start.value()
|
||||||
|
self._config['end'] = self._ui.end.value()
|
||||||
|
self._config['steps'] = self._ui.steps.value()
|
||||||
|
|
||||||
|
self._config['settle_time'] = self._ui.settle_time.value()
|
||||||
|
self._config['samples'] = self._ui.samples.value()
|
||||||
|
self._config['sample_time'] = self._ui.sample_time.value()
|
||||||
|
|
||||||
|
json.dump(self._config, f)
|
||||||
|
|
||||||
|
def load_settings(self):
|
||||||
|
with open('settings.json', 'r') as f:
|
||||||
|
self._config = json.load(f)
|
||||||
|
|
||||||
|
self._ui.mode.setCurrentIndex(self._config['mode'])
|
||||||
|
self._ui.control_variable.setCurrentIndex(self._config['control_variable'])
|
||||||
|
self._ui.other_variable.setValue(self._config['other_variable'])
|
||||||
|
self._ui.start.setValue(self._config['start'])
|
||||||
|
self._ui.end.setValue(self._config['end'])
|
||||||
|
self._ui.steps.setValue(self._config['steps'])
|
||||||
|
|
||||||
|
self._ui.settle_time.setValue(self._config['settle_time'])
|
||||||
|
self._ui.samples.setValue(self._config['samples'])
|
||||||
|
self._ui.sample_time.setValue(self._config['sample_time'])
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
app = QApplication(sys.argv)
|
||||||
|
|
||||||
|
main = Main()
|
||||||
|
main.init_connections()
|
||||||
|
|
||||||
|
r = app.exec()
|
||||||
|
main.closeEvent(None)
|
||||||
|
sys.exit(r)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
199
main.ui
Normal file
199
main.ui
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>879</width>
|
||||||
|
<height>617</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>MainWindow</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralwidget">
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0" rowspan="2">
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>GroupBox</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>Mode</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="mode">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>CV</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>CC</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>ERROR</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="other_variable"/>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>End</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="end"/>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Steps</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QSpinBox" name="steps"/>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0" colspan="2">
|
||||||
|
<widget class="Line" name="line">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Settle Time</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="settle_time"/>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="0">
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="text">
|
||||||
|
<string>Samples</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="1">
|
||||||
|
<widget class="QSpinBox" name="samples"/>
|
||||||
|
</item>
|
||||||
|
<item row="9" column="0">
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Sample Time</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="9" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="sample_time"/>
|
||||||
|
</item>
|
||||||
|
<item row="10" column="0">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="11" column="0" colspan="2">
|
||||||
|
<widget class="QPushButton" name="perform">
|
||||||
|
<property name="text">
|
||||||
|
<string>Perform</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_8">
|
||||||
|
<property name="text">
|
||||||
|
<string>Start</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="start"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_9">
|
||||||
|
<property name="text">
|
||||||
|
<string>Variable</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="control_variable">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Voltage</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Current</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1" rowspan="2">
|
||||||
|
<widget class="QChartView" name="chart" native="true"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenuBar" name="menubar">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>879</width>
|
||||||
|
<height>22</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>QChartView</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>PyQt5.QtChart</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
1
settings.json
Normal file
1
settings.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"mode": 1, "control_variable": 1, "other_variable": 60.0, "start": 0.0, "end": 5.0, "steps": 10, "settle_time": 0.25, "samples": 10, "sample_time": 0.0}
|
Loading…
Reference in a new issue