Browse Source

DATAQ SDK device configuration widget. Still requires channel configuration widget.

Neal Wilson 11 years ago
parent
commit
6ced403dde
3 changed files with 162 additions and 13 deletions
  1. 153
    2
      src/dataqsdk.w
  2. 9
    8
      src/typica.w
  3. 0
    3
      src/units.w

+ 153
- 2
src/dataqsdk.w View File

631
 	value.setProperty("newChannel", engine->newFunction(DataqSdkDevice_newChannel));
631
 	value.setProperty("newChannel", engine->newFunction(DataqSdkDevice_newChannel));
632
 }
632
 }
633
 
633
 
634
-@ The |newChannel()| wrapper requires two arguments.
634
+@ The |newChannel()| wrapper requires one argument to specify the measurement
635
+unit that will eventually be produced from that channel.
635
 
636
 
636
 @<Functions for scripting@>=
637
 @<Functions for scripting@>=
637
 QScriptValue DataqSdkDevice_newChannel(QScriptContext *context, QScriptEngine *engine)
638
 QScriptValue DataqSdkDevice_newChannel(QScriptContext *context, QScriptEngine *engine)
644
 		setChannelProperties(object, engine);
645
 		setChannelProperties(object, engine);
645
 	}
646
 	}
646
 	return object;
647
 	return object;
647
-}
648
+}
649
+
650
+@ In order to configure supported devices within Typica, a set of configuration
651
+controls is required. First there is the base device configuration widget.
652
+
653
+@<Class declarations@>=
654
+class DataqSdkDeviceConfWidget : public BasicDeviceConfigurationWidget
655
+{
656
+	Q_OBJECT
657
+	public:
658
+		Q_INVOKABLE DataqSdkDeviceConfWidget(DeviceTreeModel *model,
659
+		                                     const QModelIndex &index);
660
+	private slots:
661
+		void updateAutoSelect(bool automatic);
662
+		void updateDeviceNumber(int deviceNumber);
663
+		void updatePort(QString portId);
664
+		void addChannel();
665
+	private:
666
+		QStackedWidget *deviceIdStack;
667
+};
668
+
669
+@ The constructor sets up the interface for updating device configuration
670
+settings.
671
+
672
+@<DataqSdkDeviceConfWidget implementation@>=
673
+DataqSdkDeviceConfWidget::DataqSdkDeviceConfWidget(DeviceTreeModel *model,
674
+                                                   const QModelIndex &index)
675
+	: BasicDeviceConfigurationWidget(model, index),
676
+	deviceIdStack(new QStackedWidget)
677
+{
678
+	QVBoxLayout *layout = new QVBoxLayout;
679
+	QCheckBox *autoDetect = new QCheckBox("Automatically select device");
680
+	layout->addWidget(autoDetect);
681
+	QWidget *autoLayerWidget = new QWidget;
682
+	QHBoxLayout *autoLayerLayout = new QHBoxLayout;
683
+	QLabel *autoLabel = new QLabel(tr("Device number"));
684
+	QSpinBox *autoNumber = new QSpinBox;
685
+	autoNumber->setMinimum(1);
686
+	autoNumber->setMaximum(99);
687
+	autoLayerLayout->addWidget(autoLabel);
688
+	autoLayerLayout->addWidget(autoNumber);
689
+	autoLayerWidget->setLayout(autoLayerLayout);
690
+	QWidget *fixedLayerWidget = new QWidget;
691
+	QHBoxLayout *fixedLayerLayout = new QHBoxLayout;
692
+	QLabel *fixedLabel = new QLabel(tr("Device port"));
693
+	QComboBox *portSelection = new QComboBox;
694
+	portSelection->setEditable(true);
695
+	portSelection->addItems(DataqSdkDevice::detectHardware());
696
+	fixedLayerLayout->addWidget(fixedLabel);
697
+	fixedLayerLayout->addWidget(portSelection);
698
+	fixedLayerWidget->setLayout(fixedLayerLayout);
699
+	deviceIdStack->addWidget(autoLayerWidget);
700
+	deviceIdStack->addWidget(fixedLayerWidget);
701
+	layout->addWidget(deviceIdStack);
702
+	QPushButton *addChannelButton = new QPushButton(tr("Add Channel"));
703
+	layout->addWidget(addChannelButton);
704
+	@<Get device configuration data for current node@>@;
705
+	for(int i = 0; i < configData.size(); i++)
706
+	{
707
+		node = configData.at(i).toElement();
708
+		if(node.attribute("name") == "autoSelect")
709
+		{
710
+			autoDetect->setChecked(node.attribute("value") == "true" ? true : false);
711
+		}
712
+		else if(node.attribute("name") == "deviceNumber")
713
+		{
714
+			autoNumber->setValue(node.attribute("value").toInt());
715
+		}
716
+		else if(node.attribute("name") == "port")
717
+		{
718
+			int index = portSelection->findText(node.attribute("value"));
719
+			if(index > -1)
720
+			{
721
+				portSelection->setCurrentIndex(index);
722
+			}
723
+			else
724
+			{
725
+				portSelection->setEditText(node.attribute("value"));
726
+			}
727
+		}
728
+	}
729
+	updateAutoSelect(autoDetect->isChecked());
730
+	updateDeviceNumber(autoNumber->value());
731
+	updatePort(portSelection->currentText());
732
+	connect(autoDetect, SIGNAL(toggled(bool)), this, SLOT(updateAutoSelect(bool)));
733
+	connect(autoNumber, SIGNAL(valueChanged(int)), this, SLOT(updateDeviceNumber(int)));
734
+	connect(portSelection, SIGNAL(currentIndexChanged(QString)), this, SLOT(updatePort(QString)));
735
+	connect(addChannelButton, SIGNAL(clicked()), this, SLOT(addChannel()));
736
+	setLayout(layout);
737
+}
738
+
739
+@ In addition to setting a value in the device configuration, the choice to
740
+automatically select devices also requires changing which controls in the
741
+configuration widget are presently available. It is recommended that automatic
742
+device selection is only used in cases where there is a single device supported
743
+by the DATAQ SDK present and it will always be the first detected device
744
+regardless of the current virtual COM port number. In cases where multiple
745
+devices must be connected, it is recommended to always plug devices into the
746
+same port and specify the port for each device explicitly.
747
+
748
+@<DataqSdkDeviceConfWidget implementation@>=
749
+void DataqSdkDeviceConfWidget::updateAutoSelect(bool automatic)
750
+{
751
+	if(automatic)
752
+	{
753
+		updateAttribute("autoSelect", "true");
754
+		deviceIdStack->setCurrentIndex(0);
755
+	}
756
+	else
757
+	{
758
+		updateAttribute("autoSelect", "false");
759
+		deviceIdStack->setCurrentIndex(1);
760
+	}
761
+}
762
+
763
+@ Other update methods only need to set a new current value.
764
+
765
+@<DataqSdkDeviceConfWidget implementation@>=
766
+void DataqSdkDeviceConfWidget::updateDeviceNumber(int deviceNumber)
767
+{
768
+	updateAttribute("deviceNumber", QString("%1").arg(deviceNumber));
769
+}
770
+
771
+void DataqSdkDeviceConfWidget::updatePort(QString portId)
772
+{
773
+	updateAttribute("port", portId);
774
+}
775
+
776
+@ The Add Channel button creates a new configuration node.
777
+
778
+@<DataqSdkDeviceConfWidget implementation@>=
779
+void DataqSdkDeviceConfWidget::addChannel()
780
+{
781
+	insertChildNode(tr("Channel"), "dataqsdkchannel");
782
+}
783
+
784
+@ These configuration widgets are registered with the configuration system.
785
+
786
+@<Register device configuration widgets@>=
787
+app.registerDeviceConfigurationWidget("dataqsdk", DataqSdkDeviceConfWidget::staticMetaObject);
788
+
789
+@ A |NodeInserter| is also added to provide access to
790
+|DataqSdkDeviceConfWidget|, but only on Windows.
791
+
792
+@<Register top level device configuration nodes@>=
793
+#ifdef Q_OS_WIN32
794
+inserter = new NodeInserter(tr("DATAQ SDK Device"), tr("DATAQ Device"),
795
+                            "dataqsdk", NULL);
796
+topLevelNodeInserters.append(inserter);
797
+#endif
798
+

