From 687c33ee637a68b5a0fe851ea9e1996abe18317f Mon Sep 17 00:00:00 2001 From: Chris Esposito Date: Fri, 20 Apr 2018 10:38:54 +1000 Subject: [PATCH] Convenience function for Sin wave added. Signal gen fixed. --- .../___librador/demo/librademo/mainwindow.cpp | 28 ++++- .../___librador/demo/librademo/mainwindow.h | 5 + .../___librador/demo/librademo/mainwindow.ui | 92 ++++++++++++++ .../demo/librademo/moc_mainwindow.cpp | 64 +++++----- .../demo/librademo/ui_mainwindow.h | 113 ++++++++++++++++++ .../___librador/librador/librador.cpp | 45 +++++++ .../___librador/librador/librador.h | 1 + .../___librador/librador/usbcallhandler.cpp | 10 +- .../___librador/librador/usbcallhandler.h | 2 +- 9 files changed, 326 insertions(+), 34 deletions(-) diff --git a/Matlab_Octave_API/___librador/demo/librademo/mainwindow.cpp b/Matlab_Octave_API/___librador/demo/librademo/mainwindow.cpp index 6804f213..4e20fb45 100644 --- a/Matlab_Octave_API/___librador/demo/librademo/mainwindow.cpp +++ b/Matlab_Octave_API/___librador/demo/librademo/mainwindow.cpp @@ -73,7 +73,7 @@ void MainWindow::on_pushButton_4_clicked() void MainWindow::on_pushButton_5_clicked() { - std::vector *from_librador = (librador_get_analog_data(current_channel, 0.5, 375000, 0.1, 0)); + std::vector *from_librador = (librador_get_analog_data(current_channel, 1, 375000, 0.1, 0)); if(from_librador == NULL){ qDebug() << "from_librador NULL!"; return; @@ -174,3 +174,29 @@ void MainWindow::on_comboBox_3_activated(int index) { current_channel = index + 1; } + +void MainWindow::signal_gen_convenience(int channel) +{ + double frequency_hz = ui->doubleSpinBox_frequency->value(); + double amplitude_v = ui->doubleSpinBox_amplitude->value(); + double offset_v = ui->doubleSpinBox_offset->value(); + + switch(ui->comboBox_signal_gen_type->currentIndex()){ + case 0: + librador_send_sin_wave(channel, frequency_hz, amplitude_v, offset_v); + break; + default: + qDebug() << "INVALID WAVEFORM"; + } + +} + +void MainWindow::on_pushButton_12_clicked() +{ + signal_gen_convenience(1); +} + +void MainWindow::on_pushButton_13_clicked() +{ + signal_gen_convenience(2); +} diff --git a/Matlab_Octave_API/___librador/demo/librademo/mainwindow.h b/Matlab_Octave_API/___librador/demo/librademo/mainwindow.h index ac42318a..7ce688d9 100644 --- a/Matlab_Octave_API/___librador/demo/librademo/mainwindow.h +++ b/Matlab_Octave_API/___librador/demo/librademo/mainwindow.h @@ -18,6 +18,7 @@ private: void initialisePlot(); double ymin = -20, ymax = 20; int current_channel = 1; + void signal_gen_convenience(int channel); private slots: void on_pushButton_clicked(); @@ -55,6 +56,10 @@ private slots: void on_comboBox_3_activated(int index); + void on_pushButton_12_clicked(); + + void on_pushButton_13_clicked(); + private: Ui::MainWindow *ui; }; diff --git a/Matlab_Octave_API/___librador/demo/librademo/mainwindow.ui b/Matlab_Octave_API/___librador/demo/librademo/mainwindow.ui index 39e5117e..03018ec5 100644 --- a/Matlab_Octave_API/___librador/demo/librademo/mainwindow.ui +++ b/Matlab_Octave_API/___librador/demo/librademo/mainwindow.ui @@ -288,6 +288,98 @@ + + + + + + + + Frequency (Hz) + + + + + + + + + + + + + + Amplitude (V) + + + + + + + 10.000000000000000 + + + + + + + + + + + Offset(V) + + + + + + + 10.000000000000000 + + + + + + + + + + + Type + + + + + + + + Sin + + + + + + + + + + + + Send CH1 + + + + + + + Send CH2 + + + + + + + diff --git a/Matlab_Octave_API/___librador/demo/librademo/moc_mainwindow.cpp b/Matlab_Octave_API/___librador/demo/librademo/moc_mainwindow.cpp index dca2957a..ff96912f 100644 --- a/Matlab_Octave_API/___librador/demo/librademo/moc_mainwindow.cpp +++ b/Matlab_Octave_API/___librador/demo/librademo/moc_mainwindow.cpp @@ -21,8 +21,8 @@ QT_BEGIN_MOC_NAMESPACE QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED struct qt_meta_stringdata_MainWindow_t { - QByteArrayData data[22]; - char stringdata0[463]; + QByteArrayData data[24]; + char stringdata0[513]; }; #define QT_MOC_LITERAL(idx, ofs, len) \ Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \ @@ -52,7 +52,9 @@ QT_MOC_LITERAL(17, 359, 5), // "index" QT_MOC_LITERAL(18, 365, 24), // "on_pushButton_10_clicked" QT_MOC_LITERAL(19, 390, 24), // "on_pushButton_11_clicked" QT_MOC_LITERAL(20, 415, 23), // "on_comboBox_2_activated" -QT_MOC_LITERAL(21, 439, 23) // "on_comboBox_3_activated" +QT_MOC_LITERAL(21, 439, 23), // "on_comboBox_3_activated" +QT_MOC_LITERAL(22, 463, 24), // "on_pushButton_12_clicked" +QT_MOC_LITERAL(23, 488, 24) // "on_pushButton_13_clicked" }, "MainWindow\0on_pushButton_clicked\0\0" @@ -67,7 +69,9 @@ QT_MOC_LITERAL(21, 439, 23) // "on_comboBox_3_activated" "on_comboBox_activated\0index\0" "on_pushButton_10_clicked\0" "on_pushButton_11_clicked\0" - "on_comboBox_2_activated\0on_comboBox_3_activated" + "on_comboBox_2_activated\0on_comboBox_3_activated\0" + "on_pushButton_12_clicked\0" + "on_pushButton_13_clicked" }; #undef QT_MOC_LITERAL @@ -77,7 +81,7 @@ static const uint qt_meta_data_MainWindow[] = { 7, // revision 0, // classname 0, 0, // classinfo - 18, 14, // methods + 20, 14, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors @@ -85,24 +89,26 @@ static const uint qt_meta_data_MainWindow[] = { 0, // signalCount // slots: name, argc, parameters, tag, flags - 1, 0, 104, 2, 0x08 /* Private */, - 3, 0, 105, 2, 0x08 /* Private */, - 4, 0, 106, 2, 0x08 /* Private */, - 5, 0, 107, 2, 0x08 /* Private */, - 6, 0, 108, 2, 0x08 /* Private */, - 7, 0, 109, 2, 0x08 /* Private */, - 8, 0, 110, 2, 0x08 /* Private */, - 9, 0, 111, 2, 0x08 /* Private */, - 10, 0, 112, 2, 0x08 /* Private */, - 11, 1, 113, 2, 0x08 /* Private */, - 13, 1, 116, 2, 0x08 /* Private */, - 14, 1, 119, 2, 0x08 /* Private */, - 15, 1, 122, 2, 0x08 /* Private */, - 16, 1, 125, 2, 0x08 /* Private */, - 18, 0, 128, 2, 0x08 /* Private */, - 19, 0, 129, 2, 0x08 /* Private */, - 20, 1, 130, 2, 0x08 /* Private */, - 21, 1, 133, 2, 0x08 /* Private */, + 1, 0, 114, 2, 0x08 /* Private */, + 3, 0, 115, 2, 0x08 /* Private */, + 4, 0, 116, 2, 0x08 /* Private */, + 5, 0, 117, 2, 0x08 /* Private */, + 6, 0, 118, 2, 0x08 /* Private */, + 7, 0, 119, 2, 0x08 /* Private */, + 8, 0, 120, 2, 0x08 /* Private */, + 9, 0, 121, 2, 0x08 /* Private */, + 10, 0, 122, 2, 0x08 /* Private */, + 11, 1, 123, 2, 0x08 /* Private */, + 13, 1, 126, 2, 0x08 /* Private */, + 14, 1, 129, 2, 0x08 /* Private */, + 15, 1, 132, 2, 0x08 /* Private */, + 16, 1, 135, 2, 0x08 /* Private */, + 18, 0, 138, 2, 0x08 /* Private */, + 19, 0, 139, 2, 0x08 /* Private */, + 20, 1, 140, 2, 0x08 /* Private */, + 21, 1, 143, 2, 0x08 /* Private */, + 22, 0, 146, 2, 0x08 /* Private */, + 23, 0, 147, 2, 0x08 /* Private */, // slots: parameters QMetaType::Void, @@ -123,6 +129,8 @@ static const uint qt_meta_data_MainWindow[] = { QMetaType::Void, QMetaType::Void, QMetaType::Int, 17, QMetaType::Void, QMetaType::Int, 17, + QMetaType::Void, + QMetaType::Void, 0 // eod }; @@ -151,6 +159,8 @@ void MainWindow::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, case 15: _t->on_pushButton_11_clicked(); break; case 16: _t->on_comboBox_2_activated((*reinterpret_cast< int(*)>(_a[1]))); break; case 17: _t->on_comboBox_3_activated((*reinterpret_cast< int(*)>(_a[1]))); break; + case 18: _t->on_pushButton_12_clicked(); break; + case 19: _t->on_pushButton_13_clicked(); break; default: ; } } @@ -181,13 +191,13 @@ int MainWindow::qt_metacall(QMetaObject::Call _c, int _id, void **_a) if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 18) + if (_id < 20) qt_static_metacall(this, _c, _id, _a); - _id -= 18; + _id -= 20; } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) { - if (_id < 18) + if (_id < 20) *reinterpret_cast(_a[0]) = -1; - _id -= 18; + _id -= 20; } return _id; } diff --git a/Matlab_Octave_API/___librador/demo/librademo/ui_mainwindow.h b/Matlab_Octave_API/___librador/demo/librademo/ui_mainwindow.h index 198c276f..c570bc64 100644 --- a/Matlab_Octave_API/___librador/demo/librademo/ui_mainwindow.h +++ b/Matlab_Octave_API/___librador/demo/librademo/ui_mainwindow.h @@ -64,6 +64,22 @@ public: QLabel *label_3; QComboBox *comboBox_3; QPushButton *pushButton_5; + QHBoxLayout *horizontalLayout_7; + QVBoxLayout *verticalLayout_3; + QLabel *label_4; + QDoubleSpinBox *doubleSpinBox_frequency; + QVBoxLayout *verticalLayout_5; + QLabel *label_6; + QDoubleSpinBox *doubleSpinBox_amplitude; + QVBoxLayout *verticalLayout_6; + QLabel *label_7; + QDoubleSpinBox *doubleSpinBox_offset; + QVBoxLayout *verticalLayout_4; + QLabel *label_5; + QComboBox *comboBox_signal_gen_type; + QVBoxLayout *verticalLayout_7; + QPushButton *pushButton_12; + QPushButton *pushButton_13; QCustomPlot *widget; QMenuBar *menuBar; QToolBar *mainToolBar; @@ -251,6 +267,95 @@ public: verticalLayout->addLayout(horizontalLayout_6); + horizontalLayout_7 = new QHBoxLayout(); + horizontalLayout_7->setSpacing(6); + horizontalLayout_7->setObjectName(QStringLiteral("horizontalLayout_7")); + verticalLayout_3 = new QVBoxLayout(); + verticalLayout_3->setSpacing(6); + verticalLayout_3->setObjectName(QStringLiteral("verticalLayout_3")); + label_4 = new QLabel(centralWidget); + label_4->setObjectName(QStringLiteral("label_4")); + + verticalLayout_3->addWidget(label_4); + + doubleSpinBox_frequency = new QDoubleSpinBox(centralWidget); + doubleSpinBox_frequency->setObjectName(QStringLiteral("doubleSpinBox_frequency")); + + verticalLayout_3->addWidget(doubleSpinBox_frequency); + + + horizontalLayout_7->addLayout(verticalLayout_3); + + verticalLayout_5 = new QVBoxLayout(); + verticalLayout_5->setSpacing(6); + verticalLayout_5->setObjectName(QStringLiteral("verticalLayout_5")); + label_6 = new QLabel(centralWidget); + label_6->setObjectName(QStringLiteral("label_6")); + + verticalLayout_5->addWidget(label_6); + + doubleSpinBox_amplitude = new QDoubleSpinBox(centralWidget); + doubleSpinBox_amplitude->setObjectName(QStringLiteral("doubleSpinBox_amplitude")); + doubleSpinBox_amplitude->setMaximum(10); + + verticalLayout_5->addWidget(doubleSpinBox_amplitude); + + + horizontalLayout_7->addLayout(verticalLayout_5); + + verticalLayout_6 = new QVBoxLayout(); + verticalLayout_6->setSpacing(6); + verticalLayout_6->setObjectName(QStringLiteral("verticalLayout_6")); + label_7 = new QLabel(centralWidget); + label_7->setObjectName(QStringLiteral("label_7")); + + verticalLayout_6->addWidget(label_7); + + doubleSpinBox_offset = new QDoubleSpinBox(centralWidget); + doubleSpinBox_offset->setObjectName(QStringLiteral("doubleSpinBox_offset")); + doubleSpinBox_offset->setMaximum(10); + + verticalLayout_6->addWidget(doubleSpinBox_offset); + + + horizontalLayout_7->addLayout(verticalLayout_6); + + verticalLayout_4 = new QVBoxLayout(); + verticalLayout_4->setSpacing(6); + verticalLayout_4->setObjectName(QStringLiteral("verticalLayout_4")); + label_5 = new QLabel(centralWidget); + label_5->setObjectName(QStringLiteral("label_5")); + + verticalLayout_4->addWidget(label_5); + + comboBox_signal_gen_type = new QComboBox(centralWidget); + comboBox_signal_gen_type->addItem(QString()); + comboBox_signal_gen_type->setObjectName(QStringLiteral("comboBox_signal_gen_type")); + + verticalLayout_4->addWidget(comboBox_signal_gen_type); + + + horizontalLayout_7->addLayout(verticalLayout_4); + + verticalLayout_7 = new QVBoxLayout(); + verticalLayout_7->setSpacing(6); + verticalLayout_7->setObjectName(QStringLiteral("verticalLayout_7")); + pushButton_12 = new QPushButton(centralWidget); + pushButton_12->setObjectName(QStringLiteral("pushButton_12")); + + verticalLayout_7->addWidget(pushButton_12); + + pushButton_13 = new QPushButton(centralWidget); + pushButton_13->setObjectName(QStringLiteral("pushButton_13")); + + verticalLayout_7->addWidget(pushButton_13); + + + horizontalLayout_7->addLayout(verticalLayout_7); + + + verticalLayout->addLayout(horizontalLayout_7); + horizontalLayout->addLayout(verticalLayout); @@ -319,6 +424,14 @@ public: comboBox_3->setItemText(1, QApplication::translate("MainWindow", "2", nullptr)); pushButton_5->setText(QApplication::translate("MainWindow", "Get Scope Data", nullptr)); + label_4->setText(QApplication::translate("MainWindow", "Frequency (Hz)", nullptr)); + label_6->setText(QApplication::translate("MainWindow", "Amplitude (V)", nullptr)); + label_7->setText(QApplication::translate("MainWindow", "Offset(V)", nullptr)); + label_5->setText(QApplication::translate("MainWindow", "Type", nullptr)); + comboBox_signal_gen_type->setItemText(0, QApplication::translate("MainWindow", "Sin", nullptr)); + + pushButton_12->setText(QApplication::translate("MainWindow", "Send CH1", nullptr)); + pushButton_13->setText(QApplication::translate("MainWindow", "Send CH2", nullptr)); } // retranslateUi }; diff --git a/Matlab_Octave_API/___librador/librador/librador.cpp b/Matlab_Octave_API/___librador/librador/librador.cpp index 446df271..c51a72be 100644 --- a/Matlab_Octave_API/___librador/librador/librador.cpp +++ b/Matlab_Octave_API/___librador/librador/librador.cpp @@ -4,6 +4,7 @@ #include #include +#include Librador::Librador() { @@ -137,3 +138,47 @@ uint8_t librador_get_device_firmware_variant(){ CHECK_API_INITIALISED return internal_librador_object->usb_driver->get_firmware_variant(); } + +int round_to_log2(double in){ + //Round down to the nearest power of 2. + return round(pow(2, floor(log2(in)))); +} + +int librador_send_sin_wave(int channel, double frequency_Hz, double amplitude_v, double offset_v){ + CHECK_API_INITIALISED + + if((amplitude_v + offset_v) > 9.6){ + return -1; + //Voltage range too high + } + if((amplitude_v < 0) | (offset_v < 0)){ + return -2; + //Negative voltage + } + + if((channel != 1) && (channel != 2)){ + return -3; + //Invalid channel + } + int num_samples = fmin(1000000.0/frequency_Hz, 512); + //The maximum number of samples that Labrador's buffer holds is 512. + //The minimum time between samples is 1us. Using T=1/f, this gives a maximum sample number of 10^6/f. + double usecs_between_samples = 1000000.0/((double)num_samples * frequency_Hz); + //Again, from T=1/f. + unsigned char* sampleBuffer = (unsigned char*)malloc(num_samples); + + int i; + double x_temp; + for(i=0; i< num_samples; i++){ + x_temp = (double)i * (2.0*M_PI/(double)num_samples); + //Generate points at interval 2*pi/num_samples. + sampleBuffer[i] = (unsigned char)round(255 * ((sin(x_temp)+1)/2)); + //Offset of 1 and divided by 2 shifts range from -1:1 to 0:1. Helpful for unsigned. + } + + librador_update_signal_gen_settings(channel, sampleBuffer, num_samples, usecs_between_samples, amplitude_v, offset_v); + librador_send_signal_gen_settings(channel); + + free(sampleBuffer); + return 0; +} diff --git a/Matlab_Octave_API/___librador/librador/librador.h b/Matlab_Octave_API/___librador/librador/librador.h index a7611425..9fe748ff 100644 --- a/Matlab_Octave_API/___librador/librador/librador.h +++ b/Matlab_Octave_API/___librador/librador/librador.h @@ -13,6 +13,7 @@ int LIBRADORSHARED_EXPORT librador_avr_debug(); //a1 int LIBRADORSHARED_EXPORT librador_update_signal_gen_settings(int channel, unsigned char* sampleBuffer, int numSamples, double usecs_between_samples, double amplitude_v, double offset_v); int LIBRADORSHARED_EXPORT librador_send_signal_gen_settings(int channel); +int LIBRADORSHARED_EXPORT librador_send_sin_wave(int channel, double frequency_Hz, double amplitude_v, double offset_v); //a2 ////As above //a3 diff --git a/Matlab_Octave_API/___librador/librador/usbcallhandler.cpp b/Matlab_Octave_API/___librador/librador/usbcallhandler.cpp index f9ee6712..9fe8fac9 100644 --- a/Matlab_Octave_API/___librador/librador/usbcallhandler.cpp +++ b/Matlab_Octave_API/___librador/librador/usbcallhandler.cpp @@ -387,16 +387,16 @@ int usbCallHandler::update_function_gen_settings(int channel, unsigned char *sam amplitude_v = amplitude_v / 3; offset_v = offset_v / 3; if(channel == 1){ - fGenTriple |= 0b00000010; //This is correct. Somehow the channels got switched around on the board's firmware and this is a duct-tape solution. + fGenTriple |= 0b00000001; } else { - fGenTriple |= 0x00000001; + fGenTriple |= 0b00000010; } } else { if(channel == 1){ - fGenTriple &= 0b11111101; - } else { fGenTriple &= 0b11111110; + } else { + fGenTriple &= 0b11111101; } } @@ -447,7 +447,7 @@ int usbCallHandler::send_function_gen_settings(int channel){ if(functionGen_CH2.numSamples == 0){ return -1; //Channel not initialised } - send_control_transfer_with_error_checks(0x40, 0xa1, functionGen_CH1.timerPeriod, functionGen_CH1.clockDividerSetting, functionGen_CH1.numSamples, functionGen_CH1.samples); + send_control_transfer_with_error_checks(0x40, 0xa1, functionGen_CH2.timerPeriod, functionGen_CH2.clockDividerSetting, functionGen_CH2.numSamples, functionGen_CH2.samples); } else { return -2; //Invalid channel } diff --git a/Matlab_Octave_API/___librador/librador/usbcallhandler.h b/Matlab_Octave_API/___librador/librador/usbcallhandler.h index c9f62fd9..6476b0c9 100644 --- a/Matlab_Octave_API/___librador/librador/usbcallhandler.h +++ b/Matlab_Octave_API/___librador/librador/usbcallhandler.h @@ -6,7 +6,7 @@ #include #define NUM_ISO_ENDPOINTS (1) -#define NUM_FUTURE_CTX (8) +#define NUM_FUTURE_CTX (4) #define ISO_PACKET_SIZE (750) #define ISO_PACKETS_PER_CTX (33) #define MAX_SUPPORTED_DEVICE_MODE (7)