+ 9
- 8
src/typica.w View File

838
 @<RateOfChange implementation@>@/
838
 @<RateOfChange implementation@>@/
839
 @<SettingsWindow implementation@>@/
839
 @<SettingsWindow implementation@>@/
840
 @<GraphSettingsWidget implementation@>@/
840
 @<GraphSettingsWidget implementation@>@/
841
+@<DataqSdkDeviceConfWidget implementation@>@/
841
 
842
 
842
 @ A few headers are required for various parts of \pn{}. These allow the use of
843
 @ A few headers are required for various parts of \pn{}. These allow the use of
843
 various Qt modules.
844
 various Qt modules.
6402
 	return object;
6403
 	return object;
6403
 }
6404
 }
6404
 
6405
 
6405
-@i dataqsdk.w
6406
-
6407
 @ Sometimes it can be useful to test other parts of the program (for example,
6406
 @ Sometimes it can be useful to test other parts of the program (for example,
6408
 when developing new scripts) when the DAQ hardware is not available. In these
6407
 when developing new scripts) when the DAQ hardware is not available. In these
6409
 cases, it is possible to temporarily use the |FakeDAQ| class. This class mimics
6408
 cases, it is possible to temporarily use the |FakeDAQ| class. This class mimics
15119
 window that may vary from one machine to the next.
15118
 window that may vary from one machine to the next.
15120
 
15119
 
15121
 All of the configuration widgets follow a similar pattern. One important detail
15120
 All of the configuration widgets follow a similar pattern. One important detail
15122
-to note is that these configuration widgets are instantiated through Qt's
15121
+to note is that these configuration widgets are instantiated through Qt'@q'@>s
15123
 meta-object system. All of these constructors take a |DeviceTreeModel *| and a
15122
 meta-object system. All of these constructors take a |DeviceTreeModel *| and a
15124
 |QModelIndex &| as arguments and they are marked as |Q_INVOKABLE|.
15123
 |QModelIndex &| as arguments and they are marked as |Q_INVOKABLE|.
15125
 
15124
 
15243
 \noindent The primary concern in supporting hardware that communicates through
15242
 \noindent The primary concern in supporting hardware that communicates through
15244
 NI-DAQmx Base is in configurations using a single NI USB 9211 (for NI-DAQmx
15243
 NI-DAQmx Base is in configurations using a single NI USB 9211 (for NI-DAQmx
15245
 Base 2.x) or NI USB 9211A (for NI-DAQmx Base 3.x), but if it is reasonable to
15244
 Base 2.x) or NI USB 9211A (for NI-DAQmx Base 3.x), but if it is reasonable to
15246
-do so I'd like to later add support for multiple device configurations and
15245
+do so I'@q'@>d like to later add support for multiple device configurations and
15247
 limited support for other devices including the ability to use devices with
15246
 limited support for other devices including the ability to use devices with
15248
 voltage inputs for non-temperature measurement data. The top priority, however,
15247
 voltage inputs for non-temperature measurement data. The top priority, however,
15249
 is in continuing to support hardware that people are already using with Typica.
15248
 is in continuing to support hardware that people are already using with Typica.
15266
 		                                        const QModelIndex &index);
15265
 		                                        const QModelIndex &index);
15267
 };
15266
 };
15268
 
15267
 
15269
-@ There is very little to configure here so there isn't much for the
15268
+@ There is very little to configure here so there isn'@q'@>t much for the
15270
 constructor to do. We do need to keep a reference to the node we are
15269
 constructor to do. We do need to keep a reference to the node we are
15271
 configuring so that child nodes can later be added. At present, no real
15270
 configuring so that child nodes can later be added. At present, no real
15272
 configuration data other than the existence of the node is required so
15271
 configuration data other than the existence of the node is required so
15380
 device. Next is the thermocouple type. Many options are supported, but I would
15379
 device. Next is the thermocouple type. Many options are supported, but I would
15381
 like to ensure that the most commonly used choices are listed first. The other
15380
 like to ensure that the most commonly used choices are listed first. The other
15382
 piece of information that DAQmx or DAQmx Base require is the measurement unit.
15381
 piece of information that DAQmx or DAQmx Base require is the measurement unit.
15383
-As all of Typica's internal operations are in Fahrenheit there is no need to
15382
+As all of Typica'@q'@>s internal operations are in Fahrenheit there is no need to
15384
 make this configurable so long as everything else that can display temperature
15383
 make this configurable so long as everything else that can display temperature
15385
 measurements can perform the appropriate conversions.
15384
 measurements can perform the appropriate conversions.
15386
 
15385
 
16473
 
16472
 
16474
 @ Set values are slightly more complicated as we may want either a fixed range
16473
 @ Set values are slightly more complicated as we may want either a fixed range
16475
 or the ability to query the device for its current allowed range, but nothing
16474
 or the ability to query the device for its current allowed range, but nothing
16476
-is here that hasn't been seen elsewhere.
16475
+is here that hasn'@q'@>t been seen elsewhere.
16477
 
16476
 
16478
 @<Class declarations@>=
16477
 @<Class declarations@>=
16479
 class ModbusRtuDeviceTSvConfWidget : public BasicDeviceConfigurationWidget
16478
 class ModbusRtuDeviceTSvConfWidget : public BasicDeviceConfigurationWidget
18294
 }
18293
 }
18295
 
18294
 
18296
 @ To update the temperature at which to match we save both the values of the
18295
 @ To update the temperature at which to match we save both the values of the
18297
-two widgets which control this and the value in Fahrenheit so we don't need to
18296
+two widgets which control this and the value in Fahrenheit so we don'@q@'@>t need to
18298
 run unit conversions during view initialization.
18297
 run unit conversions during view initialization.
18299
 
18298
 
18300
 @<TranslationConfWidget implementation@>=
18299
 @<TranslationConfWidget implementation@>=
18324
 
18323
 
18325
 @i rate.w
18324
 @i rate.w
18326
 
18325
 
18326
+@i dataqsdk.w
18327
+
18327
 @** Local changes.
18328
 @** Local changes.
18328
 
18329
 
18329
 \noindent This is the end of \pn{} as distributed by its author. It is expected
18330
 \noindent This is the end of \pn{} as distributed by its author. It is expected

+ 0
- 3
src/units.w View File

35
 
35
 
36
 @(units.cpp@>=
36
 @(units.cpp@>=
37
 #include "units.h"
37
 #include "units.h"
38
-#ifndef Q_OS_WIN32
39
-#include "moc_units.cpp"
40
-#endif
41
 
38
 
42
 @ The |isTemperatureUnit()| method may seem counter-intuitive while the enum
39
 @ The |isTemperatureUnit()| method may seem counter-intuitive while the enum
43
 only contains represenations of temperature measurements, but there are plans
40
 only contains represenations of temperature measurements, but there are plans

Loading…
Cancel
Save